eslint-plugin-tailwind-variants 2.0.3 → 2.1.1

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 (45) hide show
  1. package/README.md +6 -4
  2. package/dist/src/index.d.ts +31 -0
  3. package/dist/src/index.d.ts.map +1 -0
  4. package/dist/src/rules/index.d.ts +7 -0
  5. package/dist/src/rules/index.d.ts.map +1 -0
  6. package/dist/src/rules/limited-inline-classes.d.ts +41 -0
  7. package/dist/src/rules/limited-inline-classes.d.ts.map +1 -0
  8. package/dist/src/rules/require-variants-call-styles-name.d.ts +19 -0
  9. package/dist/src/rules/require-variants-call-styles-name.d.ts.map +1 -0
  10. package/dist/src/rules/require-variants-suffix.d.ts +19 -0
  11. package/dist/src/rules/require-variants-suffix.d.ts.map +1 -0
  12. package/dist/src/rules/sort-custom-properties.d.ts +86 -0
  13. package/dist/src/rules/sort-custom-properties.d.ts.map +1 -0
  14. package/dist/src/utils/create-rule-visitors.d.ts +2 -0
  15. package/dist/src/utils/create-rule-visitors.d.ts.map +1 -0
  16. package/dist/src/utils/get-bind-class-expression.d.ts +3 -0
  17. package/dist/src/utils/get-bind-class-expression.d.ts.map +1 -0
  18. package/package.json +43 -37
  19. package/src/index.js +61 -0
  20. package/{dist → src}/rules/index.js +5 -5
  21. package/src/rules/limited-inline-classes.js +440 -0
  22. package/src/rules/limited-inline-classes.test.js +268 -0
  23. package/src/rules/require-variants-call-styles-name.js +195 -0
  24. package/src/rules/require-variants-call-styles-name.test.js +105 -0
  25. package/src/rules/require-variants-suffix.js +146 -0
  26. package/src/rules/require-variants-suffix.test.js +81 -0
  27. package/src/rules/sort-custom-properties.js +596 -0
  28. package/src/rules/sort-custom-properties.test.js +758 -0
  29. package/src/utils/create-rule-visitors.js +28 -0
  30. package/src/utils/get-bind-class-expression.js +36 -0
  31. package/dist/index.d.ts +0 -11
  32. package/dist/index.js +0 -43
  33. package/dist/rules/index.d.ts +0 -2
  34. package/dist/rules/limited-inline-classes.d.ts +0 -23
  35. package/dist/rules/limited-inline-classes.js +0 -198
  36. package/dist/rules/require-variants-call-styles-name.d.ts +0 -17
  37. package/dist/rules/require-variants-call-styles-name.js +0 -75
  38. package/dist/rules/require-variants-suffix.d.ts +0 -17
  39. package/dist/rules/require-variants-suffix.js +0 -66
  40. package/dist/rules/sort-custom-properties.d.ts +0 -37
  41. package/dist/rules/sort-custom-properties.js +0 -210
  42. package/dist/utils/create-rule-visitors.d.ts +0 -6
  43. package/dist/utils/create-rule-visitors.js +0 -18
  44. package/dist/utils/get-bind-class-expression.d.ts +0 -6
  45. package/dist/utils/get-bind-class-expression.js +0 -20
@@ -0,0 +1,758 @@
1
+ import css from "@eslint/css";
2
+ import { RuleTester } from "eslint";
3
+
4
+ import { MESSAGE_IDS, rule } from "./sort-custom-properties";
5
+
6
+ const tester = new RuleTester({
7
+ language: "css/css",
8
+ plugins: { css },
9
+ });
10
+
11
+ /** @type {import("eslint").RuleTester.ValidTestCase[]} */
12
+ const valid = [
13
+ {
14
+ code: `
15
+ :root {
16
+ --font-family: Arial;
17
+ --color-primary: #007bff;
18
+ }
19
+ `,
20
+ filename: "styles.css",
21
+ name: "Properties already sorted correctly (default order)",
22
+ },
23
+ {
24
+ code: `
25
+ :root {
26
+ --spacing-lg: 2rem;
27
+ --spacing-sm: 1rem;
28
+ --font-family: Arial;
29
+ --font-size: 16px;
30
+ --transition-duration: 300ms;
31
+ --transition-easing: ease-in-out;
32
+ --color-primary: #007bff;
33
+ --color-secondary: #6c757d;
34
+ }
35
+ `,
36
+ filename: "styles.css",
37
+ name: "All default order groups already in correct order",
38
+ },
39
+ {
40
+ code: `
41
+ :root {
42
+ --font-weight: bold;
43
+ --margin-top: 10px;
44
+ --padding-left: 5px;
45
+ }
46
+ `,
47
+ filename: "styles.css",
48
+ name: "Properties without specified order (should go to end)",
49
+ },
50
+ {
51
+ code: `
52
+ :root {
53
+ --font-family: Arial;
54
+ }
55
+ `,
56
+ filename: "styles.css",
57
+ name: "Single custom property",
58
+ },
59
+ {
60
+ code: `
61
+ :root {
62
+ --font-family: Arial;
63
+ --color-primary: #007bff;
64
+
65
+ .dark {
66
+ --font-family: Arial;
67
+ --color-primary: #007bff;
68
+ }
69
+ }
70
+ `,
71
+ filename: "styles.css",
72
+ name: "Nested blocks",
73
+ },
74
+ {
75
+ code: `
76
+ :root {
77
+ regular-property: value;
78
+ --font-family: Arial;
79
+ --color-primary: #007bff;
80
+ }
81
+ `,
82
+ filename: "styles.css",
83
+ name: "Mixed regular and custom properties",
84
+ },
85
+ {
86
+ code: `
87
+ :root {
88
+ --font-family: Arial;
89
+ --font-size: 16px;
90
+ }
91
+ `,
92
+ filename: "styles.css",
93
+ name: "Multiple properties with same order pattern in alphabetical order",
94
+ },
95
+ {
96
+ code: `
97
+ @theme {
98
+ --font-family: Arial;
99
+ --color-primary: #007bff;
100
+ }
101
+
102
+ @utility example {
103
+ --font-family: Arial;
104
+ --color-primary: #007bff;
105
+ }
106
+ `,
107
+ filename: "styles.css",
108
+ name: "Work in tailwind syntax",
109
+ },
110
+ // Options
111
+ {
112
+ code: `
113
+ :root {
114
+ --color-primary: #007bff;
115
+ --font-family: Arial;
116
+ }
117
+ `,
118
+ filename: "styles.css",
119
+ name: "Custom order",
120
+ options: [{ order: ["^--color-", "^--font-"] }],
121
+ },
122
+ {
123
+ code: `
124
+ :root {
125
+ --custom-primary: red;
126
+ --spacing-lg: 2rem;
127
+ --font-family: Arial;
128
+ }
129
+ `,
130
+ filename: "styles.css",
131
+ name: "Custom order with unlisted patterns at end",
132
+ options: [{ order: ["^--custom-", "^--spacing-"] }],
133
+ },
134
+ {
135
+ code: `
136
+ :root {
137
+ --spacing-lg: 2rem;
138
+
139
+ --font-family: Arial;
140
+ }
141
+ `,
142
+ filename: "styles.css",
143
+ name: "Empty line between groups",
144
+ options: [{ emptyLineBetweenGroups: true }],
145
+ },
146
+ {
147
+ code: `
148
+ :root {
149
+ --spacing-lg: 2rem;
150
+ --spacing-sm: 1rem;
151
+
152
+ --font-family: Arial;
153
+ --font-size: 16px;
154
+
155
+ --color-primary: #007bff;
156
+ }
157
+ `,
158
+ filename: "styles.css",
159
+ name: "Multiple groups already correctly spaced with empty lines",
160
+ options: [{ emptyLineBetweenGroups: true }],
161
+ },
162
+ {
163
+ code: `
164
+ :root {
165
+ --font-family: Arial;
166
+ }
167
+ `,
168
+ filename: "styles.css",
169
+ name: "Single property with emptyLineBetweenGroups enabled",
170
+ options: [{ emptyLineBetweenGroups: true }],
171
+ },
172
+ // Suffix-based order patterns
173
+ {
174
+ code: `
175
+ :root {
176
+ --button-size: large;
177
+ --input-size: medium;
178
+ --primary-color: blue;
179
+ --secondary-color: red;
180
+ }
181
+ `,
182
+ filename: "styles.css",
183
+ name: "Properties ordered by suffix (-size before -color)",
184
+ options: [{ order: ["-size$", "-color$"] }],
185
+ },
186
+ {
187
+ code: `
188
+ :root {
189
+ --border-radius: 4px;
190
+ --button-radius: 8px;
191
+ --card-width: 300px;
192
+ --sidebar-width: 250px;
193
+ }
194
+ `,
195
+ filename: "styles.css",
196
+ name: "Properties ordered by multiple suffix patterns",
197
+ options: [{ order: ["-radius$", "-width$"] }],
198
+ },
199
+ // Substring-based patterns
200
+ {
201
+ code: `
202
+ :root {
203
+ --dark-primary: black;
204
+ --dark-secondary: gray;
205
+ --light-primary: white;
206
+ --light-secondary: lightgray;
207
+ --primary-font: Arial;
208
+ }
209
+ `,
210
+ filename: "styles.css",
211
+ name: "Properties ordered by substring patterns (dark, light, then others)",
212
+ options: [{ order: ["dark", "light"] }],
213
+ },
214
+ // Exact name patterns
215
+ {
216
+ code: `
217
+ :root {
218
+ --z-index: 999;
219
+ --opacity: 0.8;
220
+ --color-primary: blue;
221
+ --font-family: Arial;
222
+ }
223
+ `,
224
+ filename: "styles.css",
225
+ name: "Properties with exact name priority",
226
+ options: [{ order: ["^--z-index$", "^--opacity$"] }],
227
+ },
228
+ {
229
+ code: `
230
+ :root {
231
+ --background-color: white;
232
+ --margin-top: 20px;
233
+ --top: 5px;
234
+ --width: 100%;
235
+ --x: 10px;
236
+ }
237
+ `,
238
+ filename: "styles.css",
239
+ name: "Properties naturally sorted alphabetically (no custom order)",
240
+ },
241
+ {
242
+ code: "",
243
+ filename: "styles.css",
244
+ name: "Empty block",
245
+ },
246
+ {
247
+ code: `
248
+ :root {
249
+ }
250
+ `,
251
+ filename: "styles.css",
252
+ name: "Empty block with braces",
253
+ },
254
+ ];
255
+
256
+ /** @type {import("eslint").RuleTester.InvalidTestCase[]} */
257
+ const invalid = [
258
+ {
259
+ code: `
260
+ :root {
261
+ --spacing-lg: 2rem;
262
+ --color-primary: #007bff;
263
+ --font-family: Arial;
264
+ --transition-duration: 300ms;
265
+ }
266
+ `,
267
+ errors: [{ messageId: MESSAGE_IDS.unsortedCustomProperties }],
268
+ filename: "styles.css",
269
+ name: "Properties in wrong order (default order)",
270
+ output: `
271
+ :root {
272
+ --spacing-lg: 2rem;
273
+ --font-family: Arial;
274
+ --transition-duration: 300ms;
275
+ --color-primary: #007bff;
276
+ }
277
+ `,
278
+ },
279
+ {
280
+ code: `
281
+ :root {
282
+ --font-size: 16px;
283
+ --font-family: Arial;
284
+ }
285
+ `,
286
+ errors: [{ messageId: MESSAGE_IDS.unsortedCustomProperties }],
287
+ filename: "styles.css",
288
+ name: "Properties with same order pattern in wrong alphabetical order",
289
+ output: `
290
+ :root {
291
+ --font-family: Arial;
292
+ --font-size: 16px;
293
+ }
294
+ `,
295
+ },
296
+ {
297
+ code: `
298
+ :root {
299
+ --color-primary: #007bff;
300
+ --transition-duration: 300ms;
301
+ --spacing-lg: 2rem;
302
+ --font-family: Arial;
303
+ }
304
+ `,
305
+ errors: [{ messageId: MESSAGE_IDS.unsortedCustomProperties }],
306
+ filename: "styles.css",
307
+ name: "All groups in completely wrong order",
308
+ output: `
309
+ :root {
310
+ --spacing-lg: 2rem;
311
+ --font-family: Arial;
312
+ --transition-duration: 300ms;
313
+ --color-primary: #007bff;
314
+ }
315
+ `,
316
+ },
317
+ {
318
+ code: `
319
+ :root {
320
+ --margin-top: 10px;
321
+ --font-family: Arial;
322
+ --padding-left: 5px;
323
+ }
324
+ `,
325
+ errors: [{ messageId: MESSAGE_IDS.unsortedCustomProperties }],
326
+ filename: "styles.css",
327
+ name: "Mix of specified and unspecified order patterns in wrong order",
328
+ output: `
329
+ :root {
330
+ --font-family: Arial;
331
+ --margin-top: 10px;
332
+ --padding-left: 5px;
333
+ }
334
+ `,
335
+ },
336
+ {
337
+ code: `
338
+ :root {
339
+ --z-index: 999;
340
+ --width: 100%;
341
+ --height: 100vh;
342
+ --margin: 0;
343
+ }
344
+ `,
345
+ errors: [{ messageId: MESSAGE_IDS.unsortedCustomProperties }],
346
+ filename: "styles.css",
347
+ name: "Unspecified order patterns in wrong alphabetical order",
348
+ output: `
349
+ :root {
350
+ --height: 100vh;
351
+ --margin: 0;
352
+ --width: 100%;
353
+ --z-index: 999;
354
+ }
355
+ `,
356
+ },
357
+ {
358
+ code: `
359
+ @theme {
360
+ --color-primary: #007bff;
361
+ --font-family: Arial;
362
+ }
363
+
364
+ @utility example {
365
+ --color-primary: #007bff;
366
+ --font-family: Arial;
367
+ }
368
+ `,
369
+ errors: [
370
+ { messageId: MESSAGE_IDS.unsortedCustomProperties },
371
+ { messageId: MESSAGE_IDS.unsortedCustomProperties },
372
+ ],
373
+ filename: "styles.css",
374
+ name: "Work in tailwind syntax",
375
+ output: `
376
+ @theme {
377
+ --font-family: Arial;
378
+ --color-primary: #007bff;
379
+ }
380
+
381
+ @utility example {
382
+ --font-family: Arial;
383
+ --color-primary: #007bff;
384
+ }
385
+ `,
386
+ },
387
+ // Custom order tests
388
+ {
389
+ code: `
390
+ :root {
391
+ --font-family: Arial;
392
+ --color-primary: #007bff;
393
+ }
394
+ `,
395
+ errors: [{ messageId: MESSAGE_IDS.unsortedCustomProperties }],
396
+ filename: "styles.css",
397
+ name: "Wrong order with custom order option",
398
+ options: [{ order: ["^--color-", "^--font-"] }],
399
+ output: `
400
+ :root {
401
+ --color-primary: #007bff;
402
+ --font-family: Arial;
403
+ }
404
+ `,
405
+ },
406
+ {
407
+ code: `
408
+ :root {
409
+ --spacing-lg: 2rem;
410
+ --custom-primary: red;
411
+ }
412
+ `,
413
+ errors: [{ messageId: MESSAGE_IDS.unsortedCustomProperties }],
414
+ filename: "styles.css",
415
+ name: "Custom order with unlisted patterns at end",
416
+ options: [{ order: ["^--custom-", "^--spacing-"] }],
417
+ output: `
418
+ :root {
419
+ --custom-primary: red;
420
+ --spacing-lg: 2rem;
421
+ }
422
+ `,
423
+ },
424
+ {
425
+ code: `
426
+ :root {
427
+ --color-fill-brand-hover: oklch(
428
+ from var(--color-fill-brand) calc(l + 0.1) c h
429
+ );
430
+ --spacing-lg: 2rem;
431
+ --color-fill-brand-active: oklch(
432
+ from var(--color-fill-brand) calc(l + 0.15) c h
433
+ );
434
+ }
435
+ `,
436
+ errors: [{ messageId: MESSAGE_IDS.unsortedCustomProperties }],
437
+ filename: "styles.css",
438
+ name: "Multi-line unsorted properties",
439
+ output: `
440
+ :root {
441
+ --spacing-lg: 2rem;
442
+ --color-fill-brand-active: oklch(
443
+ from var(--color-fill-brand) calc(l + 0.15) c h
444
+ );
445
+ --color-fill-brand-hover: oklch(
446
+ from var(--color-fill-brand) calc(l + 0.1) c h
447
+ );
448
+ }
449
+ `,
450
+ },
451
+ // Empty line between groups tests
452
+ {
453
+ code: `
454
+ :root {
455
+ --spacing-lg: 2rem;
456
+ --font-family: Arial;
457
+ }
458
+ `,
459
+ errors: [{ messageId: MESSAGE_IDS.missingEmptyLineBetweenGroups }],
460
+ filename: "styles.css",
461
+ name: "Missing empty line between different order pattern groups",
462
+ options: [{ emptyLineBetweenGroups: true }],
463
+ output: `
464
+ :root {
465
+ --spacing-lg: 2rem;
466
+
467
+ --font-family: Arial;
468
+ }
469
+ `,
470
+ },
471
+ {
472
+ code: `
473
+ :root {
474
+ --spacing-lg: 2rem;
475
+ --spacing-sm: 1rem;
476
+ --font-family: Arial;
477
+ --font-size: 16px;
478
+ --color-primary: #007bff;
479
+ }
480
+ `,
481
+ errors: [{ messageId: MESSAGE_IDS.missingEmptyLineBetweenGroups }],
482
+ filename: "styles.css",
483
+ name: "Properties already sorted but missing empty lines between groups",
484
+ options: [{ emptyLineBetweenGroups: true }],
485
+ output: `
486
+ :root {
487
+ --spacing-lg: 2rem;
488
+ --spacing-sm: 1rem;
489
+
490
+ --font-family: Arial;
491
+ --font-size: 16px;
492
+
493
+ --color-primary: #007bff;
494
+ }
495
+ `,
496
+ },
497
+ {
498
+ code: `
499
+ :root {
500
+ --font-family: Arial;
501
+ --spacing-lg: 2rem;
502
+ --color-primary: #007bff;
503
+ }
504
+ `,
505
+ errors: [{ messageId: MESSAGE_IDS.unsortedCustomProperties }],
506
+ filename: "styles.css",
507
+ name: "Wrong order with emptyLineBetweenGroups (should fix order first)",
508
+ options: [{ emptyLineBetweenGroups: true }],
509
+ output: `
510
+ :root {
511
+ --spacing-lg: 2rem;
512
+
513
+ --font-family: Arial;
514
+
515
+ --color-primary: #007bff;
516
+ }
517
+ `,
518
+ },
519
+ {
520
+ code: `
521
+ :root {
522
+ --font-weight: bold;
523
+ --font-family: Arial;
524
+ --margin-top: 10px;
525
+ --padding-left: 5px;
526
+ }
527
+ `,
528
+ errors: [{ messageId: MESSAGE_IDS.unsortedCustomProperties }],
529
+ filename: "styles.css",
530
+ name: "Mixed specified and unspecified order patterns with emptyLineBetweenGroups",
531
+ options: [{ emptyLineBetweenGroups: true }],
532
+ output: `
533
+ :root {
534
+ --font-family: Arial;
535
+ --font-weight: bold;
536
+
537
+ --margin-top: 10px;
538
+ --padding-left: 5px;
539
+ }
540
+ `,
541
+ },
542
+ {
543
+ code: `
544
+ :root {
545
+ --color-primary: #fff;
546
+
547
+ --spacing-sm-md: 0.6rem;
548
+
549
+
550
+ --spacing-xs: 0.25rem;
551
+
552
+ --spacing-sm: 0.5rem;
553
+
554
+
555
+
556
+ --spacing-md: 0.75rem;
557
+
558
+ --spacing-lg: 1rem;
559
+
560
+ --spacing-xl: 1.5rem;
561
+
562
+ --spacing-2xl: 2rem;
563
+ }
564
+ `,
565
+ errors: [{ messageId: MESSAGE_IDS.unsortedCustomProperties }],
566
+ filename: "styles.css",
567
+ name: "Properties with same order pattern in wrong alphabetical order with pre-existing empty lines",
568
+ options: [{ emptyLineBetweenGroups: true }],
569
+ output: `
570
+ :root {
571
+ --spacing-2xl: 2rem;
572
+ --spacing-lg: 1rem;
573
+ --spacing-md: 0.75rem;
574
+ --spacing-sm: 0.5rem;
575
+ --spacing-sm-md: 0.6rem;
576
+ --spacing-xl: 1.5rem;
577
+ --spacing-xs: 0.25rem;
578
+
579
+ --color-primary: #fff;
580
+ }
581
+ `,
582
+ },
583
+ // Nested blocks
584
+ {
585
+ code: `
586
+ :root {
587
+ --color-primary: #007bff;
588
+ --font-family: Arial;
589
+
590
+ .dark {
591
+ --font-size: 14px;
592
+ --spacing-lg: 2rem;
593
+ }
594
+ }
595
+ `,
596
+ errors: [
597
+ { messageId: MESSAGE_IDS.unsortedCustomProperties },
598
+ { messageId: MESSAGE_IDS.unsortedCustomProperties },
599
+ ],
600
+ filename: "styles.css",
601
+ name: "Wrong order in nested blocks",
602
+ output: `
603
+ :root {
604
+ --font-family: Arial;
605
+ --color-primary: #007bff;
606
+
607
+ .dark {
608
+ --spacing-lg: 2rem;
609
+ --font-size: 14px;
610
+ }
611
+ }
612
+ `,
613
+ },
614
+ // Suffix-based order pattern tests
615
+ {
616
+ code: `
617
+ :root {
618
+ --primary-color: blue;
619
+ --button-size: large;
620
+ --secondary-color: red;
621
+ --input-size: medium;
622
+ }
623
+ `,
624
+ errors: [{ messageId: MESSAGE_IDS.unsortedCustomProperties }],
625
+ filename: "styles.css",
626
+ name: "Wrong order with suffix-based patterns (-size should come before -color)",
627
+ options: [{ order: ["-size$", "-color$"] }],
628
+ output: `
629
+ :root {
630
+ --button-size: large;
631
+ --input-size: medium;
632
+ --primary-color: blue;
633
+ --secondary-color: red;
634
+ }
635
+ `,
636
+ },
637
+ {
638
+ code: `
639
+ :root {
640
+ --sidebar-width: 250px;
641
+ --border-radius: 4px;
642
+ --card-width: 300px;
643
+ --button-radius: 8px;
644
+ }
645
+ `,
646
+ errors: [{ messageId: MESSAGE_IDS.unsortedCustomProperties }],
647
+ filename: "styles.css",
648
+ name: "Wrong order with multiple suffix patterns (*-radius before *-width)",
649
+ options: [{ order: ["-radius$", "-width$"] }],
650
+ output: `
651
+ :root {
652
+ --border-radius: 4px;
653
+ --button-radius: 8px;
654
+ --card-width: 300px;
655
+ --sidebar-width: 250px;
656
+ }
657
+ `,
658
+ },
659
+ // Substring-based pattern tests
660
+ {
661
+ code: `
662
+ :root {
663
+ --light-primary: white;
664
+ --dark-primary: black;
665
+ --primary-font: Arial;
666
+ --light-secondary: lightgray;
667
+ --dark-secondary: gray;
668
+ }
669
+ `,
670
+ errors: [{ messageId: MESSAGE_IDS.unsortedCustomProperties }],
671
+ filename: "styles.css",
672
+ name: "Wrong order with substring patterns (dark should come before light)",
673
+ options: [{ order: ["dark", "light"] }],
674
+ output: `
675
+ :root {
676
+ --dark-primary: black;
677
+ --dark-secondary: gray;
678
+ --light-primary: white;
679
+ --light-secondary: lightgray;
680
+ --primary-font: Arial;
681
+ }
682
+ `,
683
+ },
684
+ // Exact name priority tests
685
+ {
686
+ code: `
687
+ :root {
688
+ --font-family: Arial;
689
+ --z-index: 999;
690
+ --color-primary: blue;
691
+ --opacity: 0.8;
692
+ }
693
+ `,
694
+ errors: [{ messageId: MESSAGE_IDS.unsortedCustomProperties }],
695
+ filename: "styles.css",
696
+ name: "Wrong order with exact name priority (--z-index and --opacity should come first)",
697
+ options: [{ order: ["^--z-index$", "^--opacity$"] }],
698
+ output: `
699
+ :root {
700
+ --z-index: 999;
701
+ --opacity: 0.8;
702
+ --color-primary: blue;
703
+ --font-family: Arial;
704
+ }
705
+ `,
706
+ },
707
+ // Mixed pattern types
708
+ {
709
+ code: `
710
+ :root {
711
+ --button-size: large;
712
+ --z-index: 999;
713
+ --dark-theme: enabled;
714
+ --primary-color: blue;
715
+ --opacity: 0.8;
716
+ }
717
+ `,
718
+ errors: [{ messageId: MESSAGE_IDS.unsortedCustomProperties }],
719
+ filename: "styles.css",
720
+ name: "Wrong order with mixed pattern types (exact names, substrings, and suffixes)",
721
+ options: [
722
+ { order: ["^--z-index", "^--opacity", "dark", "-color$", "-size$"] },
723
+ ],
724
+ output: `
725
+ :root {
726
+ --z-index: 999;
727
+ --opacity: 0.8;
728
+ --dark-theme: enabled;
729
+ --primary-color: blue;
730
+ --button-size: large;
731
+ }
732
+ `,
733
+ },
734
+ // Pattern too long tests
735
+ {
736
+ code: `
737
+ :root {
738
+ --color-primary: #007bff;
739
+ --font-family: Arial;
740
+ }
741
+ `,
742
+ errors: [{ messageId: MESSAGE_IDS.patternTooLong }],
743
+ filename: "styles.css",
744
+ name: "Pattern longer than 100 characters should trigger pattern too long error",
745
+ options: [
746
+ {
747
+ order: [
748
+ "^--this-is-a-very-long-pattern-that-exceeds-one-hundred-characters-and-should-trigger-the-pattern-too-long-error-message-because-it-is-way-too-long-for-performance-reasons$",
749
+ ],
750
+ },
751
+ ],
752
+ },
753
+ ];
754
+
755
+ tester.run("sort-custom-properties", rule, {
756
+ invalid,
757
+ valid,
758
+ });