@dimensional-innovations/tool-config 1.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 (50) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +646 -0
  3. package/bin/setup-tool-config.js +675 -0
  4. package/package.json +168 -0
  5. package/src/detectors.js +261 -0
  6. package/src/index.js +64 -0
  7. package/src/tools/eslint/index.js +287 -0
  8. package/src/tools/eslint/presets/base.js +82 -0
  9. package/src/tools/eslint/presets/environments/browser.js +16 -0
  10. package/src/tools/eslint/presets/environments/node.js +21 -0
  11. package/src/tools/eslint/presets/environments/universal.js +18 -0
  12. package/src/tools/eslint/presets/frameworks/angular.js +74 -0
  13. package/src/tools/eslint/presets/frameworks/astro.js +38 -0
  14. package/src/tools/eslint/presets/frameworks/node.js +57 -0
  15. package/src/tools/eslint/presets/frameworks/react.js +76 -0
  16. package/src/tools/eslint/presets/frameworks/solid.js +45 -0
  17. package/src/tools/eslint/presets/frameworks/svelte.js +78 -0
  18. package/src/tools/eslint/presets/frameworks/vanilla.js +16 -0
  19. package/src/tools/eslint/presets/frameworks/vue.js +125 -0
  20. package/src/tools/eslint/presets/imports.js +41 -0
  21. package/src/tools/eslint/presets/typescript.js +131 -0
  22. package/src/tools/prettier/README.md +398 -0
  23. package/src/tools/prettier/index.js +114 -0
  24. package/src/tools/prettier/presets/base.js +36 -0
  25. package/src/tools/prettier/presets/frameworks/astro.js +15 -0
  26. package/src/tools/prettier/presets/frameworks/react.js +15 -0
  27. package/src/tools/prettier/presets/frameworks/svelte.js +22 -0
  28. package/src/tools/prettier/presets/frameworks/vanilla.js +13 -0
  29. package/src/tools/prettier/presets/frameworks/vue.js +20 -0
  30. package/src/tools/prettier/presets/prettierignore.js +56 -0
  31. package/src/tools/semantic-release/CI_SETUP.md +66 -0
  32. package/src/tools/semantic-release/README.md +533 -0
  33. package/src/tools/semantic-release/index.js +130 -0
  34. package/src/tools/semantic-release/presets/default.js +37 -0
  35. package/src/tools/semantic-release/presets/library.js +58 -0
  36. package/src/tools/semantic-release/presets/monorepo.js +48 -0
  37. package/src/tools/semantic-release/templates/.gitlab-ci.yml +85 -0
  38. package/src/tools/semantic-release/templates/bitbucket-pipelines.yml +100 -0
  39. package/src/tools/semantic-release/templates/github-workflow.yml +107 -0
  40. package/src/tools/stylelint/README.md +425 -0
  41. package/src/tools/stylelint/index.js +191 -0
  42. package/src/tools/stylelint/presets/base.js +50 -0
  43. package/src/tools/stylelint/presets/css-modules.js +43 -0
  44. package/src/tools/stylelint/presets/frameworks/react.js +18 -0
  45. package/src/tools/stylelint/presets/frameworks/svelte.js +28 -0
  46. package/src/tools/stylelint/presets/frameworks/vanilla.js +14 -0
  47. package/src/tools/stylelint/presets/frameworks/vue.js +38 -0
  48. package/src/tools/stylelint/presets/scss.js +83 -0
  49. package/src/tools/stylelint/presets/tailwind.js +49 -0
  50. package/src/utils/package-reader.js +42 -0
@@ -0,0 +1,425 @@
1
+ # Stylelint Configuration
2
+
3
+ Framework-aware Stylelint configuration for CSS quality linting across all supported frameworks.
4
+
5
+ ## Philosophy
6
+
7
+ This Stylelint configuration focuses on **CSS quality**, not formatting:
8
+
9
+ - **Quality Rules**: Catches errors, enforces best practices, prevents common mistakes
10
+ - **Formatting**: Left to Prettier (never conflicts)
11
+ - **Framework-Aware**: Automatically applies framework-specific rules
12
+ - **Zero Config**: Works out of the box with sensible defaults
13
+
14
+ **Key Principle**: Stylelint is for CSS files and component styles (Vue `<style>`, Svelte `<style>`). CSS-in-JS (styled-components, emotion) should use ESLint plugins instead.
15
+
16
+ ## Installation
17
+
18
+ The Stylelint tool and core config are included as dependencies. For Vue projects, install optional peer dependencies:
19
+
20
+ ```bash
21
+ # Vue projects only
22
+ npm install --save-dev stylelint-config-standard-vue postcss-html
23
+
24
+ # Svelte projects need postcss-html for component parsing
25
+ npm install --save-dev postcss-html
26
+ ```
27
+
28
+ ## Usage
29
+
30
+ ### Auto-Detection (Recommended)
31
+
32
+ ```javascript
33
+ // stylelint.config.js
34
+ import { createConfig } from '@dimensional-innovations/tool-config'
35
+
36
+ export default createConfig('stylelint')
37
+ ```
38
+
39
+ The factory automatically detects your framework and applies appropriate rules.
40
+
41
+ ### Explicit Framework
42
+
43
+ ```javascript
44
+ // stylelint.config.js
45
+ import { createConfig } from '@dimensional-innovations/tool-config'
46
+
47
+ export default createConfig('stylelint', {
48
+ framework: 'vue' // react, vue, svelte, solid, astro, angular, vanilla, node
49
+ })
50
+ ```
51
+
52
+ ### With Custom Rules
53
+
54
+ ```javascript
55
+ // stylelint.config.js
56
+ import { createConfig } from '@dimensional-innovations/tool-config'
57
+
58
+ export default createConfig('stylelint', {
59
+ rules: {
60
+ 'color-hex-length': 'long',
61
+ 'max-nesting-depth': 4
62
+ }
63
+ })
64
+ ```
65
+
66
+ ## Framework Support
67
+
68
+ | Framework | Support Level | Features |
69
+ | ----------- | ------------- | ------------------------------------------------------------------ |
70
+ | **Vue** | Full | Scoped styles, `:deep()`, `:global()`, `:slotted()` pseudo-classes |
71
+ | **Svelte** | Full | Component styles, `:global()` pseudo-class |
72
+ | **React** | CSS Modules | `:global()`, `:local()`, `:export`, `:import` pseudo-classes |
73
+ | **Solid** | CSS Modules | Same as React (CSS Modules support) |
74
+ | **Angular** | Base | Standard CSS linting |
75
+ | **Astro** | Base | Standard CSS linting |
76
+ | **Vanilla** | Full | Standard CSS linting |
77
+ | **Node.js** | N/A | Not applicable (no CSS in Node.js backends) |
78
+
79
+ ### When to Use Stylelint
80
+
81
+ **Use Stylelint for:**
82
+
83
+ - Separate CSS files (`styles.css`)
84
+ - Vue Single File Components (`<style>` blocks)
85
+ - Svelte components (`<style>` blocks)
86
+ - CSS Modules (`.module.css`)
87
+ - Sass/SCSS files
88
+
89
+ **Don't use Stylelint for:**
90
+
91
+ - CSS-in-JS (styled-components, emotion) → Use ESLint plugins
92
+ - Inline styles in JSX → Use ESLint plugins
93
+ - Tailwind classes → Not linted (utility-first)
94
+
95
+ ## Base Configuration
96
+
97
+ All frameworks start with these base rules:
98
+
99
+ ### Color Rules
100
+
101
+ - `color-hex-length`: Prefer short hex colors (`#fff` not `#ffffff`)
102
+ - `color-named`: Disallow named colors (use hex/rgb instead)
103
+
104
+ ### Property Rules
105
+
106
+ - `declaration-block-no-redundant-longhand-properties`: Use shorthands where possible
107
+ - `shorthand-property-no-redundant-values`: Avoid redundant values in shorthands
108
+
109
+ ### Selector Rules
110
+
111
+ - `selector-max-id`: No ID selectors (use classes)
112
+ - `selector-no-qualifying-type`: Don't qualify selectors with type (`div.foo` → `.foo`)
113
+ - `selector-class-pattern`: Enforce BEM or kebab-case naming
114
+
115
+ ### Structure Rules
116
+
117
+ - `max-nesting-depth`: Maximum 3 levels of nesting
118
+ - `no-descending-specificity`: Disabled (too strict for real-world CSS)
119
+
120
+ ### Tailwind Support
121
+
122
+ Automatically ignores Tailwind at-rules:
123
+
124
+ - `@tailwind`
125
+ - `@apply`
126
+ - `@variants`
127
+ - `@responsive`
128
+ - `@screen`
129
+
130
+ ## Framework-Specific Features
131
+
132
+ ### Vue (Scoped Styles)
133
+
134
+ ```vue
135
+ <style scoped>
136
+ /* Standard scoped styles work */
137
+ .button {
138
+ }
139
+
140
+ /* Deep selectors supported */
141
+ :deep(.child) {
142
+ }
143
+ :global(.utility) {
144
+ }
145
+ :slotted(span) {
146
+ }
147
+ </style>
148
+ ```
149
+
150
+ **Configuration**: Extends `stylelint-config-standard-vue`, uses `postcss-html` parser.
151
+
152
+ ### Svelte (Component Styles)
153
+
154
+ ```svelte
155
+ <style>
156
+ /* Component-scoped by default */
157
+ .button { }
158
+
159
+ /* Global styles supported */
160
+ :global(.utility) { }
161
+ </style>
162
+ ```
163
+
164
+ **Configuration**: Uses `postcss-html` parser for `.svelte` files.
165
+
166
+ ### React/Solid (CSS Modules)
167
+
168
+ ```css
169
+ /* styles.module.css */
170
+ .button {
171
+ }
172
+
173
+ :global(.utility) {
174
+ }
175
+ :local(.scoped) {
176
+ }
177
+
178
+ /* Exports for JavaScript */
179
+ :export {
180
+ primaryColor: blue;
181
+ }
182
+ ```
183
+
184
+ **Configuration**: Supports CSS Modules pseudo-classes (`:global`, `:local`, `:export`, `:import`).
185
+
186
+ ### Angular/Astro/Vanilla
187
+
188
+ Standard CSS linting with base rules. No framework-specific features needed.
189
+
190
+ ## Package.json Scripts
191
+
192
+ Add these scripts to your `package.json`:
193
+
194
+ ```json
195
+ {
196
+ "scripts": {
197
+ "style": "stylelint '**/*.css'",
198
+ "style:fix": "stylelint '**/*.css' --fix"
199
+ }
200
+ }
201
+ ```
202
+
203
+ ### Framework-Specific Patterns
204
+
205
+ **Vue**:
206
+
207
+ ```json
208
+ {
209
+ "scripts": {
210
+ "style": "stylelint '**/*.css' '**/*.vue'",
211
+ "style:fix": "stylelint '**/*.css' '**/*.vue' --fix"
212
+ }
213
+ }
214
+ ```
215
+
216
+ **Svelte**:
217
+
218
+ ```json
219
+ {
220
+ "scripts": {
221
+ "style": "stylelint '**/*.css' '**/*.svelte'",
222
+ "style:fix": "stylelint '**/*.css' '**/*.svelte' --fix"
223
+ }
224
+ }
225
+ ```
226
+
227
+ **React/Angular/Vanilla**:
228
+
229
+ ```json
230
+ {
231
+ "scripts": {
232
+ "style": "stylelint '**/*.css'",
233
+ "style:fix": "stylelint '**/*.css' --fix'
234
+ }
235
+ }
236
+ ```
237
+
238
+ ## Integration with Other Tools
239
+
240
+ ### Stylelint + Prettier
241
+
242
+ No conflicts! They work together perfectly:
243
+
244
+ - **Stylelint**: CSS quality (errors, best practices)
245
+ - **Prettier**: CSS formatting (indentation, line breaks, spacing)
246
+
247
+ Run them sequentially:
248
+
249
+ ```bash
250
+ npm run style && npm run prettier:fix
251
+ ```
252
+
253
+ ### Stylelint + ESLint
254
+
255
+ No conflicts! Different file types:
256
+
257
+ - **ESLint**: JavaScript/TypeScript files
258
+ - **Stylelint**: CSS files and component styles
259
+ - **CSS-in-JS**: Use ESLint plugins (not Stylelint)
260
+
261
+ ### VSCode Integration
262
+
263
+ Install the Stylelint extension:
264
+
265
+ ```json
266
+ {
267
+ "stylelint.validate": ["css", "scss", "vue", "svelte"],
268
+ "editor.codeActionsOnSave": {
269
+ "source.fixAll.stylelint": "explicit"
270
+ }
271
+ }
272
+ ```
273
+
274
+ ## Common Overrides
275
+
276
+ ### Allow Deeper Nesting
277
+
278
+ ```javascript
279
+ export default createConfig('stylelint', {
280
+ rules: {
281
+ 'max-nesting-depth': 5
282
+ }
283
+ })
284
+ ```
285
+
286
+ ### Allow ID Selectors
287
+
288
+ ```javascript
289
+ export default createConfig('stylelint', {
290
+ rules: {
291
+ 'selector-max-id': 2 // Allow up to 2 IDs
292
+ }
293
+ })
294
+ ```
295
+
296
+ ### Custom Class Naming Pattern
297
+
298
+ ```javascript
299
+ export default createConfig('stylelint', {
300
+ rules: {
301
+ 'selector-class-pattern': '^[a-z][a-zA-Z0-9]+$' // camelCase only
302
+ }
303
+ })
304
+ ```
305
+
306
+ ### Disable Specific Rule
307
+
308
+ ```javascript
309
+ export default createConfig('stylelint', {
310
+ rules: {
311
+ 'color-named': null // Allow named colors
312
+ }
313
+ })
314
+ ```
315
+
316
+ ## Troubleshooting
317
+
318
+ ### "Cannot find module 'stylelint-config-standard-vue'"
319
+
320
+ **Vue projects only**: Install the optional peer dependency:
321
+
322
+ ```bash
323
+ npm install --save-dev stylelint-config-standard-vue postcss-html
324
+ ```
325
+
326
+ ### "Cannot find module 'postcss-html'"
327
+
328
+ **Vue/Svelte projects**: Install the parser:
329
+
330
+ ```bash
331
+ npm install --save-dev postcss-html
332
+ ```
333
+
334
+ ### Stylelint Not Linting .vue Files
335
+
336
+ Make sure your script includes `.vue` files:
337
+
338
+ ```json
339
+ {
340
+ "scripts": {
341
+ "style": "stylelint '**/*.css' '**/*.vue'"
342
+ }
343
+ }
344
+ ```
345
+
346
+ ### Conflicts with Prettier
347
+
348
+ This shouldn't happen! Our Stylelint config focuses on quality, not formatting. If you encounter conflicts:
349
+
350
+ 1. Check that Prettier is formatting CSS (it should be)
351
+ 2. Disable formatting-related Stylelint rules:
352
+ ```javascript
353
+ export default createConfig('stylelint', {
354
+ rules: {
355
+ indentation: null,
356
+ 'string-quotes': null
357
+ }
358
+ })
359
+ ```
360
+
361
+ ### "Unknown rule" Errors
362
+
363
+ Make sure you're using Stylelint 16+:
364
+
365
+ ```bash
366
+ npm install --save-dev stylelint@^16.0.0
367
+ ```
368
+
369
+ ## Rule Philosophy
370
+
371
+ ### Error vs Warning
372
+
373
+ **Error (Red)**: Will break your CSS or violate critical best practices
374
+
375
+ - `color-named`: Named colors are unreliable across browsers
376
+ - `selector-max-id`: IDs have high specificity and cause maintenance issues
377
+ - `max-nesting-depth`: Deep nesting makes CSS hard to maintain
378
+
379
+ **Warning (Yellow)**: Not used in this config (all rules are errors)
380
+
381
+ **Off**: Rule disabled (conflicts with Prettier or too opinionated)
382
+
383
+ ### Why We Don't Use Warnings
384
+
385
+ Warnings create ambiguity. Either something is wrong (error) or it's acceptable (off). Our approach:
386
+
387
+ - **Error**: Fix this (quality/correctness issue)
388
+ - **Off**: We don't care about this (formatting/style)
389
+
390
+ ## Examples
391
+
392
+ See working examples in the `examples/` directory:
393
+
394
+ - [examples/vue-app/](../../examples/vue-app/) - Vue 3 with scoped styles
395
+ - [examples/svelte-app/](../../examples/svelte-app/) - Svelte 5 with component styles
396
+ - [examples/react-app/](../../examples/react-app/) - React with CSS Modules
397
+ - [examples/angular-app/](../../examples/angular-app/) - Angular with standard CSS
398
+ - [examples/vanilla-js/](../../examples/vanilla-js/) - Vanilla JS with standard CSS
399
+
400
+ ## API Reference
401
+
402
+ ### createConfig(tool, options)
403
+
404
+ **Parameters**:
405
+
406
+ - `tool` (string): Must be `'stylelint'`
407
+ - `options` (object):
408
+ - `framework` (string): `'auto'` (default) | `'react'` | `'vue'` | `'svelte'` | `'solid'` | `'astro'` | `'angular'` | `'vanilla'` | `'node'`
409
+ - `cwd` (string): Working directory for auto-detection (default: `process.cwd()`)
410
+ - `rules` (object): Rule overrides
411
+ - `extends` (string|array): Additional configs to extend
412
+ - `overrides` (array): File-specific overrides
413
+
414
+ **Returns**: Stylelint configuration object
415
+
416
+ ## Related Documentation
417
+
418
+ - [Stylelint Official Docs](https://stylelint.io/)
419
+ - [stylelint-config-standard](https://github.com/stylelint/stylelint-config-standard)
420
+ - [stylelint-config-standard-vue](https://github.com/ota-meshi/stylelint-config-standard-vue)
421
+ - [postcss-html](https://github.com/gucong3000/postcss-html)
422
+
423
+ ## License
424
+
425
+ MIT
@@ -0,0 +1,191 @@
1
+ /**
2
+ * Stylelint configuration factory
3
+ *
4
+ * Creates Stylelint configurations with framework-aware defaults for CSS linting.
5
+ *
6
+ * Note: Stylelint is for CSS files and component styles (Vue, Svelte).
7
+ * CSS-in-JS (React styled-components, emotion) should use ESLint plugins instead.
8
+ */
9
+
10
+ import { autoDetect, detectCssType } from '../../detectors.js'
11
+
12
+ import basePreset from './presets/base.js'
13
+ import cssModulesPreset from './presets/css-modules.js'
14
+ import reactPreset from './presets/frameworks/react.js'
15
+ import sveltePreset from './presets/frameworks/svelte.js'
16
+ import vuePreset from './presets/frameworks/vue.js'
17
+ import scssPreset from './presets/scss.js'
18
+ import tailwindPreset from './presets/tailwind.js'
19
+
20
+ /**
21
+ * Merge framework preset into config
22
+ * @param {Object} config - Base config
23
+ * @param {Object} preset - Framework preset
24
+ * @returns {void}
25
+ */
26
+ function mergePreset(config, preset) {
27
+ if (preset.extends) {
28
+ config.extends = [...(config.extends || []), ...preset.extends]
29
+ }
30
+ if (preset.overrides) {
31
+ config.overrides = [...(config.overrides || []), ...preset.overrides]
32
+ }
33
+ if (preset.rules) {
34
+ config.rules = { ...config.rules, ...preset.rules }
35
+ }
36
+ }
37
+
38
+ /**
39
+ * Apply user overrides to config
40
+ * @param {Object} config - Current config
41
+ * @param {Object} userOverrides - User-provided overrides
42
+ * @returns {void}
43
+ */
44
+ function applyUserOverrides(config, userOverrides) {
45
+ // Handle arrays (extends, plugins, overrides)
46
+ if (userOverrides.extends) {
47
+ const userExtends = Array.isArray(userOverrides.extends)
48
+ ? userOverrides.extends
49
+ : [userOverrides.extends]
50
+ config.extends = [...(config.extends || []), ...userExtends]
51
+ delete userOverrides.extends
52
+ }
53
+ if (userOverrides.plugins) {
54
+ const userPlugins = Array.isArray(userOverrides.plugins)
55
+ ? userOverrides.plugins
56
+ : [userOverrides.plugins]
57
+ config.plugins = [...(config.plugins || []), ...userPlugins]
58
+ delete userOverrides.plugins
59
+ }
60
+ if (userOverrides.overrides) {
61
+ const userOverridesArray = Array.isArray(userOverrides.overrides)
62
+ ? userOverrides.overrides
63
+ : [userOverrides.overrides]
64
+ config.overrides = [...(config.overrides || []), ...userOverridesArray]
65
+ delete userOverrides.overrides
66
+ }
67
+ if (userOverrides.rules) {
68
+ config.rules = { ...config.rules, ...userOverrides.rules }
69
+ delete userOverrides.rules
70
+ }
71
+
72
+ // Merge remaining overrides
73
+ Object.assign(config, userOverrides)
74
+ }
75
+
76
+ /**
77
+ * Create a Stylelint configuration
78
+ *
79
+ * @param {Object} options - Configuration options
80
+ * @param {string} [options.framework='auto'] - Framework to configure for
81
+ * @param {string|Object} [options.cssType='auto'] - CSS type ('auto', 'css', 'scss', or detection object)
82
+ * @param {string} [options.cwd=process.cwd()] - Working directory for auto-detection
83
+ * @param {Object} [options.rules] - User rule overrides
84
+ * @param {Array|string} [options.extends] - Additional configs to extend
85
+ * @param {Array} [options.overrides] - File-specific overrides
86
+ * @returns {Object} Stylelint configuration object
87
+ *
88
+ * @example
89
+ * // Auto-detect framework
90
+ * export default createStylelintConfig();
91
+ *
92
+ * @example
93
+ * // Explicit framework
94
+ * export default createStylelintConfig({ framework: 'vue' });
95
+ *
96
+ * @example
97
+ * // Explicit CSS type
98
+ * export default createStylelintConfig({ cssType: 'scss' });
99
+ *
100
+ * @example
101
+ * // With overrides
102
+ * export default createStylelintConfig({
103
+ * framework: 'vue',
104
+ * cssType: 'scss',
105
+ * rules: {
106
+ * 'color-hex-length': 'long'
107
+ * }
108
+ * });
109
+ */
110
+ export function createStylelintConfig(options = {}) {
111
+ const {
112
+ framework: explicitFramework = 'auto',
113
+ cssType: explicitCssType = 'auto',
114
+ cwd = process.cwd(),
115
+ ...userOverrides
116
+ } = options
117
+
118
+ // Auto-detect framework if needed
119
+ const framework = explicitFramework === 'auto' ? autoDetect(cwd).framework : explicitFramework
120
+
121
+ // Auto-detect CSS type if needed
122
+ const cssType = explicitCssType === 'auto' ? detectCssType(cwd) : explicitCssType
123
+
124
+ // Start with appropriate base configuration (SCSS or plain CSS)
125
+ const config =
126
+ cssType?.preprocessor === 'scss' || cssType === 'scss'
127
+ ? { ...scssPreset, customSyntax: 'postcss-scss' }
128
+ : { ...basePreset }
129
+
130
+ // Apply Tailwind preset if detected
131
+ if (cssType?.tailwind) {
132
+ mergePreset(config, tailwindPreset)
133
+ }
134
+
135
+ // CSS Modules support (for React/Next.js projects)
136
+ if ((framework === 'react' || framework === 'solid') && !cssType?.tailwind) {
137
+ mergePreset(config, cssModulesPreset)
138
+ }
139
+
140
+ // Build CSS type description
141
+ let cssTypeDesc = cssType?.preprocessor === 'scss' ? 'SCSS' : 'CSS'
142
+ if (cssType?.tailwind) cssTypeDesc += ' + Tailwind'
143
+ if ((framework === 'react' || framework === 'solid') && !cssType?.tailwind) {
144
+ cssTypeDesc += ' Modules'
145
+ }
146
+
147
+ // Apply framework-specific preset
148
+ switch (framework) {
149
+ case 'vue': {
150
+ mergePreset(config, vuePreset)
151
+ console.warn(`🎨 Stylelint: Detected Vue.js - linting .vue component styles (${cssTypeDesc})`)
152
+ break
153
+ }
154
+
155
+ case 'svelte': {
156
+ mergePreset(config, sveltePreset)
157
+ console.warn(
158
+ `🎨 Stylelint: Detected Svelte - linting .svelte component styles (${cssTypeDesc})`
159
+ )
160
+ break
161
+ }
162
+
163
+ case 'react':
164
+ case 'solid': {
165
+ mergePreset(config, reactPreset)
166
+ console.warn(
167
+ `🎨 Stylelint: Detected ${framework} - linting ${cssTypeDesc} (CSS-in-JS uses ESLint)`
168
+ )
169
+ break
170
+ }
171
+
172
+ case 'angular':
173
+ case 'node':
174
+ case 'vanilla':
175
+ case 'astro': {
176
+ console.warn(`🎨 Stylelint: Detected ${framework} - linting ${cssTypeDesc} files`)
177
+ break
178
+ }
179
+
180
+ default: {
181
+ console.warn(`⚠️ Unknown framework "${framework}", using base ${cssTypeDesc} linting`)
182
+ }
183
+ }
184
+
185
+ // Apply user overrides
186
+ applyUserOverrides(config, userOverrides)
187
+
188
+ return config
189
+ }
190
+
191
+ export default createStylelintConfig
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Base Stylelint preset
3
+ *
4
+ * Standard CSS linting rules for all projects.
5
+ * Focuses on code quality and best practices, NOT formatting (that's Prettier's job).
6
+ *
7
+ * Key principles:
8
+ * - Use modern CSS practices
9
+ * - Avoid common mistakes
10
+ * - Maintain consistency
11
+ * - Don't fight with Prettier
12
+ */
13
+
14
+ export default {
15
+ extends: ['stylelint-config-standard'],
16
+
17
+ rules: {
18
+ // Color rules
19
+ 'color-hex-length': 'short',
20
+ 'color-named': 'never',
21
+
22
+ // Property rules
23
+ 'declaration-block-no-redundant-longhand-properties': true,
24
+ 'shorthand-property-no-redundant-values': true,
25
+
26
+ // Selector rules
27
+ 'selector-max-id': 0,
28
+ 'selector-no-qualifying-type': true,
29
+ 'selector-class-pattern': [
30
+ '^[a-z]([a-z0-9-]+)?(__([a-z0-9]+-?)+)?(--([a-z0-9]+-?)+){0,2}$',
31
+ {
32
+ message: 'Expected class selector to be kebab-case or BEM format'
33
+ }
34
+ ],
35
+
36
+ // Nesting
37
+ 'max-nesting-depth': 3,
38
+
39
+ // Specificity
40
+ 'no-descending-specificity': null,
41
+
42
+ // At-rules
43
+ 'at-rule-no-unknown': [
44
+ true,
45
+ {
46
+ ignoreAtRules: ['tailwind', 'apply', 'variants', 'responsive', 'screen']
47
+ }
48
+ ]
49
+ }
50
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * CSS Modules Stylelint preset
3
+ *
4
+ * Configuration for projects using CSS Modules.
5
+ * Allows CSS Modules-specific pseudo-classes and conventions.
6
+ *
7
+ * Key principles:
8
+ * - Support :global() and :local() pseudo-classes
9
+ * - Allow composition with composes
10
+ * - Support @value imports
11
+ * - Work alongside regular CSS/SCSS
12
+ */
13
+
14
+ export default {
15
+ rules: {
16
+ // Allow CSS Modules pseudo-classes
17
+ 'selector-pseudo-class-no-unknown': [
18
+ true,
19
+ {
20
+ ignorePseudoClasses: ['global', 'local', 'export', 'import']
21
+ }
22
+ ],
23
+
24
+ // Allow @value (CSS Modules constants)
25
+ 'at-rule-no-unknown': [
26
+ true,
27
+ {
28
+ ignoreAtRules: ['value']
29
+ }
30
+ ],
31
+
32
+ // Allow 'composes' property (CSS Modules composition)
33
+ 'property-no-unknown': [
34
+ true,
35
+ {
36
+ ignoreProperties: ['composes', 'compose-with']
37
+ }
38
+ ],
39
+
40
+ // CSS Modules often use camelCase
41
+ 'selector-class-pattern': null // Disable pattern check for modules
42
+ }
43
+ }