Skip to content

Commit 6a83d67

Browse files
akulsr0ljharb
authored andcommitted
[New] jsx-handler-names: support ignoring component names
1 parent 6ce58e5 commit 6a83d67

File tree

4 files changed

+87
-1
lines changed

4 files changed

+87
-1
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
1010
* export flat configs from plugin root and fix flat config crash ([#3694][] @bradzacher @mdjermanovic)
1111
* add [`jsx-props-no-spread-multi`] ([#3724][] @SimonSchick)
1212
* [`forbid-component-props`]: add `propNamePattern` to allow / disallow prop name patterns ([#3774][] @akulsr0)
13+
* [`jsx-handler-names`]: support ignoring component names ([#3772][] @akulsr0)
1314

1415
[#3774]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3774
16+
[#3772]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3772
1517
[#3759]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3759
1618
[#3724]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3724
1719
[#3694]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3694

docs/rules/jsx-handler-names.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ Examples of **correct** code for this rule:
3434
"eventHandlerPrefix": <eventHandlerPrefix>,
3535
"eventHandlerPropPrefix": <eventHandlerPropPrefix>,
3636
"checkLocalVariables": <boolean>,
37-
"checkInlineFunction": <boolean>
37+
"checkInlineFunction": <boolean>,
38+
"ignoreComponentNames": Array<string>
3839
}]
3940
...
4041
```
@@ -43,6 +44,7 @@ Examples of **correct** code for this rule:
4344
- `eventHandlerPropPrefix`: Prefix for props that are used as event handlers. Defaults to `on`
4445
- `checkLocalVariables`: Determines whether event handlers stored as local variables are checked. Defaults to `false`
4546
- `checkInlineFunction`: Determines whether event handlers set as inline functions are checked. Defaults to `false`
47+
- `ignoreComponentNames`: Array of glob strings, when matched with component name, ignores the rule on that component. Defaults to `[]`
4648

4749
## When Not To Use It
4850

lib/rules/jsx-handler-names.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
'use strict';
77

8+
const minimatch = require('minimatch');
89
const docsUrl = require('../util/docsUrl');
910
const getText = require('../util/eslint').getText;
1011
const report = require('../util/report');
@@ -39,6 +40,11 @@ module.exports = {
3940
eventHandlerPropPrefix: { type: 'string' },
4041
checkLocalVariables: { type: 'boolean' },
4142
checkInlineFunction: { type: 'boolean' },
43+
ignoreComponentNames: {
44+
type: 'array',
45+
uniqueItems: true,
46+
items: { type: 'string' },
47+
},
4248
},
4349
additionalProperties: false,
4450
}, {
@@ -51,6 +57,11 @@ module.exports = {
5157
},
5258
checkLocalVariables: { type: 'boolean' },
5359
checkInlineFunction: { type: 'boolean' },
60+
ignoreComponentNames: {
61+
type: 'array',
62+
uniqueItems: true,
63+
items: { type: 'string' },
64+
},
5465
},
5566
additionalProperties: false,
5667
}, {
@@ -63,6 +74,11 @@ module.exports = {
6374
eventHandlerPropPrefix: { type: 'string' },
6475
checkLocalVariables: { type: 'boolean' },
6576
checkInlineFunction: { type: 'boolean' },
77+
ignoreComponentNames: {
78+
type: 'array',
79+
uniqueItems: true,
80+
items: { type: 'string' },
81+
},
6682
},
6783
additionalProperties: false,
6884
}, {
@@ -78,6 +94,16 @@ module.exports = {
7894
},
7995
additionalProperties: false,
8096
},
97+
{
98+
type: 'object',
99+
properties: {
100+
ignoreComponentNames: {
101+
type: 'array',
102+
uniqueItems: true,
103+
items: { type: 'string' },
104+
},
105+
},
106+
},
81107
],
82108
}],
83109
},
@@ -111,8 +137,17 @@ module.exports = {
111137

112138
const checkInlineFunction = !!configuration.checkInlineFunction;
113139

140+
const ignoreComponentNames = configuration.ignoreComponentNames || [];
141+
114142
return {
115143
JSXAttribute(node) {
144+
const componentName = node.parent.name.name;
145+
146+
const isComponentNameIgnored = ignoreComponentNames.some((ignoredComponentNamePattern) => {
147+
const isIgnored = minimatch(componentName, ignoredComponentNamePattern);
148+
return isIgnored;
149+
});
150+
116151
if (
117152
!node.value
118153
|| !node.value.expression
@@ -124,6 +159,7 @@ module.exports = {
124159
: !node.value.expression.object
125160
)
126161
)
162+
|| isComponentNameIgnored
127163
) {
128164
return;
129165
}

tests/lib/rules/jsx-handler-names.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,24 @@ ruleTester.run('jsx-handler-names', rule, {
181181
code: '<TestComponent someProp={props.onChange} />',
182182
options: [{ eventHandlerPropPrefix: false }],
183183
},
184+
{
185+
code: '<ComponentFromOtherLibraryBar customPropNameBar={handleSomething} />;',
186+
options: [{ checkLocalVariables: true, ignoreComponentNames: ['ComponentFromOtherLibraryBar'] }],
187+
},
188+
{
189+
code: `
190+
function App() {
191+
return (
192+
<div>
193+
<MyLibInput customPropNameBar={handleSomething} />;
194+
<MyLibCheckbox customPropNameBar={handleSomething} />;
195+
<MyLibButtom customPropNameBar={handleSomething} />;
196+
</div>
197+
)
198+
}
199+
`,
200+
options: [{ checkLocalVariables: true, ignoreComponentNames: ['MyLib*'] }],
201+
},
184202
]),
185203

186204
invalid: parsers.all([
@@ -369,5 +387,33 @@ ruleTester.run('jsx-handler-names', rule, {
369387
},
370388
],
371389
},
390+
{
391+
code: `
392+
function App() {
393+
return (
394+
<div>
395+
<MyLibInput customPropNameBar={handleInput} />;
396+
<MyLibCheckbox customPropNameBar={handleCheckbox} />;
397+
<MyLibButtom customPropNameBar={handleButton} />;
398+
</div>
399+
)
400+
}
401+
`,
402+
options: [{ checkLocalVariables: true, ignoreComponentNames: ['MyLibrary*'] }],
403+
errors: [
404+
{
405+
messageId: 'badPropKey',
406+
data: { propValue: 'handleInput', handlerPropPrefix: 'on' },
407+
},
408+
{
409+
messageId: 'badPropKey',
410+
data: { propValue: 'handleCheckbox', handlerPropPrefix: 'on' },
411+
},
412+
{
413+
messageId: 'badPropKey',
414+
data: { propValue: 'handleButton', handlerPropPrefix: 'on' },
415+
},
416+
],
417+
},
372418
]),
373419
});

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy