Skip to content

Commit 2d1757d

Browse files
committed
Fix order and properties-order weren't recognizing SCSS nested properties
1 parent f9d21e8 commit 2d1757d

File tree

6 files changed

+181
-5
lines changed

6 files changed

+181
-5
lines changed

rules/order/index.js

+12
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,18 @@ function getOrderData(expectedOrder, node) {
321321
&& !node.extendRule
322322
) {
323323
nodeType = 'less-mixins';
324+
} else if (
325+
node.type === 'rule'
326+
&& utils.isScssNestedPropertiesRoot(node)
327+
) {
328+
const prop = node.selector.slice(0, -1);
329+
330+
if (
331+
utils.isStandardSyntaxProperty(prop)
332+
&& !utils.isCustomProperty(prop)
333+
) {
334+
nodeType = 'declarations';
335+
}
324336
} else if (node.type === 'rule') {
325337
nodeType = {
326338
type: 'rule',

rules/order/tests/index.js

+79
Original file line numberDiff line numberDiff line change
@@ -810,3 +810,82 @@ testRule(rule, {
810810
},
811811
],
812812
});
813+
814+
testRule(rule, {
815+
ruleName,
816+
syntax: 'scss',
817+
config: [[
818+
'declarations',
819+
'rules',
820+
]],
821+
822+
accept: [
823+
{
824+
description: 'scss 1',
825+
code: `a {
826+
margin: {
827+
top: 3px;
828+
right: 6px;
829+
bottom: 3px;
830+
left: 7px;
831+
}
832+
padding: 0;
833+
834+
b {}
835+
}`,
836+
},
837+
{
838+
description: 'scss 2',
839+
code: `a {
840+
padding: 0;
841+
margin: {
842+
top: 3px;
843+
right: 6px;
844+
bottom: 3px;
845+
left: 7px;
846+
}
847+
848+
b {}
849+
}`,
850+
},
851+
{
852+
description: 'scss 3',
853+
code: `a {
854+
margin: 0 {
855+
left: 7px;
856+
}
857+
padding: 0;
858+
859+
b {}
860+
}`,
861+
},
862+
],
863+
864+
reject: [
865+
{
866+
description: 'scss 4',
867+
code: `a {
868+
padding: 0;
869+
b {}
870+
margin: {
871+
top: 3px;
872+
right: 6px;
873+
bottom: 3px;
874+
left: 7px;
875+
}
876+
}`,
877+
message: messages.expected('declaration', 'rule'),
878+
},
879+
{
880+
description: 'scss 5',
881+
code: `a {
882+
padding: 0;
883+
b {}
884+
margin: 0 {
885+
left: 7px;
886+
}
887+
}`,
888+
message: messages.expected('declaration', 'rule'),
889+
},
890+
],
891+
});

rules/properties-order/index.js

+20-5
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,15 @@ const rule = function (expectation, options) {
6868
node: child,
6969
};
7070

71-
if (child.type === 'decl') {
72-
const prop = child.prop;
71+
if (
72+
child.type === 'decl'
73+
|| utils.isScssNestedPropertiesRoot(child)
74+
) {
75+
let prop = child.prop;
76+
77+
if (utils.isScssNestedPropertiesRoot(child)) {
78+
prop = child.selector.slice(0, -1);
79+
}
7380

7481
if (
7582
utils.isStandardSyntaxProperty(prop)
@@ -96,11 +103,19 @@ const rule = function (expectation, options) {
96103

97104
allNodesData.push(nodeData);
98105

99-
// current node should be a standard declaration
100106
if (
101107
child.type !== 'decl'
102-
|| !utils.isStandardSyntaxProperty(nodeData.node.prop)
103-
|| utils.isCustomProperty(nodeData.node.prop)
108+
&& !utils.isScssNestedPropertiesRoot(child)
109+
) {
110+
return;
111+
}
112+
113+
// current node should have standard property name
114+
const propertyName = utils.isScssNestedPropertiesRoot(child) ? nodeData.name : nodeData.node.prop;
115+
116+
if (
117+
!utils.isStandardSyntaxProperty(propertyName)
118+
|| utils.isCustomProperty(propertyName)
104119
) {
105120
return;
106121
}

rules/properties-order/tests/flat.js

+56
Original file line numberDiff line numberDiff line change
@@ -309,3 +309,59 @@ testRule(rule, {
309309
message: messages.expected('left', 'margin'),
310310
}],
311311
});
312+
313+
testRule(rule, {
314+
ruleName,
315+
316+
config: [[
317+
'margin',
318+
'padding',
319+
]],
320+
syntax: 'scss',
321+
322+
accept: [
323+
{
324+
code: `a {
325+
margin: {
326+
top: 3px;
327+
right: 6px;
328+
bottom: 3px;
329+
left: 7px;
330+
}
331+
padding: 0;
332+
}`,
333+
},
334+
{
335+
code: `a {
336+
margin: 0 {
337+
left: 7px;
338+
}
339+
padding: 0;
340+
}`,
341+
},
342+
],
343+
344+
reject: [
345+
{
346+
code: `a {
347+
padding: 0;
348+
margin: {
349+
top: 3px;
350+
right: 6px;
351+
bottom: 3px;
352+
left: 7px;
353+
}
354+
}`,
355+
message: messages.expected('margin', 'padding'),
356+
},
357+
{
358+
code: `a {
359+
padding: 0;
360+
margin: 0 {
361+
left: 7px;
362+
}
363+
}`,
364+
message: messages.expected('margin', 'padding'),
365+
},
366+
],
367+
});

utils/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@ module.exports = {
44
isStandardSyntaxProperty: require('./isStandardSyntaxProperty'),
55
isDollarVariable: require('./isDollarVariable'),
66
isAtVariable: require('./isAtVariable'),
7+
isScssNestedPropertiesRoot: require('./isScssNestedPropertiesRoot'),
78
renamedRuleWarning: require('./renamedRuleWarning'),
89
};

utils/isScssNestedPropertiesRoot.js

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/**
2+
* Check whether a rule is a SCSS nested properties root
3+
*
4+
* a {
5+
* margin: { ← nested properties root
6+
* left: 10px;
7+
* }
8+
* }
9+
*/
10+
11+
module.exports = function isScssNestedPropertiesRoot(node) {
12+
return node && node.type === 'rule' && node.selector.slice(-1) === ':';
13+
};

0 commit comments

Comments
 (0)