Skip to content

Commit fa43041

Browse files
committed
Add jsx-sort-props ignoreTags option
1 parent 1185b37 commit fa43041

File tree

3 files changed

+42
-0
lines changed

3 files changed

+42
-0
lines changed

docs/rules/jsx-sort-props.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,16 @@ With `reservedFirst: ["key"]`, the following will **not** warn:
9898
<Hello key={'uuid'} name="John" ref="ref" />
9999
```
100100

101+
### `ignoreTags`
102+
103+
An array of element (tag) names to ignore when checking the properties order.
104+
105+
With `ignoreTags: ["Can"]`, the following will **not** warn:
106+
107+
```jsx
108+
<Can i="create" a="post" />
109+
```
110+
101111
## When not to use
102112

103113
This rule is a formatting preference and not following it won't negatively affect the quality of your code. If alphabetizing props isn't a part of your coding standards, then you can leave this rule off.

lib/rules/jsx-sort-props.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,9 @@ module.exports = {
249249
},
250250
reservedFirst: {
251251
type: ['array', 'boolean']
252+
},
253+
ignoreTags: {
254+
type: 'array'
252255
}
253256
},
254257
additionalProperties: false
@@ -265,9 +268,27 @@ module.exports = {
265268
const reservedFirst = configuration.reservedFirst || false;
266269
const reservedFirstError = validateReservedFirstConfig(context, reservedFirst);
267270
let reservedList = Array.isArray(reservedFirst) ? reservedFirst : RESERVED_PROPS_LIST;
271+
const ignoreTags = configuration.ignoreTags || [];
272+
const getTagNameFromMemberExpression = (node) => `${node.property.parent.object.name}.${node.property.name}`;
268273

269274
return {
270275
JSXOpeningElement(node) {
276+
if (ignoreTags.length > 0) {
277+
const jsxOpeningElement = node.name;
278+
const type = jsxOpeningElement.type;
279+
let tagName;
280+
if (type === 'JSXIdentifier') {
281+
tagName = jsxOpeningElement.name;
282+
} else if (type === 'JSXMemberExpression') {
283+
tagName = getTagNameFromMemberExpression(jsxOpeningElement);
284+
} else {
285+
tagName = undefined;
286+
}
287+
if (tagName && ignoreTags.includes(tagName)) {
288+
return;
289+
}
290+
}
291+
271292
// `dangerouslySetInnerHTML` is only "reserved" on DOM components
272293
if (reservedFirst && !jsxUtil.isDOMComponent(node)) {
273294
reservedList = reservedList.filter((prop) => prop !== 'dangerouslySetInnerHTML');

tests/lib/rules/jsx-sort-props.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ const reservedFirstAsEmptyArrayArgs = [{
9999
const reservedFirstAsInvalidArrayArgs = [{
100100
reservedFirst: ['notReserved']
101101
}];
102+
const ignoreTagsApp = [{
103+
ignoreTags: ['App']
104+
}];
102105

103106
ruleTester.run('jsx-sort-props', rule, {
104107
valid: [
@@ -165,6 +168,10 @@ ruleTester.run('jsx-sort-props', rule, {
165168
{
166169
code: '<App key="key" c="c" b />',
167170
options: reservedFirstWithShorthandLast
171+
},
172+
{
173+
code: '<App c b a />;',
174+
options: ignoreTagsApp
168175
}
169176
],
170177
invalid: [
@@ -484,6 +491,10 @@ ruleTester.run('jsx-sort-props', rule, {
484491
code: '<App key={5} />',
485492
options: reservedFirstAsInvalidArrayArgs,
486493
errors: [expectedInvalidReservedFirstError]
494+
},
495+
{
496+
code: '<NoApp c b a />;',
497+
options: ignoreTagsApp
487498
}
488499
]
489500
});

0 commit comments

Comments
 (0)