stylelint-gamut 1.3.2 → 1.3.3

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 CHANGED
@@ -1,14 +1,17 @@
1
1
  {
2
2
  "name": "stylelint-gamut",
3
- "version": "1.3.2",
3
+ "version": "1.3.3",
4
4
  "description": "Stylelint plugin for working with different color spaces",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
7
+ "format": "prettier --write",
8
+ "lint": "eslint --fix",
7
9
  "test": "jest",
8
10
  "prepare": "husky install"
9
11
  },
10
12
  "lint-staged": {
11
- "*.js": "eslint --fix"
13
+ "*.js": "npm run lint",
14
+ ".": "npm run format"
12
15
  },
13
16
  "engines": {
14
17
  "node": ">=16.0.0"
@@ -40,19 +43,21 @@
40
43
  "stylelint": "^14.0.0 || ^15.0.0"
41
44
  },
42
45
  "devDependencies": {
43
- "eslint": "^8.22.0",
44
- "eslint-config-standard": "^17.0.0",
45
- "eslint-plugin-import": "^2.26.0",
46
- "eslint-plugin-n": "^15.2.4",
47
- "eslint-plugin-promise": "^6.0.0",
48
- "husky": "^8.0.1",
49
- "jest": "^28.1.3",
50
- "jest-cli": "^28.1.3",
51
- "jest-preset-stylelint": "^5.0.4",
52
- "lint-staged": "^13.0.3",
53
- "stylelint": "^14.10.0"
46
+ "eslint": "^8.43.0",
47
+ "eslint-config-prettier": "^8.8.0",
48
+ "eslint-config-standard": "^17.1.0",
49
+ "eslint-plugin-import": "^2.27.5",
50
+ "eslint-plugin-n": "^16.0.0",
51
+ "eslint-plugin-promise": "^6.1.1",
52
+ "husky": "^8.0.3",
53
+ "jest": "^29.5.0",
54
+ "jest-cli": "^29.5.0",
55
+ "jest-preset-stylelint": "^6.1.0",
56
+ "lint-staged": "^13.2.2",
57
+ "prettier": "^2.8.8",
58
+ "stylelint": "^15.7.0"
54
59
  },
55
60
  "dependencies": {
56
- "colorjs.io": "^0.4.0"
61
+ "colorjs.io": "^0.4.5"
57
62
  }
58
63
  }
package/src/README.md CHANGED
@@ -4,9 +4,7 @@ Disallow out of gamut range colors.
4
4
 
5
5
  <!-- prettier-ignore -->
6
6
  ```css
7
- a { color: lch(48% 82 283) }
8
- /** ↑
9
- * This color is out of sRGB gamut range */
7
+ a { color: lch(48% 82 283) } /* This color is out of sRGB gamut range */
10
8
  ```
11
9
 
12
10
  Colors declared using lch, oklch, lab and oklab functions can move from sRGB to P3 or Rec2020 color spaces, which are not supported by most of screens right now. It can happen by mistake. For instance, by converting colors from one space to another.
@@ -17,20 +15,18 @@ This rule checks if the color is in sRGB, p3 or rec2020 space. If it's not in sR
17
15
  @media (color-gamut: p3) {
18
16
  a {
19
17
  color: lch(29.8% 42.5 109.485);
18
+ /* This color is in p3 gamut range */
20
19
  }
21
20
  }
22
- /** ↑
23
- * This color is in p3 gamut range */
24
21
  ```
25
22
 
26
23
  ```css
27
24
  @media (color-gamut: rec2020) {
28
25
  a {
29
26
  color: lch(25.1% 42.5 109.485);
27
+ /* This color is in rec2020 gamut range */
30
28
  }
31
29
  }
32
- /** ↑
33
- * This color is in rec2020 gamut range */
34
30
  ```
35
31
 
36
32
  In case of **css custom properties** you should wrap either the custom property declaration:
package/src/index.js CHANGED
@@ -1,97 +1,108 @@
1
- 'use strict'
1
+ "use strict";
2
2
 
3
- const stylelint = require('stylelint')
4
- const Color = require('colorjs.io').default
3
+ const stylelint = require("stylelint");
4
+ const Color = require("colorjs.io").default;
5
5
  const {
6
- isInColorGamutP3MediaQuery,
7
- isStandardSyntaxProperty,
8
- declarationValueIndex,
9
- isInColorGamutRec2020MediaQuery,
10
- startsWithNumber
11
- } = require('./utils')
6
+ isInColorGamutP3MediaQuery,
7
+ isStandardSyntaxProperty,
8
+ declarationValueIndex,
9
+ isInColorGamutRec2020MediaQuery,
10
+ startsWithNumber,
11
+ } = require("./utils");
12
12
 
13
- const ruleName = 'gamut/color-no-out-gamut-range'
13
+ const ruleName = "gamut/color-no-out-gamut-range";
14
14
 
15
15
  const messages = stylelint.utils.ruleMessages(ruleName, {
16
- rejected: (color) => `Unexpected color out of gamut range "${color}"`
17
- })
16
+ rejected: color => `Unexpected color out of gamut range "${color}"`,
17
+ });
18
18
 
19
19
  const meta = {
20
- url: 'https://github.com/fpetrakov/stylelint-gamut/blob/master/src/README.md'
21
- }
20
+ url: "https://github.com/fpetrakov/stylelint-gamut/blob/master/src/README.md",
21
+ };
22
22
 
23
23
  /** @type {import('stylelint').Rule} */
24
- const ruleFunction = (primary) => {
25
- return (root, result) => {
26
- const validOptions = stylelint.utils.validateOptions(result, ruleName, {
27
- actual: primary
28
- })
29
-
30
- if (!validOptions) {
31
- return
32
- }
33
-
34
- const customProperties = {}
35
-
36
- root.walkDecls((decl) => {
37
- if (!isStandardSyntaxProperty(decl.prop)) return
38
-
39
- const values = decl.value.match(/(oklch|oklab|lab|lch|var)\([^)]+\)/g)
40
- if (values) {
41
- for (const value of values) {
42
- check(value)
43
- }
44
- }
45
-
46
- // value is e.g. lch(48% 82 283 / 67%)
47
- function check (value) {
48
- const shouldBeIgnored =
49
- !value.startsWith('var(--') &&
50
- (
51
- value.includes('var(--') ||
52
- !startsWithNumber(value.split('(')[1])
53
- )
54
-
55
- if (shouldBeIgnored) return
56
-
57
- let customPropValue
58
- if (value.startsWith('var(--')) {
59
- const varName = value.slice(4, -1)
60
- if (customProperties[varName] && !customProperties[varName].inQuery) {
61
- customPropValue = customProperties[varName].value
62
- } else {
63
- return
64
- }
65
- }
66
-
67
- const color = new Color(customPropValue || value)
68
-
69
- if (color.inGamut('srgb')) return
70
- if (color.inGamut('p3') && isInColorGamutP3MediaQuery(decl)) return
71
- if (color.inGamut('rec2020') && isInColorGamutRec2020MediaQuery(decl)) return
72
-
73
- if (decl.prop && decl.prop.startsWith('--')) {
74
- customProperties[decl.prop] = { value: decl.value.trim(), inQuery: false }
75
- return
76
- }
77
-
78
- const index = declarationValueIndex(decl)
79
- const endIndex = index + decl.value.length
80
- stylelint.utils.report({
81
- message: messages.rejected(value),
82
- node: decl,
83
- index,
84
- endIndex,
85
- result,
86
- ruleName
87
- })
88
- }
89
- })
90
- }
91
- }
92
-
93
- ruleFunction.ruleName = ruleName
94
- ruleFunction.messages = messages
95
- ruleFunction.meta = meta
96
-
97
- module.exports = stylelint.createPlugin(ruleName, ruleFunction)
24
+ const ruleFunction = primary => {
25
+ return (root, result) => {
26
+ const validOptions = stylelint.utils.validateOptions(result, ruleName, {
27
+ actual: primary,
28
+ });
29
+
30
+ if (!validOptions) {
31
+ return;
32
+ }
33
+
34
+ const customProperties = {};
35
+
36
+ root.walkDecls(decl => {
37
+ if (!isStandardSyntaxProperty(decl.prop)) return;
38
+
39
+ const values = decl.value.match(
40
+ /(oklch|oklab|lab|lch|var)\([^)]+\)/g,
41
+ );
42
+ if (values) {
43
+ for (const value of values) {
44
+ check(value);
45
+ }
46
+ }
47
+
48
+ // value is e.g. lch(48% 82 283 / 67%)
49
+ function check(value) {
50
+ const shouldBeIgnored =
51
+ !value.startsWith("var(--") &&
52
+ (value.includes("var(--") ||
53
+ !startsWithNumber(value.split("(")[1]));
54
+
55
+ if (shouldBeIgnored) return;
56
+
57
+ let customPropValue;
58
+ if (value.startsWith("var(--")) {
59
+ const varName = value.slice(4, -1);
60
+ if (
61
+ customProperties[varName] &&
62
+ !customProperties[varName].inQuery
63
+ ) {
64
+ customPropValue = customProperties[varName].value;
65
+ } else {
66
+ return;
67
+ }
68
+ }
69
+
70
+ const color = new Color(customPropValue || value);
71
+
72
+ if (color.inGamut("srgb")) return;
73
+ if (color.inGamut("p3") && isInColorGamutP3MediaQuery(decl))
74
+ return;
75
+ if (
76
+ color.inGamut("rec2020") &&
77
+ isInColorGamutRec2020MediaQuery(decl)
78
+ )
79
+ return;
80
+
81
+ if (decl.prop && decl.prop.startsWith("--")) {
82
+ customProperties[decl.prop] = {
83
+ value: decl.value.trim(),
84
+ inQuery: false,
85
+ };
86
+ return;
87
+ }
88
+
89
+ const index = declarationValueIndex(decl);
90
+ const endIndex = index + decl.value.length;
91
+ stylelint.utils.report({
92
+ message: messages.rejected(value),
93
+ node: decl,
94
+ index,
95
+ endIndex,
96
+ result,
97
+ ruleName,
98
+ });
99
+ }
100
+ });
101
+ };
102
+ };
103
+
104
+ ruleFunction.ruleName = ruleName;
105
+ ruleFunction.messages = messages;
106
+ ruleFunction.meta = meta;
107
+
108
+ module.exports = stylelint.createPlugin(ruleName, ruleFunction);
package/src/utils.js CHANGED
@@ -1,4 +1,4 @@
1
- 'use strict'
1
+ "use strict";
2
2
 
3
3
  /**
4
4
  * Get the index of a declaration's value
@@ -6,22 +6,22 @@
6
6
  * @param {import('postcss').Declaration} decl
7
7
  * @returns {number}
8
8
  */
9
- function declarationValueIndex (decl) {
10
- const raws = decl.raws
11
-
12
- return [
13
- raws.prop && raws.prop.prefix,
14
- (raws.prop && raws.prop.raw) || decl.prop,
15
- raws.prop && raws.prop.suffix,
16
- raws.between || ':',
17
- raws.value && raws.value.prefix
18
- ].reduce((count, str) => {
19
- if (str) {
20
- return count + str.length
21
- }
22
-
23
- return count
24
- }, 0)
9
+ function declarationValueIndex(decl) {
10
+ const raws = decl.raws;
11
+
12
+ return [
13
+ raws.prop && raws.prop.prefix,
14
+ (raws.prop && raws.prop.raw) || decl.prop,
15
+ raws.prop && raws.prop.suffix,
16
+ raws.between || ":",
17
+ raws.value && raws.value.prefix,
18
+ ].reduce((count, str) => {
19
+ if (str) {
20
+ return count + str.length;
21
+ }
22
+
23
+ return count;
24
+ }, 0);
25
25
  }
26
26
 
27
27
  /**
@@ -30,83 +30,89 @@ function declarationValueIndex (decl) {
30
30
  * @param {string} property
31
31
  * @return {boolean} If `true`, the property is standard
32
32
  */
33
- function isStandardSyntaxProperty (property) {
34
- // SCSS var (e.g. $var: x), list (e.g. $list: (x)) or map (e.g. $map: (key:value))
35
- if (property.startsWith('$')) {
36
- return false
37
- }
38
-
39
- // Less var (e.g. @var: x)
40
- if (property.startsWith('@')) {
41
- return false
42
- }
43
-
44
- // SCSS or Less interpolation
45
- if (/#{.+?}|@{.+?}|\$\(.+?\)/.test(property)) {
46
- return false
47
- }
48
-
49
- return true
33
+ function isStandardSyntaxProperty(property) {
34
+ // SCSS var (e.g. $var: x), list (e.g. $list: (x)) or map (e.g. $map: (key:value))
35
+ if (property.startsWith("$")) {
36
+ return false;
37
+ }
38
+
39
+ // Less var (e.g. @var: x)
40
+ if (property.startsWith("@")) {
41
+ return false;
42
+ }
43
+
44
+ // SCSS or Less interpolation
45
+ if (/#{.+?}|@{.+?}|\$\(.+?\)/.test(property)) {
46
+ return false;
47
+ }
48
+
49
+ return true;
50
50
  }
51
51
 
52
52
  /**
53
53
  * @param {import('postcss').Declaration} decl
54
54
  * @returns {boolean}
55
55
  */
56
- function isInColorGamutP3MediaQuery (decl) {
57
- const parentMediaQuery = getMediaQueryParent(decl)
56
+ function isInColorGamutP3MediaQuery(decl) {
57
+ const parentMediaQuery = getMediaQueryParent(decl);
58
58
 
59
- if (parentMediaQuery && /\(color-gamut:\s*p3\)/.test(parentMediaQuery.params)) {
60
- return true
61
- }
59
+ if (
60
+ parentMediaQuery &&
61
+ /\(color-gamut:\s*p3\)/.test(parentMediaQuery.params)
62
+ ) {
63
+ return true;
64
+ }
62
65
 
63
- return false
66
+ return false;
64
67
  }
65
68
 
66
69
  /**
67
70
  * @param {import('postcss').Declaration} decl
68
71
  * @returns {boolean}
69
72
  */
70
- function isInColorGamutRec2020MediaQuery (decl) {
71
- const parentMediaQuery = getMediaQueryParent(decl)
73
+ function isInColorGamutRec2020MediaQuery(decl) {
74
+ const parentMediaQuery = getMediaQueryParent(decl);
72
75
 
73
- if (parentMediaQuery && /\(color-gamut:\s*rec2020\)/.test(parentMediaQuery.params)) {
74
- return true
75
- }
76
+ if (
77
+ parentMediaQuery &&
78
+ /\(color-gamut:\s*rec2020\)/.test(parentMediaQuery.params)
79
+ ) {
80
+ return true;
81
+ }
76
82
 
77
- return false
83
+ return false;
78
84
  }
79
85
 
80
86
  /**
81
87
  * @param {import('postcss').Declaration} decl
82
88
  * @returns {boolean | decl}
83
89
  */
84
- function getMediaQueryParent (decl) {
85
- let parent = decl.parent
90
+ function getMediaQueryParent(decl) {
91
+ let parent = decl.parent;
86
92
 
87
- if (parent && isMediaQuery(parent)) return parent
93
+ if (parent && isMediaQuery(parent)) return parent;
88
94
 
89
- parent = parent.parent
95
+ parent = parent.parent;
90
96
 
91
- return isMediaQuery(parent) && parent
97
+ return isMediaQuery(parent) && parent;
92
98
  }
93
99
 
94
100
  /**
95
101
  * @param {import('postcss').Declaration} decl
96
102
  * @returns {boolean}
97
103
  */
98
- function isMediaQuery (decl) {
99
- return decl.type === 'atrule' && decl.name === 'media'
104
+ function isMediaQuery(decl) {
105
+ return decl.type === "atrule" && decl.name === "media";
100
106
  }
101
107
 
102
- function startsWithNumber (str) {
103
- return /^\d/.test(str)
108
+ function startsWithNumber(str) {
109
+ return /^\d/.test(str);
104
110
  }
105
111
 
106
112
  module.exports = {
107
- isStandardSyntaxProperty,
108
- declarationValueIndex,
109
- isInColorGamutP3MediaQuery,
110
- isInColorGamutRec2020MediaQuery,
111
- startsWithNumber
112
- }
113
+ isStandardSyntaxProperty,
114
+ declarationValueIndex,
115
+ isInColorGamutP3MediaQuery,
116
+ isInColorGamutRec2020MediaQuery,
117
+ startsWithNumber,
118
+ };