@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,225 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'bun:test'
|
|
2
|
-
import { defaultConfig } from '../src/config'
|
|
3
|
-
import { CSSGenerator } from '../src/generator'
|
|
4
|
-
|
|
5
|
-
describe('Pseudo-Class and Pseudo-Element Variants', () => {
|
|
6
|
-
describe('Form pseudo-classes', () => {
|
|
7
|
-
it('should handle placeholder variant', () => {
|
|
8
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
9
|
-
gen.generate('placeholder:text-gray-500')
|
|
10
|
-
const css = gen.toCSS(false)
|
|
11
|
-
expect(css).toContain('::placeholder')
|
|
12
|
-
expect(css).toContain('color: oklch(55.1% 0.027 264.364)')
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
it('should handle selection variant', () => {
|
|
16
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
17
|
-
gen.generate('selection:bg-blue-500')
|
|
18
|
-
const css = gen.toCSS(false)
|
|
19
|
-
expect(css).toContain('::selection')
|
|
20
|
-
expect(css).toContain('background-color: oklch(62.3% 0.214 259.815)')
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
it('should handle file variant', () => {
|
|
24
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
25
|
-
gen.generate('file:border-blue-500')
|
|
26
|
-
const css = gen.toCSS(false)
|
|
27
|
-
expect(css).toContain('::file-selector-button')
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
it('should handle required variant', () => {
|
|
31
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
32
|
-
gen.generate('required:border-red-500')
|
|
33
|
-
const css = gen.toCSS(false)
|
|
34
|
-
expect(css).toContain(':required')
|
|
35
|
-
expect(css).toContain('border-color: oklch(63.7% 0.237 25.331)')
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
it('should handle valid variant', () => {
|
|
39
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
40
|
-
gen.generate('valid:border-green-500')
|
|
41
|
-
const css = gen.toCSS(false)
|
|
42
|
-
expect(css).toContain(':valid')
|
|
43
|
-
expect(css).toContain('border-color: oklch(72.3% 0.219 149.579)')
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
it('should handle invalid variant', () => {
|
|
47
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
48
|
-
gen.generate('invalid:border-red-500')
|
|
49
|
-
const css = gen.toCSS(false)
|
|
50
|
-
expect(css).toContain(':invalid')
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
it('should handle read-only variant', () => {
|
|
54
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
55
|
-
gen.generate('read-only:bg-gray-100')
|
|
56
|
-
const css = gen.toCSS(false)
|
|
57
|
-
expect(css).toContain(':read-only')
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
it('should handle autofill variant', () => {
|
|
61
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
62
|
-
gen.generate('autofill:bg-yellow-100')
|
|
63
|
-
const css = gen.toCSS(false)
|
|
64
|
-
expect(css).toContain(':autofill')
|
|
65
|
-
})
|
|
66
|
-
})
|
|
67
|
-
|
|
68
|
-
describe('State pseudo-classes', () => {
|
|
69
|
-
it('should handle open variant', () => {
|
|
70
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
71
|
-
gen.generate('open:bg-blue-500')
|
|
72
|
-
const css = gen.toCSS(false)
|
|
73
|
-
expect(css).toContain('[open]')
|
|
74
|
-
})
|
|
75
|
-
|
|
76
|
-
it('should handle closed variant', () => {
|
|
77
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
78
|
-
gen.generate('closed:hidden')
|
|
79
|
-
const css = gen.toCSS(false)
|
|
80
|
-
expect(css).toContain(':not([open])')
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
it('should handle empty variant', () => {
|
|
84
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
85
|
-
gen.generate('empty:hidden')
|
|
86
|
-
const css = gen.toCSS(false)
|
|
87
|
-
expect(css).toContain(':empty')
|
|
88
|
-
})
|
|
89
|
-
|
|
90
|
-
it('should handle enabled variant', () => {
|
|
91
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
92
|
-
gen.generate('enabled:bg-white')
|
|
93
|
-
const css = gen.toCSS(false)
|
|
94
|
-
expect(css).toContain(':enabled')
|
|
95
|
-
})
|
|
96
|
-
|
|
97
|
-
it('should handle only variant', () => {
|
|
98
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
99
|
-
gen.generate('only:m-0')
|
|
100
|
-
const css = gen.toCSS(false)
|
|
101
|
-
expect(css).toContain(':only-child')
|
|
102
|
-
})
|
|
103
|
-
|
|
104
|
-
it('should handle target variant', () => {
|
|
105
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
106
|
-
gen.generate('target:bg-yellow-100')
|
|
107
|
-
const css = gen.toCSS(false)
|
|
108
|
-
expect(css).toContain(':target')
|
|
109
|
-
})
|
|
110
|
-
|
|
111
|
-
it('should handle indeterminate variant', () => {
|
|
112
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
113
|
-
gen.generate('indeterminate:bg-gray-300')
|
|
114
|
-
const css = gen.toCSS(false)
|
|
115
|
-
expect(css).toContain(':indeterminate')
|
|
116
|
-
})
|
|
117
|
-
|
|
118
|
-
it('should handle default variant', () => {
|
|
119
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
120
|
-
gen.generate('default:border-2')
|
|
121
|
-
const css = gen.toCSS(false)
|
|
122
|
-
expect(css).toContain(':default')
|
|
123
|
-
})
|
|
124
|
-
|
|
125
|
-
it('should handle optional variant', () => {
|
|
126
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
127
|
-
gen.generate('optional:border-gray-300')
|
|
128
|
-
const css = gen.toCSS(false)
|
|
129
|
-
expect(css).toContain(':optional')
|
|
130
|
-
})
|
|
131
|
-
})
|
|
132
|
-
|
|
133
|
-
describe('Marker pseudo-element', () => {
|
|
134
|
-
it('should handle marker variant', () => {
|
|
135
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
136
|
-
gen.generate('marker:text-blue-500')
|
|
137
|
-
const css = gen.toCSS(false)
|
|
138
|
-
expect(css).toContain('::marker')
|
|
139
|
-
expect(css).toContain('color: oklch(62.3% 0.214 259.815)')
|
|
140
|
-
})
|
|
141
|
-
|
|
142
|
-
it('should handle marker with multiple properties', () => {
|
|
143
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
144
|
-
gen.generate('marker:text-red-500')
|
|
145
|
-
const css = gen.toCSS(false)
|
|
146
|
-
expect(css).toContain('::marker')
|
|
147
|
-
expect(css).toContain('color: oklch(63.7% 0.237 25.331)')
|
|
148
|
-
})
|
|
149
|
-
})
|
|
150
|
-
|
|
151
|
-
describe('Complex variant combinations', () => {
|
|
152
|
-
it('should handle multiple variants together', () => {
|
|
153
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
154
|
-
gen.generate('hover:focus:placeholder:text-gray-500')
|
|
155
|
-
const css = gen.toCSS(false)
|
|
156
|
-
expect(css).toContain(':hover')
|
|
157
|
-
expect(css).toContain(':focus')
|
|
158
|
-
expect(css).toContain('::placeholder')
|
|
159
|
-
})
|
|
160
|
-
|
|
161
|
-
it('should handle responsive with new variants', () => {
|
|
162
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
163
|
-
gen.generate('md:required:border-red-500')
|
|
164
|
-
const css = gen.toCSS(false)
|
|
165
|
-
expect(css).toContain('@media (min-width: 768px)')
|
|
166
|
-
expect(css).toContain(':required')
|
|
167
|
-
})
|
|
168
|
-
|
|
169
|
-
it('should handle important with variants', () => {
|
|
170
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
171
|
-
gen.generate('!placeholder:text-gray-400')
|
|
172
|
-
const css = gen.toCSS(false)
|
|
173
|
-
expect(css).toContain('!important')
|
|
174
|
-
})
|
|
175
|
-
|
|
176
|
-
it('should handle dark mode with form variants', () => {
|
|
177
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
178
|
-
gen.generate('dark:invalid:text-red-400')
|
|
179
|
-
const css = gen.toCSS(false)
|
|
180
|
-
expect(css).toContain('.dark')
|
|
181
|
-
expect(css).toContain(':invalid')
|
|
182
|
-
})
|
|
183
|
-
|
|
184
|
-
it('should combine all new pseudo-classes', () => {
|
|
185
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
186
|
-
gen.generate('required:text-red-500')
|
|
187
|
-
gen.generate('valid:text-green-500')
|
|
188
|
-
gen.generate('invalid:text-red-700')
|
|
189
|
-
gen.generate('optional:text-gray-500')
|
|
190
|
-
const css = gen.toCSS(false)
|
|
191
|
-
expect(css).toContain(':required')
|
|
192
|
-
expect(css).toContain(':valid')
|
|
193
|
-
expect(css).toContain(':invalid')
|
|
194
|
-
expect(css).toContain(':optional')
|
|
195
|
-
})
|
|
196
|
-
})
|
|
197
|
-
|
|
198
|
-
describe('Variant edge cases', () => {
|
|
199
|
-
it('should handle chained form variants', () => {
|
|
200
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
201
|
-
gen.generate('focus:required:invalid:border-red-700')
|
|
202
|
-
const css = gen.toCSS(false)
|
|
203
|
-
expect(css).toContain(':focus')
|
|
204
|
-
expect(css).toContain(':required')
|
|
205
|
-
expect(css).toContain(':invalid')
|
|
206
|
-
})
|
|
207
|
-
|
|
208
|
-
it('should handle responsive + dark + form variant', () => {
|
|
209
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
210
|
-
gen.generate('lg:dark:placeholder:text-gray-600')
|
|
211
|
-
const css = gen.toCSS(false)
|
|
212
|
-
expect(css).toContain('@media (min-width: 1024px)')
|
|
213
|
-
expect(css).toContain('.dark')
|
|
214
|
-
expect(css).toContain('::placeholder')
|
|
215
|
-
})
|
|
216
|
-
|
|
217
|
-
it('should handle group with new variants', () => {
|
|
218
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
219
|
-
gen.generate('group-hover:marker:text-blue-500')
|
|
220
|
-
const css = gen.toCSS(false)
|
|
221
|
-
expect(css).toContain('.group:hover')
|
|
222
|
-
expect(css).toContain('::marker')
|
|
223
|
-
})
|
|
224
|
-
})
|
|
225
|
-
})
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'bun:test'
|
|
2
|
-
import { defaultConfig } from '../src/config'
|
|
3
|
-
import { CSSGenerator } from '../src/generator'
|
|
4
|
-
|
|
5
|
-
describe('Group and Peer Variants', () => {
|
|
6
|
-
describe('Group variants', () => {
|
|
7
|
-
it('should generate group-hover', () => {
|
|
8
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
9
|
-
gen.generate('group-hover:bg-gray-500')
|
|
10
|
-
const css = gen.toCSS(false)
|
|
11
|
-
expect(css).toContain('.group:hover')
|
|
12
|
-
expect(css).toContain('background-color: oklch(55.1% 0.027 264.364);')
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
it('should generate group-focus', () => {
|
|
16
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
17
|
-
gen.generate('group-focus:text-gray-800')
|
|
18
|
-
const css = gen.toCSS(false)
|
|
19
|
-
expect(css).toContain('.group:focus')
|
|
20
|
-
expect(css).toContain('color: oklch(27.8% 0.033 256.848);')
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
it('should handle group with responsive and state', () => {
|
|
24
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
25
|
-
gen.generate('lg:group-hover:first:bg-gray-500')
|
|
26
|
-
const css = gen.toCSS(false)
|
|
27
|
-
expect(css).toContain('@media (min-width: 1024px)')
|
|
28
|
-
expect(css).toContain('.group:hover')
|
|
29
|
-
expect(css).toContain(':first-child')
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
it('should handle group with new variants', () => {
|
|
33
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
34
|
-
gen.generate('group-hover:marker:text-blue-500')
|
|
35
|
-
const css = gen.toCSS(false)
|
|
36
|
-
expect(css).toContain('.group:hover')
|
|
37
|
-
expect(css).toContain('::marker')
|
|
38
|
-
})
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
describe('Peer variants', () => {
|
|
42
|
-
it('should generate peer-checked', () => {
|
|
43
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
44
|
-
gen.generate('peer-checked:bg-gray-500')
|
|
45
|
-
const css = gen.toCSS(false)
|
|
46
|
-
expect(css).toContain('.peer:checked')
|
|
47
|
-
expect(css).toContain('background-color: oklch(55.1% 0.027 264.364);')
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
it('should generate peer-focus', () => {
|
|
51
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
52
|
-
gen.generate('peer-focus:border-gray-300')
|
|
53
|
-
const css = gen.toCSS(false)
|
|
54
|
-
expect(css).toContain('.peer:focus')
|
|
55
|
-
expect(css).toContain('border-color: oklch(87.2% 0.01 258.338);')
|
|
56
|
-
})
|
|
57
|
-
|
|
58
|
-
it('should handle peer-checked with responsive', () => {
|
|
59
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
60
|
-
gen.generate('lg:peer-checked:bg-green-500')
|
|
61
|
-
const css = gen.toCSS(false)
|
|
62
|
-
expect(css).toContain('@media (min-width: 1024px)')
|
|
63
|
-
expect(css).toContain('.peer:checked')
|
|
64
|
-
})
|
|
65
|
-
})
|
|
66
|
-
})
|
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'bun:test'
|
|
2
|
-
import { defaultConfig } from '../src/config'
|
|
3
|
-
import { CSSGenerator } from '../src/generator'
|
|
4
|
-
|
|
5
|
-
describe('Media Query and Feature Variants', () => {
|
|
6
|
-
describe('Responsive variants', () => {
|
|
7
|
-
it('should generate responsive sm variant', () => {
|
|
8
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
9
|
-
gen.generate('sm:p-4')
|
|
10
|
-
const css = gen.toCSS(false)
|
|
11
|
-
expect(css).toContain('@media (min-width: 640px)')
|
|
12
|
-
})
|
|
13
|
-
|
|
14
|
-
it('should generate responsive md variant', () => {
|
|
15
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
16
|
-
gen.generate('md:p-4')
|
|
17
|
-
const css = gen.toCSS(false)
|
|
18
|
-
expect(css).toContain('@media (min-width: 768px)')
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
it('should generate responsive lg variant', () => {
|
|
22
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
23
|
-
gen.generate('lg:p-4')
|
|
24
|
-
const css = gen.toCSS(false)
|
|
25
|
-
expect(css).toContain('@media (min-width: 1024px)')
|
|
26
|
-
})
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
describe('Print variant', () => {
|
|
30
|
-
it('should generate print variant', () => {
|
|
31
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
32
|
-
gen.generate('print:hidden')
|
|
33
|
-
const css = gen.toCSS(false)
|
|
34
|
-
expect(css).toContain('@media print')
|
|
35
|
-
expect(css).toContain('display: none;')
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
it('should handle print with dark mode', () => {
|
|
39
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
40
|
-
gen.generate('print:dark:text-black')
|
|
41
|
-
const css = gen.toCSS(false)
|
|
42
|
-
expect(css).toContain('@media print')
|
|
43
|
-
expect(css).toContain('.dark')
|
|
44
|
-
})
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
describe('Dark mode variant', () => {
|
|
48
|
-
it('should generate dark variant', () => {
|
|
49
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
50
|
-
gen.generate('dark:bg-gray-900')
|
|
51
|
-
const css = gen.toCSS(false)
|
|
52
|
-
expect(css).toContain('.dark')
|
|
53
|
-
expect(css).toContain('background-color: oklch(21% 0.034 264.665);')
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
it('should handle dark + responsive + hover', () => {
|
|
57
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
58
|
-
gen.generate('dark:md:hover:text-gray-100')
|
|
59
|
-
const css = gen.toCSS(false)
|
|
60
|
-
expect(css).toContain('.dark')
|
|
61
|
-
expect(css).toContain('@media (min-width: 768px)')
|
|
62
|
-
expect(css).toContain(':hover')
|
|
63
|
-
})
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
describe('Direction variants', () => {
|
|
67
|
-
it('should generate rtl variant', () => {
|
|
68
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
69
|
-
gen.generate('rtl:text-right')
|
|
70
|
-
const css = gen.toCSS(false)
|
|
71
|
-
expect(css).toContain('[dir="rtl"]')
|
|
72
|
-
expect(css).toContain('text-align: right;')
|
|
73
|
-
})
|
|
74
|
-
|
|
75
|
-
it('should generate ltr variant', () => {
|
|
76
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
77
|
-
gen.generate('ltr:text-left')
|
|
78
|
-
const css = gen.toCSS(false)
|
|
79
|
-
expect(css).toContain('[dir="ltr"]')
|
|
80
|
-
expect(css).toContain('text-align: left;')
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
it('should handle rtl with responsive and hover', () => {
|
|
84
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
85
|
-
gen.generate('rtl:md:hover:text-right')
|
|
86
|
-
const css = gen.toCSS(false)
|
|
87
|
-
expect(css).toContain('[dir="rtl"]')
|
|
88
|
-
expect(css).toContain('@media (min-width: 768px)')
|
|
89
|
-
expect(css).toContain(':hover')
|
|
90
|
-
})
|
|
91
|
-
})
|
|
92
|
-
|
|
93
|
-
describe('Motion variants', () => {
|
|
94
|
-
it('should generate motion-safe variant', () => {
|
|
95
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
96
|
-
gen.generate('motion-safe:p-4')
|
|
97
|
-
const css = gen.toCSS(false)
|
|
98
|
-
expect(css).toContain('@media (prefers-reduced-motion: no-preference)')
|
|
99
|
-
expect(css).toContain('padding: 1rem;')
|
|
100
|
-
})
|
|
101
|
-
|
|
102
|
-
it('should generate motion-reduce variant', () => {
|
|
103
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
104
|
-
gen.generate('motion-reduce:p-0')
|
|
105
|
-
const css = gen.toCSS(false)
|
|
106
|
-
expect(css).toContain('@media (prefers-reduced-motion: reduce)')
|
|
107
|
-
expect(css).toContain('padding: 0;')
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
it('should handle motion-safe with responsive', () => {
|
|
111
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
112
|
-
gen.generate('motion-safe:lg:p-4')
|
|
113
|
-
const css = gen.toCSS(false)
|
|
114
|
-
expect(css).toContain('@media (prefers-reduced-motion: no-preference)')
|
|
115
|
-
expect(css).toContain('padding: 1rem;')
|
|
116
|
-
})
|
|
117
|
-
})
|
|
118
|
-
|
|
119
|
-
describe('Contrast variants', () => {
|
|
120
|
-
it('should generate contrast-more variant', () => {
|
|
121
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
122
|
-
gen.generate('contrast-more:border-gray-900')
|
|
123
|
-
const css = gen.toCSS(false)
|
|
124
|
-
expect(css).toContain('@media (prefers-contrast: more)')
|
|
125
|
-
})
|
|
126
|
-
|
|
127
|
-
it('should generate contrast-less variant', () => {
|
|
128
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
129
|
-
gen.generate('contrast-less:border-gray-400')
|
|
130
|
-
const css = gen.toCSS(false)
|
|
131
|
-
expect(css).toContain('@media (prefers-contrast: less)')
|
|
132
|
-
})
|
|
133
|
-
})
|
|
134
|
-
|
|
135
|
-
describe('Container query variants', () => {
|
|
136
|
-
it('should generate @container utility', () => {
|
|
137
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
138
|
-
gen.generate('@container')
|
|
139
|
-
const css = gen.toCSS(false)
|
|
140
|
-
expect(css).toContain('container-type: inline-size;')
|
|
141
|
-
})
|
|
142
|
-
|
|
143
|
-
it('should generate @container-normal utility', () => {
|
|
144
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
145
|
-
gen.generate('@container-normal')
|
|
146
|
-
const css = gen.toCSS(false)
|
|
147
|
-
expect(css).toContain('container-type: normal;')
|
|
148
|
-
})
|
|
149
|
-
|
|
150
|
-
it('should generate named container with @container/name', () => {
|
|
151
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
152
|
-
gen.generate('@container/sidebar')
|
|
153
|
-
const css = gen.toCSS(false)
|
|
154
|
-
expect(css).toContain('container-type: inline-size;')
|
|
155
|
-
expect(css).toContain('container-name: sidebar;')
|
|
156
|
-
})
|
|
157
|
-
|
|
158
|
-
it('should generate @sm container query variant', () => {
|
|
159
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
160
|
-
gen.generate('@sm:p-4')
|
|
161
|
-
const css = gen.toCSS(false)
|
|
162
|
-
expect(css).toContain('@container (min-width: 640px)')
|
|
163
|
-
expect(css).toContain('padding: 1rem;')
|
|
164
|
-
})
|
|
165
|
-
|
|
166
|
-
it('should generate @md container query variant', () => {
|
|
167
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
168
|
-
gen.generate('@md:flex')
|
|
169
|
-
const css = gen.toCSS(false)
|
|
170
|
-
expect(css).toContain('@container (min-width: 768px)')
|
|
171
|
-
expect(css).toContain('display: flex;')
|
|
172
|
-
})
|
|
173
|
-
|
|
174
|
-
it('should generate @lg container query variant', () => {
|
|
175
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
176
|
-
gen.generate('@lg:hidden')
|
|
177
|
-
const css = gen.toCSS(false)
|
|
178
|
-
expect(css).toContain('@container (min-width: 1024px)')
|
|
179
|
-
expect(css).toContain('display: none;')
|
|
180
|
-
})
|
|
181
|
-
|
|
182
|
-
it('should generate @xl container query variant', () => {
|
|
183
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
184
|
-
gen.generate('@xl:grid')
|
|
185
|
-
const css = gen.toCSS(false)
|
|
186
|
-
expect(css).toContain('@container (min-width: 1280px)')
|
|
187
|
-
expect(css).toContain('display: grid;')
|
|
188
|
-
})
|
|
189
|
-
|
|
190
|
-
it('should generate @2xl container query variant', () => {
|
|
191
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
192
|
-
gen.generate('@2xl:inline-flex')
|
|
193
|
-
const css = gen.toCSS(false)
|
|
194
|
-
expect(css).toContain('@container (min-width: 1536px)')
|
|
195
|
-
expect(css).toContain('display: inline-flex;')
|
|
196
|
-
})
|
|
197
|
-
|
|
198
|
-
it('should escape @ in selector for container queries', () => {
|
|
199
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
200
|
-
gen.generate('@sm:p-4')
|
|
201
|
-
const css = gen.toCSS(false)
|
|
202
|
-
expect(css).toContain('.\\@sm\\:p-4')
|
|
203
|
-
})
|
|
204
|
-
|
|
205
|
-
it('should handle container query with hover variant', () => {
|
|
206
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
207
|
-
gen.generate('@md:hover:bg-blue-500')
|
|
208
|
-
const css = gen.toCSS(false)
|
|
209
|
-
expect(css).toContain('@container (min-width: 768px)')
|
|
210
|
-
expect(css).toContain(':hover')
|
|
211
|
-
})
|
|
212
|
-
})
|
|
213
|
-
})
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'bun:test'
|
|
2
|
-
import { defaultConfig } from '../src/config'
|
|
3
|
-
import { CSSGenerator } from '../src/generator'
|
|
4
|
-
|
|
5
|
-
describe('Positional Variants', () => {
|
|
6
|
-
it('should generate first variant', () => {
|
|
7
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
8
|
-
gen.generate('first:bg-gray-500')
|
|
9
|
-
const css = gen.toCSS(false)
|
|
10
|
-
expect(css).toContain(':first-child')
|
|
11
|
-
expect(css).toContain('background-color: oklch(55.1% 0.027 264.364);')
|
|
12
|
-
})
|
|
13
|
-
|
|
14
|
-
it('should generate last variant', () => {
|
|
15
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
16
|
-
gen.generate('last:border-gray-300')
|
|
17
|
-
const css = gen.toCSS(false)
|
|
18
|
-
expect(css).toContain(':last-child')
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
it('should generate odd variant', () => {
|
|
22
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
23
|
-
gen.generate('odd:bg-gray-50')
|
|
24
|
-
const css = gen.toCSS(false)
|
|
25
|
-
expect(css).toContain(':nth-child(odd)')
|
|
26
|
-
expect(css).toContain('background-color: oklch(98.5% 0.002 247.839);')
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
it('should generate even variant', () => {
|
|
30
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
31
|
-
gen.generate('even:bg-gray-100')
|
|
32
|
-
const css = gen.toCSS(false)
|
|
33
|
-
expect(css).toContain(':nth-child(even)')
|
|
34
|
-
expect(css).toContain('background-color: oklch(96.7% 0.003 264.542);')
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
it('should generate first-of-type variant', () => {
|
|
38
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
39
|
-
gen.generate('first-of-type:mt-0')
|
|
40
|
-
const css = gen.toCSS(false)
|
|
41
|
-
expect(css).toContain(':first-of-type')
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
it('should generate last-of-type variant', () => {
|
|
45
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
46
|
-
gen.generate('last-of-type:mb-0')
|
|
47
|
-
const css = gen.toCSS(false)
|
|
48
|
-
expect(css).toContain(':last-of-type')
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
it('should handle all positional variants', () => {
|
|
52
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
53
|
-
gen.generate('first:last:odd:even:bg-red-500')
|
|
54
|
-
const css = gen.toCSS(false)
|
|
55
|
-
expect(css).toContain(':first-child')
|
|
56
|
-
expect(css).toContain(':last-child')
|
|
57
|
-
})
|
|
58
|
-
})
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'bun:test'
|
|
2
|
-
import { defaultConfig } from '../src/config'
|
|
3
|
-
import { CSSGenerator } from '../src/generator'
|
|
4
|
-
|
|
5
|
-
describe('Pseudo-element Variants', () => {
|
|
6
|
-
describe('before and after', () => {
|
|
7
|
-
it('should generate before variant', () => {
|
|
8
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
9
|
-
gen.generate('before:content-[""]')
|
|
10
|
-
const css = gen.toCSS(false)
|
|
11
|
-
expect(css).toContain('::before')
|
|
12
|
-
})
|
|
13
|
-
|
|
14
|
-
it('should generate after variant', () => {
|
|
15
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
16
|
-
gen.generate('after:content-[""]')
|
|
17
|
-
const css = gen.toCSS(false)
|
|
18
|
-
expect(css).toContain('::after')
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
it('should generate before with block display', () => {
|
|
22
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
23
|
-
gen.generate('before:block')
|
|
24
|
-
const css = gen.toCSS(false)
|
|
25
|
-
expect(css).toContain('::before')
|
|
26
|
-
expect(css).toContain('display: block;')
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
it('should handle responsive + hover + pseudo-element', () => {
|
|
30
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
31
|
-
gen.generate('md:hover:before:block')
|
|
32
|
-
const css = gen.toCSS(false)
|
|
33
|
-
expect(css).toContain('@media (min-width: 768px)')
|
|
34
|
-
expect(css).toContain(':hover')
|
|
35
|
-
expect(css).toContain('::before')
|
|
36
|
-
expect(css).toContain('display: block;')
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
it('should handle before with important', () => {
|
|
40
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
41
|
-
gen.generate('!before:block')
|
|
42
|
-
const css = gen.toCSS(false)
|
|
43
|
-
expect(css).toContain('::before')
|
|
44
|
-
expect(css).toContain('!important')
|
|
45
|
-
})
|
|
46
|
-
})
|
|
47
|
-
})
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'bun:test'
|
|
2
|
-
import { defaultConfig } from '../src/config'
|
|
3
|
-
import { CSSGenerator } from '../src/generator'
|
|
4
|
-
|
|
5
|
-
describe('State Variants', () => {
|
|
6
|
-
it('should generate visited variant', () => {
|
|
7
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
8
|
-
gen.generate('visited:text-gray-500')
|
|
9
|
-
const css = gen.toCSS(false)
|
|
10
|
-
expect(css).toContain(':visited')
|
|
11
|
-
expect(css).toContain('color: oklch(55.1% 0.027 264.364);')
|
|
12
|
-
})
|
|
13
|
-
|
|
14
|
-
it('should generate checked variant', () => {
|
|
15
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
16
|
-
gen.generate('checked:bg-gray-500')
|
|
17
|
-
const css = gen.toCSS(false)
|
|
18
|
-
expect(css).toContain(':checked')
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
it('should generate focus-within variant', () => {
|
|
22
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
23
|
-
gen.generate('focus-within:border-gray-300')
|
|
24
|
-
const css = gen.toCSS(false)
|
|
25
|
-
expect(css).toContain(':focus-within')
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
it('should generate focus-visible variant', () => {
|
|
29
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
30
|
-
gen.generate('focus-visible:ring')
|
|
31
|
-
const css = gen.toCSS(false)
|
|
32
|
-
expect(css).toContain(':focus-visible')
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
it('should generate disabled variant', () => {
|
|
36
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
37
|
-
gen.generate('disabled:opacity-50')
|
|
38
|
-
const css = gen.toCSS(false)
|
|
39
|
-
expect(css).toContain(':disabled')
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
it('should generate hover variant', () => {
|
|
43
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
44
|
-
gen.generate('hover:bg-gray-100')
|
|
45
|
-
const css = gen.toCSS(false)
|
|
46
|
-
expect(css).toContain(':hover')
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
it('should generate focus variant', () => {
|
|
50
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
51
|
-
gen.generate('focus:outline-none')
|
|
52
|
-
const css = gen.toCSS(false)
|
|
53
|
-
expect(css).toContain(':focus')
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
it('should generate active variant', () => {
|
|
57
|
-
const gen = new CSSGenerator(defaultConfig)
|
|
58
|
-
gen.generate('active:bg-gray-200')
|
|
59
|
-
const css = gen.toCSS(false)
|
|
60
|
-
expect(css).toContain(':active')
|
|
61
|
-
})
|
|
62
|
-
})
|
package/tsconfig.json
DELETED