@primer/stylelint-config 12.9.2 → 13.0.0-rc.04ba287
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 +1288 -0
- package/dist/index.mjs +1285 -0
- package/package.json +61 -26
- package/plugins/README.md +1 -157
- package/plugins/borders.js +196 -63
- package/plugins/box-shadow.js +2 -2
- package/plugins/colors.js +2 -2
- package/plugins/lib/decl-validator.js +4 -4
- package/plugins/lib/utils.js +45 -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 +72 -73
- 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
|
@@ -1,27 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import stylelint from 'stylelint'
|
|
2
|
+
import declarationValidator from './decl-validator.js'
|
|
3
|
+
import variables from '@primer/css/dist/variables.json' with {type: 'json'}
|
|
4
4
|
|
|
5
|
-
const CSS_IMPORTANT = '!important'
|
|
6
|
-
const CSS_DIRECTIONS = ['top', 'right', 'bottom', 'left']
|
|
7
|
-
const CSS_CORNERS = ['top-right', 'bottom-right', 'bottom-left', 'top-left']
|
|
8
|
-
|
|
9
|
-
module.exports = {
|
|
10
|
-
createVariableRule,
|
|
11
|
-
CSS_DIRECTIONS,
|
|
12
|
-
CSS_CORNERS,
|
|
13
|
-
CSS_IMPORTANT,
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function createVariableRule(ruleName, rules, url) {
|
|
17
|
-
let variables = {}
|
|
18
|
-
try {
|
|
19
|
-
variables = requirePrimerFile('dist/variables.json')
|
|
20
|
-
} catch (error) {
|
|
21
|
-
// eslint-disable-next-line no-console
|
|
22
|
-
console.warn(`Unable to get variables.json from @primer/css. Replacements will need to be specified manually.`)
|
|
23
|
-
}
|
|
5
|
+
export const CSS_IMPORTANT = '!important'
|
|
6
|
+
export const CSS_DIRECTIONS = ['top', 'right', 'bottom', 'left']
|
|
7
|
+
export const CSS_CORNERS = ['top-right', 'bottom-right', 'bottom-left', 'top-left']
|
|
24
8
|
|
|
9
|
+
export function createVariableRule(ruleName, rules, url) {
|
|
25
10
|
const plugin = stylelint.createPlugin(ruleName, (enabled, options = {}, context) => {
|
|
26
11
|
if (enabled === false) {
|
|
27
12
|
return noop
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import stylelint from 'stylelint'
|
|
2
|
+
import matchAll from 'string.prototype.matchall'
|
|
3
3
|
|
|
4
|
-
const ruleName = 'primer/no-display-colors'
|
|
5
|
-
const messages = stylelint.utils.ruleMessages(ruleName, {
|
|
4
|
+
export const ruleName = 'primer/no-display-colors'
|
|
5
|
+
export const messages = stylelint.utils.ruleMessages(ruleName, {
|
|
6
6
|
rejected: varName => `${varName} is in alpha and should be used with caution with approval from the Primer team`,
|
|
7
7
|
})
|
|
8
8
|
|
|
@@ -10,7 +10,7 @@ const messages = stylelint.utils.ruleMessages(ruleName, {
|
|
|
10
10
|
// eslint-disable-next-line no-useless-escape
|
|
11
11
|
const variableReferenceRegex = /var\(([^\),]+)(,.*)?\)/g
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
export default stylelint.createPlugin(ruleName, (enabled, options = {}) => {
|
|
14
14
|
if (!enabled) {
|
|
15
15
|
return noop
|
|
16
16
|
}
|
|
@@ -48,6 +48,3 @@ module.exports = stylelint.createPlugin(ruleName, (enabled, options = {}) => {
|
|
|
48
48
|
})
|
|
49
49
|
|
|
50
50
|
function noop() {}
|
|
51
|
-
|
|
52
|
-
module.exports.ruleName = ruleName
|
|
53
|
-
module.exports.messages = messages
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import stylelint from 'stylelint'
|
|
2
|
+
import declarationValueIndex from 'stylelint/lib/utils/declarationValueIndex.cjs'
|
|
3
|
+
import valueParser from 'postcss-value-parser'
|
|
4
4
|
|
|
5
|
-
const ruleName = 'primer/responsive-widths'
|
|
5
|
+
export const ruleName = 'primer/responsive-widths'
|
|
6
6
|
|
|
7
|
-
const messages = stylelint.utils.ruleMessages(ruleName, {
|
|
7
|
+
export const messages = stylelint.utils.ruleMessages(ruleName, {
|
|
8
8
|
rejected: value => {
|
|
9
9
|
return `A value larger than the smallest viewport could break responsive pages. Use a width value smaller than ${value}. https://primer.style/css/support/breakpoints`
|
|
10
10
|
},
|
|
@@ -24,7 +24,7 @@ const walkGroups = (root, validate) => {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
// eslint-disable-next-line no-unused-vars
|
|
27
|
-
|
|
27
|
+
export default stylelint.createPlugin(ruleName, (enabled, options = {}, context) => {
|
|
28
28
|
if (!enabled) {
|
|
29
29
|
return noop
|
|
30
30
|
}
|
|
@@ -93,6 +93,3 @@ module.exports = stylelint.createPlugin(ruleName, (enabled, options = {}, contex
|
|
|
93
93
|
})
|
|
94
94
|
|
|
95
95
|
function noop() {}
|
|
96
|
-
|
|
97
|
-
module.exports.ruleName = ruleName
|
|
98
|
-
module.exports.messages = messages
|
package/plugins/spacing.js
CHANGED
|
@@ -1,69 +1,60 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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
|
-
}
|
|
26
|
-
|
|
27
|
-
const ruleName = 'primer/spacing'
|
|
28
|
-
const messages = stylelint.utils.ruleMessages(ruleName, {
|
|
1
|
+
import stylelint from 'stylelint'
|
|
2
|
+
import declarationValueIndex from 'stylelint/lib/utils/declarationValueIndex.cjs'
|
|
3
|
+
import valueParser from 'postcss-value-parser'
|
|
4
|
+
import {primitivesVariables, walkGroups} from './lib/utils.js'
|
|
5
|
+
|
|
6
|
+
const {
|
|
7
|
+
createPlugin,
|
|
8
|
+
utils: {report, ruleMessages, validateOptions},
|
|
9
|
+
} = stylelint
|
|
10
|
+
|
|
11
|
+
export const ruleName = 'primer/spacing'
|
|
12
|
+
export const messages = ruleMessages(ruleName, {
|
|
29
13
|
rejected: (value, replacement) => {
|
|
30
|
-
if (replacement
|
|
31
|
-
return `Please use a primer
|
|
14
|
+
if (!replacement) {
|
|
15
|
+
return `Please use a primer size variable instead of '${value}'. Consult the primer docs for a suitable replacement. https://primer.style/foundations/primitives/size`
|
|
32
16
|
}
|
|
33
17
|
|
|
34
|
-
return `Please replace ${value} with
|
|
18
|
+
return `Please replace '${value}' with size variable '${replacement['name']}'. https://primer.style/foundations/primitives/size`
|
|
35
19
|
},
|
|
36
20
|
})
|
|
37
21
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
22
|
+
// Props that we want to check
|
|
23
|
+
const propList = ['padding', 'margin', 'top', 'right', 'bottom', 'left']
|
|
24
|
+
// Values that we want to ignore
|
|
25
|
+
const valueList = ['${']
|
|
26
|
+
|
|
27
|
+
const sizes = primitivesVariables('spacing')
|
|
28
|
+
|
|
29
|
+
// Add +-1px to each value
|
|
30
|
+
for (const size of sizes) {
|
|
31
|
+
const values = size['values']
|
|
32
|
+
const px = parseInt(values.find(value => value.includes('px')))
|
|
33
|
+
if (![2, 6].includes(px)) {
|
|
34
|
+
values.push(`${px + 1}px`)
|
|
35
|
+
values.push(`${px - 1}px`)
|
|
45
36
|
}
|
|
46
|
-
return root
|
|
47
37
|
}
|
|
48
38
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
39
|
+
/** @type {import('stylelint').Rule} */
|
|
40
|
+
const ruleFunction = (primary, secondaryOptions, context) => {
|
|
41
|
+
return (root, result) => {
|
|
42
|
+
const validOptions = validateOptions(result, ruleName, {
|
|
43
|
+
actual: primary,
|
|
44
|
+
possible: [true],
|
|
45
|
+
})
|
|
54
46
|
|
|
55
|
-
|
|
56
|
-
root.walk(decl => {
|
|
57
|
-
if (decl.type !== 'decl' || !decl.prop.match(/^(padding|margin)/)) {
|
|
58
|
-
return noop
|
|
59
|
-
}
|
|
47
|
+
if (!validOptions) return
|
|
60
48
|
|
|
61
|
-
|
|
49
|
+
root.walkDecls(declNode => {
|
|
50
|
+
const {prop, value} = declNode
|
|
62
51
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const cleanValue = node.value.replace(/^-/g, '')
|
|
52
|
+
if (!propList.some(spacingProp => prop.startsWith(spacingProp))) return
|
|
53
|
+
if (valueList.some(valueToIgnore => value.includes(valueToIgnore))) return
|
|
66
54
|
|
|
55
|
+
const problems = []
|
|
56
|
+
|
|
57
|
+
const parsedValue = walkGroups(valueParser(value), node => {
|
|
67
58
|
// Only check word types. https://github.com/TrySound/postcss-value-parser#word
|
|
68
59
|
if (node.type !== 'word') {
|
|
69
60
|
return
|
|
@@ -74,30 +65,36 @@ module.exports = stylelint.createPlugin(ruleName, (enabled, options = {}, contex
|
|
|
74
65
|
return
|
|
75
66
|
}
|
|
76
67
|
|
|
77
|
-
const valueUnit = valueParser.unit(
|
|
68
|
+
const valueUnit = valueParser.unit(node.value)
|
|
69
|
+
|
|
70
|
+
if (valueUnit && (valueUnit.unit === '' || !/^-?[0-9.]+$/.test(valueUnit.number))) {
|
|
71
|
+
return
|
|
72
|
+
}
|
|
78
73
|
|
|
79
|
-
if
|
|
74
|
+
// Skip if the value unit isn't a supported unit.
|
|
75
|
+
if (valueUnit && !['px', 'rem', 'em'].includes(valueUnit.unit)) {
|
|
80
76
|
return
|
|
81
77
|
}
|
|
82
78
|
|
|
83
|
-
// If the
|
|
79
|
+
// If the variable is found in the value, skip it.
|
|
84
80
|
if (
|
|
85
|
-
|
|
86
|
-
new RegExp(`${variable.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`).test(
|
|
81
|
+
sizes.some(variable =>
|
|
82
|
+
new RegExp(`${variable['name'].replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`).test(node.value),
|
|
87
83
|
)
|
|
88
84
|
) {
|
|
89
85
|
return
|
|
90
86
|
}
|
|
91
87
|
|
|
92
|
-
const replacement =
|
|
93
|
-
const
|
|
88
|
+
const replacement = sizes.find(variable => variable.values.includes(node.value.replace('-', '')))
|
|
89
|
+
const fixable = replacement && valueUnit && !valueUnit.number.includes('-')
|
|
94
90
|
|
|
95
|
-
if (
|
|
96
|
-
node.value = node.value.replace(
|
|
91
|
+
if (fixable && context.fix) {
|
|
92
|
+
node.value = node.value.replace(node.value, `var(${replacement['name']})`)
|
|
97
93
|
} else {
|
|
98
94
|
problems.push({
|
|
99
|
-
index: declarationValueIndex(
|
|
100
|
-
|
|
95
|
+
index: declarationValueIndex(declNode) + node.sourceIndex,
|
|
96
|
+
endIndex: declarationValueIndex(declNode) + node.sourceIndex + node.value.length,
|
|
97
|
+
message: messages.rejected(node.value, replacement),
|
|
101
98
|
})
|
|
102
99
|
}
|
|
103
100
|
|
|
@@ -105,15 +102,16 @@ module.exports = stylelint.createPlugin(ruleName, (enabled, options = {}, contex
|
|
|
105
102
|
})
|
|
106
103
|
|
|
107
104
|
if (context.fix) {
|
|
108
|
-
|
|
105
|
+
declNode.value = parsedValue.toString()
|
|
109
106
|
}
|
|
110
107
|
|
|
111
108
|
if (problems.length) {
|
|
112
109
|
for (const err of problems) {
|
|
113
|
-
|
|
110
|
+
report({
|
|
114
111
|
index: err.index,
|
|
112
|
+
endIndex: err.endIndex,
|
|
115
113
|
message: err.message,
|
|
116
|
-
node:
|
|
114
|
+
node: declNode,
|
|
117
115
|
result,
|
|
118
116
|
ruleName,
|
|
119
117
|
})
|
|
@@ -121,11 +119,12 @@ module.exports = stylelint.createPlugin(ruleName, (enabled, options = {}, contex
|
|
|
121
119
|
}
|
|
122
120
|
})
|
|
123
121
|
}
|
|
122
|
+
}
|
|
124
123
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
124
|
+
ruleFunction.ruleName = ruleName
|
|
125
|
+
ruleFunction.messages = messages
|
|
126
|
+
ruleFunction.meta = {
|
|
127
|
+
fixable: true,
|
|
128
|
+
}
|
|
129
129
|
|
|
130
|
-
|
|
131
|
-
module.exports.messages = messages
|
|
130
|
+
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
|
-
}
|