Skip to content

Commit

Permalink
Change multiline property from exclusive booleans to enums
Browse files Browse the repository at this point in the history
  • Loading branch information
duhamelgm committed Feb 6, 2022
1 parent 7b53c41 commit 39b452b
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 36 deletions.
23 changes: 13 additions & 10 deletions docs/rules/jsx-sort-props.md
Expand Up @@ -29,8 +29,7 @@ Examples of **correct** code for this rule:
"callbacksLast": <boolean>,
"shorthandFirst": <boolean>,
"shorthandLast": <boolean>,
"multilineFirst": <boolean>,
"multilineLast": <boolean>,
"multiline": "ignore" | "first" | "last",
"ignoreCase": <boolean>,
"noSortAlphabetically": <boolean>,
"reservedFirst": <boolean>|<array<string>>,
Expand Down Expand Up @@ -72,11 +71,20 @@ When `true`, short hand props must be listed after all other props (unless `call
<Hello name="John" tel={5555555} active validate />
```

### `multilineFirst`
### `multiline`

When `true`, multiline props must be listed before all other props (unless `shorthandFirst` is set), but still respecting the alphabetical order:
Enforced sorting for multiline props

* `ignore`: Multiline props will not be taken in consideration for sorting.

* `first`: Multiline props must be listed before all other props (unless `shorthandFirst` is set), but still respecting the alphabetical order.

* `last`: Multiline props must be listed after all other props (unless either `callbacksLast` or `shorthandLast` are set), but still respecting the alphabetical order.

Defaults to `ignore`.

```jsx
// 'jsx-sort-props': [1, { multiline: 'first' }]
<Hello
classes={{
greetings: classes.greetings,
Expand All @@ -86,13 +94,8 @@ When `true`, multiline props must be listed before all other props (unless `shor
name="John"
tel={5555555}
/>
```

### `multilineLast`

When `true`, multiline props must be listed after all other props (unless either `callbacksLast` or `shorthandLast` are set), but still respecting the alphabetical order:

```jsx
// 'jsx-sort-props': [1, { multiline: 'last' }]
<Hello
active
validate
Expand Down
31 changes: 12 additions & 19 deletions lib/rules/jsx-sort-props.js
Expand Up @@ -81,8 +81,8 @@ function contextCompare(a, b, options) {
}
}

if (options.multilineFirst || options.multilineLast) {
const multilineSign = options.multilineFirst ? -1 : 1;
if (options.multiline === 'first' || options.multiline === 'last') {
const multilineSign = options.multiline === 'first' ? -1 : 1;
const aIsMultiline = isMultilineProp(a);
const bIsMultiline = isMultilineProp(b);
if (aIsMultiline && !bIsMultiline) {
Expand Down Expand Up @@ -145,8 +145,7 @@ const generateFixerFunction = (node, context, reservedList) => {
const callbacksLast = configuration.callbacksLast || false;
const shorthandFirst = configuration.shorthandFirst || false;
const shorthandLast = configuration.shorthandLast || false;
const multilineFirst = configuration.multilineFirst || false;
const multilineLast = configuration.multilineLast || false;
const multiline = configuration.multiline || 'ignore';
const noSortAlphabetically = configuration.noSortAlphabetically || false;
const reservedFirst = configuration.reservedFirst || false;

Expand All @@ -158,8 +157,7 @@ const generateFixerFunction = (node, context, reservedList) => {
callbacksLast,
shorthandFirst,
shorthandLast,
multilineFirst,
multilineLast,
multiline,
noSortAlphabetically,
reservedFirst,
reservedList,
Expand Down Expand Up @@ -263,13 +261,9 @@ module.exports = {
shorthandLast: {
type: 'boolean',
},
// Whether multiline properties should be listed first
multilineFirst: {
type: 'boolean',
},
// Whether multiline properties should be listed last
multilineLast: {
type: 'boolean',
// Whether multiline properties should be listed first or last
multiline: {
enum: ['ignore', 'first', 'last'],
},
ignoreCase: {
type: 'boolean',
Expand All @@ -292,8 +286,7 @@ module.exports = {
const callbacksLast = configuration.callbacksLast || false;
const shorthandFirst = configuration.shorthandFirst || false;
const shorthandLast = configuration.shorthandLast || false;
const multilineFirst = configuration.multilineFirst || false;
const multilineLast = configuration.multilineLast || false;
const multiline = configuration.multiline || 'ignore';
const noSortAlphabetically = configuration.noSortAlphabetically || false;
const reservedFirst = configuration.reservedFirst || false;
const reservedFirstError = validateReservedFirstConfig(context, reservedFirst);
Expand Down Expand Up @@ -367,7 +360,7 @@ module.exports = {
}
if (!currentValue && previousValue) {
report(context, messages.listShorthandFirst, 'listShorthandFirst', {
node: memo.name,
node: decl.name,
fix: generateFixerFunction(node, context, reservedList),
});
return memo;
Expand All @@ -387,22 +380,22 @@ module.exports = {
}
}

if (multilineFirst) {
if (multiline === 'first') {
if (previousIsMultiline && !currentIsMultiline) {
// Exiting the multiline prop section
return decl;
}
if (!previousIsMultiline && currentIsMultiline) {
// Encountered a non-multiline prop before a multiline prop
report(context, messages.listMultilineFirst, 'listMultilineFirst', {
node: memo.name,
node: decl.name,
fix: generateFixerFunction(node, context, reservedList),
});
return memo;
}
}

if (multilineLast) {
if (multiline === 'last') {
if (!previousIsMultiline && currentIsMultiline) {
// Entering the multiline prop section
return decl;
Expand Down
58 changes: 51 additions & 7 deletions tests/lib/rules/jsx-sort-props.js
Expand Up @@ -103,17 +103,17 @@ const reservedFirstWithShorthandLast = [
];
const reservedFirstAsEmptyArrayArgs = [{ reservedFirst: [] }];
const reservedFirstAsInvalidArrayArgs = [{ reservedFirst: ['notReserved'] }];
const multilineFirstArgs = [{ multilineFirst: true }];
const multilineFirstArgs = [{ multiline: 'first' }];
const multilineAndShorthandFirstArgs = [
{
multilineFirst: true,
multiline: 'first',
shorthandFirst: true,
},
];
const multilineLastArgs = [{ multilineLast: true }];
const multilineLastArgs = [{ multiline: 'last' }];
const multilineAndShorthandAndCallbackLastArgs = [
{
multilineLast: true,
multiline: 'last',
shorthandLast: true,
callbacksLast: true,
},
Expand Down Expand Up @@ -680,6 +680,7 @@ ruleTester.run('jsx-sort-props', rule, {
aA: 1,
}}
b
inline={1}
onClick={() => ({
c: 1
})}
Expand All @@ -691,10 +692,28 @@ ruleTester.run('jsx-sort-props', rule, {
/>
`,
options: multilineAndShorthandAndCallbackLastArgs,
errors: 3,
errors: [
{
messageId: 'listShorthandLast',
line: 6,
},
{
messageId: 'listCallbacksLast',
line: 8,
},
{
messageId: 'listCallbacksLast',
line: 8,
},
{
messageId: 'listCallbacksLast',
line: 8,
},
],
output: `
<App
d="dD"
inline={1}
a={{
aA: 1,
}}
Expand Down Expand Up @@ -738,7 +757,7 @@ ruleTester.run('jsx-sort-props', rule, {
`,
options: [
{
multilineLast: true,
multiline: 'last',
shorthandFirst: true,
callbacksLast: true,
reservedFirst: true,
Expand Down Expand Up @@ -771,7 +790,32 @@ ruleTester.run('jsx-sort-props', rule, {
{...rest}
/>
`,
errors: 6,
errors: [
{
messageId: 'listMultilineLast',
line: 4,
},
{
messageId: 'listMultilineLast',
line: 4,
},
{
messageId: 'listReservedPropsFirst',
line: 12,
},
{
messageId: 'listShorthandFirst',
line: 13,
},
{
messageId: 'listCallbacksLast',
line: 19,
},
{
messageId: 'listCallbacksLast',
line: 19,
},
],
},
]),
});

0 comments on commit 39b452b

Please sign in to comment.