@double-great/stylelint-a11y 2.0.0

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.
Files changed (80) hide show
  1. package/.babelrc +3 -0
  2. package/.eslintignore +2 -0
  3. package/.eslintrc.js +27 -0
  4. package/.github/dependabot.yml +10 -0
  5. package/.github/workflows/test.yml +21 -0
  6. package/.husky/pre-commit +4 -0
  7. package/LICENSE +21 -0
  8. package/README.md +68 -0
  9. package/dist/index.js +18 -0
  10. package/dist/rules/content-property-no-static-value/__tests__/index.js +37 -0
  11. package/dist/rules/content-property-no-static-value/index.js +90 -0
  12. package/dist/rules/font-size-is-readable/__tests__/index.js +35 -0
  13. package/dist/rules/font-size-is-readable/index.js +77 -0
  14. package/dist/rules/index.js +48 -0
  15. package/dist/rules/line-height-is-vertical-rhythmed/__tests__/index.js +59 -0
  16. package/dist/rules/line-height-is-vertical-rhythmed/index.js +84 -0
  17. package/dist/rules/media-prefers-color-scheme/__tests__/index.js +47 -0
  18. package/dist/rules/media-prefers-color-scheme/index.js +121 -0
  19. package/dist/rules/media-prefers-reduced-motion/__tests__/index.js +41 -0
  20. package/dist/rules/media-prefers-reduced-motion/index.js +175 -0
  21. package/dist/rules/no-display-none/__tests__/index.js +17 -0
  22. package/dist/rules/no-display-none/index.js +76 -0
  23. package/dist/rules/no-obsolete-attribute/__tests__/index.js +27 -0
  24. package/dist/rules/no-obsolete-attribute/index.js +78 -0
  25. package/dist/rules/no-obsolete-attribute/obsoleteAttributes.js +8 -0
  26. package/dist/rules/no-obsolete-element/__tests__/index.js +27 -0
  27. package/dist/rules/no-obsolete-element/index.js +78 -0
  28. package/dist/rules/no-obsolete-element/obsoleteElements.js +8 -0
  29. package/dist/rules/no-outline-none/__tests__/index.js +40 -0
  30. package/dist/rules/no-outline-none/index.js +88 -0
  31. package/dist/rules/no-spread-text/__tests__/index.js +32 -0
  32. package/dist/rules/no-spread-text/index.js +75 -0
  33. package/dist/rules/no-text-align-justify/__tests__/index.js +32 -0
  34. package/dist/rules/no-text-align-justify/index.js +76 -0
  35. package/dist/rules/selector-pseudo-class-focus/__tests__/index.js +46 -0
  36. package/dist/rules/selector-pseudo-class-focus/index.js +121 -0
  37. package/jest.config.js +20 -0
  38. package/jest.setup.js +5 -0
  39. package/package.json +63 -0
  40. package/recommended.js +8 -0
  41. package/src/index.js +8 -0
  42. package/src/rules/content-property-no-static-value/README.md +34 -0
  43. package/src/rules/content-property-no-static-value/__tests__/index.js +48 -0
  44. package/src/rules/content-property-no-static-value/index.js +72 -0
  45. package/src/rules/font-size-is-readable/README.md +34 -0
  46. package/src/rules/font-size-is-readable/__tests__/index.js +45 -0
  47. package/src/rules/font-size-is-readable/index.js +57 -0
  48. package/src/rules/index.js +27 -0
  49. package/src/rules/line-height-is-vertical-rhythmed/README.md +51 -0
  50. package/src/rules/line-height-is-vertical-rhythmed/__tests__/index.js +75 -0
  51. package/src/rules/line-height-is-vertical-rhythmed/index.js +61 -0
  52. package/src/rules/media-prefers-color-scheme/README.md +72 -0
  53. package/src/rules/media-prefers-color-scheme/__tests__/index.js +60 -0
  54. package/src/rules/media-prefers-color-scheme/index.js +115 -0
  55. package/src/rules/media-prefers-reduced-motion/README.md +60 -0
  56. package/src/rules/media-prefers-reduced-motion/__tests__/index.js +55 -0
  57. package/src/rules/media-prefers-reduced-motion/index.js +164 -0
  58. package/src/rules/no-display-none/README.md +27 -0
  59. package/src/rules/no-display-none/__tests__/index.js +21 -0
  60. package/src/rules/no-display-none/index.js +58 -0
  61. package/src/rules/no-obsolete-attribute/README.md +35 -0
  62. package/src/rules/no-obsolete-attribute/__tests__/index.js +33 -0
  63. package/src/rules/no-obsolete-attribute/index.js +58 -0
  64. package/src/rules/no-obsolete-attribute/obsoleteAttributes.js +204 -0
  65. package/src/rules/no-obsolete-element/README.md +20 -0
  66. package/src/rules/no-obsolete-element/__tests__/index.js +33 -0
  67. package/src/rules/no-obsolete-element/index.js +57 -0
  68. package/src/rules/no-obsolete-element/obsoleteElements.js +32 -0
  69. package/src/rules/no-outline-none/README.md +84 -0
  70. package/src/rules/no-outline-none/__tests__/index.js +51 -0
  71. package/src/rules/no-outline-none/index.js +75 -0
  72. package/src/rules/no-spread-text/README.md +50 -0
  73. package/src/rules/no-spread-text/__tests__/index.js +42 -0
  74. package/src/rules/no-spread-text/index.js +72 -0
  75. package/src/rules/no-text-align-justify/README.md +52 -0
  76. package/src/rules/no-text-align-justify/__tests__/index.js +42 -0
  77. package/src/rules/no-text-align-justify/index.js +60 -0
  78. package/src/rules/selector-pseudo-class-focus/README.md +43 -0
  79. package/src/rules/selector-pseudo-class-focus/__tests__/index.js +51 -0
  80. package/src/rules/selector-pseudo-class-focus/index.js +85 -0
@@ -0,0 +1,204 @@
1
+ export const obsoleteAttributes = new Set([
2
+ '[dropzone]',
3
+ 'a[charset]',
4
+ 'link[charset]',
5
+ 'a[coords]',
6
+ 'a[shape]',
7
+ 'a[methods]',
8
+ 'link[methods]',
9
+ 'a[name]',
10
+ 'option[name]',
11
+ 'embed[name]',
12
+ 'img[name]',
13
+ 'a[rev]',
14
+ 'link[rev]',
15
+ 'a[urn]',
16
+ 'link[urn]',
17
+ 'form[accept]',
18
+ 'head[profile]',
19
+ 'html[version]',
20
+ 'link[target]',
21
+ 'param[type]',
22
+ 'param[valuetype]',
23
+ 'script[language]',
24
+ 'script[event]',
25
+ 'script[for]',
26
+ 'table[datapagesize]',
27
+ 'table[summary]',
28
+ 'td[axis]',
29
+ 'th[axis]',
30
+ 'td[scope]',
31
+ 'td[abbr]',
32
+ 'a[datasrc]',
33
+ 'applet[datasrc]',
34
+ 'button[datasrc]',
35
+ 'div[datasrc]',
36
+ 'frame[datasrc]',
37
+ 'label[datasrc]',
38
+ 'legend[datasrc]',
39
+ 'marquee[datasrc]',
40
+ 'option[datasrc]',
41
+ 'span[datasrc]',
42
+ 'table[datasrc]',
43
+ 'a[datafld]',
44
+ 'applet[datafld]',
45
+ 'button[datafld]',
46
+ 'div[datafld]',
47
+ 'fieldset[datafld]',
48
+ 'frame[datafld]',
49
+ 'label[datafld]',
50
+ 'legend[datafld]',
51
+ 'marquee[datafld]',
52
+ 'param[datafld]',
53
+ 'span[datafld]',
54
+ 'button[dataformatas]',
55
+ 'div[dataformatas]',
56
+ 'label[dataformatas]',
57
+ 'legend[dataformatas]',
58
+ 'marquee[dataformatas]',
59
+ 'option[dataformatas]',
60
+ 'span[dataformatas]',
61
+ 'table[dataformatas]',
62
+ 'body[alink]',
63
+ 'body[bgcolor]',
64
+ 'table[bgcolor]',
65
+ 'td[bgcolor]',
66
+ 'th[bgcolor]',
67
+ 'tr[bgcolor]',
68
+ 'body[link]',
69
+ 'body[marginbottom]',
70
+ 'body[marginheight]',
71
+ 'body[marginleft]',
72
+ 'body[marginright]',
73
+ 'body[margintop]',
74
+ 'body[marginwidth]',
75
+ 'body[text]',
76
+ 'body[vlink]',
77
+ 'col[char]',
78
+ 'tbody[char]',
79
+ 'thead[char]',
80
+ 'tfoot[char]',
81
+ 'td[char]',
82
+ 'th[char]',
83
+ 'tr[char]',
84
+ 'col[charoff]',
85
+ 'tbody[charoff]',
86
+ 'thead[charoff]',
87
+ 'tfoot[charoff]',
88
+ 'td[charoff]',
89
+ 'th[charoff]',
90
+ 'tr[charoff]',
91
+ 'col[valign]',
92
+ 'tbody[valign]',
93
+ 'thead[valign]',
94
+ 'tfoot[valign]',
95
+ 'td[valign]',
96
+ 'th[valign]',
97
+ 'tr[valign]',
98
+ 'col[width]',
99
+ 'pre[width]',
100
+ 'table[width]',
101
+ 'td[width]',
102
+ 'th[width]',
103
+ 'dl[compact]',
104
+ 'ol[compact]',
105
+ 'ul[compact]',
106
+ 'h1[align]',
107
+ 'h2[align]',
108
+ 'h3[align]',
109
+ 'h4[align]',
110
+ 'h5[align]',
111
+ 'h6[align]',
112
+ 'caption[align]',
113
+ 'col[align]',
114
+ 'div[align]',
115
+ 'legend[align]',
116
+ 'p[align]',
117
+ 'table[align]',
118
+ 'tbody[align]',
119
+ 'thead[align]',
120
+ 'tfoot[align]',
121
+ 'td[align]',
122
+ 'th[align]',
123
+ 'tr[align]',
124
+ 'li[type]',
125
+ 'ul[type]',
126
+ 'table[cellpadding]',
127
+ 'table[cellspacing]',
128
+ 'table[frame]',
129
+ 'table[rules]',
130
+ 'td[height]',
131
+ 'th[height]',
132
+ 'td[nowrap]',
133
+ 'th[nowrap]',
134
+ 'body[background]',
135
+ 'table[background]',
136
+ 'thead[background]',
137
+ 'tbody[background]',
138
+ 'tfoot[background]',
139
+ 'tr[background]',
140
+ 'td[background]',
141
+ 'th[background]',
142
+ 'embed[name]',
143
+ 'img[name]',
144
+ 'area[nohref]',
145
+ 'area[type]',
146
+ 'area[hreflang]',
147
+ 'input[ismap]',
148
+ 'input[usemap]',
149
+ 'iframe[longdesc]',
150
+ 'img[longdesc]',
151
+ 'img[lowsrc]',
152
+ 'object[archive]',
153
+ 'object[classid]',
154
+ 'object[code]',
155
+ 'object[codebase]',
156
+ 'object[codetype]',
157
+ 'object[declare]',
158
+ 'object[standby]',
159
+ 'iframe[datasrc]',
160
+ 'img[datasrc]',
161
+ 'input[datasrc]',
162
+ 'object[datasrc]',
163
+ 'select[datasrc]',
164
+ 'textarea[datasrc]',
165
+ 'iframe[datafld]',
166
+ 'img[datafld]',
167
+ 'input[datafld]',
168
+ 'object[datafld]',
169
+ 'select[datafld]',
170
+ 'textarea[datafld]',
171
+ 'input[dataformatas]',
172
+ 'object[dataformatas]',
173
+ 'select[dataformatas]',
174
+ 'iframe[marginheight]',
175
+ 'iframe[marginwidth]',
176
+ 'br[clear]',
177
+ 'hr[width]',
178
+ 'embed[hspace]',
179
+ 'iframe[hspace]',
180
+ 'input[hspace]',
181
+ 'img[hspace]',
182
+ 'object[hspace]',
183
+ 'embed[vspace]',
184
+ 'iframe[vspace]',
185
+ 'input[vspace]',
186
+ 'img[vspace]',
187
+ 'object[vspace]',
188
+ 'hr[color]',
189
+ 'hr[noshade]',
190
+ 'hr[size]',
191
+ 'iframe[align]',
192
+ 'embed[align]',
193
+ 'hr[align]',
194
+ 'input[align]',
195
+ 'img[align]',
196
+ 'object[align]',
197
+ 'iframe[allowtransparency]',
198
+ 'iframe[frameborder]',
199
+ 'iframe[framespacing]',
200
+ 'iframe[scrolling]',
201
+ 'img[border]',
202
+ 'object[border]',
203
+ 'input[inputmode]',
204
+ ]);
@@ -0,0 +1,20 @@
1
+ # no-obsolete-element
2
+
3
+ Disallow obsolete selectors using.
4
+
5
+ **Sources:**
6
+
7
+ - [W3G Obsolete features](https://www.w3.org/TR/html5/obsolete.html#obsolete)
8
+ - [W3G Features removed](https://www.w3.org/TR/html52/changes.html#features-removed)
9
+
10
+ ## Options
11
+
12
+ ### true
13
+
14
+ The following pattern are considered violations:
15
+
16
+ ```css
17
+ blink {
18
+ color: pink;
19
+ }
20
+ ```
@@ -0,0 +1,33 @@
1
+ import { ruleName, messages } from '../index';
2
+
3
+ testRule({
4
+ ruleName,
5
+ config: [true],
6
+
7
+ accept: [
8
+ {
9
+ code: '.foo { color: pink; }',
10
+ },
11
+ ],
12
+
13
+ reject: [
14
+ {
15
+ code: 'blink { color: pink; }',
16
+ message: messages.expected('blink'),
17
+ line: 1,
18
+ column: 3,
19
+ },
20
+ {
21
+ code: 'applet, a { color: pink; }',
22
+ message: messages.expected('applet, a'),
23
+ line: 1,
24
+ column: 3,
25
+ },
26
+ {
27
+ code: 'applet, blink { color: pink; }',
28
+ message: messages.expected('applet, blink'),
29
+ line: 1,
30
+ column: 3,
31
+ },
32
+ ],
33
+ });
@@ -0,0 +1,57 @@
1
+ import { utils } from 'stylelint';
2
+ import isStandardSyntaxRule from 'stylelint/lib/utils/isStandardSyntaxRule';
3
+ import { obsoleteElements } from './obsoleteElements';
4
+
5
+ export const ruleName = 'a11y/no-obsolete-element';
6
+
7
+ export const messages = utils.ruleMessages(ruleName, {
8
+ expected: (selector) => `Unexpected using obsolete selector "${selector}"`,
9
+ });
10
+
11
+ function check(selector, node) {
12
+ if (node.type !== 'rule') {
13
+ return true;
14
+ }
15
+ return !node.selectors.some((sel) => {
16
+ return obsoleteElements.has(sel);
17
+ });
18
+ }
19
+
20
+ export default function (actual) {
21
+ return (root, result) => {
22
+ const validOptions = utils.validateOptions(result, ruleName, { actual });
23
+
24
+ if (!validOptions || !actual) {
25
+ return;
26
+ }
27
+
28
+ root.walk((node) => {
29
+ let selector = null;
30
+
31
+ if (node.type === 'rule') {
32
+ if (!isStandardSyntaxRule(node)) {
33
+ return;
34
+ }
35
+ selector = node.selector;
36
+ } else if (node.type === 'atrule' && node.name.toLowerCase() === 'page' && node.params) {
37
+ selector = node.params;
38
+ }
39
+
40
+ if (!selector) {
41
+ return;
42
+ }
43
+
44
+ const isAccepted = check(selector, node);
45
+
46
+ if (!isAccepted) {
47
+ utils.report({
48
+ index: node.lastEach,
49
+ message: messages.expected(selector),
50
+ node,
51
+ ruleName,
52
+ result,
53
+ });
54
+ }
55
+ });
56
+ };
57
+ }
@@ -0,0 +1,32 @@
1
+ export const obsoleteElements = new Set([
2
+ 'applet',
3
+ 'acronym',
4
+ 'bgsound',
5
+ 'dir',
6
+ 'frame',
7
+ 'frameset',
8
+ 'noframes',
9
+ 'hgroup',
10
+ 'isindex',
11
+ 'listing',
12
+ 'nextid',
13
+ 'noembed',
14
+ 'plaintext',
15
+ 'rb',
16
+ 'rtc',
17
+ 'strike',
18
+ 'xmp',
19
+ 'basefont',
20
+ 'big',
21
+ 'blink',
22
+ 'center',
23
+ 'font',
24
+ 'marquee',
25
+ 'multicol',
26
+ 'nobr',
27
+ 'spacer',
28
+ 'tt',
29
+ 'keygen',
30
+ 'menu',
31
+ 'menuitem',
32
+ ]);
@@ -0,0 +1,84 @@
1
+ # no-outline-none
2
+
3
+ Disallow outline clearing.
4
+
5
+ Why? [Because](https://www.w3.org/TR/2008/REC-WCAG20-20081211/#navigation-mechanisms-focus-visible)
6
+
7
+ **Sources:**
8
+
9
+ - [DON'T DO IT!](http://www.outlinenone.com/)
10
+ - [a11yproject](https://a11yproject.com/posts/never-remove-css-outlines/)
11
+ - [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/outline)
12
+
13
+ ## Options
14
+
15
+ ### true
16
+
17
+ The following pattern are considered violations:
18
+
19
+ ```css
20
+ .foo:focus {
21
+ outline: 0;
22
+ }
23
+ ```
24
+
25
+ ```css
26
+ .bar:focus {
27
+ outline: none;
28
+ }
29
+ ```
30
+
31
+ ```css
32
+ .baz:focus {
33
+ outline: none;
34
+ border: transparent;
35
+ }
36
+ ```
37
+
38
+ ```scss
39
+ .quux {
40
+ .quuux:focus {
41
+ outline: 0;
42
+ }
43
+ }
44
+ ```
45
+
46
+ The following patterns are _not_ considered violations:
47
+
48
+ ```css
49
+ .foo {
50
+ outline: 0;
51
+ }
52
+ ```
53
+
54
+ ```scss
55
+ $primary-color: #333;
56
+ .bar:focus {
57
+ outline: 1px solid $primary-color;
58
+ }
59
+ ```
60
+
61
+ ```css
62
+ .baz:focus {
63
+ outline: 1px solid #333;
64
+ }
65
+ ```
66
+
67
+ ```css
68
+ .quux:focus {
69
+ outline: 0;
70
+ border: 1px solid #000;
71
+ }
72
+ ```
73
+
74
+ ## Note
75
+
76
+ [Similar rule](https://github.com/stylelint/stylelint/blob/master/lib/rules/declaration-property-value-blacklist/README.md) is in [Stylelint](https://github.com/stylelint/stylelint), but it triggers another error message and does not check for `:focus` selector and `border` property.
77
+
78
+ ```json
79
+ {
80
+ "declaration-property-value-blacklist": {
81
+ "outline": ["none", "0"]
82
+ }
83
+ }
84
+ ```
@@ -0,0 +1,51 @@
1
+ import { messages, ruleName } from '../index';
2
+
3
+ testRule({
4
+ ruleName,
5
+ config: [true],
6
+
7
+ accept: [
8
+ {
9
+ code: '.foo { outline: 0; }',
10
+ },
11
+ {
12
+ code: '$primary-color: #333; .bar:focus { outline: 1px solid $primary-color; }',
13
+ },
14
+ {
15
+ code: '.baz:focus { outline: none; border-color: #333; }',
16
+ },
17
+ {
18
+ code: '.quux:focus { outline: 0; border: 1px solid #000; }',
19
+ },
20
+ {
21
+ code: '.quuux:focus { outline: none; box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); }',
22
+ },
23
+ ],
24
+
25
+ reject: [
26
+ {
27
+ code: '.foo1:focus { outline: none; } .foo2:focus { outline: 1px solid red; }',
28
+ message: messages.expected('.foo1:focus'),
29
+ line: 1,
30
+ column: 3,
31
+ },
32
+ {
33
+ code: '.bar:focus { outline: none; }',
34
+ message: messages.expected('.bar:focus'),
35
+ line: 1,
36
+ column: 3,
37
+ },
38
+ {
39
+ code: '.baz:focus { outline: none; border: transparent; }',
40
+ message: messages.expected('.baz:focus'),
41
+ line: 1,
42
+ column: 3,
43
+ },
44
+ {
45
+ code: '.quux { .quuux:focus { outline: 0; } }',
46
+ message: messages.expected('.quuux:focus'),
47
+ line: 1,
48
+ column: 11,
49
+ },
50
+ ],
51
+ });
@@ -0,0 +1,75 @@
1
+ import { utils } from 'stylelint';
2
+ import isStandardSyntaxRule from 'stylelint/lib/utils/isStandardSyntaxRule';
3
+
4
+ export const ruleName = 'a11y/no-outline-none';
5
+
6
+ export const messages = utils.ruleMessages(ruleName, {
7
+ expected: (selector) => `Unexpected using "outline" property in ${selector}`,
8
+ });
9
+
10
+ function check(selector, node) {
11
+ if (node.type !== 'rule') {
12
+ return true;
13
+ }
14
+
15
+ if (!selector.match(/:focus/gi)) {
16
+ return true;
17
+ }
18
+
19
+ const hasEmptyOutline = node.nodes.some(
20
+ (o) =>
21
+ o.type === 'decl' &&
22
+ o.prop.toLowerCase() === 'outline' &&
23
+ ['0', 'none'].indexOf(o.value.toLowerCase()) >= 0
24
+ );
25
+
26
+ if (hasEmptyOutline) {
27
+ return node.nodes.some(
28
+ (o) =>
29
+ o.type === 'decl' &&
30
+ ['border', 'border-color', 'box-shadow'].indexOf(o.prop.toLowerCase()) >= 0 &&
31
+ !o.value.toLowerCase().match(/transparent/gi)
32
+ );
33
+ }
34
+
35
+ return true;
36
+ }
37
+
38
+ export default function (actual) {
39
+ return (root, result) => {
40
+ const validOptions = utils.validateOptions(result, ruleName, { actual });
41
+
42
+ if (!validOptions || !actual) {
43
+ return;
44
+ }
45
+
46
+ root.walk((node) => {
47
+ let selector = null;
48
+
49
+ if (node.type === 'rule') {
50
+ if (!isStandardSyntaxRule(node)) {
51
+ return;
52
+ }
53
+ selector = node.selector;
54
+ } else if (node.type === 'atrule' && node.name.toLowerCase() === 'page' && node.params) {
55
+ selector = node.params;
56
+ }
57
+
58
+ if (!selector) {
59
+ return;
60
+ }
61
+
62
+ const isAccepted = check(selector, node);
63
+
64
+ if (!isAccepted) {
65
+ utils.report({
66
+ index: node.lastEach,
67
+ message: messages.expected(selector),
68
+ node,
69
+ ruleName,
70
+ result,
71
+ });
72
+ }
73
+ });
74
+ };
75
+ }
@@ -0,0 +1,50 @@
1
+ # no-spread-text
2
+
3
+ Require width of text greater than 45 characters and less than 80 characters.
4
+
5
+ **Sources:**
6
+
7
+ - [Ryan Mack](https://ryanmack.me/quick-measure)
8
+ - [Manuel Matuzovic](https://medium.com/@matuzo/writing-css-with-accessibility-in-mind-8514a0007939)
9
+
10
+ > Warning! This rule use some heuristics for define css node with styles for text. It may be unstable.
11
+
12
+ ## Options
13
+
14
+ ### true
15
+
16
+ The following pattern are considered violations:
17
+
18
+ ```css
19
+ .foo {
20
+ text-transform: lowercase;
21
+ max-width: 40ch;
22
+ }
23
+ ```
24
+
25
+ ```css
26
+ .foo {
27
+ line-height: 1.8;
28
+ max-width: 82ch;
29
+ }
30
+ ```
31
+
32
+ The following patterns are _not_ considered violations:
33
+
34
+ ```css
35
+ .foo {
36
+ max-width: 65ch;
37
+ }
38
+ ```
39
+
40
+ ```css
41
+ .foo {
42
+ max-width: 82ch;
43
+ }
44
+ ```
45
+
46
+ ```css
47
+ .foo {
48
+ max-width: 100px;
49
+ }
50
+ ```
@@ -0,0 +1,42 @@
1
+ import { messages, ruleName } from '../index';
2
+
3
+ testRule({
4
+ ruleName,
5
+ config: [true],
6
+
7
+ accept: [
8
+ {
9
+ code: '.foo { }',
10
+ },
11
+ {
12
+ code: '.foo { display: flex; max-width: 82ch; }',
13
+ },
14
+ {
15
+ code: '.foo { height: 100%; max-width: 82ch; }',
16
+ },
17
+ {
18
+ code: '.foo { text-transform: lowercase; max-width: 65ch; }',
19
+ },
20
+ {
21
+ code: '.bar { word-spacing: -5px; max-width: 100px; }',
22
+ },
23
+ {
24
+ code: '.baz { MAX-WIDTH: 63CH; }',
25
+ },
26
+ ],
27
+
28
+ reject: [
29
+ {
30
+ code: '.foo { text-transform: lowercase; max-width: 40ch; }',
31
+ message: messages.expected('.foo'),
32
+ line: 1,
33
+ column: 3,
34
+ },
35
+ {
36
+ code: '.bar { LINE-HEIGHT: 1.8; MAX-WIDTH: 81CH; }',
37
+ message: messages.expected('.bar'),
38
+ line: 1,
39
+ column: 3,
40
+ },
41
+ ],
42
+ });