@primer/stylelint-config 12.9.2-rc.46fe2e1 → 13.0.0-rc.22bf91a
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/package.json +45 -21
- 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/primer-utilities.js +1 -1
- package/plugins/lib/variable-rules.js +7 -22
- package/plugins/new-color-vars-have-fallback.js +5 -9
- package/plugins/no-deprecated-colors.js +6 -12
- package/plugins/no-display-colors.js +5 -8
- package/plugins/no-override.js +13 -35
- package/plugins/no-scale-colors.js +5 -8
- package/plugins/no-undefined-vars.js +9 -12
- package/plugins/no-unused-vars.js +8 -8
- package/plugins/responsive-widths.js +6 -9
- package/plugins/spacing.js +7 -10
- package/plugins/typography.js +2 -2
- package/plugins/utilities.js +5 -8
- package/property-order.js +1 -1
- package/browsers.js +0 -7
- package/index.js +0 -106
- package/plugins/lib/primer.js +0 -26
- package/plugins/no-experimental-vars.js +0 -47
package/package.json
CHANGED
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@primer/stylelint-config",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "13.0.0-rc.22bf91a",
|
|
4
4
|
"description": "Sharable stylelint config used by GitHub's CSS",
|
|
5
|
-
"homepage": "http://primer.style/css/tools/linting",
|
|
6
5
|
"author": "GitHub, Inc.",
|
|
7
6
|
"license": "MIT",
|
|
8
|
-
"
|
|
9
|
-
"
|
|
7
|
+
"type": "module",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"require": "./dist/index.cjs"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"browserslist": "extends @github/browserslist-config",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/primer/stylelint-config.git"
|
|
18
|
+
},
|
|
10
19
|
"keywords": [
|
|
11
20
|
"github",
|
|
12
21
|
"primer",
|
|
@@ -15,44 +24,59 @@
|
|
|
15
24
|
"stylelint"
|
|
16
25
|
],
|
|
17
26
|
"files": [
|
|
27
|
+
"dist/",
|
|
18
28
|
"property-order.js",
|
|
19
|
-
"browsers.js",
|
|
20
29
|
"plugins/"
|
|
21
30
|
],
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">16.0.0"
|
|
33
|
+
},
|
|
22
34
|
"scripts": {
|
|
23
|
-
"
|
|
35
|
+
"build": "rollup -c",
|
|
36
|
+
"clean": "rimraf dist",
|
|
37
|
+
"test": "NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules\" jest --coverage false",
|
|
38
|
+
"test:stylelint": "stylelint __tests__/__fixtures__/uses-vars.scss",
|
|
24
39
|
"lint": "eslint .",
|
|
25
40
|
"release": "changeset publish"
|
|
26
41
|
},
|
|
27
42
|
"dependencies": {
|
|
43
|
+
"@github/browserslist-config": "^1.0.0",
|
|
44
|
+
"@primer/css": "^21.0.8",
|
|
45
|
+
"@primer/primitives": "^7.16.0",
|
|
28
46
|
"anymatch": "^3.1.1",
|
|
29
47
|
"globby": "^11.0.1",
|
|
30
48
|
"postcss-scss": "^4.0.2",
|
|
31
49
|
"postcss-value-parser": "^4.0.2",
|
|
32
50
|
"string.prototype.matchall": "^4.0.2",
|
|
33
|
-
"stylelint": "^
|
|
34
|
-
"stylelint-config-standard": "^
|
|
35
|
-
"stylelint-no-unsupported-browser-features": "^
|
|
36
|
-
"stylelint-order": "^6.0.
|
|
37
|
-
"stylelint-scss": "^
|
|
51
|
+
"stylelint": "^16.3.1",
|
|
52
|
+
"stylelint-config-standard": "^36.0.0",
|
|
53
|
+
"stylelint-no-unsupported-browser-features": "^8.0.0",
|
|
54
|
+
"stylelint-order": "^6.0.4",
|
|
55
|
+
"stylelint-scss": "^6.2.0",
|
|
38
56
|
"tap-map": "^1.0.0"
|
|
39
57
|
},
|
|
58
|
+
"prettier": "@github/prettier-config",
|
|
40
59
|
"devDependencies": {
|
|
41
60
|
"@changesets/changelog-github": "0.4.7",
|
|
42
61
|
"@changesets/cli": "2.26.1",
|
|
43
|
-
"@github/prettier-config": "0.0.6",
|
|
44
|
-
"@
|
|
45
|
-
"@
|
|
62
|
+
"@github/prettier-config": "^0.0.6",
|
|
63
|
+
"@rollup/plugin-commonjs": "^25.0.7",
|
|
64
|
+
"@rollup/plugin-json": "^6.1.0",
|
|
65
|
+
"@rollup/plugin-node-resolve": "^15.2.3",
|
|
66
|
+
"@typescript-eslint/parser": "^7.7.0",
|
|
46
67
|
"dedent": "1.5.1",
|
|
47
|
-
"eslint": "8.
|
|
48
|
-
"eslint-plugin-github": "4.
|
|
49
|
-
"eslint-plugin-jest": "
|
|
50
|
-
"eslint-plugin-prettier": "
|
|
51
|
-
"jest": "29.
|
|
52
|
-
"jest-preset-stylelint": "
|
|
53
|
-
"prettier": "2.
|
|
68
|
+
"eslint": "^8.0.1",
|
|
69
|
+
"eslint-plugin-github": "^4.10.2",
|
|
70
|
+
"eslint-plugin-jest": "^28.2.0",
|
|
71
|
+
"eslint-plugin-prettier": "^5.1.3",
|
|
72
|
+
"jest": "^29.7.0",
|
|
73
|
+
"jest-preset-stylelint": "^7.0.0",
|
|
74
|
+
"prettier": "^3.2.5",
|
|
75
|
+
"rimraf": "^5.0.5",
|
|
76
|
+
"rollup": "^4.14.3"
|
|
54
77
|
},
|
|
55
78
|
"jest": {
|
|
79
|
+
"transform": {},
|
|
56
80
|
"preset": "jest-preset-stylelint",
|
|
57
81
|
"collectCoverage": true,
|
|
58
82
|
"collectCoverageFrom": [
|
package/plugins/borders.js
CHANGED
package/plugins/box-shadow.js
CHANGED
package/plugins/colors.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import {createVariableRule} from './lib/variable-rules.js'
|
|
2
2
|
|
|
3
3
|
const bgVars = [
|
|
4
4
|
'$bg-*',
|
|
@@ -12,7 +12,7 @@ const bgVars = [
|
|
|
12
12
|
/var\((.+-)*iconColor(-.+)*\)/,
|
|
13
13
|
]
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
export default createVariableRule(
|
|
16
16
|
'primer/colors',
|
|
17
17
|
{
|
|
18
18
|
'background-color': {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import anymatch from 'anymatch'
|
|
2
|
+
import valueParser from 'postcss-value-parser'
|
|
3
|
+
import TapMap from 'tap-map'
|
|
4
4
|
|
|
5
5
|
const SKIP_VALUE_NODE_TYPES = new Set(['space', 'div'])
|
|
6
6
|
const SKIP_AT_RULE_NAMES = new Set(['each', 'for', 'function', 'mixin'])
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
export default function declarationValidator(rules, options = {}) {
|
|
9
9
|
const {formatMessage = defaultMessageFormatter, variables, verbose = false} = options
|
|
10
10
|
const variableReplacements = new TapMap()
|
|
11
11
|
if (variables) {
|
|
@@ -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,14 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
import stylelint from 'stylelint'
|
|
2
|
+
import variables from './lib/new-color-css-vars-map.json' with {type: 'json'}
|
|
2
3
|
|
|
3
|
-
const ruleName = 'primer/new-color-vars-have-fallback'
|
|
4
|
-
const messages = stylelint.utils.ruleMessages(ruleName, {
|
|
4
|
+
export const ruleName = 'primer/new-color-vars-have-fallback'
|
|
5
|
+
export const messages = stylelint.utils.ruleMessages(ruleName, {
|
|
5
6
|
expectedFallback: variable =>
|
|
6
7
|
`Expected a fallback value for CSS variable ${variable}. New color variables fallbacks, check primer.style/primitives to find the correct value`,
|
|
7
8
|
})
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
const variables = require('./lib/new-color-css-vars-map.json')
|
|
11
|
-
|
|
10
|
+
export default stylelint.createPlugin(ruleName, enabled => {
|
|
12
11
|
if (!enabled) {
|
|
13
12
|
return noop
|
|
14
13
|
}
|
|
@@ -34,6 +33,3 @@ module.exports = stylelint.createPlugin(ruleName, enabled => {
|
|
|
34
33
|
})
|
|
35
34
|
|
|
36
35
|
function noop() {}
|
|
37
|
-
|
|
38
|
-
module.exports.ruleName = ruleName
|
|
39
|
-
module.exports.messages = messages
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const ruleName = 'primer/no-deprecated-colors'
|
|
5
|
-
const messages = stylelint.utils.ruleMessages(ruleName, {
|
|
1
|
+
import stylelint from 'stylelint'
|
|
2
|
+
import matchAll from 'string.prototype.matchall'
|
|
3
|
+
import variableChecks from './lib/primitives-v8.json' with {type: 'json'}
|
|
4
|
+
export const ruleName = 'primer/no-deprecated-colors'
|
|
5
|
+
export const messages = stylelint.utils.ruleMessages(ruleName, {
|
|
6
6
|
rejected: (varName, replacement, property) => {
|
|
7
7
|
if (replacement === null) {
|
|
8
8
|
return `Variable ${varName} is deprecated for property ${property}. Please consult the primer color docs for a replacement. https://primer.style/primitives/storybook/?path=/story/migration-tables`
|
|
@@ -19,7 +19,7 @@ const variableReferenceRegex = /var\(([^\),]+)(,.*)?\)/g
|
|
|
19
19
|
const replacedVars = {}
|
|
20
20
|
const newVars = {}
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
export default stylelint.createPlugin(ruleName, (enabled, options = {}, context) => {
|
|
23
23
|
const {inlineFallback = false} = options
|
|
24
24
|
|
|
25
25
|
if (!enabled) {
|
|
@@ -33,9 +33,6 @@ module.exports = stylelint.createPlugin(ruleName, (enabled, options = {}, contex
|
|
|
33
33
|
// Keep track of declarations we've already seen
|
|
34
34
|
const seen = new WeakMap()
|
|
35
35
|
|
|
36
|
-
// eslint-disable-next-line import/no-dynamic-require
|
|
37
|
-
const variableChecks = require(options.deprecatedFile || './lib/primitives-v8.json')
|
|
38
|
-
|
|
39
36
|
const lintResult = (root, result) => {
|
|
40
37
|
// Walk all declarations
|
|
41
38
|
root.walk(node => {
|
|
@@ -98,6 +95,3 @@ module.exports = stylelint.createPlugin(ruleName, (enabled, options = {}, contex
|
|
|
98
95
|
})
|
|
99
96
|
|
|
100
97
|
function noop() {}
|
|
101
|
-
|
|
102
|
-
module.exports.ruleName = ruleName
|
|
103
|
-
module.exports.messages = messages
|
|
@@ -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
|
package/plugins/no-override.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import stylelint from 'stylelint'
|
|
2
|
+
import primerJson from '@primer/css/dist/stats/primer.json' with {type: 'json'}
|
|
3
3
|
|
|
4
4
|
const ruleName = 'primer/no-override'
|
|
5
5
|
const CLASS_PATTERN = /(\.[-\w]+)/
|
|
6
6
|
const CLASS_PATTERN_ALL = new RegExp(CLASS_PATTERN, 'g')
|
|
7
7
|
const CLASS_PATTERN_ONLY = /^\.[-\w]+(:{1,2}[-\w]+)?$/
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
export default stylelint.createPlugin(ruleName, (enabled, options = {}) => {
|
|
10
10
|
if (!enabled) {
|
|
11
11
|
return noop
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
const {
|
|
14
|
+
const {ignoreSelectors = []} = options
|
|
15
15
|
|
|
16
16
|
const isSelectorIgnored =
|
|
17
17
|
typeof ignoreSelectors === 'function'
|
|
@@ -22,50 +22,30 @@ module.exports = stylelint.createPlugin(ruleName, (enabled, options = {}) => {
|
|
|
22
22
|
})
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
const primerMeta = requirePrimerFile('dist/meta.json')
|
|
26
|
-
const availableBundles = Object.keys(primerMeta.bundles)
|
|
27
|
-
|
|
28
25
|
// These map selectors to the bundle in which they're defined.
|
|
29
26
|
// If there's no entry for a given selector, it means that it's not defined
|
|
30
27
|
// in one of the *specified* bundles, since we're iterating over the list of
|
|
31
28
|
// bundle names in the options.
|
|
32
|
-
const immutableSelectors = new
|
|
33
|
-
const immutableClassSelectors = new
|
|
29
|
+
const immutableSelectors = new Set()
|
|
30
|
+
const immutableClassSelectors = new Set()
|
|
34
31
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const selectors = stats.selectors.values
|
|
41
|
-
for (const selector of selectors) {
|
|
42
|
-
immutableSelectors.set(selector, bundle)
|
|
43
|
-
for (const classSelector of getClassSelectors(selector)) {
|
|
44
|
-
immutableClassSelectors.set(classSelector, bundle)
|
|
45
|
-
}
|
|
32
|
+
const selectors = primerJson.selectors.values
|
|
33
|
+
for (const selector of selectors) {
|
|
34
|
+
immutableSelectors.add(selector)
|
|
35
|
+
for (const classSelector of getClassSelectors(selector)) {
|
|
36
|
+
immutableClassSelectors.add(classSelector)
|
|
46
37
|
}
|
|
47
38
|
}
|
|
48
39
|
|
|
49
40
|
const messages = stylelint.utils.ruleMessages(ruleName, {
|
|
50
|
-
rejected: ({rule, selector
|
|
51
|
-
const definedIn = ` (defined in @primer/css/${bundle})`
|
|
41
|
+
rejected: ({rule, selector}) => {
|
|
52
42
|
const ruleSelector = collapseWhitespace(rule.selector)
|
|
53
43
|
const context = selector === rule.selector ? '' : ` in "${ruleSelector}"`
|
|
54
|
-
return `"${collapseWhitespace(selector)}" should not be overridden${context}
|
|
44
|
+
return `Primer CSS class "${collapseWhitespace(selector)}" should not be overridden${context}.`
|
|
55
45
|
},
|
|
56
46
|
})
|
|
57
47
|
|
|
58
48
|
return (root, result) => {
|
|
59
|
-
if (!Array.isArray(bundles) || bundles.some(bundle => !availableBundles.includes(bundle))) {
|
|
60
|
-
const invalidBundles = Array.isArray(bundles)
|
|
61
|
-
? `"${bundles.filter(bundle => !availableBundles.includes(bundle)).join('", "')}"`
|
|
62
|
-
: '(not an array)'
|
|
63
|
-
result.warn(`The "bundles" option must be an array of valid bundles; got: ${invalidBundles}`, {
|
|
64
|
-
stylelintType: 'invalidOption',
|
|
65
|
-
stylelintReference: 'https://github.com/primer/stylelint-config#options',
|
|
66
|
-
})
|
|
67
|
-
}
|
|
68
|
-
|
|
69
49
|
const report = subject =>
|
|
70
50
|
stylelint.utils.report({
|
|
71
51
|
message: messages.rejected(subject),
|
|
@@ -81,7 +61,6 @@ module.exports = stylelint.createPlugin(ruleName, (enabled, options = {}) => {
|
|
|
81
61
|
if (!isSelectorIgnored(selector)) {
|
|
82
62
|
return report({
|
|
83
63
|
rule,
|
|
84
|
-
bundle: immutableSelectors.get(selector),
|
|
85
64
|
selector,
|
|
86
65
|
})
|
|
87
66
|
}
|
|
@@ -94,7 +73,6 @@ module.exports = stylelint.createPlugin(ruleName, (enabled, options = {}) => {
|
|
|
94
73
|
if (!isSelectorIgnored(classSelector)) {
|
|
95
74
|
return report({
|
|
96
75
|
rule,
|
|
97
|
-
bundle: immutableClassSelectors.get(classSelector),
|
|
98
76
|
selector: classSelector,
|
|
99
77
|
})
|
|
100
78
|
}
|
|
@@ -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-scale-colors'
|
|
5
|
-
const messages = stylelint.utils.ruleMessages(ruleName, {
|
|
4
|
+
export const ruleName = 'primer/no-scale-colors'
|
|
5
|
+
export const messages = stylelint.utils.ruleMessages(ruleName, {
|
|
6
6
|
rejected: varName =>
|
|
7
7
|
`${varName} is a non-functional scale color and cannot be used without being wrapped in the color-variables mixin`,
|
|
8
8
|
})
|
|
@@ -11,7 +11,7 @@ const messages = stylelint.utils.ruleMessages(ruleName, {
|
|
|
11
11
|
// eslint-disable-next-line no-useless-escape
|
|
12
12
|
const variableReferenceRegex = /var\(([^\),]+)(,.*)?\)/g
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
export default stylelint.createPlugin(ruleName, (enabled, options = {}) => {
|
|
15
15
|
if (!enabled) {
|
|
16
16
|
return noop
|
|
17
17
|
}
|
|
@@ -49,6 +49,3 @@ module.exports = stylelint.createPlugin(ruleName, (enabled, options = {}) => {
|
|
|
49
49
|
})
|
|
50
50
|
|
|
51
51
|
function noop() {}
|
|
52
|
-
|
|
53
|
-
module.exports.ruleName = ruleName
|
|
54
|
-
module.exports.messages = messages
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const ruleName = 'primer/no-undefined-vars'
|
|
8
|
-
const messages = stylelint.utils.ruleMessages(ruleName, {
|
|
1
|
+
import fs from 'fs'
|
|
2
|
+
import stylelint from 'stylelint'
|
|
3
|
+
import matchAll from 'string.prototype.matchall'
|
|
4
|
+
import globby from 'globby'
|
|
5
|
+
import TapMap from 'tap-map'
|
|
6
|
+
|
|
7
|
+
export const ruleName = 'primer/no-undefined-vars'
|
|
8
|
+
export const messages = stylelint.utils.ruleMessages(ruleName, {
|
|
9
9
|
rejected: varName => `${varName} is not defined`,
|
|
10
10
|
})
|
|
11
11
|
|
|
@@ -19,7 +19,7 @@ const colorModeVariableDefinitionRegex = /^[^/\n]*\(["']?([^'"\s,]+)["']?,\s*\(l
|
|
|
19
19
|
// eslint-disable-next-line no-useless-escape
|
|
20
20
|
const variableReferenceRegex = /var\(([^\),]+)(,.*)?\)/g
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
export default stylelint.createPlugin(ruleName, (enabled, options = {}) => {
|
|
23
23
|
if (!enabled) {
|
|
24
24
|
return noop
|
|
25
25
|
}
|
|
@@ -116,6 +116,3 @@ function getDefinedVariables(globs, log) {
|
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
function noop() {}
|
|
119
|
-
|
|
120
|
-
module.exports.ruleName = ruleName
|
|
121
|
-
module.exports.messages = messages
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import TapMap from 'tap-map'
|
|
2
|
+
import globby from 'globby'
|
|
3
|
+
import matchAll from 'string.prototype.matchall'
|
|
4
|
+
import stylelint from 'stylelint'
|
|
5
|
+
import {readFileSync} from 'fs'
|
|
6
6
|
|
|
7
|
-
const ruleName = 'primer/no-unused-vars'
|
|
7
|
+
export const ruleName = 'primer/no-unused-vars'
|
|
8
8
|
|
|
9
9
|
const cwd = process.cwd()
|
|
10
10
|
const COLON = ':'
|
|
11
11
|
const SCSS_VARIABLE_PATTERN = /(\$[-\w]+)/g
|
|
12
12
|
|
|
13
|
-
const messages = stylelint.utils.ruleMessages(ruleName, {
|
|
13
|
+
export const messages = stylelint.utils.ruleMessages(ruleName, {
|
|
14
14
|
rejected: name => `The variable "${name}" is not referenced.`,
|
|
15
15
|
})
|
|
16
16
|
|
|
17
17
|
const cache = new TapMap()
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
export default stylelint.createPlugin(ruleName, (enabled, options = {}) => {
|
|
20
20
|
if (!enabled) {
|
|
21
21
|
return noop
|
|
22
22
|
}
|
|
@@ -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,6 +1,6 @@
|
|
|
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
5
|
// TODO: Pull this in from primer/primitives
|
|
6
6
|
const spacerValues = {
|
|
@@ -24,11 +24,11 @@ const spacerValues = {
|
|
|
24
24
|
'$em-spacer-6': '0.75em',
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
const ruleName = 'primer/spacing'
|
|
28
|
-
const messages = stylelint.utils.ruleMessages(ruleName, {
|
|
27
|
+
export const ruleName = 'primer/spacing'
|
|
28
|
+
export const messages = stylelint.utils.ruleMessages(ruleName, {
|
|
29
29
|
rejected: (value, replacement) => {
|
|
30
30
|
if (replacement === null) {
|
|
31
|
-
return `Please use a primer spacer variable instead of '${value}'. Consult the primer docs for a suitable replacement. https://primer.style/css/support
|
|
31
|
+
return `Please use a primer spacer variable instead of '${value}'. Consult the primer docs for a suitable replacement. https://primer.style/css/storybook/?path=/docs/support-spacing--docs`
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
return `Please replace ${value} with spacing variable '${replacement}'.`
|
|
@@ -47,7 +47,7 @@ const walkGroups = (root, validate) => {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
// eslint-disable-next-line no-unused-vars
|
|
50
|
-
|
|
50
|
+
export default stylelint.createPlugin(ruleName, (enabled, options = {}, context) => {
|
|
51
51
|
if (!enabled) {
|
|
52
52
|
return noop
|
|
53
53
|
}
|
|
@@ -126,6 +126,3 @@ module.exports = stylelint.createPlugin(ruleName, (enabled, options = {}, contex
|
|
|
126
126
|
})
|
|
127
127
|
|
|
128
128
|
function noop() {}
|
|
129
|
-
|
|
130
|
-
module.exports.ruleName = ruleName
|
|
131
|
-
module.exports.messages = messages
|
package/plugins/typography.js
CHANGED
package/plugins/utilities.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import stylelint from 'stylelint'
|
|
2
|
+
import utilities from './lib/primer-utilities.js'
|
|
3
3
|
|
|
4
|
-
const ruleName = 'primer/utilities'
|
|
4
|
+
export const ruleName = 'primer/utilities'
|
|
5
5
|
|
|
6
|
-
const messages = stylelint.utils.ruleMessages(ruleName, {
|
|
6
|
+
export const messages = stylelint.utils.ruleMessages(ruleName, {
|
|
7
7
|
rejected: (selector, utilityClass) => {
|
|
8
8
|
return `Consider using the Primer utility '.${utilityClass}' instead of the selector '${selector}' in your html. https://primer.style/css/utilities`
|
|
9
9
|
},
|
|
10
10
|
})
|
|
11
11
|
|
|
12
12
|
// eslint-disable-next-line no-unused-vars
|
|
13
|
-
|
|
13
|
+
export default stylelint.createPlugin(ruleName, (enabled, options = {}, context) => {
|
|
14
14
|
if (!enabled) {
|
|
15
15
|
return noop
|
|
16
16
|
}
|
|
@@ -50,6 +50,3 @@ module.exports = stylelint.createPlugin(ruleName, (enabled, options = {}, contex
|
|
|
50
50
|
})
|
|
51
51
|
|
|
52
52
|
function noop() {}
|
|
53
|
-
|
|
54
|
-
module.exports.ruleName = ruleName
|
|
55
|
-
module.exports.messages = messages
|
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
|
-
}
|
package/plugins/lib/primer.js
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
const {existsSync} = require('fs')
|
|
2
|
-
const {join} = require('path')
|
|
3
|
-
|
|
4
|
-
module.exports = {
|
|
5
|
-
getPrimerModuleDir,
|
|
6
|
-
requirePrimerFile,
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
function getPrimerModuleDir() {
|
|
10
|
-
const cwd = process.cwd()
|
|
11
|
-
const localPackageJson = join(cwd, 'package.json')
|
|
12
|
-
if (existsSync(localPackageJson)) {
|
|
13
|
-
// eslint-disable-next-line import/no-dynamic-require
|
|
14
|
-
const {name} = require(localPackageJson)
|
|
15
|
-
if (name === '@primer/css') {
|
|
16
|
-
return cwd
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
return '@primer/css'
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function requirePrimerFile(path) {
|
|
23
|
-
const fullPath = join(getPrimerModuleDir(), path)
|
|
24
|
-
// eslint-disable-next-line import/no-dynamic-require
|
|
25
|
-
return require(fullPath)
|
|
26
|
-
}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
const stylelint = require('stylelint')
|
|
2
|
-
const declarationValueIndex = require('stylelint/lib/utils/declarationValueIndex')
|
|
3
|
-
|
|
4
|
-
const ruleName = 'primer/no-experimental-vars'
|
|
5
|
-
const messages = stylelint.utils.ruleMessages(ruleName, {
|
|
6
|
-
rejected: value => {
|
|
7
|
-
return `Do not use experimental variable \`var(--${value})\`. Experimental variables are undergoing testing, see https://github.com/github/primer/issues/889 for more details.`
|
|
8
|
-
},
|
|
9
|
-
})
|
|
10
|
-
|
|
11
|
-
// eslint-disable-next-line no-unused-vars
|
|
12
|
-
module.exports = stylelint.createPlugin(ruleName, (enabled, options = {}, context) => {
|
|
13
|
-
if (!enabled) {
|
|
14
|
-
return noop
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
// eslint-disable-next-line import/no-dynamic-require
|
|
18
|
-
const designTokens = require(options.designTokens)
|
|
19
|
-
|
|
20
|
-
let experimentalVars = null
|
|
21
|
-
for (const tokenType of Object.keys(designTokens)) {
|
|
22
|
-
experimentalVars = new Set(designTokens[tokenType].map(t => t['name']))
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const lintResult = (root, result) => {
|
|
26
|
-
root.walkDecls(decl => {
|
|
27
|
-
for (const expVar of experimentalVars) {
|
|
28
|
-
if (decl.value.includes(`var(--${expVar})`)) {
|
|
29
|
-
stylelint.utils.report({
|
|
30
|
-
index: declarationValueIndex(decl),
|
|
31
|
-
message: messages.rejected(expVar),
|
|
32
|
-
node: decl,
|
|
33
|
-
result,
|
|
34
|
-
ruleName,
|
|
35
|
-
})
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
})
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
return lintResult
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
function noop() {}
|
|
45
|
-
|
|
46
|
-
module.exports.ruleName = ruleName
|
|
47
|
-
module.exports.messages = messages
|