diff --git a/lib/rules/jsx-sort-props.js b/lib/rules/jsx-sort-props.js
index 10ca976af3..cb09747bb7 100644
--- a/lib/rules/jsx-sort-props.js
+++ b/lib/rules/jsx-sort-props.js
@@ -40,11 +40,21 @@ function isReservedPropName(name, list) {
return list.indexOf(name) >= 0;
}
-function alphabeticalCompare(a, b, ignoreCase) {
- if (ignoreCase) {
+function propNameCompare(a, b, options) {
+ if (options.ignoreCase) {
a = a.toLowerCase();
b = b.toLowerCase();
}
+ if (options.reservedFirst) {
+ const aIsReserved = isReservedPropName(a, options.reservedList);
+ const bIsReserved = isReservedPropName(b, options.reservedList);
+ if ((aIsReserved && bIsReserved) || (!aIsReserved && !bIsReserved)) {
+ return a.localeCompare(b);
+ } else if (aIsReserved && !bIsReserved) {
+ return -1;
+ }
+ return 1;
+ }
return a.localeCompare(b);
}
@@ -77,11 +87,12 @@ function getGroupsOfSortableAttributes(attributes) {
return sortableAttributeGroups;
}
-const generateFixerFunction = (node, context) => {
+const generateFixerFunction = (node, context, reservedList) => {
const sourceCode = context.getSourceCode();
const attributes = node.attributes.slice(0);
const configuration = context.options[0] || {};
const ignoreCase = configuration.ignoreCase || false;
+ const reservedFirst = configuration.reservedFirst || false;
// Sort props according to the context. Only supports ignoreCase.
// Since we cannot safely move JSXSpreadAttribute (due to potential variable overrides),
@@ -89,7 +100,7 @@ const generateFixerFunction = (node, context) => {
const sortableAttributeGroups = getGroupsOfSortableAttributes(attributes);
const sortedAttributeGroups = sortableAttributeGroups.slice(0).map(group =>
group.slice(0).sort((a, b) =>
- alphabeticalCompare(propName(a), propName(b), ignoreCase)
+ propNameCompare(propName(a), propName(b), {ignoreCase, reservedFirst, reservedList})
)
);
@@ -235,23 +246,22 @@ module.exports = {
const previousIsReserved = isReservedPropName(previousPropName, reservedList);
const currentIsReserved = isReservedPropName(currentPropName, reservedList);
- if (previousIsReserved && currentIsReserved) {
+ if ((previousIsReserved && currentIsReserved) || (!previousIsReserved && !currentIsReserved)) {
if (!noSortAlphabetically && currentPropName < previousPropName) {
context.report({
node: decl,
message: 'Props should be sorted alphabetically',
- fix: generateFixerFunction(node, context)
+ fix: generateFixerFunction(node, context, reservedList)
});
return memo;
}
- return decl;
}
if (!previousIsReserved && currentIsReserved) {
context.report({
node: decl,
- message: 'Reserved props must be listed before all other props'
+ message: 'Reserved props must be listed before all other props',
+ fix: generateFixerFunction(node, context, reservedList)
});
- return memo;
}
return decl;
}
diff --git a/tests/lib/rules/jsx-sort-props.js b/tests/lib/rules/jsx-sort-props.js
index 4cd54ce7b0..9439d4ea64 100644
--- a/tests/lib/rules/jsx-sort-props.js
+++ b/tests/lib/rules/jsx-sort-props.js
@@ -271,8 +271,21 @@ ruleTester.run('jsx-sort-props', rule, {
errors: [expectedError]
},
{
- code: '',
+ code: '',
options: reservedFirstAsBooleanArgs,
+ output: '',
+ errors: [expectedError]
+ },
+ {
+ code: '',
+ options: reservedFirstAsBooleanArgs,
+ output: '',
+ errors: [expectedError]
+ },
+ {
+ code: '',
+ options: reservedFirstAsBooleanArgs,
+ output: '',
errors: [expectedReservedFirstError]
},
{