@primer/stylelint-config 12.9.2 → 13.0.0-rc.095cb19
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/README.md +0 -5
- package/dist/index.cjs +1154 -0
- package/dist/index.mjs +1151 -0
- package/package.json +61 -26
- package/plugins/README.md +1 -157
- package/plugins/borders.js +2 -2
- package/plugins/box-shadow.js +2 -2
- package/plugins/colors.js +2 -2
- package/plugins/lib/decl-validator.js +4 -4
- package/plugins/lib/primitives.js +36 -0
- package/plugins/lib/variable-rules.js +7 -22
- package/plugins/no-display-colors.js +5 -8
- package/plugins/responsive-widths.js +6 -9
- package/plugins/spacing.js +71 -69
- package/plugins/typography.js +2 -2
- package/property-order.js +1 -1
- package/browsers.js +0 -7
- package/index.js +0 -106
- package/plugins/lib/primer-utilities.js +0 -526
- package/plugins/lib/primer.js +0 -26
- package/plugins/new-color-vars-have-fallback.js +0 -39
- package/plugins/no-deprecated-colors.js +0 -103
- package/plugins/no-experimental-vars.js +0 -47
- package/plugins/no-override.js +0 -120
- package/plugins/no-scale-colors.js +0 -54
- package/plugins/no-undefined-vars.js +0 -121
- package/plugins/no-unused-vars.js +0 -96
- package/plugins/utilities.js +0 -55
package/plugins/spacing.js
CHANGED
|
@@ -1,39 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
// TODO: Pull this in from primer/primitives
|
|
6
|
-
const spacerValues = {
|
|
7
|
-
'$spacer-1': '4px',
|
|
8
|
-
'$spacer-2': '8px',
|
|
9
|
-
'$spacer-3': '16px',
|
|
10
|
-
'$spacer-4': '24px',
|
|
11
|
-
'$spacer-5': '32px',
|
|
12
|
-
'$spacer-6': '40px',
|
|
13
|
-
'$spacer-7': '48px',
|
|
14
|
-
'$spacer-8': '64px',
|
|
15
|
-
'$spacer-9': '80px',
|
|
16
|
-
'$spacer-10': '96px',
|
|
17
|
-
'$spacer-11': '112px',
|
|
18
|
-
'$spacer-12': '128px',
|
|
19
|
-
'$em-spacer-1': '0.0625em',
|
|
20
|
-
'$em-spacer-2': '0.125em',
|
|
21
|
-
'$em-spacer-3': '0.25em',
|
|
22
|
-
'$em-spacer-4': '0.375em',
|
|
23
|
-
'$em-spacer-5': '0.5em',
|
|
24
|
-
'$em-spacer-6': '0.75em',
|
|
25
|
-
}
|
|
1
|
+
import stylelint from 'stylelint'
|
|
2
|
+
import declarationValueIndex from 'stylelint/lib/utils/declarationValueIndex.cjs'
|
|
3
|
+
import valueParser from 'postcss-value-parser'
|
|
4
|
+
import {primitivesVariables} from './lib/primitives.js'
|
|
26
5
|
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
return `Please use a primer spacer variable instead of '${value}'. Consult the primer docs for a suitable replacement. https://primer.style/css/support/spacing`
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
return `Please replace ${value} with spacing variable '${replacement}'.`
|
|
35
|
-
},
|
|
36
|
-
})
|
|
6
|
+
const {
|
|
7
|
+
createPlugin,
|
|
8
|
+
utils: {report, ruleMessages, validateOptions},
|
|
9
|
+
} = stylelint
|
|
37
10
|
|
|
38
11
|
const walkGroups = (root, validate) => {
|
|
39
12
|
for (const node of root.nodes) {
|
|
@@ -46,24 +19,47 @@ const walkGroups = (root, validate) => {
|
|
|
46
19
|
return root
|
|
47
20
|
}
|
|
48
21
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
22
|
+
export const ruleName = 'primer/spacing'
|
|
23
|
+
export const messages = ruleMessages(ruleName, {
|
|
24
|
+
rejected: (value, replacement) => {
|
|
25
|
+
if (!replacement) {
|
|
26
|
+
return `Please use a primer size variable instead of '${value}'. Consult the primer docs for a suitable replacement. https://primer.style/foundations/primitives/size`
|
|
27
|
+
}
|
|
54
28
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
return noop
|
|
59
|
-
}
|
|
29
|
+
return `Please replace '${value}' with size variable '${replacement['name']}'. https://primer.style/foundations/primitives/size`
|
|
30
|
+
},
|
|
31
|
+
})
|
|
60
32
|
|
|
61
|
-
|
|
33
|
+
const meta = {
|
|
34
|
+
fixable: true,
|
|
35
|
+
}
|
|
62
36
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
37
|
+
/** @type {import('stylelint').Rule} */
|
|
38
|
+
const ruleFunction = (primary, secondaryOptions, context) => {
|
|
39
|
+
return async (root, result) => {
|
|
40
|
+
// Props that we want to check
|
|
41
|
+
const propList = ['padding', 'margin', 'top', 'right', 'bottom', 'left']
|
|
42
|
+
// Values that we want to ignore
|
|
43
|
+
const valueList = ['${']
|
|
66
44
|
|
|
45
|
+
const sizes = await primitivesVariables('size')
|
|
46
|
+
|
|
47
|
+
const validOptions = validateOptions(result, ruleName, {
|
|
48
|
+
actual: primary,
|
|
49
|
+
possible: [true],
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
if (!validOptions) return
|
|
53
|
+
|
|
54
|
+
root.walkDecls(declNode => {
|
|
55
|
+
const {prop, value} = declNode
|
|
56
|
+
|
|
57
|
+
if (!propList.some(spacingProp => prop.startsWith(spacingProp))) return
|
|
58
|
+
if (valueList.some(valueToIgnore => value.includes(valueToIgnore))) return
|
|
59
|
+
|
|
60
|
+
const problems = []
|
|
61
|
+
|
|
62
|
+
const parsedValue = walkGroups(valueParser(value), node => {
|
|
67
63
|
// Only check word types. https://github.com/TrySound/postcss-value-parser#word
|
|
68
64
|
if (node.type !== 'word') {
|
|
69
65
|
return
|
|
@@ -74,30 +70,36 @@ module.exports = stylelint.createPlugin(ruleName, (enabled, options = {}, contex
|
|
|
74
70
|
return
|
|
75
71
|
}
|
|
76
72
|
|
|
77
|
-
const valueUnit = valueParser.unit(
|
|
73
|
+
const valueUnit = valueParser.unit(node.value)
|
|
74
|
+
|
|
75
|
+
if (valueUnit && (valueUnit.unit === '' || !/^-?[0-9.]+$/.test(valueUnit.number))) {
|
|
76
|
+
return
|
|
77
|
+
}
|
|
78
78
|
|
|
79
|
-
if
|
|
79
|
+
// Skip if the value unit isn't a supported unit.
|
|
80
|
+
if (valueUnit && !['px', 'rem', 'em'].includes(valueUnit.unit)) {
|
|
80
81
|
return
|
|
81
82
|
}
|
|
82
83
|
|
|
83
|
-
// If the
|
|
84
|
+
// If the variable is found in the value, skip it.
|
|
84
85
|
if (
|
|
85
|
-
|
|
86
|
-
new RegExp(`${variable.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`).test(
|
|
86
|
+
sizes.some(variable =>
|
|
87
|
+
new RegExp(`${variable['name'].replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`).test(node.value),
|
|
87
88
|
)
|
|
88
89
|
) {
|
|
89
90
|
return
|
|
90
91
|
}
|
|
91
92
|
|
|
92
|
-
const replacement =
|
|
93
|
-
const
|
|
93
|
+
const replacement = sizes.find(variable => variable.values.includes(node.value.replace('-', '')))
|
|
94
|
+
const fixable = replacement && valueUnit && !valueUnit.number.includes('-')
|
|
94
95
|
|
|
95
|
-
if (
|
|
96
|
-
node.value = node.value.replace(
|
|
96
|
+
if (fixable && context.fix) {
|
|
97
|
+
node.value = node.value.replace(node.value, `var(${replacement['name']})`)
|
|
97
98
|
} else {
|
|
98
99
|
problems.push({
|
|
99
|
-
index: declarationValueIndex(
|
|
100
|
-
|
|
100
|
+
index: declarationValueIndex(declNode) + node.sourceIndex,
|
|
101
|
+
endIndex: declarationValueIndex(declNode) + node.sourceIndex + node.value.length,
|
|
102
|
+
message: messages.rejected(node.value, replacement),
|
|
101
103
|
})
|
|
102
104
|
}
|
|
103
105
|
|
|
@@ -105,15 +107,16 @@ module.exports = stylelint.createPlugin(ruleName, (enabled, options = {}, contex
|
|
|
105
107
|
})
|
|
106
108
|
|
|
107
109
|
if (context.fix) {
|
|
108
|
-
|
|
110
|
+
declNode.value = parsedValue.toString()
|
|
109
111
|
}
|
|
110
112
|
|
|
111
113
|
if (problems.length) {
|
|
112
114
|
for (const err of problems) {
|
|
113
|
-
|
|
115
|
+
report({
|
|
114
116
|
index: err.index,
|
|
117
|
+
endIndex: err.endIndex,
|
|
115
118
|
message: err.message,
|
|
116
|
-
node:
|
|
119
|
+
node: declNode,
|
|
117
120
|
result,
|
|
118
121
|
ruleName,
|
|
119
122
|
})
|
|
@@ -121,11 +124,10 @@ module.exports = stylelint.createPlugin(ruleName, (enabled, options = {}, contex
|
|
|
121
124
|
}
|
|
122
125
|
})
|
|
123
126
|
}
|
|
127
|
+
}
|
|
124
128
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
function noop() {}
|
|
129
|
+
ruleFunction.ruleName = ruleName
|
|
130
|
+
ruleFunction.messages = messages
|
|
131
|
+
ruleFunction.meta = meta
|
|
129
132
|
|
|
130
|
-
|
|
131
|
-
module.exports.messages = messages
|
|
133
|
+
export default createPlugin(ruleName, ruleFunction)
|
package/plugins/typography.js
CHANGED
package/property-order.js
CHANGED
package/browsers.js
DELETED
package/index.js
DELETED
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
const browsers = require('./browsers')
|
|
2
|
-
const propertyOrder = require('./property-order')
|
|
3
|
-
|
|
4
|
-
module.exports = {
|
|
5
|
-
extends: ['stylelint-config-standard'],
|
|
6
|
-
customSyntax: require('postcss-scss'),
|
|
7
|
-
ignoreFiles: ['**/*.js', '**/*.cjs'],
|
|
8
|
-
plugins: [
|
|
9
|
-
'stylelint-no-unsupported-browser-features',
|
|
10
|
-
'stylelint-order',
|
|
11
|
-
'stylelint-scss',
|
|
12
|
-
'./plugins/borders',
|
|
13
|
-
'./plugins/box-shadow',
|
|
14
|
-
'./plugins/colors',
|
|
15
|
-
'./plugins/no-deprecated-colors',
|
|
16
|
-
'./plugins/no-experimental-vars',
|
|
17
|
-
'./plugins/no-override',
|
|
18
|
-
'./plugins/no-scale-colors',
|
|
19
|
-
'./plugins/no-undefined-vars',
|
|
20
|
-
'./plugins/no-unused-vars',
|
|
21
|
-
'./plugins/responsive-widths',
|
|
22
|
-
'./plugins/spacing',
|
|
23
|
-
'./plugins/typography',
|
|
24
|
-
'./plugins/utilities',
|
|
25
|
-
'./plugins/new-color-vars-have-fallback',
|
|
26
|
-
'./plugins/no-display-colors',
|
|
27
|
-
],
|
|
28
|
-
rules: {
|
|
29
|
-
'alpha-value-notation': 'number',
|
|
30
|
-
'at-rule-disallowed-list': ['extend'],
|
|
31
|
-
'at-rule-no-unknown': null,
|
|
32
|
-
'block-no-empty': true,
|
|
33
|
-
'color-function-notation': null,
|
|
34
|
-
'color-named': 'never',
|
|
35
|
-
'color-no-invalid-hex': true,
|
|
36
|
-
'comment-no-empty': null,
|
|
37
|
-
'custom-property-pattern': null,
|
|
38
|
-
'declaration-block-no-duplicate-properties': [true, {ignore: ['consecutive-duplicates']}],
|
|
39
|
-
'declaration-block-no-redundant-longhand-properties': null,
|
|
40
|
-
'declaration-block-no-shorthand-property-overrides': true,
|
|
41
|
-
'declaration-property-value-disallowed-list': {
|
|
42
|
-
'/^transition/': ['/all/'],
|
|
43
|
-
'/^background/': ['http:', 'https:'],
|
|
44
|
-
'/^border/': ['none'],
|
|
45
|
-
'/.+/': ['initial'],
|
|
46
|
-
},
|
|
47
|
-
'function-calc-no-unspaced-operator': true,
|
|
48
|
-
'function-linear-gradient-no-nonstandard-direction': true,
|
|
49
|
-
'function-no-unknown': null,
|
|
50
|
-
'keyframes-name-pattern': null,
|
|
51
|
-
'max-nesting-depth': 3,
|
|
52
|
-
'media-feature-name-no-unknown': null,
|
|
53
|
-
'media-feature-name-no-vendor-prefix': null,
|
|
54
|
-
'no-descending-specificity': null,
|
|
55
|
-
'no-duplicate-selectors': true,
|
|
56
|
-
'no-invalid-position-at-import-rule': [true, {ignoreAtRules: ['use']}],
|
|
57
|
-
'number-max-precision': null,
|
|
58
|
-
'order/properties-order': propertyOrder,
|
|
59
|
-
'plugin/no-unsupported-browser-features': [true, {severity: 'warning', browsers}],
|
|
60
|
-
'primer/borders': true,
|
|
61
|
-
'primer/box-shadow': true,
|
|
62
|
-
'primer/colors': true,
|
|
63
|
-
'primer/no-deprecated-colors': true,
|
|
64
|
-
'primer/no-experimental-vars': [
|
|
65
|
-
true,
|
|
66
|
-
{
|
|
67
|
-
designTokens: '@primer/primitives/tokens-v2-private/docs/docValues.json',
|
|
68
|
-
},
|
|
69
|
-
],
|
|
70
|
-
'primer/no-override': true,
|
|
71
|
-
'primer/no-undefined-vars': [
|
|
72
|
-
true,
|
|
73
|
-
{severity: 'warning', files: 'node_modules/@primer/primitives/dist/scss/colors*/*.scss'},
|
|
74
|
-
],
|
|
75
|
-
'primer/no-unused-vars': [true, {severity: 'warning'}],
|
|
76
|
-
'primer/responsive-widths': true,
|
|
77
|
-
'primer/spacing': true,
|
|
78
|
-
'primer/typography': true,
|
|
79
|
-
'primer/utilities': null,
|
|
80
|
-
'primer/new-color-vars-have-fallback': [true, {severity: 'error'}],
|
|
81
|
-
'scss/at-extend-no-missing-placeholder': true,
|
|
82
|
-
'scss/at-rule-no-unknown': true,
|
|
83
|
-
'scss/declaration-nested-properties-no-divided-groups': true,
|
|
84
|
-
'scss/dollar-variable-no-missing-interpolation': true,
|
|
85
|
-
'scss/function-quote-no-quoted-strings-inside': true,
|
|
86
|
-
'scss/function-unquote-no-unquoted-strings-inside': true,
|
|
87
|
-
'scss/no-duplicate-mixins': true,
|
|
88
|
-
'scss/selector-no-redundant-nesting-selector': true,
|
|
89
|
-
'selector-class-pattern': null,
|
|
90
|
-
'selector-max-compound-selectors': 3,
|
|
91
|
-
'selector-max-id': 0,
|
|
92
|
-
'selector-max-specificity': '0,4,0',
|
|
93
|
-
'selector-max-type': 0,
|
|
94
|
-
'selector-no-qualifying-type': true,
|
|
95
|
-
'selector-pseudo-element-no-unknown': true,
|
|
96
|
-
'string-no-newline': true,
|
|
97
|
-
'unit-no-unknown': true,
|
|
98
|
-
'value-keyword-case': null,
|
|
99
|
-
'selector-not-notation': null,
|
|
100
|
-
'import-notation': ['string'],
|
|
101
|
-
'annotation-no-unknown': null,
|
|
102
|
-
'keyframe-selector-notation': ['percentage-unless-within-keyword-only-block'],
|
|
103
|
-
'media-query-no-invalid': null,
|
|
104
|
-
'media-feature-range-notation': ['prefix'],
|
|
105
|
-
},
|
|
106
|
-
}
|