@cwcss/crosswind 0.1.5 → 0.2.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 (87) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +52 -0
  3. package/dist/bin/cli.js +14615 -0
  4. package/dist/build.d.ts +24 -0
  5. package/dist/config.d.ts +5 -0
  6. package/dist/generator.d.ts +31 -0
  7. package/dist/index.d.ts +10 -0
  8. package/dist/parser.d.ts +42 -0
  9. package/dist/plugin.d.ts +22 -0
  10. package/dist/preflight-forms.d.ts +5 -0
  11. package/dist/preflight.d.ts +2 -0
  12. package/dist/rules-advanced.d.ts +27 -0
  13. package/dist/rules-effects.d.ts +25 -0
  14. package/dist/rules-forms.d.ts +7 -0
  15. package/dist/rules-grid.d.ts +13 -0
  16. package/dist/rules-interactivity.d.ts +41 -0
  17. package/dist/rules-layout.d.ts +26 -0
  18. package/dist/rules-transforms.d.ts +33 -0
  19. package/dist/rules-typography.d.ts +41 -0
  20. package/dist/rules.d.ts +39 -0
  21. package/dist/scanner.d.ts +18 -0
  22. package/dist/src/index.js +12848 -0
  23. package/dist/transformer-compile-class.d.ts +37 -0
  24. package/{src/types.ts → dist/types.d.ts} +17 -86
  25. package/package.json +2 -16
  26. package/PLUGIN.md +0 -235
  27. package/benchmark/framework-comparison.bench.ts +0 -850
  28. package/bin/cli.ts +0 -365
  29. package/bin/crosswind +0 -0
  30. package/bin/headwind +0 -0
  31. package/build.ts +0 -8
  32. package/crosswind.config.ts +0 -9
  33. package/example/comprehensive.html +0 -70
  34. package/example/index.html +0 -21
  35. package/example/output.css +0 -236
  36. package/examples/plugin/README.md +0 -112
  37. package/examples/plugin/build.ts +0 -32
  38. package/examples/plugin/src/index.html +0 -34
  39. package/examples/plugin/src/index.ts +0 -7
  40. package/headwind +0 -2
  41. package/src/build.ts +0 -101
  42. package/src/config.ts +0 -529
  43. package/src/generator.ts +0 -2173
  44. package/src/index.ts +0 -10
  45. package/src/parser.ts +0 -1471
  46. package/src/plugin.ts +0 -118
  47. package/src/preflight-forms.ts +0 -229
  48. package/src/preflight.ts +0 -388
  49. package/src/rules-advanced.ts +0 -477
  50. package/src/rules-effects.ts +0 -461
  51. package/src/rules-forms.ts +0 -103
  52. package/src/rules-grid.ts +0 -241
  53. package/src/rules-interactivity.ts +0 -525
  54. package/src/rules-layout.ts +0 -385
  55. package/src/rules-transforms.ts +0 -412
  56. package/src/rules-typography.ts +0 -486
  57. package/src/rules.ts +0 -809
  58. package/src/scanner.ts +0 -84
  59. package/src/transformer-compile-class.ts +0 -275
  60. package/test/advanced-features.test.ts +0 -911
  61. package/test/arbitrary.test.ts +0 -396
  62. package/test/attributify.test.ts +0 -592
  63. package/test/bracket-syntax.test.ts +0 -1133
  64. package/test/build.test.ts +0 -99
  65. package/test/colors.test.ts +0 -934
  66. package/test/flexbox.test.ts +0 -669
  67. package/test/generator.test.ts +0 -597
  68. package/test/grid.test.ts +0 -584
  69. package/test/layout.test.ts +0 -404
  70. package/test/modifiers.test.ts +0 -417
  71. package/test/parser.test.ts +0 -564
  72. package/test/performance-regression.test.ts +0 -376
  73. package/test/performance.test.ts +0 -568
  74. package/test/plugin.test.ts +0 -160
  75. package/test/scanner.test.ts +0 -94
  76. package/test/sizing.test.ts +0 -481
  77. package/test/spacing.test.ts +0 -394
  78. package/test/transformer-compile-class.test.ts +0 -287
  79. package/test/transforms.test.ts +0 -448
  80. package/test/typography.test.ts +0 -632
  81. package/test/variants-form-states.test.ts +0 -225
  82. package/test/variants-group-peer.test.ts +0 -66
  83. package/test/variants-media.test.ts +0 -213
  84. package/test/variants-positional.test.ts +0 -58
  85. package/test/variants-pseudo-elements.test.ts +0 -47
  86. package/test/variants-state.test.ts +0 -62
  87. package/tsconfig.json +0 -18
@@ -1,564 +0,0 @@
1
- import { describe, expect, it } from 'bun:test'
2
- import { extractClasses, parseClass } from '../src/parser'
3
-
4
- describe('parseClass', () => {
5
- it('should parse simple utility without value', () => {
6
- const result = parseClass('flex')
7
- expect(result).toEqual({
8
- raw: 'flex',
9
- variants: [],
10
- utility: 'flex',
11
- value: undefined,
12
- important: false,
13
- arbitrary: false,
14
- })
15
- })
16
-
17
- it('should parse utility with value', () => {
18
- const result = parseClass('p-4')
19
- expect(result).toEqual({
20
- raw: 'p-4',
21
- variants: [],
22
- utility: 'p',
23
- value: '4',
24
- important: false,
25
- arbitrary: false,
26
- })
27
- })
28
-
29
- it('should parse important modifier', () => {
30
- const result = parseClass('!p-4')
31
- expect(result).toEqual({
32
- raw: '!p-4',
33
- variants: [],
34
- utility: 'p',
35
- value: '4',
36
- important: true,
37
- arbitrary: false,
38
- })
39
- })
40
-
41
- it('should parse arbitrary value', () => {
42
- const result = parseClass('w-[100px]')
43
- expect(result).toEqual({
44
- raw: 'w-[100px]',
45
- variants: [],
46
- utility: 'w',
47
- value: '100px',
48
- important: false,
49
- arbitrary: true,
50
- })
51
- })
52
-
53
- it('should parse arbitrary color value', () => {
54
- const result = parseClass('bg-[#ff0000]')
55
- expect(result).toEqual({
56
- raw: 'bg-[#ff0000]',
57
- variants: [],
58
- utility: 'bg',
59
- value: '#ff0000',
60
- important: false,
61
- arbitrary: true,
62
- })
63
- })
64
-
65
- it('should parse arbitrary value with important', () => {
66
- const result = parseClass('!w-[100px]')
67
- expect(result).toEqual({
68
- raw: '!w-[100px]',
69
- variants: [],
70
- utility: 'w',
71
- value: '100px',
72
- important: true,
73
- arbitrary: true,
74
- })
75
- })
76
-
77
- it('should parse utility with compound value', () => {
78
- const result = parseClass('bg-blue-500')
79
- expect(result).toEqual({
80
- raw: 'bg-blue-500',
81
- variants: [],
82
- utility: 'bg',
83
- value: 'blue-500',
84
- important: false,
85
- arbitrary: false,
86
- })
87
- })
88
-
89
- it('should parse utility with single variant', () => {
90
- const result = parseClass('hover:bg-blue-500')
91
- expect(result).toEqual({
92
- raw: 'hover:bg-blue-500',
93
- variants: ['hover'],
94
- utility: 'bg',
95
- value: 'blue-500',
96
- important: false,
97
- arbitrary: false,
98
- })
99
- })
100
-
101
- it('should parse utility with multiple variants', () => {
102
- const result = parseClass('sm:hover:flex')
103
- expect(result).toEqual({
104
- raw: 'sm:hover:flex',
105
- variants: ['sm', 'hover'],
106
- utility: 'flex',
107
- value: undefined,
108
- important: false,
109
- arbitrary: false,
110
- })
111
- })
112
-
113
- it('should parse responsive variant with value', () => {
114
- const result = parseClass('md:p-8')
115
- expect(result).toEqual({
116
- raw: 'md:p-8',
117
- variants: ['md'],
118
- utility: 'p',
119
- value: '8',
120
- important: false,
121
- arbitrary: false,
122
- })
123
- })
124
-
125
- it('should parse complex multi-variant utility', () => {
126
- const result = parseClass('lg:dark:hover:text-gray-800')
127
- expect(result).toEqual({
128
- raw: 'lg:dark:hover:text-gray-800',
129
- variants: ['lg', 'dark', 'hover'],
130
- utility: 'text',
131
- value: 'gray-800',
132
- important: false,
133
- arbitrary: false,
134
- })
135
- })
136
- })
137
-
138
- describe('extractClasses', () => {
139
- it('should extract classes from class attribute', () => {
140
- const html = '<div class="flex p-4 bg-blue-500"></div>'
141
- const result = extractClasses(html)
142
- expect(result).toEqual(new Set(['flex', 'p-4', 'bg-blue-500']))
143
- })
144
-
145
- it('should extract classes from className attribute', () => {
146
- const jsx = '<div className="flex p-4 bg-blue-500"></div>'
147
- const result = extractClasses(jsx)
148
- expect(result).toEqual(new Set(['flex', 'p-4', 'bg-blue-500']))
149
- })
150
-
151
- it('should extract classes from className with curly braces', () => {
152
- const jsx = '<div className={"flex p-4"}></div>'
153
- const result = extractClasses(jsx)
154
- expect(result).toEqual(new Set(['flex', 'p-4']))
155
- })
156
-
157
- it('should extract classes from template literals', () => {
158
- const jsx = '<div className={`flex p-4 hover:bg-blue-500`}></div>'
159
- const result = extractClasses(jsx)
160
- expect(result).toEqual(new Set(['flex', 'p-4', 'hover:bg-blue-500']))
161
- })
162
-
163
- it('should handle multiple elements', () => {
164
- const html = `
165
- <div class="flex p-4">
166
- <span className="text-sm">Text</span>
167
- </div>
168
- `
169
- const result = extractClasses(html)
170
- expect(result).toEqual(new Set(['flex', 'p-4', 'text-sm']))
171
- })
172
-
173
- it('should handle variants', () => {
174
- const html = '<div class="sm:flex md:p-8 hover:bg-blue-500"></div>'
175
- const result = extractClasses(html)
176
- expect(result).toEqual(new Set(['sm:flex', 'md:p-8', 'hover:bg-blue-500']))
177
- })
178
-
179
- it('should ignore empty strings', () => {
180
- const html = '<div class=" flex p-4 "></div>'
181
- const result = extractClasses(html)
182
- expect(result).toEqual(new Set(['flex', 'p-4']))
183
- })
184
-
185
- it('should return empty set for content without classes', () => {
186
- const html = '<div><p>No classes here</p></div>'
187
- const result = extractClasses(html)
188
- expect(result.size).toBe(0)
189
- })
190
- })
191
-
192
- describe('parseClass - Edge Cases', () => {
193
- it('should handle empty string', () => {
194
- const result = parseClass('')
195
- expect(result.utility).toBe('')
196
- expect(result.variants).toEqual([])
197
- })
198
-
199
- it('should handle very long class name', () => {
200
- const longClass = 'a'.repeat(1000)
201
- const result = parseClass(longClass)
202
- expect(result.utility).toBe(longClass)
203
- })
204
-
205
- it('should handle class with only dashes', () => {
206
- const result = parseClass('---')
207
- // Parser splits on last dash, so --- becomes -- with no value
208
- expect(result.utility).toBe('--')
209
- expect(result.value).toBeUndefined()
210
- })
211
-
212
- it('should handle class with trailing colon', () => {
213
- const result = parseClass('hover:')
214
- expect(result.variants).toEqual(['hover'])
215
- expect(result.utility).toBe('')
216
- })
217
-
218
- it('should handle class with leading colon', () => {
219
- const result = parseClass(':flex')
220
- expect(result.variants).toEqual([''])
221
- expect(result.utility).toBe('flex')
222
- })
223
-
224
- it('should handle multiple consecutive colons', () => {
225
- const result = parseClass('sm::hover::flex')
226
- expect(result.variants).toEqual(['sm', '', 'hover', ''])
227
- expect(result.utility).toBe('flex')
228
- })
229
-
230
- it('should handle negative zero value', () => {
231
- const result = parseClass('-m-0')
232
- expect(result).toEqual({
233
- raw: '-m-0',
234
- variants: [],
235
- utility: 'm',
236
- value: '-0',
237
- important: false,
238
- arbitrary: false,
239
- })
240
- })
241
-
242
- it('should handle fractional zero', () => {
243
- const result = parseClass('w-0/0')
244
- expect(result).toEqual({
245
- raw: 'w-0/0',
246
- variants: [],
247
- utility: 'w',
248
- value: '0/0',
249
- important: false,
250
- arbitrary: false,
251
- })
252
- })
253
-
254
- it('should handle arbitrary value with nested brackets', () => {
255
- const result = parseClass('w-[calc(100%-20px)]')
256
- expect(result.arbitrary).toBe(true)
257
- expect(result.utility).toBe('w')
258
- expect(result.value).toBe('calc(100%-20px)')
259
- })
260
-
261
- it('should handle arbitrary value with special characters', () => {
262
- const result = parseClass('bg-[rgba(255,0,0,0.5)]')
263
- expect(result.arbitrary).toBe(true)
264
- expect(result.value).toContain('rgba')
265
- })
266
-
267
- it('should handle multiple important modifiers', () => {
268
- const result = parseClass('!!p-4')
269
- // Should only process the first !
270
- expect(result.important).toBe(true)
271
- expect(result.raw).toBe('!!p-4')
272
- })
273
-
274
- it('should handle important with no utility', () => {
275
- const result = parseClass('!')
276
- expect(result.important).toBe(true)
277
- expect(result.utility).toBe('')
278
- })
279
-
280
- it('should handle complex variant chain', () => {
281
- const result = parseClass('2xl:dark:group-hover:peer-checked:first:focus:bg-red-500')
282
- expect(result.variants).toEqual(['2xl', 'dark', 'group-hover', 'peer-checked', 'first', 'focus'])
283
- expect(result.utility).toBe('bg')
284
- expect(result.value).toBe('red-500')
285
- })
286
-
287
- it('should handle compound utility with multiple dashes', () => {
288
- const result = parseClass('grid-cols-12')
289
- expect(result.utility).toBe('grid-cols')
290
- expect(result.value).toBe('12')
291
- })
292
-
293
- it('should handle negative compound utility', () => {
294
- const result = parseClass('-translate-x-full')
295
- expect(result.utility).toBe('translate-x')
296
- expect(result.value).toBe('-full')
297
- })
298
-
299
- it('should handle arbitrary property with numbers', () => {
300
- const result = parseClass('[line-height:1.5]')
301
- expect(result.arbitrary).toBe(true)
302
- expect(result.utility).toBe('line-height')
303
- expect(result.value).toBe('1.5')
304
- })
305
-
306
- it('should handle arbitrary property with spaces in value', () => {
307
- const result = parseClass('[font-family:ui-sans-serif]')
308
- expect(result.arbitrary).toBe(true)
309
- expect(result.utility).toBe('font-family')
310
- })
311
-
312
- it('should handle utility with uppercase letters', () => {
313
- const result = parseClass('BG-RED-500')
314
- // Lowercase is expected in utility names
315
- expect(result.raw).toBe('BG-RED-500')
316
- })
317
-
318
- it('should handle fraction with large numbers', () => {
319
- const result = parseClass('w-999/1000')
320
- expect(result.utility).toBe('w')
321
- expect(result.value).toBe('999/1000')
322
- })
323
-
324
- it('should handle negative fraction', () => {
325
- const result = parseClass('-m-1/2')
326
- expect(result.utility).toBe('m')
327
- expect(result.value).toBe('-1/2')
328
- })
329
-
330
- it('should handle space-x without value', () => {
331
- const result = parseClass('space-x')
332
- expect(result.utility).toBe('space')
333
- expect(result.value).toBe('x')
334
- })
335
-
336
- it('should handle divide-x without value', () => {
337
- const result = parseClass('divide-x')
338
- expect(result.utility).toBe('divide-x')
339
- expect(result.value).toBe(undefined)
340
- })
341
- })
342
-
343
- describe('extractClasses - Edge Cases', () => {
344
- it('should handle empty HTML', () => {
345
- const result = extractClasses('')
346
- expect(result.size).toBe(0)
347
- })
348
-
349
- it('should handle malformed HTML', () => {
350
- const html = '<div class="flex p-4'
351
- const result = extractClasses(html)
352
- // May not extract properly without closing quote
353
- expect(result.size).toBeGreaterThanOrEqual(0)
354
- })
355
-
356
- it('should handle classes with newlines', () => {
357
- const html = `<div class="flex
358
- p-4
359
- bg-blue-500"></div>`
360
- const result = extractClasses(html)
361
- expect(result.has('flex')).toBe(true)
362
- expect(result.has('p-4')).toBe(true)
363
- expect(result.has('bg-blue-500')).toBe(true)
364
- })
365
-
366
- it('should handle classes with tabs', () => {
367
- const html = '<div class="flex\tp-4\tbg-blue-500"></div>'
368
- const result = extractClasses(html)
369
- expect(result.has('flex')).toBe(true)
370
- expect(result.has('p-4')).toBe(true)
371
- })
372
-
373
- it('should handle duplicate classes', () => {
374
- const html = '<div class="flex flex p-4 p-4"></div>'
375
- const result = extractClasses(html)
376
- expect(result.size).toBe(2) // Set removes duplicates
377
- })
378
-
379
- it('should handle classes with special characters in attribute', () => {
380
- const html = '<div data-test="flex" class="p-4"></div>'
381
- const result = extractClasses(html)
382
- expect(result.has('p-4')).toBe(true)
383
- // Should only extract from class/className attributes
384
- })
385
-
386
- it('should handle mixed quotes', () => {
387
- const html = `<div class='flex "p-4"'></div>`
388
- const result = extractClasses(html)
389
- // Should extract from single-quoted attribute
390
- expect(result.size).toBeGreaterThan(0)
391
- })
392
-
393
- it('should handle template literal with expressions', () => {
394
- // eslint-disable-next-line no-template-curly-in-string
395
- const jsx = '<div className={`flex ${isActive ? "active" : ""} p-4`}></div>'
396
- const result = extractClasses(jsx)
397
- expect(result.has('flex')).toBe(true)
398
- expect(result.has('p-4')).toBe(true)
399
- })
400
-
401
- it('should handle very long class string', () => {
402
- const classes = Array.from({ length: 1000 }).fill('p-4').join(' ')
403
- const html = `<div class="${classes}"></div>`
404
- const result = extractClasses(html)
405
- expect(result.has('p-4')).toBe(true)
406
- })
407
-
408
- it('should ignore invalid class names', () => {
409
- const html = '<div class="123invalid -flex @media"></div>'
410
- const result = extractClasses(html)
411
- // Should filter out invalid patterns
412
- expect(result.has('123invalid')).toBe(false)
413
- })
414
-
415
- it('should handle consecutive spaces', () => {
416
- const html = '<div class="flex p-4 bg-blue-500"></div>'
417
- const result = extractClasses(html)
418
- expect(result.size).toBe(3)
419
- })
420
- })
421
-
422
- describe('parseClass - Extreme Edge Cases', () => {
423
- it('should handle null-like strings', () => {
424
- expect(() => parseClass('null')).not.toThrow()
425
- expect(() => parseClass('undefined')).not.toThrow()
426
- expect(() => parseClass('NaN')).not.toThrow()
427
- })
428
-
429
- it('should handle numbers as class names', () => {
430
- const result = parseClass('123')
431
- expect(result.utility).toBe('123')
432
- expect(result.value).toBeUndefined()
433
- })
434
-
435
- it('should handle special characters in class names', () => {
436
- expect(() => parseClass('@apply')).not.toThrow()
437
- expect(() => parseClass('$variable')).not.toThrow()
438
- expect(() => parseClass('#id-like')).not.toThrow()
439
- })
440
-
441
- it('should handle unicode characters', () => {
442
- const result = parseClass('w-[20px]') // Normal
443
- expect(result.arbitrary).toBe(true)
444
-
445
- const result2 = parseClass('text-[📝]') // Emoji
446
- expect(result2.arbitrary).toBe(true)
447
- })
448
-
449
- it('should handle extremely nested brackets', () => {
450
- const result = parseClass('w-[calc(calc(100%-10px)-5px)]')
451
- expect(result.arbitrary).toBe(true)
452
- expect(result.value).toContain('calc')
453
- })
454
-
455
- it('should handle URL in arbitrary value', () => {
456
- const result = parseClass('bg-[url(https://example.com/image.jpg)]')
457
- expect(result.arbitrary).toBe(true)
458
- expect(result.value).toContain('url')
459
- })
460
-
461
- it('should handle data URL in arbitrary value', () => {
462
- const result = parseClass('bg-[url(data:image/svg+xml;base64,ABC123)]')
463
- expect(result.arbitrary).toBe(true)
464
- expect(result.value).toContain('data:')
465
- })
466
-
467
- it('should handle CSS variables in arbitrary value', () => {
468
- const result = parseClass('w-[var(--custom-width)]')
469
- expect(result.arbitrary).toBe(true)
470
- expect(result.value).toContain('var(--')
471
- })
472
-
473
- it('should handle clamp in arbitrary value', () => {
474
- const result = parseClass('text-[clamp(1rem,5vw,3rem)]')
475
- expect(result.arbitrary).toBe(true)
476
- expect(result.value).toContain('clamp')
477
- })
478
-
479
- it('should handle min/max in arbitrary value', () => {
480
- const result = parseClass('w-[min(100%,500px)]')
481
- expect(result.arbitrary).toBe(true)
482
- expect(result.value).toContain('min')
483
- })
484
-
485
- it('should handle zero with units', () => {
486
- expect(() => parseClass('w-[0px]')).not.toThrow()
487
- expect(() => parseClass('h-[0rem]')).not.toThrow()
488
- expect(() => parseClass('p-[0em]')).not.toThrow()
489
- })
490
-
491
- it('should handle extremely large numbers', () => {
492
- const result = parseClass('w-[99999999px]')
493
- expect(result.arbitrary).toBe(true)
494
- expect(result.value).toBe('99999999px')
495
- })
496
-
497
- it('should handle extremely small numbers', () => {
498
- const result = parseClass('w-[0.0001px]')
499
- expect(result.arbitrary).toBe(true)
500
- expect(result.value).toBe('0.0001px')
501
- })
502
-
503
- it('should handle scientific notation', () => {
504
- const result = parseClass('w-[1e10px]')
505
- expect(result.arbitrary).toBe(true)
506
- expect(result.value).toBe('1e10px')
507
- })
508
- })
509
-
510
- describe('extractClasses - Arbitrary Values', () => {
511
- it('should extract arbitrary z-index values', () => {
512
- const html = '<div class="z-[1] z-[999] z-[-1]"></div>'
513
- const result = extractClasses(html)
514
- expect(result).toEqual(new Set(['z-[1]', 'z-[999]', 'z-[-1]']))
515
- })
516
-
517
- it('should extract arbitrary width/height values', () => {
518
- const html = '<div class="w-[100px] h-[50vh] min-w-[200px]"></div>'
519
- const result = extractClasses(html)
520
- expect(result).toEqual(new Set(['w-[100px]', 'h-[50vh]', 'min-w-[200px]']))
521
- })
522
-
523
- it('should extract arbitrary color values', () => {
524
- const html = '<div class="bg-[#ff0000] text-[rgb(0,0,0)] border-[hsl(0,100%,50%)]"></div>'
525
- const result = extractClasses(html)
526
- expect(result).toEqual(new Set(['bg-[#ff0000]', 'text-[rgb(0,0,0)]', 'border-[hsl(0,100%,50%)]']))
527
- })
528
-
529
- it('should extract arbitrary values with variants', () => {
530
- const html = '<div class="hover:z-[10] sm:w-[50%] focus:bg-[#000]"></div>'
531
- const result = extractClasses(html)
532
- expect(result).toEqual(new Set(['hover:z-[10]', 'sm:w-[50%]', 'focus:bg-[#000]']))
533
- })
534
-
535
- it('should extract arbitrary properties', () => {
536
- const html = '<div class="[color:red] [mask-type:luminance] [display:grid]"></div>'
537
- const result = extractClasses(html)
538
- expect(result).toEqual(new Set(['[color:red]', '[mask-type:luminance]', '[display:grid]']))
539
- })
540
-
541
- it('should extract important arbitrary values', () => {
542
- const html = '<div class="!z-[9999] !w-[100%]"></div>'
543
- const result = extractClasses(html)
544
- expect(result).toEqual(new Set(['!z-[9999]', '!w-[100%]']))
545
- })
546
-
547
- it('should extract negative arbitrary values', () => {
548
- const html = '<div class="-mt-[20px] -translate-x-[50%]"></div>'
549
- const result = extractClasses(html)
550
- expect(result).toEqual(new Set(['-mt-[20px]', '-translate-x-[50%]']))
551
- })
552
-
553
- it('should extract arbitrary values with calc()', () => {
554
- const html = '<div class="w-[calc(100%-2rem)] h-[calc(100vh-64px)]"></div>'
555
- const result = extractClasses(html)
556
- expect(result).toEqual(new Set(['w-[calc(100%-2rem)]', 'h-[calc(100vh-64px)]']))
557
- })
558
-
559
- it('should extract mixed regular and arbitrary classes', () => {
560
- const html = '<div class="flex p-4 z-[1] w-[100px] bg-blue-500 hover:z-[999]"></div>'
561
- const result = extractClasses(html)
562
- expect(result).toEqual(new Set(['flex', 'p-4', 'z-[1]', 'w-[100px]', 'bg-blue-500', 'hover:z-[999]']))
563
- })
564
- })