@master/eslint-plugin-css 2.0.0-beta.182 → 2.0.0-beta.183
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/rules/class-order.js +17 -0
- package/lib/util/ast.js +1 -2
- package/package.json +1 -1
- package/tests/class-order/core.js +112 -0
- package/tests/class-order/svelte.js +25 -0
- package/tests/class-order/vue.js +25 -0
- package/tests/class-order.js +0 -134
package/lib/rules/class-order.js
CHANGED
|
@@ -138,6 +138,14 @@ module.exports = {
|
|
|
138
138
|
start = arg.range[0] + 1
|
|
139
139
|
end = arg.range[1] - 1
|
|
140
140
|
break
|
|
141
|
+
case 'SvelteLiteral':
|
|
142
|
+
originalClassNamesValue = arg.value
|
|
143
|
+
if (originalClassNamesValue === '') {
|
|
144
|
+
return
|
|
145
|
+
}
|
|
146
|
+
start = arg.range[0]
|
|
147
|
+
end = arg.range[1]
|
|
148
|
+
break;
|
|
141
149
|
case 'TemplateElement':
|
|
142
150
|
originalClassNamesValue = arg.value.raw
|
|
143
151
|
if (originalClassNamesValue === '') {
|
|
@@ -223,6 +231,15 @@ module.exports = {
|
|
|
223
231
|
|
|
224
232
|
const scriptVisitor = {
|
|
225
233
|
JSXAttribute: attributeVisitor,
|
|
234
|
+
SvelteAttribute: function (node) {
|
|
235
|
+
if (!node.key?.name) return
|
|
236
|
+
if (!new RegExp(classRegex).test(node.key.name) || skipClassAttribute) {
|
|
237
|
+
return
|
|
238
|
+
}
|
|
239
|
+
for (const eachValue of node.value) {
|
|
240
|
+
sortNodeArgumentValue(node, eachValue)
|
|
241
|
+
}
|
|
242
|
+
},
|
|
226
243
|
TextAttribute: attributeVisitor,
|
|
227
244
|
CallExpression: callExpressionVisitor,
|
|
228
245
|
TaggedTemplateExpression: function (node) {
|
package/lib/util/ast.js
CHANGED
|
@@ -131,8 +131,7 @@ function isLiteralAttributeValue(node) {
|
|
|
131
131
|
if (node.value) {
|
|
132
132
|
switch (node.value.type) {
|
|
133
133
|
case 'Literal':
|
|
134
|
-
|
|
135
|
-
return !/\{|\?|\}/.test(node.value.value)
|
|
134
|
+
return true
|
|
136
135
|
case 'JSXExpressionContainer':
|
|
137
136
|
// className={"..."}
|
|
138
137
|
return node.value.expression.type === 'Literal'
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@master/eslint-plugin-css","scripts":{"test":"mocha tests --recursive --timeout 10000"},"keywords":["mastercss","eslint","eslintplugin"],"license":"MIT","description":"Master CSS ESLint Plugin","author":"Aoyue Design LLC.","funding":"https://css.master.co/docs/donate","homepage":"https://css.master.co","bugs":{"url":"https://github.com/master-co/css/issues"},"repository":{"type":"git","url":"https://github.com/master-co/css.git","directory":"packages/eslint-plugin"},"sideEffects":false,"main":"./lib/index.js","exports":"./lib/index.js","publishConfig":{"access":"public"},"dependencies":{"@master/css":"^2.0.0-beta.
|
|
1
|
+
{"name":"@master/eslint-plugin-css","scripts":{"test":"mocha tests --recursive --timeout 10000","test:file":"mocha tests"},"keywords":["mastercss","eslint","eslintplugin"],"license":"MIT","description":"Master CSS ESLint Plugin","author":"Aoyue Design LLC.","funding":"https://css.master.co/docs/donate","homepage":"https://css.master.co","bugs":{"url":"https://github.com/master-co/css/issues"},"repository":{"type":"git","url":"https://github.com/master-co/css.git","directory":"packages/eslint-plugin"},"sideEffects":false,"main":"./lib/index.js","exports":"./lib/index.js","publishConfig":{"access":"public"},"dependencies":{"@master/css":"^2.0.0-beta.183","explore-config":"^2.2.10","requireindex":"^1.2.0"},"devDependencies":{"@angular-eslint/template-parser":"^16.2.0","@types/node":"^20.6.0","@typescript-eslint/parser":"^5.50.0","eslint":"^7.1.0","mocha":"^10.2.0","svelte-eslint-parser":"^0.33.1","vue-eslint-parser":"^9.3.1"},"version":"2.0.0-beta.183"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Use a consistent orders for the Master CSS classnames, based on property then on variants
|
|
3
|
+
* @author Miles
|
|
4
|
+
*/
|
|
5
|
+
'use strict'
|
|
6
|
+
|
|
7
|
+
// Modified from https://github.com/francoismassart/eslint-plugin-tailwindcss
|
|
8
|
+
|
|
9
|
+
//------------------------------------------------------------------------------
|
|
10
|
+
// Requirements
|
|
11
|
+
//------------------------------------------------------------------------------
|
|
12
|
+
|
|
13
|
+
var rule = require('../../lib/rules/class-order')
|
|
14
|
+
var RuleTester = require('eslint').RuleTester
|
|
15
|
+
var parserOptions = {
|
|
16
|
+
ecmaVersion: 2019,
|
|
17
|
+
sourceType: 'module',
|
|
18
|
+
ecmaFeatures: {
|
|
19
|
+
jsx: true,
|
|
20
|
+
},
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
var ruleTester = new RuleTester({ parserOptions })
|
|
24
|
+
ruleTester.run('class order', rule, {
|
|
25
|
+
valid: [
|
|
26
|
+
{
|
|
27
|
+
code: `<div class="bg:black fg:white f:24 m:8 p:8">Simple, basic</div>`,
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
code: `<div test="bg:black fg:white f:24 m:8 p:8">Simple, using 'test' prop</div>`,
|
|
31
|
+
options: [
|
|
32
|
+
{
|
|
33
|
+
classRegex: '^test$',
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
invalid: [
|
|
39
|
+
// jsx
|
|
40
|
+
{
|
|
41
|
+
code: `
|
|
42
|
+
export interface FakePropsInterface {
|
|
43
|
+
readonly name?: string;
|
|
44
|
+
}
|
|
45
|
+
function Fake({
|
|
46
|
+
name = 'yolo'
|
|
47
|
+
}: FakeProps) {
|
|
48
|
+
return (
|
|
49
|
+
<>
|
|
50
|
+
<h1 className={"m:8 bg:black p:8 fg:white f:24"}>Welcome {name}</h1>
|
|
51
|
+
<p>Bye {name}</p>
|
|
52
|
+
</>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
export default Fake;
|
|
56
|
+
`,
|
|
57
|
+
output: `
|
|
58
|
+
export interface FakePropsInterface {
|
|
59
|
+
readonly name?: string;
|
|
60
|
+
}
|
|
61
|
+
function Fake({
|
|
62
|
+
name = 'yolo'
|
|
63
|
+
}: FakeProps) {
|
|
64
|
+
return (
|
|
65
|
+
<>
|
|
66
|
+
<h1 className={"bg:black fg:white f:24 m:8 p:8"}>Welcome {name}</h1>
|
|
67
|
+
<p>Bye {name}</p>
|
|
68
|
+
</>
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
export default Fake;
|
|
72
|
+
`,
|
|
73
|
+
parser: require.resolve('@typescript-eslint/parser'),
|
|
74
|
+
errors: [{ messageId: 'invalidOrder' }],
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
code: `<div class="fg:white f:24 m:8 p:8 bg:black">Classnames will be ordered</div>`,
|
|
78
|
+
output: `<div class="bg:black fg:white f:24 m:8 p:8">Classnames will be ordered</div>`,
|
|
79
|
+
errors: [{ messageId: 'invalidOrder' }],
|
|
80
|
+
},
|
|
81
|
+
// html, angular
|
|
82
|
+
{
|
|
83
|
+
code: `
|
|
84
|
+
<div class="
|
|
85
|
+
m:8
|
|
86
|
+
bg:black
|
|
87
|
+
p:8
|
|
88
|
+
fg:white
|
|
89
|
+
f:24
|
|
90
|
+
">
|
|
91
|
+
:)
|
|
92
|
+
</div>`,
|
|
93
|
+
output: `
|
|
94
|
+
<div class="
|
|
95
|
+
bg:black
|
|
96
|
+
fg:white
|
|
97
|
+
f:24
|
|
98
|
+
m:8
|
|
99
|
+
p:8
|
|
100
|
+
">
|
|
101
|
+
:)
|
|
102
|
+
</div>`,
|
|
103
|
+
errors: [{ messageId: 'invalidOrder' }],
|
|
104
|
+
parser: require.resolve('@angular-eslint/template-parser'),
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
code: `<div class="flex uppercase m:0 m:0>li text-decoration:none>li>a px:4>li align-items:baseline fg:gray-30>li>a gap-x:28 font:12 font:semibold pb:6>li pt:20 pt:10>li {bb:3|solid|black}>li:has(>.router-link-active) {fg:black}>li:has(>.router-link-active)>a fg:gray-10>li>a:hover box-shadow:none>li>a:focus">Group</div>`,
|
|
108
|
+
output: `<div class="flex uppercase align-items:baseline box-shadow:none>li>a:focus fg:gray-30>li>a fg:gray-10>li>a:hover gap-x:28 font:12 font:semibold {bb:3|solid|black}>li:has(>.router-link-active) {fg:black}>li:has(>.router-link-active)>a m:0 m:0>li pb:6>li pt:20 pt:10>li px:4>li text-decoration:none>li>a">Group</div>`,
|
|
109
|
+
errors: [{ messageId: 'invalidOrder' }],
|
|
110
|
+
}
|
|
111
|
+
],
|
|
112
|
+
})
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
var rule = require('../../lib/rules/class-order')
|
|
4
|
+
var RuleTester = require('eslint').RuleTester
|
|
5
|
+
var parserOptions = {
|
|
6
|
+
ecmaVersion: 2019,
|
|
7
|
+
sourceType: 'module',
|
|
8
|
+
ecmaFeatures: {
|
|
9
|
+
jsx: true,
|
|
10
|
+
},
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
var ruleTester = new RuleTester({ parserOptions })
|
|
14
|
+
ruleTester.run('svelte class order', rule, {
|
|
15
|
+
valid: [{ code: `<div class="bg:black fg:white f:24 m:8 p:8">Simple, basic</div>` }],
|
|
16
|
+
invalid: [
|
|
17
|
+
{
|
|
18
|
+
code: `<div class="m:8 bg:black p:8 fg:white f:24 {flipped ? 'flipped' : ''}">Enhancing readability</div>`,
|
|
19
|
+
output: `<div class="bg:black fg:white f:24 m:8 p:8 {flipped ? 'flipped' : ''}">Enhancing readability</div>`,
|
|
20
|
+
errors: [{ messageId: 'invalidOrder' }],
|
|
21
|
+
filename: 'test.svelte',
|
|
22
|
+
parser: require.resolve('svelte-eslint-parser'),
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
})
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
var rule = require('../../lib/rules/class-order')
|
|
4
|
+
var RuleTester = require('eslint').RuleTester
|
|
5
|
+
var parserOptions = {
|
|
6
|
+
ecmaVersion: 2019,
|
|
7
|
+
sourceType: 'module',
|
|
8
|
+
ecmaFeatures: {
|
|
9
|
+
jsx: true,
|
|
10
|
+
},
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
var ruleTester = new RuleTester({ parserOptions })
|
|
14
|
+
ruleTester.run('vue class order', rule, {
|
|
15
|
+
valid: [{ code: `<div class="bg:black fg:white f:24 m:8 p:8">Simple, basic</div>` }],
|
|
16
|
+
invalid: [
|
|
17
|
+
{
|
|
18
|
+
code: `<template><div class="m:8 bg:black p:8 fg:white f:24">Enhancing readability</div></template>`,
|
|
19
|
+
output: `<template><div class="bg:black fg:white f:24 m:8 p:8">Enhancing readability</div></template>`,
|
|
20
|
+
errors: [{ messageId: 'invalidOrder' }],
|
|
21
|
+
filename: 'test.vue',
|
|
22
|
+
parser: require.resolve('vue-eslint-parser'),
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
})
|
package/tests/class-order.js
DELETED
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Use a consistent orders for the Master CSS classnames, based on property then on variants
|
|
3
|
-
* @author Miles
|
|
4
|
-
*/
|
|
5
|
-
'use strict'
|
|
6
|
-
|
|
7
|
-
// Modified from https://github.com/francoismassart/eslint-plugin-tailwindcss
|
|
8
|
-
|
|
9
|
-
//------------------------------------------------------------------------------
|
|
10
|
-
// Requirements
|
|
11
|
-
//------------------------------------------------------------------------------
|
|
12
|
-
|
|
13
|
-
var rule = require('../lib/rules/class-order')
|
|
14
|
-
var RuleTester = require('eslint').RuleTester
|
|
15
|
-
var parserOptions = {
|
|
16
|
-
ecmaVersion: 2019,
|
|
17
|
-
sourceType: 'module',
|
|
18
|
-
ecmaFeatures: {
|
|
19
|
-
jsx: true,
|
|
20
|
-
},
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
//------------------------------------------------------------------------------
|
|
24
|
-
// Tests
|
|
25
|
-
//------------------------------------------------------------------------------
|
|
26
|
-
|
|
27
|
-
describe('class-order', function () {
|
|
28
|
-
it('basic', function () {
|
|
29
|
-
var ruleTester = new RuleTester({ parserOptions })
|
|
30
|
-
const generateErrors = (count) => {
|
|
31
|
-
const errors = []
|
|
32
|
-
|
|
33
|
-
for (let i = 0; i < count; i++) {
|
|
34
|
-
errors.push({
|
|
35
|
-
messageId: 'invalidOrder',
|
|
36
|
-
})
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return errors
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const errors = generateErrors(1)
|
|
43
|
-
|
|
44
|
-
ruleTester.run('class-order', rule, {
|
|
45
|
-
valid: [
|
|
46
|
-
{
|
|
47
|
-
code: `<div class="bg:black fg:white f:24 m:8 p:8">Simple, basic</div>`,
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
code: `<div test="bg:black fg:white f:24 m:8 p:8">Simple, using 'test' prop</div>`,
|
|
51
|
-
options: [
|
|
52
|
-
{
|
|
53
|
-
classRegex: '^test$',
|
|
54
|
-
},
|
|
55
|
-
],
|
|
56
|
-
},
|
|
57
|
-
],
|
|
58
|
-
invalid: [
|
|
59
|
-
{
|
|
60
|
-
code: `
|
|
61
|
-
export interface FakePropsInterface {
|
|
62
|
-
readonly name?: string;
|
|
63
|
-
}
|
|
64
|
-
function Fake({
|
|
65
|
-
name = 'yolo'
|
|
66
|
-
}: FakeProps) {
|
|
67
|
-
return (
|
|
68
|
-
<>
|
|
69
|
-
<h1 className={"m:8 bg:black p:8 fg:white f:24"}>Welcome {name}</h1>
|
|
70
|
-
<p>Bye {name}</p>
|
|
71
|
-
</>
|
|
72
|
-
);
|
|
73
|
-
}
|
|
74
|
-
export default Fake;
|
|
75
|
-
`,
|
|
76
|
-
output: `
|
|
77
|
-
export interface FakePropsInterface {
|
|
78
|
-
readonly name?: string;
|
|
79
|
-
}
|
|
80
|
-
function Fake({
|
|
81
|
-
name = 'yolo'
|
|
82
|
-
}: FakeProps) {
|
|
83
|
-
return (
|
|
84
|
-
<>
|
|
85
|
-
<h1 className={"bg:black fg:white f:24 m:8 p:8"}>Welcome {name}</h1>
|
|
86
|
-
<p>Bye {name}</p>
|
|
87
|
-
</>
|
|
88
|
-
);
|
|
89
|
-
}
|
|
90
|
-
export default Fake;
|
|
91
|
-
`,
|
|
92
|
-
parser: require.resolve('@typescript-eslint/parser'),
|
|
93
|
-
errors: errors,
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
code: `<div class="fg:white f:24 m:8 p:8 bg:black">Classnames will be ordered</div>`,
|
|
97
|
-
output: `<div class="bg:black fg:white f:24 m:8 p:8">Classnames will be ordered</div>`,
|
|
98
|
-
errors: errors,
|
|
99
|
-
},
|
|
100
|
-
{
|
|
101
|
-
code: `<template><div class="m:8 bg:black p:8 fg:white f:24">Enhancing readability</div></template>`,
|
|
102
|
-
output: `<template><div class="bg:black fg:white f:24 m:8 p:8">Enhancing readability</div></template>`,
|
|
103
|
-
errors: errors,
|
|
104
|
-
filename: 'test.vue',
|
|
105
|
-
parser: require.resolve('vue-eslint-parser'),
|
|
106
|
-
},
|
|
107
|
-
{
|
|
108
|
-
code: `
|
|
109
|
-
<div class="
|
|
110
|
-
m:8
|
|
111
|
-
bg:black
|
|
112
|
-
p:8
|
|
113
|
-
fg:white
|
|
114
|
-
f:24
|
|
115
|
-
">
|
|
116
|
-
:)
|
|
117
|
-
</div>`,
|
|
118
|
-
output: `
|
|
119
|
-
<div class="
|
|
120
|
-
bg:black
|
|
121
|
-
fg:white
|
|
122
|
-
f:24
|
|
123
|
-
m:8
|
|
124
|
-
p:8
|
|
125
|
-
">
|
|
126
|
-
:)
|
|
127
|
-
</div>`,
|
|
128
|
-
errors: errors,
|
|
129
|
-
parser: require.resolve('@angular-eslint/template-parser'),
|
|
130
|
-
}
|
|
131
|
-
],
|
|
132
|
-
})
|
|
133
|
-
})
|
|
134
|
-
})
|