Skip to content

Commit

Permalink
[New] jsx-handler-names: support ignoring component names
Browse files Browse the repository at this point in the history
  • Loading branch information
akulsr0 authored and ljharb committed Jun 21, 2024
1 parent 6ce58e5 commit 6a83d67
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
* export flat configs from plugin root and fix flat config crash ([#3694][] @bradzacher @mdjermanovic)
* add [`jsx-props-no-spread-multi`] ([#3724][] @SimonSchick)
* [`forbid-component-props`]: add `propNamePattern` to allow / disallow prop name patterns ([#3774][] @akulsr0)
* [`jsx-handler-names`]: support ignoring component names ([#3772][] @akulsr0)

[#3774]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3774
[#3772]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3772
[#3759]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3759
[#3724]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3724
[#3694]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3694
Expand Down
4 changes: 3 additions & 1 deletion docs/rules/jsx-handler-names.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ Examples of **correct** code for this rule:
"eventHandlerPrefix": <eventHandlerPrefix>,
"eventHandlerPropPrefix": <eventHandlerPropPrefix>,
"checkLocalVariables": <boolean>,
"checkInlineFunction": <boolean>
"checkInlineFunction": <boolean>,
"ignoreComponentNames": Array<string>
}]
...
```
Expand All @@ -43,6 +44,7 @@ Examples of **correct** code for this rule:
- `eventHandlerPropPrefix`: Prefix for props that are used as event handlers. Defaults to `on`
- `checkLocalVariables`: Determines whether event handlers stored as local variables are checked. Defaults to `false`
- `checkInlineFunction`: Determines whether event handlers set as inline functions are checked. Defaults to `false`
- `ignoreComponentNames`: Array of glob strings, when matched with component name, ignores the rule on that component. Defaults to `[]`

## When Not To Use It

Expand Down
36 changes: 36 additions & 0 deletions lib/rules/jsx-handler-names.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

'use strict';

const minimatch = require('minimatch');
const docsUrl = require('../util/docsUrl');
const getText = require('../util/eslint').getText;
const report = require('../util/report');
Expand Down Expand Up @@ -39,6 +40,11 @@ module.exports = {
eventHandlerPropPrefix: { type: 'string' },
checkLocalVariables: { type: 'boolean' },
checkInlineFunction: { type: 'boolean' },
ignoreComponentNames: {
type: 'array',
uniqueItems: true,
items: { type: 'string' },
},
},
additionalProperties: false,
}, {
Expand All @@ -51,6 +57,11 @@ module.exports = {
},
checkLocalVariables: { type: 'boolean' },
checkInlineFunction: { type: 'boolean' },
ignoreComponentNames: {
type: 'array',
uniqueItems: true,
items: { type: 'string' },
},
},
additionalProperties: false,
}, {
Expand All @@ -63,6 +74,11 @@ module.exports = {
eventHandlerPropPrefix: { type: 'string' },
checkLocalVariables: { type: 'boolean' },
checkInlineFunction: { type: 'boolean' },
ignoreComponentNames: {
type: 'array',
uniqueItems: true,
items: { type: 'string' },
},
},
additionalProperties: false,
}, {
Expand All @@ -78,6 +94,16 @@ module.exports = {
},
additionalProperties: false,
},
{
type: 'object',
properties: {
ignoreComponentNames: {
type: 'array',
uniqueItems: true,
items: { type: 'string' },
},
},
},
],
}],
},
Expand Down Expand Up @@ -111,8 +137,17 @@ module.exports = {

const checkInlineFunction = !!configuration.checkInlineFunction;

const ignoreComponentNames = configuration.ignoreComponentNames || [];

return {
JSXAttribute(node) {
const componentName = node.parent.name.name;

const isComponentNameIgnored = ignoreComponentNames.some((ignoredComponentNamePattern) => {
const isIgnored = minimatch(componentName, ignoredComponentNamePattern);
return isIgnored;
});

if (
!node.value
|| !node.value.expression
Expand All @@ -124,6 +159,7 @@ module.exports = {
: !node.value.expression.object
)
)
|| isComponentNameIgnored
) {
return;
}
Expand Down
46 changes: 46 additions & 0 deletions tests/lib/rules/jsx-handler-names.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,24 @@ ruleTester.run('jsx-handler-names', rule, {
code: '<TestComponent someProp={props.onChange} />',
options: [{ eventHandlerPropPrefix: false }],
},
{
code: '<ComponentFromOtherLibraryBar customPropNameBar={handleSomething} />;',
options: [{ checkLocalVariables: true, ignoreComponentNames: ['ComponentFromOtherLibraryBar'] }],
},
{
code: `
function App() {
return (
<div>
<MyLibInput customPropNameBar={handleSomething} />;
<MyLibCheckbox customPropNameBar={handleSomething} />;
<MyLibButtom customPropNameBar={handleSomething} />;
</div>
)
}
`,
options: [{ checkLocalVariables: true, ignoreComponentNames: ['MyLib*'] }],
},
]),

invalid: parsers.all([
Expand Down Expand Up @@ -369,5 +387,33 @@ ruleTester.run('jsx-handler-names', rule, {
},
],
},
{
code: `
function App() {
return (
<div>
<MyLibInput customPropNameBar={handleInput} />;
<MyLibCheckbox customPropNameBar={handleCheckbox} />;
<MyLibButtom customPropNameBar={handleButton} />;
</div>
)
}
`,
options: [{ checkLocalVariables: true, ignoreComponentNames: ['MyLibrary*'] }],
errors: [
{
messageId: 'badPropKey',
data: { propValue: 'handleInput', handlerPropPrefix: 'on' },
},
{
messageId: 'badPropKey',
data: { propValue: 'handleCheckbox', handlerPropPrefix: 'on' },
},
{
messageId: 'badPropKey',
data: { propValue: 'handleButton', handlerPropPrefix: 'on' },
},
],
},
]),
});

0 comments on commit 6a83d67

Please sign in to comment.