Skip to content

Commit d6cc5d1

Browse files
committed
Merge with master
1 parent a81ab29 commit d6cc5d1

File tree

5 files changed

+582
-56
lines changed

5 files changed

+582
-56
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,14 @@ In order to whitelist all *browser-like* globals, add `react-native/react-native
6464
}
6565
```
6666

67+
To use another stylesheet providers.
68+
69+
```json
70+
settings: {
71+
'react-native/style-sheet-object-names': ['EStyleSheet', 'OtherStyleSheet', 'PStyleSheet']
72+
}
73+
```
74+
6775
Finally, enable all of the rules that you would like to use.
6876

6977
```json

lib/rules/no-unused-styles.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@ module.exports = Components.detect((context, components) => {
4141
}
4242
},
4343

44-
VariableDeclarator: function (node) {
45-
if (astHelpers.isStyleSheetDeclaration(node.init, context.settings)) {
44+
CallExpression: function (node) {
45+
if (astHelpers.isStyleSheetDeclaration(node, context.settings)) {
4646
const styleSheetName = astHelpers.getStyleSheetName(node);
47-
const styles = astHelpers.getStyleDeclarations(node.init);
47+
const styles = astHelpers.getStyleDeclarations(node);
4848

4949
styleSheets.add(styleSheetName, styles);
5050
}

lib/rules/sort-styles.js

Lines changed: 69 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@
1212
const { astHelpers } = require('../util/stylesheet');
1313

1414
const {
15-
getStyleDeclarations,
15+
getStyleDeclarationsChunks,
16+
getPropertiesChunks,
1617
getStylePropertyIdentifier,
1718
isStyleSheetDeclaration,
19+
isEitherShortHand,
1820
} = astHelpers;
1921

2022
//------------------------------------------------------------------------------
@@ -28,13 +30,54 @@ module.exports = (context) => {
2830
const ignoreStyleProperties = options.ignoreStyleProperties;
2931
const isValidOrder = order === 'asc' ? (a, b) => a <= b : (a, b) => a >= b;
3032

31-
function report(type, node, prev, current) {
33+
const sourceCode = context.getSourceCode();
34+
35+
function sort(array) {
36+
return [].concat(array).sort((a, b) => {
37+
const identifierA = getStylePropertyIdentifier(a);
38+
const identifierB = getStylePropertyIdentifier(b);
39+
40+
let sortOrder = 0;
41+
if (isEitherShortHand(identifierA, identifierB)) {
42+
return a.range[0] - b.range[0];
43+
} else if (identifierA < identifierB) {
44+
sortOrder = -1;
45+
} else if (identifierA > identifierB) {
46+
sortOrder = 1;
47+
}
48+
return sortOrder * (order === 'asc' ? 1 : -1);
49+
});
50+
}
51+
52+
function report(array, type, node, prev, current) {
3253
const currentName = getStylePropertyIdentifier(current);
3354
const prevName = getStylePropertyIdentifier(prev);
55+
const hasComments = array
56+
.map(prop => sourceCode.getComments(prop))
57+
.reduce(
58+
(hasComment, comment) =>
59+
hasComment || comment.leading.length > 0 || comment.trailing > 0,
60+
false
61+
);
62+
3463
context.report({
3564
node,
3665
message: `Expected ${type} to be in ${order}ending order. '${currentName}' should be before '${prevName}'.`,
3766
loc: current.key.loc,
67+
fix: hasComments ? undefined : (fixer) => {
68+
const sortedArray = sort(array);
69+
return array
70+
.map((item, i) => {
71+
if (item !== sortedArray[i]) {
72+
return fixer.replaceText(
73+
item,
74+
sourceCode.getText(sortedArray[i])
75+
);
76+
}
77+
return null;
78+
})
79+
.filter(Boolean);
80+
},
3881
});
3982
}
4083

@@ -50,8 +93,15 @@ module.exports = (context) => {
5093
const prevName = getStylePropertyIdentifier(previous);
5194
const currentName = getStylePropertyIdentifier(current);
5295

96+
if (
97+
arrayName === 'style properties' &&
98+
isEitherShortHand(prevName, currentName)
99+
) {
100+
return;
101+
}
102+
53103
if (!isValidOrder(prevName, currentName)) {
54-
return report(arrayName, node, previous, current);
104+
return report(array, arrayName, node, previous, current);
55105
}
56106
}
57107
}
@@ -62,26 +112,33 @@ module.exports = (context) => {
62112
return;
63113
}
64114

65-
const classDefinitions = getStyleDeclarations(node);
115+
const classDefinitionsChunks = getStyleDeclarationsChunks(node);
66116

67117
if (!ignoreClassNames) {
68-
checkIsSorted(classDefinitions, 'class names', node);
118+
classDefinitionsChunks.forEach((classDefinitions) => {
119+
checkIsSorted(classDefinitions, 'class names', node);
120+
});
69121
}
70122

71123
if (ignoreStyleProperties) return;
72124

73-
classDefinitions.forEach((classDefinition) => {
74-
const styleProperties = classDefinition.value.properties;
75-
if (!styleProperties || styleProperties.length < 2) {
76-
return;
77-
}
78-
79-
checkIsSorted(styleProperties, 'style properties', node);
125+
classDefinitionsChunks.forEach((classDefinitions) => {
126+
classDefinitions.forEach((classDefinition) => {
127+
const styleProperties = classDefinition.value.properties;
128+
if (!styleProperties || styleProperties.length < 2) {
129+
return;
130+
}
131+
const stylePropertyChunks = getPropertiesChunks(styleProperties);
132+
stylePropertyChunks.forEach((stylePropertyChunk) => {
133+
checkIsSorted(stylePropertyChunk, 'style properties', node);
134+
});
135+
});
80136
});
81137
},
82138
};
83139
};
84140

141+
module.exports.fixable = 'code';
85142
module.exports.schema = [
86143
{
87144
enum: ['asc', 'desc'],

lib/util/stylesheet.js

Lines changed: 61 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,6 @@ const astHelpers = {
109109

110110
containsCreateCall: function (node) {
111111
return Boolean(
112-
node &&
113112
node &&
114113
node.callee &&
115114
node.callee.property &&
@@ -127,30 +126,74 @@ const astHelpers = {
127126
},
128127

129128
getStyleSheetName: function (node) {
129+
if (node && node.parent && node.parent.id) {
130+
return node.parent.id.name;
131+
}
132+
},
133+
134+
getStyleDeclarations: function (node) {
130135
if (
131136
node &&
132-
node.id
137+
node.type === 'CallExpression' &&
138+
node.arguments &&
139+
node.arguments[0] &&
140+
node.arguments[0].properties
133141
) {
134-
return node.id.name;
142+
return node.arguments[0].properties.filter(property => property.type === 'Property');
135143
}
144+
145+
return [];
136146
},
137147

138-
getStyleDeclarations: function (node) {
148+
getStyleDeclarationsChunks: function (node) {
139149
if (
140150
node &&
151+
node.type === 'CallExpression' &&
141152
node.arguments &&
142153
node.arguments[0] &&
143154
node.arguments[0].properties
144155
) {
145-
return node
146-
.arguments[0]
147-
.properties
148-
.filter(property => property.type === 'Property');
156+
const properties = node.arguments[0].properties;
157+
158+
const result = [];
159+
let chunk = [];
160+
for (let i = 0; i < properties.length; i += 1) {
161+
const property = properties[i];
162+
if (property.type === 'Property') {
163+
chunk.push(property);
164+
} else if (chunk.length) {
165+
result.push(chunk);
166+
chunk = [];
167+
}
168+
}
169+
if (chunk.length) {
170+
result.push(chunk);
171+
}
172+
173+
return result;
149174
}
150175

151176
return [];
152177
},
153178

179+
getPropertiesChunks: function (properties) {
180+
const result = [];
181+
let chunk = [];
182+
for (let i = 0; i < properties.length; i += 1) {
183+
const property = properties[i];
184+
if (property.type === 'Property') {
185+
chunk.push(property);
186+
} else if (chunk.length) {
187+
result.push(chunk);
188+
chunk = [];
189+
}
190+
}
191+
if (chunk.length) {
192+
result.push(chunk);
193+
}
194+
return result;
195+
},
196+
154197
getExpressionIdentifier: function (node) {
155198
if (node) {
156199
switch (node.type) {
@@ -435,6 +478,16 @@ const astHelpers = {
435478
return [node.object.name, node.property.name].join('.');
436479
}
437480
},
481+
482+
isEitherShortHand: function (property1, property2) {
483+
const shorthands = ['margin', 'padding', 'border', 'flex'];
484+
if (shorthands.includes(property1)) {
485+
return property2.startsWith(property1);
486+
} else if (shorthands.includes(property2)) {
487+
return property1.startsWith(property2);
488+
}
489+
return false;
490+
},
438491
};
439492

440493
module.exports.astHelpers = astHelpers;

0 commit comments

Comments
 (0)