@d-zero/stylelint-config 5.0.0-dev.92 → 5.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.
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2023 D-ZERO Co., Ltd.
3
+ Copyright (c) 2024 D-ZERO Co., Ltd.
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,4 +1,54 @@
1
1
  # `@d-zero/stylelint-config`
2
2
 
3
- - 使用: 🆗 使用可
4
- - 解説: 🚧 準備中
3
+ ## 個別インストール
4
+
5
+ ```sh
6
+ npm install -D @d-zero/stylelint-config
7
+ ```
8
+
9
+ ## 使い方
10
+
11
+ `.stylelintrc`を作成し、[`extends`](https://stylelint.io/user-guide/configure#extends)機能を使って読み込みます。
12
+
13
+ ```json
14
+ {
15
+ "extends": ["@d-zero/stylelint-config"]
16
+ }
17
+ ```
18
+
19
+ ### 拡張
20
+
21
+ プロジェクトに合わせて設定を追加します。
22
+
23
+ ```json
24
+ {
25
+ "extends": "@d-zero/stylelint-config",
26
+ "rules": {
27
+ // 例: @ルールで未知のルールを許可する
28
+ "at-rule-no-unknown": null
29
+ }
30
+ }
31
+ ```
32
+
33
+ ## 種類別プリセット
34
+
35
+ | パッケージパス | 用途 |
36
+ | --------------------------------- | ---------------- |
37
+ | `@d-zero/stylelint-config` | フルセット |
38
+ | `@d-zero/stylelint-config/base` | 基本セット |
39
+ | `@d-zero/stylelint-config/name` | 命名規則 |
40
+ | `@d-zero/stylelint-config/order` | プロパティの順番 |
41
+ | `@d-zero/stylelint-config/values` | プロパティ値 |
42
+ | `@d-zero/stylelint-config/scss` | SCSS関連 |
43
+
44
+ `@d-zero/stylelint-config`はすべてのルールを含んでいるので、一部のルールのみを利用する場合は、それぞれ種類別のものを利用します。
45
+
46
+ ```json
47
+ {
48
+ "extends": [
49
+ "@d-zero/stylelint-config/scss",
50
+ "@d-zero/stylelint-config/base",
51
+ "@d-zero/stylelint-config/values"
52
+ ]
53
+ }
54
+ ```
package/base.js CHANGED
@@ -1,67 +1,26 @@
1
1
  module.exports = {
2
- extends: ['stylelint-config-standard', 'stylelint-config-recess-order'],
3
- plugins: ['stylelint-scss', 'stylelint-order'],
2
+ plugins: ['stylelint-use-logical', '@d-zero/stylelint-rules'],
3
+ extends: ['stylelint-config-recommended'],
4
4
  rules: {
5
- 'order/order': [
6
- 'dollar-variables',
7
- 'custom-properties',
8
- {
9
- type: 'at-rule',
10
- name: 'custom-media',
11
- },
12
- {
13
- type: 'at-rule',
14
- name: 'extend',
15
- },
16
- {
17
- type: 'at-rule',
18
- name: 'mixin',
19
- },
20
- 'declarations',
21
- {
22
- type: 'at-rule',
23
- name: 'supports',
24
- },
25
- {
26
- type: 'at-rule',
27
- name: 'media',
28
- hasBlock: true,
29
- },
30
- 'rules',
31
- ],
32
5
  'at-rule-disallowed-list': null,
33
- 'at-rule-empty-line-before': [
34
- 'always',
35
- {
36
- except: ['blockless-after-same-name-blockless', 'first-nested'],
37
- ignore: ['after-comment'],
38
- },
39
- ],
6
+
40
7
  'at-rule-no-vendor-prefix': true,
41
- 'at-rule-no-unknown': [
42
- true,
43
- {
44
- ignoreAtRules: ['mixin', 'extend', 'for', 'if', 'include', 'use', 'forward'],
45
- },
46
- ],
8
+ 'at-rule-no-unknown': true,
47
9
  'color-hex-length': 'short',
48
10
  'color-named': 'never',
49
11
  'color-no-invalid-hex': true,
50
12
  'comment-empty-line-before': [
51
13
  'always',
52
14
  {
53
- ignore: ['stylelint-commands'],
15
+ except: ['first-nested'],
54
16
  },
55
17
  ],
56
18
  'comment-no-empty': true,
57
- 'comment-whitespace-inside': 'always',
58
19
  'comment-word-disallowed-list': ['/^TODO:/'],
59
- 'custom-property-empty-line-before': 'never',
60
20
  'declaration-block-no-duplicate-properties': true,
61
21
  'declaration-block-no-redundant-longhand-properties': true,
62
22
  'declaration-block-no-shorthand-property-overrides': true,
63
23
  'declaration-block-single-line-max-declarations': 80,
64
- 'declaration-empty-line-before': 'never',
65
24
  'declaration-no-important': true,
66
25
  'declaration-property-value-disallowed-list': null,
67
26
  'declaration-property-value-allowed-list': null,
@@ -72,15 +31,11 @@ module.exports = {
72
31
  'function-calc-no-unspaced-operator': true,
73
32
  'function-linear-gradient-no-nonstandard-direction': true,
74
33
  'function-name-case': 'lower',
75
- 'function-no-unknown': [
76
- true,
77
- {
78
- ignoreFunctions: ['a', 'lighten', 'darken', 'resolve'],
79
- },
80
- ],
34
+ 'function-no-unknown': true,
81
35
  'function-url-scheme-allowed-list': null,
82
36
  'function-url-no-scheme-relative': true,
83
37
  'function-url-quotes': 'always',
38
+ 'import-notation': 'string',
84
39
  'keyframe-declaration-no-important': true,
85
40
  'length-zero-no-unit': true,
86
41
  'max-nesting-depth': 8,
@@ -102,17 +57,17 @@ module.exports = {
102
57
  },
103
58
  ],
104
59
  'rule-empty-line-before': [
105
- 'always-multi-line',
60
+ 'always',
106
61
  {
107
- except: ['after-single-line-comment', 'first-nested'],
62
+ except: ['first-nested'],
108
63
  ignore: ['after-comment'],
109
64
  },
110
65
  ],
111
66
  'selector-attribute-operator-disallowed-list': null,
112
67
  'selector-attribute-quotes': 'always',
113
68
  'selector-max-compound-selectors': 8,
114
- 'selector-max-specificity': '0,10,10',
115
- 'selector-max-id': 0,
69
+ 'selector-max-specificity': null,
70
+ 'selector-max-id': [0, { message: 'スタイル定義でIDセレクタは使わないでください' }],
116
71
  'selector-max-universal': 1,
117
72
  'selector-no-vendor-prefix': true,
118
73
  'selector-pseudo-class-disallowed-list': ['link'],
@@ -127,14 +82,16 @@ module.exports = {
127
82
  'value-keyword-case': null,
128
83
  'value-no-vendor-prefix': true,
129
84
 
85
+ // Plugin stylelint-use-logical
86
+ 'csstools/use-logical': 'always',
87
+
88
+ // Plugin @d-zero/stylelint-rules
89
+ '@d-zero/prefer-individual-transform-properties': true,
90
+ '@d-zero/shorthand-property-use-logical': true,
91
+
130
92
  // Overwrite stylelint-config-standard
131
93
  'custom-media-pattern': null,
132
94
  'custom-property-pattern': null,
95
+ 'selector-class-pattern': null,
133
96
  },
134
- overrides: [
135
- {
136
- files: ['__assets/**/*.scss'],
137
- customSyntax: 'postcss-scss',
138
- },
139
- ],
140
97
  };
package/index.js CHANGED
@@ -1,18 +1,20 @@
1
1
  const base = require('./base');
2
2
  const name = require('./name');
3
+ const order = require('./order');
4
+ const scss = require('./scss');
3
5
  const values = require('./values');
4
6
 
5
7
  module.exports = {
8
+ ...scss,
6
9
  ...base,
7
- ignoreFiles: [
8
- '__assets/**/*.{js,jsx,ts,tsx,html,pug}',
9
- '__assets/css/_syntax-rules.scss',
10
- 'htdocs/**/*',
11
- 'docs/**/*.md',
12
- ],
10
+ extends: [...base.extends, ...order.extends],
11
+ plugins: [...scss.plugins, ...base.plugins, ...order.plugins, ...values.plugins],
12
+ ignoreFiles: ['**/*.{js,jsx,ts,tsx,html,pug}', 'htdocs/**/*', 'docs/**/*.md'],
13
13
  rules: {
14
14
  ...base.rules,
15
+ ...order.rules,
15
16
  ...name.rules,
16
17
  ...values.rules,
18
+ ...scss.rules,
17
19
  },
18
20
  };
package/name.js CHANGED
@@ -1,17 +1,41 @@
1
1
  module.exports = {
2
2
  rules: {
3
- 'scss/dollar-variable-pattern':
4
- '^(?:[a-z]{2,}-[a-z0-9-]+|_[a-z][a-z0-9]*(?:-[a-z0-9]+)*)$',
5
- 'scss/percent-placeholder-pattern': '^[a-z]{2,}(-[a-z0-9-]+)?$',
6
3
  'custom-media-pattern': '[a-z][a-z-]*',
7
4
  'custom-property-pattern': '[a-z][a-z-]*',
8
5
  'selector-class-pattern': [
9
6
  '^c-[a-z][a-z0-9]*(?:-[a-z0-9]+)*(?:__[a-z0-9]+(?:-[a-z0-9]+)*)?$',
10
7
  {
11
8
  resolveNestedSelectors: true,
9
+ /**
10
+ * @param {string} selector
11
+ * @returns {string}
12
+ */
13
+ message: (selector) => {
14
+ if (!selector.startsWith('.c-')) {
15
+ return `クラス名は「c-」から始めてください: ${selector}`;
16
+ }
17
+ if (selector.split('__').length > 2) {
18
+ return `「__」はコンポーネント名とエレメント名の区切りを表します。エレメント名の文字区切りは「-」を使います: ${selector}`;
19
+ }
20
+ return `クラス名に命名規則にない文字が含まれています: ${selector}`;
21
+ },
12
22
  },
13
23
  ],
14
- 'selector-id-pattern': '^$',
15
- 'selector-nested-pattern': '^[^.]+.*',
24
+ 'selector-nested-pattern': [
25
+ '^[^.]+.*',
26
+ {
27
+ /**
28
+ * @param {string} selector
29
+ * @returns {string}
30
+ */
31
+ message: (selector) => {
32
+ return `コンポーネントのスタイル定義の中で別のコンポーネントを定義してはいけません: ${selector}`;
33
+ },
34
+ },
35
+ ],
36
+
37
+ 'scss/dollar-variable-pattern':
38
+ '^(?:[a-z]{2,}-[a-z0-9-]+|_[a-z][a-z0-9]*(?:-[a-z0-9]+)*)$',
39
+ 'scss/percent-placeholder-pattern': '^[a-z]{2,}(-[a-z0-9-]+)?$',
16
40
  },
17
41
  };
package/order.js ADDED
@@ -0,0 +1,33 @@
1
+ module.exports = {
2
+ extends: ['stylelint-config-recess-order'],
3
+ plugins: ['stylelint-order'],
4
+ rules: {
5
+ 'order/order': [
6
+ 'dollar-variables',
7
+ 'custom-properties',
8
+ {
9
+ type: 'at-rule',
10
+ name: 'custom-media',
11
+ },
12
+ {
13
+ type: 'at-rule',
14
+ name: 'extend',
15
+ },
16
+ {
17
+ type: 'at-rule',
18
+ name: 'mixin',
19
+ },
20
+ 'declarations',
21
+ {
22
+ type: 'at-rule',
23
+ name: 'supports',
24
+ },
25
+ {
26
+ type: 'at-rule',
27
+ name: 'media',
28
+ hasBlock: true,
29
+ },
30
+ 'rules',
31
+ ],
32
+ },
33
+ };
package/package.json CHANGED
@@ -1,34 +1,38 @@
1
1
  {
2
2
  "name": "@d-zero/stylelint-config",
3
- "version": "5.0.0-dev.92+cac5756",
3
+ "version": "5.0.0",
4
4
  "description": "Configurations of Stylelint",
5
- "repository": "https://github.com/d-zero-dev/node-dev-env.git",
5
+ "repository": "https://github.com/d-zero-dev/linters.git",
6
6
  "author": "D-ZERO Co., Ltd.",
7
7
  "license": "MIT",
8
- "private": false,
9
8
  "publishConfig": {
10
9
  "access": "public"
11
10
  },
11
+ "engines": {
12
+ "node": ">=22.0.0"
13
+ },
12
14
  "type": "commonjs",
13
15
  "exports": {
14
16
  ".": "./index.js",
15
17
  "./base": "./base.js",
16
18
  "./name": "./name.js",
19
+ "./order": "./order.js",
20
+ "./scss": "./scss.js",
17
21
  "./values": "./values.js"
18
22
  },
19
23
  "files": [
20
- "base.js",
21
- "index.js",
22
- "name.js",
23
- "values.js"
24
+ "*.js"
24
25
  ],
25
26
  "main": "index.js",
26
27
  "dependencies": {
27
- "stylelint": "16.1.0",
28
- "stylelint-config-recess-order": "4.4.0",
29
- "stylelint-config-standard": "36.0.0",
30
- "stylelint-order": "6.0.4",
31
- "stylelint-scss": "6.0.0"
28
+ "@d-zero/stylelint-rules": "5.0.0",
29
+ "postcss-scss": "4.0.9",
30
+ "stylelint": "16.26.1",
31
+ "stylelint-config-recess-order": "7.4.0",
32
+ "stylelint-config-standard": "39.0.1",
33
+ "stylelint-order": "7.0.1",
34
+ "stylelint-scss": "6.14.0",
35
+ "stylelint-use-logical": "2.1.2"
32
36
  },
33
- "gitHead": "cac5756806a90edaa73a57e49f0dcd45495290ab"
37
+ "gitHead": "7f635ad8bbb1455d0d362fe00478a2f7bd216924"
34
38
  }
package/scss.js ADDED
@@ -0,0 +1,18 @@
1
+ module.exports = {
2
+ customSyntax: 'postcss-scss',
3
+ plugins: ['stylelint-scss'],
4
+ rules: {
5
+ 'at-rule-no-unknown': [
6
+ true,
7
+ {
8
+ ignoreAtRules: ['mixin', 'extend', 'for', 'if', 'include', 'use', 'forward'],
9
+ },
10
+ ],
11
+ 'no-invalid-position-at-import-rule': [
12
+ true,
13
+ {
14
+ ignoreAtRules: ['use'],
15
+ },
16
+ ],
17
+ },
18
+ };
package/values.js CHANGED
@@ -1,51 +1,207 @@
1
+ /**
2
+ * @see https://drafts.csswg.org/css-values-4/#viewport-relative-lengths
3
+ */
4
+ const VIEWPORT_PERCENTAGE_LENGTHS = '[ls]?v(?:w|h|i|d|max|min)';
5
+
6
+ const PERCENTATE_UNITS = `(?:%|${VIEWPORT_PERCENTAGE_LENGTHS})`;
7
+
1
8
  module.exports = {
9
+ plugins: ['@d-zero/stylelint-rules'],
2
10
  rules: {
3
- 'declaration-property-value-disallowed-list': {
4
- '/^(?:color|background|background-color|border|border-color|outline|outline-color)$/':
5
- ['/#[0-9a-f]{3}/', '/(?:rgb|hsl)a?\\(.+?\\)/'],
6
- content: ['/^\\"\\\\[0-9a-fA-F]{1,6}\\"$/'],
7
- flex: ['/calc/'],
8
- '/^(?:max-|min-)?(?:width|height)|^flex/': [
9
- '/[1-9]*\\.[0-9]+(?:%|vw|vh)/',
10
- '/(?:^|[^0-9])[0-9](?:%|vw|vh)/',
11
- '/(?:^|[^0-9])[0-9]{2}(?:%|vw|vh)/',
12
- '/1[0-9][1-9](?:%|vw|vh)/',
13
- '/1[1-9][0-9](?:%|vw|vh)/',
14
- '/[2-9][0-9][0-9](?:%|vw|vh)/',
15
- '/[0-9]{4,}(?:%|vw|vh)/',
16
- ],
17
- },
11
+ 'declaration-property-value-disallowed-list': [
12
+ {
13
+ display: [
14
+ /* @see https://drafts.csswg.org/css-display/#display-value-summary */
15
+ 'block',
16
+ 'flow-root',
17
+ 'inline',
18
+ 'inline-block',
19
+ 'list-item',
20
+ 'inline list-item',
21
+ 'flex',
22
+ 'inline-flex',
23
+ 'grid',
24
+ 'inline-grid',
25
+ 'ruby',
26
+ 'table',
27
+ 'inline-table',
28
+ ],
29
+ 'z-index': ['/^-?\\d+$/'],
30
+ '/^(?:color|background|background-color|border|border-color|outline|outline-color)$/':
31
+ [/#[0-9a-f]{3}/, /(?:rgb|hsl)a?\(.+?\)/],
32
+ content: [/^"\\[0-9a-f]{1,6}"$/i],
33
+ },
34
+ {
35
+ message: (name, value) => {
36
+ switch (name) {
37
+ case 'display': {
38
+ let multiValue = '';
39
+ switch (value) {
40
+ case 'block': {
41
+ multiValue = 'block flow';
42
+ break;
43
+ }
44
+ case 'flow-root': {
45
+ multiValue = 'block flow-root';
46
+ break;
47
+ }
48
+ case 'inline': {
49
+ multiValue = 'inline flow';
50
+ break;
51
+ }
52
+ case 'inline-block': {
53
+ multiValue = 'inline flow-root';
54
+ break;
55
+ }
56
+ case 'list-item': {
57
+ multiValue = 'block flow list-item';
58
+ break;
59
+ }
60
+ case 'inline list-item': {
61
+ multiValue = 'inline flow list-item';
62
+ break;
63
+ }
64
+ case 'flex': {
65
+ multiValue = 'block flex';
66
+ break;
67
+ }
68
+ case 'inline-flex': {
69
+ multiValue = 'inline flex';
70
+ break;
71
+ }
72
+ case 'grid': {
73
+ multiValue = 'block grid';
74
+ break;
75
+ }
76
+ case 'inline-grid': {
77
+ multiValue = 'inline grid';
78
+ break;
79
+ }
80
+ case 'ruby': {
81
+ multiValue = 'inline ruby';
82
+ break;
83
+ }
84
+ case 'table': {
85
+ multiValue = 'block table';
86
+ break;
87
+ }
88
+ case 'inline-table': {
89
+ multiValue = 'inline table';
90
+ break;
91
+ }
92
+ }
93
+ return `\`${value}\`の代わりに複数キーワード構文\`${multiValue}\`を使用してください。`;
94
+ }
95
+ case 'z-index': {
96
+ return `数値の\`${name}\`ではなくグローバルで定義されたCSS変数を使用してください。`;
97
+ }
98
+ case 'content': {
99
+ return `Unicode値\`${value}\`を指定せず、表示したいテキストをそのまま指定してください。`;
100
+ }
101
+ default: {
102
+ return `ハードコードされた値\`${value}\`の代わりにCSS変数を使用してください。`;
103
+ }
104
+ }
105
+ },
106
+ severity: 'warning',
107
+ },
108
+ ],
18
109
  'declaration-property-value-allowed-list': {
19
110
  'font-size': [
20
111
  'inherit',
21
- '$root-font-size',
22
- '$base-font-size',
112
+ /^\$[a-z][a-z0-9]*-font-size(?:-[a-z0-9]+)?$/,
23
113
  '1em',
24
- '/^calc\\((?:\\$[a-z_][a-z0-9_-]*|(?:[0-9]*\\.)?[0-9]+) \\/ (?:\\$[a-z_][a-z0-9_-]*|(?:[0-9]*\\.)?[0-9]+) \\* (?:1em|100vw)\\)$/',
25
- '/^(?:[0-9]*\\.)?[0-9]+rem/',
26
- '/^clamp\\(/',
114
+ /^calc\(\s*(?:(?:\d*\.)?\d+|var\(\s*--[a-z][a-z0-9_-]+\s*\))\s*\/\s*(?:(?:\d*\.)?\d+|var\(\s*--[a-z][a-z0-9_-]+\s*\))\s*\*\s*(?:1em|1rem|100vw)\s*\)$/,
115
+ /^(?:\d*\.)?\d+rem/,
116
+ /^clamp\(/,
117
+ // Custom properties
118
+ /^var\(/,
27
119
  ],
120
+ flex: [
121
+ /^\s*[01]\s+[01]\s.+/,
122
+ // Custom properties
123
+ /^var\(/,
124
+ ],
125
+ 'flex-grow': ['0', '1'],
126
+ 'flex-shrink': ['0', '1'],
28
127
  },
29
128
  'unit-disallowed-list': [
30
- 'ex',
31
- 'ch',
32
- 'mm',
33
- 'q',
34
- 'cm',
35
- 'in',
36
- 'pt',
37
- 'pc',
38
- 'vm',
39
- 's',
40
- 'grad',
41
- 'rad',
42
- 'turn',
129
+ [
130
+ 'ex',
131
+ 'ch',
132
+ 'mm',
133
+ 'q',
134
+ 'cm',
135
+ 'in',
136
+ 'pt',
137
+ 'pc',
138
+ 'vm',
139
+ 's',
140
+ 'grad',
141
+ 'rad',
142
+ 'turn',
143
+ 'vw',
144
+ 'vh',
145
+ 'vi',
146
+ 'vb',
147
+ 'vmin',
148
+ 'vmax',
149
+ ],
150
+ {
151
+ message: (unit) => {
152
+ const recommendationMap = {
153
+ ex: 'em, rem',
154
+ ch: 'em, rem',
155
+ mm: 'px, rem',
156
+ q: 'px, rem',
157
+ cm: 'px, rem',
158
+ in: 'px, rem',
159
+ pt: 'px, rem',
160
+ pc: 'px, rem',
161
+ s: 'ms',
162
+ grad: 'deg',
163
+ rad: 'deg',
164
+ turn: 'deg',
165
+ vw: 'svw, dvw, lvw',
166
+ vh: 'svh, dvh, lvh',
167
+ vi: 'svi, dvi, lvi',
168
+ vb: 'svb, dvb, lvb',
169
+ vmin: 'svmin, dvmin, lvmin',
170
+ vmax: 'svmax, dvmax, lvmax',
171
+ };
172
+ return `\`${unit}\`は使用しないでください。代わりに\`${recommendationMap[unit]}\`を検討してください。`;
173
+ },
174
+ severity: 'warning',
175
+ },
43
176
  ],
44
177
  'value-keyword-case': [
45
178
  'lower',
46
179
  {
47
- ignoreProperties: ['/^\\$font-family-/'],
180
+ ignoreProperties: [/^\$font-family-/],
48
181
  },
49
182
  ],
183
+
184
+ '@d-zero/declaration-value-type-disallowed-list': {
185
+ '/^length|percentage$/': {
186
+ ignoreProperties: ['font-size'],
187
+ patterns: [
188
+ // float
189
+ `/[0-9]*?\\.[0-9]+?${PERCENTATE_UNITS}/`,
190
+
191
+ // 1000% or larger
192
+ `/[1-9][0-9]{3,}?${PERCENTATE_UNITS}/`,
193
+
194
+ // 200% - 999%
195
+ `/[2-9][0-9][0-9]${PERCENTATE_UNITS}/`,
196
+
197
+ // 101% - 199%
198
+ `/1[0-9][1-9]${PERCENTATE_UNITS}/`,
199
+ `/1[1-9][0-9]${PERCENTATE_UNITS}/`,
200
+
201
+ // 1% - 99%
202
+ `/[1-9][0-9]?${PERCENTATE_UNITS}/`,
203
+ ],
204
+ },
205
+ },
50
206
  },
51
207
  };