@cwcss/crosswind 0.1.5 → 0.1.6
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.md +21 -0
- package/README.md +390 -0
- package/dist/build.d.ts +24 -0
- package/dist/config.d.ts +5 -0
- package/dist/generator.d.ts +31 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +12798 -0
- package/dist/parser.d.ts +42 -0
- package/dist/plugin.d.ts +22 -0
- package/dist/preflight-forms.d.ts +5 -0
- package/dist/preflight.d.ts +2 -0
- package/dist/rules-advanced.d.ts +27 -0
- package/dist/rules-effects.d.ts +25 -0
- package/dist/rules-forms.d.ts +7 -0
- package/dist/rules-grid.d.ts +13 -0
- package/dist/rules-interactivity.d.ts +41 -0
- package/dist/rules-layout.d.ts +26 -0
- package/dist/rules-transforms.d.ts +33 -0
- package/dist/rules-typography.d.ts +41 -0
- package/dist/rules.d.ts +39 -0
- package/dist/scanner.d.ts +18 -0
- package/dist/transformer-compile-class.d.ts +37 -0
- package/{src/types.ts → dist/types.d.ts} +17 -86
- package/package.json +1 -1
- package/PLUGIN.md +0 -235
- package/benchmark/framework-comparison.bench.ts +0 -850
- package/bin/cli.ts +0 -365
- package/bin/crosswind +0 -0
- package/bin/headwind +0 -0
- package/build.ts +0 -8
- package/crosswind.config.ts +0 -9
- package/example/comprehensive.html +0 -70
- package/example/index.html +0 -21
- package/example/output.css +0 -236
- package/examples/plugin/README.md +0 -112
- package/examples/plugin/build.ts +0 -32
- package/examples/plugin/src/index.html +0 -34
- package/examples/plugin/src/index.ts +0 -7
- package/headwind +0 -2
- package/src/build.ts +0 -101
- package/src/config.ts +0 -529
- package/src/generator.ts +0 -2173
- package/src/index.ts +0 -10
- package/src/parser.ts +0 -1471
- package/src/plugin.ts +0 -118
- package/src/preflight-forms.ts +0 -229
- package/src/preflight.ts +0 -388
- package/src/rules-advanced.ts +0 -477
- package/src/rules-effects.ts +0 -461
- package/src/rules-forms.ts +0 -103
- package/src/rules-grid.ts +0 -241
- package/src/rules-interactivity.ts +0 -525
- package/src/rules-layout.ts +0 -385
- package/src/rules-transforms.ts +0 -412
- package/src/rules-typography.ts +0 -486
- package/src/rules.ts +0 -809
- package/src/scanner.ts +0 -84
- package/src/transformer-compile-class.ts +0 -275
- package/test/advanced-features.test.ts +0 -911
- package/test/arbitrary.test.ts +0 -396
- package/test/attributify.test.ts +0 -592
- package/test/bracket-syntax.test.ts +0 -1133
- package/test/build.test.ts +0 -99
- package/test/colors.test.ts +0 -934
- package/test/flexbox.test.ts +0 -669
- package/test/generator.test.ts +0 -597
- package/test/grid.test.ts +0 -584
- package/test/layout.test.ts +0 -404
- package/test/modifiers.test.ts +0 -417
- package/test/parser.test.ts +0 -564
- package/test/performance-regression.test.ts +0 -376
- package/test/performance.test.ts +0 -568
- package/test/plugin.test.ts +0 -160
- package/test/scanner.test.ts +0 -94
- package/test/sizing.test.ts +0 -481
- package/test/spacing.test.ts +0 -394
- package/test/transformer-compile-class.test.ts +0 -287
- package/test/transforms.test.ts +0 -448
- package/test/typography.test.ts +0 -632
- package/test/variants-form-states.test.ts +0 -225
- package/test/variants-group-peer.test.ts +0 -66
- package/test/variants-media.test.ts +0 -213
- package/test/variants-positional.test.ts +0 -58
- package/test/variants-pseudo-elements.test.ts +0 -47
- package/test/variants-state.test.ts +0 -62
- package/tsconfig.json +0 -18
|
@@ -1,911 +0,0 @@
|
|
|
1
|
-
import type { CustomRule } from '../src/types'
|
|
2
|
-
import { describe, expect, it } from 'bun:test'
|
|
3
|
-
import { defaultConfig } from '../src/config'
|
|
4
|
-
import { CSSGenerator } from '../src/generator'
|
|
5
|
-
|
|
6
|
-
describe('Advanced Features', () => {
|
|
7
|
-
describe('Filter utilities', () => {
|
|
8
|
-
it('should handle blur filter', () => {
|
|
9
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
10
|
-
gen.generate('blur')
|
|
11
|
-
gen.generate('blur-sm')
|
|
12
|
-
gen.generate('blur-lg')
|
|
13
|
-
gen.generate('blur-none')
|
|
14
|
-
const css = gen.toCSS(false)
|
|
15
|
-
expect(css).toContain('blur')
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
it('should handle brightness filter', () => {
|
|
19
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
20
|
-
gen.generate('brightness-0')
|
|
21
|
-
gen.generate('brightness-50')
|
|
22
|
-
gen.generate('brightness-100')
|
|
23
|
-
gen.generate('brightness-150')
|
|
24
|
-
const css = gen.toCSS(false)
|
|
25
|
-
expect(css).toContain('brightness')
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
it('should handle contrast filter', () => {
|
|
29
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
30
|
-
gen.generate('contrast-0')
|
|
31
|
-
gen.generate('contrast-100')
|
|
32
|
-
gen.generate('contrast-150')
|
|
33
|
-
const css = gen.toCSS(false)
|
|
34
|
-
expect(css).toContain('contrast')
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
it('should handle grayscale filter', () => {
|
|
38
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
39
|
-
gen.generate('grayscale-0')
|
|
40
|
-
gen.generate('grayscale')
|
|
41
|
-
const css = gen.toCSS(false)
|
|
42
|
-
expect(css).toContain('grayscale')
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
it('should handle invert filter', () => {
|
|
46
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
47
|
-
gen.generate('invert-0')
|
|
48
|
-
gen.generate('invert')
|
|
49
|
-
const css = gen.toCSS(false)
|
|
50
|
-
expect(css).toContain('invert')
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
it('should handle saturate filter', () => {
|
|
54
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
55
|
-
gen.generate('saturate-0')
|
|
56
|
-
gen.generate('saturate-50')
|
|
57
|
-
gen.generate('saturate-100')
|
|
58
|
-
gen.generate('saturate-200')
|
|
59
|
-
const css = gen.toCSS(false)
|
|
60
|
-
expect(css).toContain('saturate')
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
it('should handle sepia filter', () => {
|
|
64
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
65
|
-
gen.generate('sepia-0')
|
|
66
|
-
gen.generate('sepia')
|
|
67
|
-
const css = gen.toCSS(false)
|
|
68
|
-
expect(css).toContain('sepia')
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
it('should handle hue-rotate filter', () => {
|
|
72
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
73
|
-
gen.generate('hue-rotate-0')
|
|
74
|
-
gen.generate('hue-rotate-30')
|
|
75
|
-
gen.generate('hue-rotate-90')
|
|
76
|
-
gen.generate('hue-rotate-180')
|
|
77
|
-
const css = gen.toCSS(false)
|
|
78
|
-
expect(css).toContain('hue')
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
it('should handle drop-shadow filter', () => {
|
|
82
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
83
|
-
gen.generate('drop-shadow')
|
|
84
|
-
gen.generate('drop-shadow-sm')
|
|
85
|
-
gen.generate('drop-shadow-lg')
|
|
86
|
-
gen.generate('drop-shadow-none')
|
|
87
|
-
const css = gen.toCSS(false)
|
|
88
|
-
expect(css).toContain('drop-shadow')
|
|
89
|
-
})
|
|
90
|
-
|
|
91
|
-
it('should handle filter-none', () => {
|
|
92
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
93
|
-
gen.generate('filter-none')
|
|
94
|
-
const css = gen.toCSS(false)
|
|
95
|
-
expect(css).toContain('filter')
|
|
96
|
-
})
|
|
97
|
-
})
|
|
98
|
-
|
|
99
|
-
describe('Backdrop filter utilities', () => {
|
|
100
|
-
it('should handle backdrop-blur', () => {
|
|
101
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
102
|
-
gen.generate('backdrop-blur')
|
|
103
|
-
gen.generate('backdrop-blur-sm')
|
|
104
|
-
gen.generate('backdrop-blur-lg')
|
|
105
|
-
gen.generate('backdrop-blur-none')
|
|
106
|
-
const css = gen.toCSS(false)
|
|
107
|
-
expect(css).toContain('backdrop')
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
it('should handle backdrop-brightness', () => {
|
|
111
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
112
|
-
gen.generate('backdrop-brightness-0')
|
|
113
|
-
gen.generate('backdrop-brightness-100')
|
|
114
|
-
gen.generate('backdrop-brightness-150')
|
|
115
|
-
const css = gen.toCSS(false)
|
|
116
|
-
expect(css).toContain('backdrop')
|
|
117
|
-
})
|
|
118
|
-
|
|
119
|
-
it('should handle backdrop-contrast', () => {
|
|
120
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
121
|
-
gen.generate('backdrop-contrast-0')
|
|
122
|
-
gen.generate('backdrop-contrast-100')
|
|
123
|
-
const css = gen.toCSS(false)
|
|
124
|
-
expect(css).toContain('backdrop')
|
|
125
|
-
})
|
|
126
|
-
|
|
127
|
-
it('should handle backdrop-grayscale', () => {
|
|
128
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
129
|
-
gen.generate('backdrop-grayscale-0')
|
|
130
|
-
gen.generate('backdrop-grayscale')
|
|
131
|
-
const css = gen.toCSS(false)
|
|
132
|
-
expect(css).toContain('backdrop')
|
|
133
|
-
})
|
|
134
|
-
|
|
135
|
-
it('should handle backdrop-saturate', () => {
|
|
136
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
137
|
-
gen.generate('backdrop-saturate-0')
|
|
138
|
-
gen.generate('backdrop-saturate-100')
|
|
139
|
-
const css = gen.toCSS(false)
|
|
140
|
-
expect(css).toContain('backdrop')
|
|
141
|
-
})
|
|
142
|
-
|
|
143
|
-
it('should handle backdrop-sepia', () => {
|
|
144
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
145
|
-
gen.generate('backdrop-sepia-0')
|
|
146
|
-
gen.generate('backdrop-sepia')
|
|
147
|
-
const css = gen.toCSS(false)
|
|
148
|
-
expect(css).toContain('backdrop')
|
|
149
|
-
})
|
|
150
|
-
|
|
151
|
-
it('should handle backdrop-invert', () => {
|
|
152
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
153
|
-
gen.generate('backdrop-invert-0')
|
|
154
|
-
gen.generate('backdrop-invert')
|
|
155
|
-
const css = gen.toCSS(false)
|
|
156
|
-
expect(css).toContain('backdrop')
|
|
157
|
-
})
|
|
158
|
-
})
|
|
159
|
-
|
|
160
|
-
describe('Transition utilities', () => {
|
|
161
|
-
it('should handle transition property', () => {
|
|
162
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
163
|
-
gen.generate('transition')
|
|
164
|
-
gen.generate('transition-none')
|
|
165
|
-
gen.generate('transition-all')
|
|
166
|
-
gen.generate('transition-colors')
|
|
167
|
-
gen.generate('transition-opacity')
|
|
168
|
-
gen.generate('transition-shadow')
|
|
169
|
-
gen.generate('transition-transform')
|
|
170
|
-
const css = gen.toCSS(false)
|
|
171
|
-
expect(css).toContain('transition')
|
|
172
|
-
})
|
|
173
|
-
|
|
174
|
-
it('should handle transition duration', () => {
|
|
175
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
176
|
-
gen.generate('duration-75')
|
|
177
|
-
gen.generate('duration-100')
|
|
178
|
-
gen.generate('duration-150')
|
|
179
|
-
gen.generate('duration-200')
|
|
180
|
-
gen.generate('duration-300')
|
|
181
|
-
gen.generate('duration-500')
|
|
182
|
-
gen.generate('duration-700')
|
|
183
|
-
gen.generate('duration-1000')
|
|
184
|
-
const css = gen.toCSS(false)
|
|
185
|
-
expect(css).toContain('duration')
|
|
186
|
-
})
|
|
187
|
-
|
|
188
|
-
it('should handle transition timing', () => {
|
|
189
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
190
|
-
gen.generate('ease-linear')
|
|
191
|
-
gen.generate('ease-in')
|
|
192
|
-
gen.generate('ease-out')
|
|
193
|
-
gen.generate('ease-in-out')
|
|
194
|
-
const css = gen.toCSS(false)
|
|
195
|
-
expect(css).toContain('ease')
|
|
196
|
-
})
|
|
197
|
-
|
|
198
|
-
it('should handle transition delay', () => {
|
|
199
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
200
|
-
gen.generate('delay-75')
|
|
201
|
-
gen.generate('delay-100')
|
|
202
|
-
gen.generate('delay-150')
|
|
203
|
-
gen.generate('delay-200')
|
|
204
|
-
gen.generate('delay-300')
|
|
205
|
-
const css = gen.toCSS(false)
|
|
206
|
-
expect(css).toContain('delay')
|
|
207
|
-
})
|
|
208
|
-
|
|
209
|
-
it('should handle custom transition duration', () => {
|
|
210
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
211
|
-
gen.generate('duration-[2s]')
|
|
212
|
-
gen.generate('delay-[500ms]')
|
|
213
|
-
const css = gen.toCSS(false)
|
|
214
|
-
expect(css).toContain('2s')
|
|
215
|
-
expect(css).toContain('500ms')
|
|
216
|
-
})
|
|
217
|
-
})
|
|
218
|
-
|
|
219
|
-
describe('Animation utilities', () => {
|
|
220
|
-
it('should handle animation types', () => {
|
|
221
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
222
|
-
gen.generate('animate-none')
|
|
223
|
-
gen.generate('animate-spin')
|
|
224
|
-
gen.generate('animate-ping')
|
|
225
|
-
gen.generate('animate-pulse')
|
|
226
|
-
gen.generate('animate-bounce')
|
|
227
|
-
const css = gen.toCSS(false)
|
|
228
|
-
expect(css).toContain('animation')
|
|
229
|
-
})
|
|
230
|
-
|
|
231
|
-
it('should handle custom animation', () => {
|
|
232
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
233
|
-
gen.generate('animate-[wiggle_1s_ease-in-out_infinite]')
|
|
234
|
-
const css = gen.toCSS(false)
|
|
235
|
-
expect(css).toContain('wiggle')
|
|
236
|
-
})
|
|
237
|
-
})
|
|
238
|
-
|
|
239
|
-
describe('Table utilities', () => {
|
|
240
|
-
it('should handle border-collapse', () => {
|
|
241
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
242
|
-
gen.generate('border-collapse')
|
|
243
|
-
gen.generate('border-separate')
|
|
244
|
-
const css = gen.toCSS(false)
|
|
245
|
-
expect(css).toContain('border-collapse')
|
|
246
|
-
})
|
|
247
|
-
|
|
248
|
-
it('should handle border-spacing', () => {
|
|
249
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
250
|
-
gen.generate('border-spacing-0')
|
|
251
|
-
gen.generate('border-spacing-1')
|
|
252
|
-
gen.generate('border-spacing-2')
|
|
253
|
-
gen.generate('border-spacing-x-4')
|
|
254
|
-
gen.generate('border-spacing-y-4')
|
|
255
|
-
const css = gen.toCSS(false)
|
|
256
|
-
expect(css).toContain('border-spacing')
|
|
257
|
-
})
|
|
258
|
-
|
|
259
|
-
it('should handle table-layout', () => {
|
|
260
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
261
|
-
gen.generate('table-auto')
|
|
262
|
-
gen.generate('table-fixed')
|
|
263
|
-
const css = gen.toCSS(false)
|
|
264
|
-
expect(css).toContain('table-layout')
|
|
265
|
-
})
|
|
266
|
-
|
|
267
|
-
it('should handle caption-side', () => {
|
|
268
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
269
|
-
gen.generate('caption-top')
|
|
270
|
-
gen.generate('caption-bottom')
|
|
271
|
-
const css = gen.toCSS(false)
|
|
272
|
-
expect(css).toContain('caption-side')
|
|
273
|
-
})
|
|
274
|
-
})
|
|
275
|
-
|
|
276
|
-
describe('Advanced interactivity', () => {
|
|
277
|
-
it('should handle accent-color', () => {
|
|
278
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
279
|
-
gen.generate('accent-auto')
|
|
280
|
-
gen.generate('accent-blue-500')
|
|
281
|
-
gen.generate('accent-red-500')
|
|
282
|
-
const css = gen.toCSS(false)
|
|
283
|
-
expect(css).toContain('accent-color')
|
|
284
|
-
})
|
|
285
|
-
|
|
286
|
-
it('should handle appearance', () => {
|
|
287
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
288
|
-
gen.generate('appearance-none')
|
|
289
|
-
gen.generate('appearance-auto')
|
|
290
|
-
const css = gen.toCSS(false)
|
|
291
|
-
expect(css).toContain('appearance')
|
|
292
|
-
})
|
|
293
|
-
|
|
294
|
-
it('should handle caret-color', () => {
|
|
295
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
296
|
-
gen.generate('caret-auto')
|
|
297
|
-
gen.generate('caret-blue-500')
|
|
298
|
-
gen.generate('caret-transparent')
|
|
299
|
-
const css = gen.toCSS(false)
|
|
300
|
-
expect(css).toContain('caret-color')
|
|
301
|
-
})
|
|
302
|
-
|
|
303
|
-
it('should handle color-scheme', () => {
|
|
304
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
305
|
-
gen.generate('color-scheme-light')
|
|
306
|
-
gen.generate('color-scheme-dark')
|
|
307
|
-
gen.generate('color-scheme-auto')
|
|
308
|
-
const css = gen.toCSS(false)
|
|
309
|
-
expect(css).toContain('color-scheme')
|
|
310
|
-
})
|
|
311
|
-
|
|
312
|
-
it('should handle field-sizing', () => {
|
|
313
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
314
|
-
gen.generate('field-sizing-content')
|
|
315
|
-
gen.generate('field-sizing-fixed')
|
|
316
|
-
const css = gen.toCSS(false)
|
|
317
|
-
expect(css).toContain('field-sizing')
|
|
318
|
-
})
|
|
319
|
-
|
|
320
|
-
it('should handle touch-action', () => {
|
|
321
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
322
|
-
gen.generate('touch-auto')
|
|
323
|
-
gen.generate('touch-none')
|
|
324
|
-
gen.generate('touch-pan-x')
|
|
325
|
-
gen.generate('touch-pan-y')
|
|
326
|
-
gen.generate('touch-pan-left')
|
|
327
|
-
gen.generate('touch-pan-right')
|
|
328
|
-
gen.generate('touch-pan-up')
|
|
329
|
-
gen.generate('touch-pan-down')
|
|
330
|
-
gen.generate('touch-pinch-zoom')
|
|
331
|
-
gen.generate('touch-manipulation')
|
|
332
|
-
const css = gen.toCSS(false)
|
|
333
|
-
expect(css).toContain('touch-action')
|
|
334
|
-
})
|
|
335
|
-
})
|
|
336
|
-
|
|
337
|
-
describe('Scroll utilities', () => {
|
|
338
|
-
it('should handle scroll-margin', () => {
|
|
339
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
340
|
-
gen.generate('scroll-m-0')
|
|
341
|
-
gen.generate('scroll-m-4')
|
|
342
|
-
gen.generate('scroll-mx-4')
|
|
343
|
-
gen.generate('scroll-my-4')
|
|
344
|
-
gen.generate('scroll-mt-4')
|
|
345
|
-
gen.generate('scroll-mr-4')
|
|
346
|
-
gen.generate('scroll-mb-4')
|
|
347
|
-
gen.generate('scroll-ml-4')
|
|
348
|
-
const css = gen.toCSS(false)
|
|
349
|
-
expect(css).toContain('scroll-margin')
|
|
350
|
-
})
|
|
351
|
-
|
|
352
|
-
it('should handle scroll-padding', () => {
|
|
353
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
354
|
-
gen.generate('scroll-p-0')
|
|
355
|
-
gen.generate('scroll-p-4')
|
|
356
|
-
gen.generate('scroll-px-4')
|
|
357
|
-
gen.generate('scroll-py-4')
|
|
358
|
-
gen.generate('scroll-pt-4')
|
|
359
|
-
gen.generate('scroll-pr-4')
|
|
360
|
-
gen.generate('scroll-pb-4')
|
|
361
|
-
gen.generate('scroll-pl-4')
|
|
362
|
-
const css = gen.toCSS(false)
|
|
363
|
-
expect(css).toContain('scroll-padding')
|
|
364
|
-
})
|
|
365
|
-
|
|
366
|
-
it('should handle scroll-snap-type', () => {
|
|
367
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
368
|
-
gen.generate('snap-none')
|
|
369
|
-
gen.generate('snap-x')
|
|
370
|
-
gen.generate('snap-y')
|
|
371
|
-
gen.generate('snap-both')
|
|
372
|
-
gen.generate('snap-mandatory')
|
|
373
|
-
gen.generate('snap-proximity')
|
|
374
|
-
const css = gen.toCSS(false)
|
|
375
|
-
expect(css).toContain('scroll-snap')
|
|
376
|
-
})
|
|
377
|
-
|
|
378
|
-
it('should handle scroll-snap-align', () => {
|
|
379
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
380
|
-
gen.generate('snap-start')
|
|
381
|
-
gen.generate('snap-end')
|
|
382
|
-
gen.generate('snap-center')
|
|
383
|
-
gen.generate('snap-align-none')
|
|
384
|
-
const css = gen.toCSS(false)
|
|
385
|
-
expect(css).toContain('scroll-snap-align')
|
|
386
|
-
})
|
|
387
|
-
|
|
388
|
-
it('should handle scroll-snap-stop', () => {
|
|
389
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
390
|
-
gen.generate('snap-normal')
|
|
391
|
-
gen.generate('snap-always')
|
|
392
|
-
const css = gen.toCSS(false)
|
|
393
|
-
expect(css).toContain('scroll-snap-stop')
|
|
394
|
-
})
|
|
395
|
-
})
|
|
396
|
-
|
|
397
|
-
describe('Child selectors', () => {
|
|
398
|
-
it('should handle space-x utilities', () => {
|
|
399
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
400
|
-
gen.generate('space-x-0')
|
|
401
|
-
gen.generate('space-x-4')
|
|
402
|
-
gen.generate('space-x-8')
|
|
403
|
-
gen.generate('space-x-reverse')
|
|
404
|
-
const css = gen.toCSS(false)
|
|
405
|
-
expect(css).toContain('--hw-space-x-reverse')
|
|
406
|
-
expect(css).toContain('margin-right')
|
|
407
|
-
expect(css).toContain('margin-left')
|
|
408
|
-
})
|
|
409
|
-
|
|
410
|
-
it('should handle space-y utilities', () => {
|
|
411
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
412
|
-
gen.generate('space-y-0')
|
|
413
|
-
gen.generate('space-y-4')
|
|
414
|
-
gen.generate('space-y-8')
|
|
415
|
-
gen.generate('space-y-reverse')
|
|
416
|
-
const css = gen.toCSS(false)
|
|
417
|
-
expect(css).toContain('--hw-space-y-reverse')
|
|
418
|
-
expect(css).toContain('margin-top')
|
|
419
|
-
expect(css).toContain('margin-bottom')
|
|
420
|
-
})
|
|
421
|
-
|
|
422
|
-
it('should handle negative space values', () => {
|
|
423
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
424
|
-
gen.generate('-space-x-4')
|
|
425
|
-
gen.generate('-space-y-4')
|
|
426
|
-
const css = gen.toCSS(false)
|
|
427
|
-
expect(css).toContain('-')
|
|
428
|
-
})
|
|
429
|
-
|
|
430
|
-
it('should handle divide-x utilities', () => {
|
|
431
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
432
|
-
gen.generate('divide-x')
|
|
433
|
-
gen.generate('divide-x-0')
|
|
434
|
-
gen.generate('divide-x-2')
|
|
435
|
-
gen.generate('divide-x-4')
|
|
436
|
-
gen.generate('divide-x-reverse')
|
|
437
|
-
const css = gen.toCSS(false)
|
|
438
|
-
expect(css).toContain('border')
|
|
439
|
-
})
|
|
440
|
-
|
|
441
|
-
it('should handle divide-y utilities', () => {
|
|
442
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
443
|
-
gen.generate('divide-y')
|
|
444
|
-
gen.generate('divide-y-0')
|
|
445
|
-
gen.generate('divide-y-2')
|
|
446
|
-
gen.generate('divide-y-4')
|
|
447
|
-
gen.generate('divide-y-reverse')
|
|
448
|
-
const css = gen.toCSS(false)
|
|
449
|
-
expect(css).toContain('border')
|
|
450
|
-
})
|
|
451
|
-
|
|
452
|
-
it('should handle divide style utilities', () => {
|
|
453
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
454
|
-
gen.generate('divide-solid')
|
|
455
|
-
gen.generate('divide-dashed')
|
|
456
|
-
gen.generate('divide-dotted')
|
|
457
|
-
gen.generate('divide-double')
|
|
458
|
-
gen.generate('divide-none')
|
|
459
|
-
const css = gen.toCSS(false)
|
|
460
|
-
expect(css).toContain('border-style')
|
|
461
|
-
})
|
|
462
|
-
|
|
463
|
-
it('should handle divide color utilities', () => {
|
|
464
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
465
|
-
gen.generate('divide-blue-500')
|
|
466
|
-
gen.generate('divide-red-500')
|
|
467
|
-
gen.generate('divide-gray-300')
|
|
468
|
-
const css = gen.toCSS(false)
|
|
469
|
-
expect(css).toContain('border-color')
|
|
470
|
-
})
|
|
471
|
-
})
|
|
472
|
-
|
|
473
|
-
describe('Custom rules', () => {
|
|
474
|
-
it('should apply custom rules', () => {
|
|
475
|
-
const customRule: CustomRule = [
|
|
476
|
-
/^custom-utility$/,
|
|
477
|
-
() => ({ 'custom-property': 'custom-value' }),
|
|
478
|
-
]
|
|
479
|
-
const config = {
|
|
480
|
-
...defaultConfig,
|
|
481
|
-
rules: [customRule],
|
|
482
|
-
}
|
|
483
|
-
const gen = new CSSGenerator(config)
|
|
484
|
-
gen.generate('custom-utility')
|
|
485
|
-
const css = gen.toCSS(false)
|
|
486
|
-
expect(css).toContain('custom-property: custom-value')
|
|
487
|
-
})
|
|
488
|
-
|
|
489
|
-
it('should handle multiple custom rules', () => {
|
|
490
|
-
const rules: CustomRule[] = [
|
|
491
|
-
[/^rule1-/, () => ({ prop1: 'value1' })],
|
|
492
|
-
[/^rule2-/, () => ({ prop2: 'value2' })],
|
|
493
|
-
]
|
|
494
|
-
const config = {
|
|
495
|
-
...defaultConfig,
|
|
496
|
-
rules,
|
|
497
|
-
}
|
|
498
|
-
const gen = new CSSGenerator(config)
|
|
499
|
-
gen.generate('rule1-test')
|
|
500
|
-
gen.generate('rule2-test')
|
|
501
|
-
const css = gen.toCSS(false)
|
|
502
|
-
expect(css).toContain('prop1: value1')
|
|
503
|
-
expect(css).toContain('prop2: value2')
|
|
504
|
-
})
|
|
505
|
-
|
|
506
|
-
it('should prioritize custom rules over default rules', () => {
|
|
507
|
-
const customRule: CustomRule = [
|
|
508
|
-
/^p-custom$/,
|
|
509
|
-
() => ({ padding: '999px' }),
|
|
510
|
-
]
|
|
511
|
-
const config = {
|
|
512
|
-
...defaultConfig,
|
|
513
|
-
rules: [customRule],
|
|
514
|
-
}
|
|
515
|
-
const gen = new CSSGenerator(config)
|
|
516
|
-
gen.generate('p-custom')
|
|
517
|
-
const css = gen.toCSS(false)
|
|
518
|
-
expect(css).toContain('padding: 999px')
|
|
519
|
-
})
|
|
520
|
-
})
|
|
521
|
-
|
|
522
|
-
describe('Presets', () => {
|
|
523
|
-
it('should apply preset theme', () => {
|
|
524
|
-
const preset = {
|
|
525
|
-
name: 'custom-preset',
|
|
526
|
-
theme: {
|
|
527
|
-
colors: {
|
|
528
|
-
preset: {
|
|
529
|
-
500: '#custom',
|
|
530
|
-
},
|
|
531
|
-
},
|
|
532
|
-
},
|
|
533
|
-
}
|
|
534
|
-
const config = {
|
|
535
|
-
...defaultConfig,
|
|
536
|
-
presets: [preset],
|
|
537
|
-
}
|
|
538
|
-
const gen = new CSSGenerator(config)
|
|
539
|
-
gen.generate('bg-preset-500')
|
|
540
|
-
const css = gen.toCSS(false)
|
|
541
|
-
expect(css).toContain('#custom')
|
|
542
|
-
})
|
|
543
|
-
|
|
544
|
-
it('should apply multiple presets', () => {
|
|
545
|
-
const preset1 = {
|
|
546
|
-
name: 'preset1',
|
|
547
|
-
theme: {
|
|
548
|
-
colors: {
|
|
549
|
-
preset1: {
|
|
550
|
-
500: '#preset1',
|
|
551
|
-
},
|
|
552
|
-
},
|
|
553
|
-
},
|
|
554
|
-
}
|
|
555
|
-
const preset2 = {
|
|
556
|
-
name: 'preset2',
|
|
557
|
-
theme: {
|
|
558
|
-
colors: {
|
|
559
|
-
preset2: {
|
|
560
|
-
500: '#preset2',
|
|
561
|
-
},
|
|
562
|
-
},
|
|
563
|
-
},
|
|
564
|
-
}
|
|
565
|
-
const config = {
|
|
566
|
-
...defaultConfig,
|
|
567
|
-
presets: [preset1, preset2],
|
|
568
|
-
}
|
|
569
|
-
const gen = new CSSGenerator(config)
|
|
570
|
-
gen.generate('bg-preset1-500')
|
|
571
|
-
gen.generate('bg-preset2-500')
|
|
572
|
-
const css = gen.toCSS(false)
|
|
573
|
-
expect(css).toContain('#preset1')
|
|
574
|
-
expect(css).toContain('#preset2')
|
|
575
|
-
})
|
|
576
|
-
|
|
577
|
-
it('should merge preset rules with default rules', () => {
|
|
578
|
-
const preset = {
|
|
579
|
-
name: 'spacing-preset',
|
|
580
|
-
theme: {
|
|
581
|
-
spacing: {
|
|
582
|
-
huge: '10rem',
|
|
583
|
-
},
|
|
584
|
-
},
|
|
585
|
-
}
|
|
586
|
-
const config = {
|
|
587
|
-
...defaultConfig,
|
|
588
|
-
presets: [preset],
|
|
589
|
-
}
|
|
590
|
-
const gen = new CSSGenerator(config)
|
|
591
|
-
gen.generate('p-huge')
|
|
592
|
-
gen.generate('p-4') // Default spacing
|
|
593
|
-
const css = gen.toCSS(false)
|
|
594
|
-
expect(css).toContain('10rem')
|
|
595
|
-
expect(css).toContain('1rem')
|
|
596
|
-
})
|
|
597
|
-
})
|
|
598
|
-
|
|
599
|
-
describe('Blocklist', () => {
|
|
600
|
-
it('should exclude blocklisted classes', () => {
|
|
601
|
-
const config = {
|
|
602
|
-
...defaultConfig,
|
|
603
|
-
blocklist: ['debug-*', 'test-*'],
|
|
604
|
-
}
|
|
605
|
-
const gen = new CSSGenerator(config)
|
|
606
|
-
gen.generate('debug-border')
|
|
607
|
-
gen.generate('test-utility')
|
|
608
|
-
gen.generate('p-4') // Should work
|
|
609
|
-
const css = gen.toCSS(false)
|
|
610
|
-
expect(css).not.toContain('debug')
|
|
611
|
-
expect(css).not.toContain('test')
|
|
612
|
-
expect(css).toContain('padding: 1rem')
|
|
613
|
-
})
|
|
614
|
-
|
|
615
|
-
it('should handle wildcard blocklist patterns', () => {
|
|
616
|
-
const config = {
|
|
617
|
-
...defaultConfig,
|
|
618
|
-
blocklist: ['*-deprecated', 'old-*'],
|
|
619
|
-
}
|
|
620
|
-
const gen = new CSSGenerator(config)
|
|
621
|
-
gen.generate('flex-deprecated')
|
|
622
|
-
gen.generate('old-utility')
|
|
623
|
-
gen.generate('flex') // Should work
|
|
624
|
-
const css = gen.toCSS(false)
|
|
625
|
-
expect(css).not.toContain('.flex-deprecated')
|
|
626
|
-
expect(css).not.toContain('.old-utility')
|
|
627
|
-
expect(css).toContain('display: flex')
|
|
628
|
-
})
|
|
629
|
-
|
|
630
|
-
it('should handle exact match blocklist', () => {
|
|
631
|
-
const config = {
|
|
632
|
-
...defaultConfig,
|
|
633
|
-
blocklist: ['p-4', 'm-4'],
|
|
634
|
-
}
|
|
635
|
-
const gen = new CSSGenerator(config)
|
|
636
|
-
gen.generate('p-4')
|
|
637
|
-
gen.generate('m-4')
|
|
638
|
-
gen.generate('p-8') // Should work
|
|
639
|
-
const css = gen.toCSS(false)
|
|
640
|
-
expect(css).not.toContain('padding: 1rem')
|
|
641
|
-
expect(css).not.toContain('margin: 1rem')
|
|
642
|
-
expect(css).toContain('padding: 2rem')
|
|
643
|
-
})
|
|
644
|
-
})
|
|
645
|
-
|
|
646
|
-
describe('Complex combinations', () => {
|
|
647
|
-
it('should handle filters with variants', () => {
|
|
648
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
649
|
-
gen.generate('hover:blur-sm')
|
|
650
|
-
gen.generate('focus:brightness-150')
|
|
651
|
-
gen.generate('dark:grayscale-100')
|
|
652
|
-
const css = gen.toCSS(false)
|
|
653
|
-
expect(css).toContain(':hover')
|
|
654
|
-
expect(css).toContain(':focus')
|
|
655
|
-
expect(css).toContain('blur')
|
|
656
|
-
expect(css).toContain('brightness')
|
|
657
|
-
expect(css).toContain('grayscale')
|
|
658
|
-
})
|
|
659
|
-
|
|
660
|
-
it('should handle transitions with important', () => {
|
|
661
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
662
|
-
gen.generate('!transition-all')
|
|
663
|
-
gen.generate('!duration-300')
|
|
664
|
-
gen.generate('!ease-in-out')
|
|
665
|
-
const css = gen.toCSS(false)
|
|
666
|
-
expect(css).toContain('!important')
|
|
667
|
-
expect(css).toContain('transition')
|
|
668
|
-
expect(css).toContain('duration')
|
|
669
|
-
})
|
|
670
|
-
|
|
671
|
-
it('should handle child selectors with responsive variants', () => {
|
|
672
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
673
|
-
gen.generate('sm:space-x-4')
|
|
674
|
-
gen.generate('md:divide-y-2')
|
|
675
|
-
gen.generate('lg:space-y-8')
|
|
676
|
-
const css = gen.toCSS(false)
|
|
677
|
-
expect(css).toContain('@media')
|
|
678
|
-
expect(css).toContain('space')
|
|
679
|
-
})
|
|
680
|
-
|
|
681
|
-
it('should handle animations with responsive variants', () => {
|
|
682
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
683
|
-
gen.generate('sm:animate-spin')
|
|
684
|
-
gen.generate('md:animate-bounce')
|
|
685
|
-
gen.generate('hover:animate-pulse')
|
|
686
|
-
const css = gen.toCSS(false)
|
|
687
|
-
expect(css).toContain('animation')
|
|
688
|
-
})
|
|
689
|
-
})
|
|
690
|
-
|
|
691
|
-
describe('Multi-segment color names', () => {
|
|
692
|
-
it('should handle blue-gray color with custom config', () => {
|
|
693
|
-
const config = {
|
|
694
|
-
...defaultConfig,
|
|
695
|
-
theme: {
|
|
696
|
-
...defaultConfig.theme,
|
|
697
|
-
colors: {
|
|
698
|
-
...defaultConfig.theme.colors,
|
|
699
|
-
'blue-gray': {
|
|
700
|
-
200: '#e2e8f0',
|
|
701
|
-
500: '#64748b',
|
|
702
|
-
700: '#334155',
|
|
703
|
-
},
|
|
704
|
-
},
|
|
705
|
-
},
|
|
706
|
-
}
|
|
707
|
-
const gen = new CSSGenerator(config)
|
|
708
|
-
gen.generate('text-blue-gray-200')
|
|
709
|
-
gen.generate('bg-blue-gray-500')
|
|
710
|
-
gen.generate('border-blue-gray-700')
|
|
711
|
-
const css = gen.toCSS(false)
|
|
712
|
-
expect(css).toContain('#e2e8f0') // blue-gray-200
|
|
713
|
-
expect(css).toContain('#64748b') // blue-gray-500
|
|
714
|
-
expect(css).toContain('#334155') // blue-gray-700
|
|
715
|
-
})
|
|
716
|
-
|
|
717
|
-
it('should handle sky color', () => {
|
|
718
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
719
|
-
gen.generate('text-sky-400')
|
|
720
|
-
gen.generate('bg-sky-500')
|
|
721
|
-
gen.generate('border-sky-600')
|
|
722
|
-
const css = gen.toCSS(false)
|
|
723
|
-
expect(css).toContain('oklch(74.6% 0.16 232.661)') // sky-400
|
|
724
|
-
expect(css).toContain('oklch(68.5% 0.169 237.323)') // sky-500
|
|
725
|
-
expect(css).toContain('oklch(58.8% 0.158 241.966)') // sky-600
|
|
726
|
-
})
|
|
727
|
-
|
|
728
|
-
it('should handle cyan color', () => {
|
|
729
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
730
|
-
gen.generate('text-cyan-400')
|
|
731
|
-
gen.generate('bg-cyan-500')
|
|
732
|
-
gen.generate('border-cyan-600')
|
|
733
|
-
const css = gen.toCSS(false)
|
|
734
|
-
expect(css).toContain('oklch(78.9% 0.154 211.53)') // cyan-400
|
|
735
|
-
expect(css).toContain('oklch(71.5% 0.143 215.221)') // cyan-500
|
|
736
|
-
expect(css).toContain('oklch(60.9% 0.126 221.723)') // cyan-600
|
|
737
|
-
})
|
|
738
|
-
})
|
|
739
|
-
|
|
740
|
-
describe('Ring offset colors', () => {
|
|
741
|
-
it('should handle ring-offset width', () => {
|
|
742
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
743
|
-
gen.generate('ring-offset-0')
|
|
744
|
-
gen.generate('ring-offset-1')
|
|
745
|
-
gen.generate('ring-offset-2')
|
|
746
|
-
gen.generate('ring-offset-4')
|
|
747
|
-
const css = gen.toCSS(false)
|
|
748
|
-
expect(css).toContain('--hw-ring-offset-width')
|
|
749
|
-
expect(css).toContain('0px')
|
|
750
|
-
expect(css).toContain('1px')
|
|
751
|
-
expect(css).toContain('2px')
|
|
752
|
-
expect(css).toContain('4px')
|
|
753
|
-
})
|
|
754
|
-
|
|
755
|
-
it('should handle ring-offset with single color', () => {
|
|
756
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
757
|
-
gen.generate('ring-offset-black')
|
|
758
|
-
gen.generate('ring-offset-white')
|
|
759
|
-
const css = gen.toCSS(false)
|
|
760
|
-
expect(css).toContain('--hw-ring-offset-color')
|
|
761
|
-
expect(css).toContain('#000')
|
|
762
|
-
expect(css).toContain('#fff')
|
|
763
|
-
})
|
|
764
|
-
|
|
765
|
-
it('should handle ring-offset with two-segment color', () => {
|
|
766
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
767
|
-
gen.generate('ring-offset-blue-500')
|
|
768
|
-
gen.generate('ring-offset-red-500')
|
|
769
|
-
gen.generate('ring-offset-gray-300')
|
|
770
|
-
const css = gen.toCSS(false)
|
|
771
|
-
expect(css).toContain('--hw-ring-offset-color')
|
|
772
|
-
expect(css).toContain('oklch(62.3% 0.214 259.815)') // blue-500
|
|
773
|
-
expect(css).toContain('oklch(63.7% 0.237 25.331)') // red-500
|
|
774
|
-
expect(css).toContain('oklch(87.2% 0.01 258.338)') // gray-300
|
|
775
|
-
})
|
|
776
|
-
|
|
777
|
-
it('should handle ring-offset with multi-segment color names', () => {
|
|
778
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
779
|
-
gen.generate('ring-offset-sky-400')
|
|
780
|
-
gen.generate('ring-offset-cyan-600')
|
|
781
|
-
const css = gen.toCSS(false)
|
|
782
|
-
expect(css).toContain('--hw-ring-offset-color')
|
|
783
|
-
expect(css).toContain('oklch(74.6% 0.16 232.661)') // sky-400
|
|
784
|
-
expect(css).toContain('oklch(60.9% 0.126 221.723)') // cyan-600
|
|
785
|
-
})
|
|
786
|
-
})
|
|
787
|
-
|
|
788
|
-
describe('Gradient utilities', () => {
|
|
789
|
-
it('should handle gradient direction utilities', () => {
|
|
790
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
791
|
-
gen.generate('bg-gradient-to-r')
|
|
792
|
-
gen.generate('bg-gradient-to-l')
|
|
793
|
-
gen.generate('bg-gradient-to-t')
|
|
794
|
-
gen.generate('bg-gradient-to-b')
|
|
795
|
-
gen.generate('bg-gradient-to-tr')
|
|
796
|
-
gen.generate('bg-gradient-to-br')
|
|
797
|
-
gen.generate('bg-gradient-to-bl')
|
|
798
|
-
gen.generate('bg-gradient-to-tl')
|
|
799
|
-
const css = gen.toCSS(false)
|
|
800
|
-
expect(css).toContain('linear-gradient')
|
|
801
|
-
expect(css).toContain('to right')
|
|
802
|
-
expect(css).toContain('to left')
|
|
803
|
-
expect(css).toContain('to top')
|
|
804
|
-
expect(css).toContain('to bottom')
|
|
805
|
-
})
|
|
806
|
-
|
|
807
|
-
it('should handle gradient color stops', () => {
|
|
808
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
809
|
-
gen.generate('from-blue-500')
|
|
810
|
-
gen.generate('via-gray-300')
|
|
811
|
-
gen.generate('to-red-500')
|
|
812
|
-
const css = gen.toCSS(false)
|
|
813
|
-
expect(css).toContain('--hw-gradient-from')
|
|
814
|
-
expect(css).toContain('--hw-gradient-to')
|
|
815
|
-
expect(css).toContain('--hw-gradient-stops')
|
|
816
|
-
expect(css).toContain('oklch(62.3% 0.214 259.815)') // blue-500
|
|
817
|
-
expect(css).toContain('oklch(63.7% 0.237 25.331)') // red-500
|
|
818
|
-
})
|
|
819
|
-
|
|
820
|
-
it('should handle gradient with multi-segment colors', () => {
|
|
821
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
822
|
-
gen.generate('via-sky-400')
|
|
823
|
-
gen.generate('to-cyan-600')
|
|
824
|
-
const css = gen.toCSS(false)
|
|
825
|
-
expect(css).toContain('--hw-gradient-to')
|
|
826
|
-
expect(css).toContain('--hw-gradient-stops')
|
|
827
|
-
expect(css).toContain('oklch(74.6% 0.16 232.661)') // sky-400
|
|
828
|
-
expect(css).toContain('oklch(60.9% 0.126 221.723)') // cyan-600
|
|
829
|
-
})
|
|
830
|
-
|
|
831
|
-
it('should handle gradient with hover variants', () => {
|
|
832
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
833
|
-
gen.generate('hover:from-sky-500')
|
|
834
|
-
gen.generate('hover:to-cyan-500')
|
|
835
|
-
gen.generate('hover:via-blue-500')
|
|
836
|
-
const css = gen.toCSS(false)
|
|
837
|
-
expect(css).toContain(':hover')
|
|
838
|
-
expect(css).toContain('--hw-gradient-from')
|
|
839
|
-
expect(css).toContain('--hw-gradient-to')
|
|
840
|
-
expect(css).toContain('oklch(68.5% 0.169 237.323)') // sky-500
|
|
841
|
-
expect(css).toContain('oklch(71.5% 0.143 215.221)') // cyan-500
|
|
842
|
-
})
|
|
843
|
-
|
|
844
|
-
it('should handle complete gradient combination', () => {
|
|
845
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
846
|
-
gen.generate('bg-gradient-to-r')
|
|
847
|
-
gen.generate('from-sky-500')
|
|
848
|
-
gen.generate('to-cyan-500')
|
|
849
|
-
const css = gen.toCSS(false)
|
|
850
|
-
expect(css).toContain('linear-gradient(to right, var(--hw-gradient-stops))')
|
|
851
|
-
expect(css).toContain('--hw-gradient-from: oklch(68.5% 0.169 237.323)') // sky-500
|
|
852
|
-
expect(css).toContain('--hw-gradient-to: oklch(71.5% 0.143 215.221)') // cyan-500
|
|
853
|
-
})
|
|
854
|
-
|
|
855
|
-
it('should properly update gradient stops when using to-{color}', () => {
|
|
856
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
857
|
-
gen.generate('from-blue-500')
|
|
858
|
-
gen.generate('to-red-500')
|
|
859
|
-
const css = gen.toCSS(false)
|
|
860
|
-
// Both from and to should set --hw-gradient-stops
|
|
861
|
-
const fromMatch = css.match(/\.from-blue-500\s*\{[^}]*\}/)
|
|
862
|
-
const toMatch = css.match(/\.to-red-500\s*\{[^}]*\}/)
|
|
863
|
-
expect(fromMatch).toBeTruthy()
|
|
864
|
-
expect(toMatch).toBeTruthy()
|
|
865
|
-
expect(fromMatch![0]).toContain('--hw-gradient-stops')
|
|
866
|
-
expect(toMatch![0]).toContain('--hw-gradient-stops')
|
|
867
|
-
})
|
|
868
|
-
})
|
|
869
|
-
|
|
870
|
-
describe('Accessibility utilities', () => {
|
|
871
|
-
it('should handle sr-only utility', () => {
|
|
872
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
873
|
-
gen.generate('sr-only')
|
|
874
|
-
const css = gen.toCSS(false)
|
|
875
|
-
expect(css).toContain('position: absolute')
|
|
876
|
-
expect(css).toContain('width: 1px')
|
|
877
|
-
expect(css).toContain('height: 1px')
|
|
878
|
-
expect(css).toContain('padding: 0')
|
|
879
|
-
expect(css).toContain('margin: -1px')
|
|
880
|
-
expect(css).toContain('overflow: hidden')
|
|
881
|
-
expect(css).toContain('clip: rect(0, 0, 0, 0)')
|
|
882
|
-
expect(css).toContain('white-space: nowrap')
|
|
883
|
-
expect(css).toContain('border-width: 0')
|
|
884
|
-
})
|
|
885
|
-
|
|
886
|
-
it('should handle not-sr-only utility', () => {
|
|
887
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
888
|
-
gen.generate('not-sr-only')
|
|
889
|
-
const css = gen.toCSS(false)
|
|
890
|
-
expect(css).toContain('position: static')
|
|
891
|
-
expect(css).toContain('width: auto')
|
|
892
|
-
expect(css).toContain('height: auto')
|
|
893
|
-
expect(css).toContain('padding: 0')
|
|
894
|
-
expect(css).toContain('margin: 0')
|
|
895
|
-
expect(css).toContain('overflow: visible')
|
|
896
|
-
expect(css).toContain('clip: auto')
|
|
897
|
-
expect(css).toContain('white-space: normal')
|
|
898
|
-
})
|
|
899
|
-
|
|
900
|
-
it('should handle accessibility in forms', () => {
|
|
901
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
902
|
-
// sr-only is typically used for labels and screen reader text
|
|
903
|
-
gen.generate('sr-only')
|
|
904
|
-
const css = gen.toCSS(false)
|
|
905
|
-
// Verify all required properties for accessibility
|
|
906
|
-
expect(css).toContain('position')
|
|
907
|
-
expect(css).toContain('width')
|
|
908
|
-
expect(css).toContain('height')
|
|
909
|
-
})
|
|
910
|
-
})
|
|
911
|
-
})
|