@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.
- package/LICENSE.md +21 -0
- package/README.md +52 -0
- package/dist/bin/cli.js +14615 -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/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/src/index.js +12848 -0
- package/dist/transformer-compile-class.d.ts +37 -0
- package/{src/types.ts → dist/types.d.ts} +17 -86
- package/package.json +2 -16
- 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
package/src/rules-advanced.ts
DELETED
|
@@ -1,477 +0,0 @@
|
|
|
1
|
-
import type { UtilityRule } from './rules'
|
|
2
|
-
|
|
3
|
-
// Advanced utilities
|
|
4
|
-
|
|
5
|
-
// Min/Max sizing
|
|
6
|
-
export const minMaxSizingRule: UtilityRule = (parsed, config) => {
|
|
7
|
-
const minMaxMap: Record<string, string> = {
|
|
8
|
-
'0': '0',
|
|
9
|
-
'full': '100%',
|
|
10
|
-
'min': 'min-content',
|
|
11
|
-
'max': 'max-content',
|
|
12
|
-
'fit': 'fit-content',
|
|
13
|
-
'none': 'none',
|
|
14
|
-
'xs': '20rem',
|
|
15
|
-
'sm': '24rem',
|
|
16
|
-
'md': '28rem',
|
|
17
|
-
'lg': '32rem',
|
|
18
|
-
'xl': '36rem',
|
|
19
|
-
'2xl': '42rem',
|
|
20
|
-
'3xl': '48rem',
|
|
21
|
-
'4xl': '56rem',
|
|
22
|
-
'5xl': '64rem',
|
|
23
|
-
'6xl': '72rem',
|
|
24
|
-
'7xl': '80rem',
|
|
25
|
-
'screen': '100vw',
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
if (parsed.utility === 'min-w' && parsed.value) {
|
|
29
|
-
const value = config.theme.spacing[parsed.value] || minMaxMap[parsed.value] || parsed.value
|
|
30
|
-
return { 'min-width': value } as Record<string, string>
|
|
31
|
-
}
|
|
32
|
-
if (parsed.utility === 'max-w' && parsed.value) {
|
|
33
|
-
const value = config.theme.spacing[parsed.value] || minMaxMap[parsed.value] || parsed.value
|
|
34
|
-
return { 'max-width': value } as Record<string, string>
|
|
35
|
-
}
|
|
36
|
-
if (parsed.utility === 'min-h' && parsed.value) {
|
|
37
|
-
const hMap: Record<string, string> = { ...minMaxMap, screen: '100vh' }
|
|
38
|
-
const value = config.theme.spacing[parsed.value] || hMap[parsed.value] || parsed.value
|
|
39
|
-
return { 'min-height': value } as Record<string, string>
|
|
40
|
-
}
|
|
41
|
-
if (parsed.utility === 'max-h' && parsed.value) {
|
|
42
|
-
const hMap: Record<string, string> = { ...minMaxMap, screen: '100vh' }
|
|
43
|
-
const value = config.theme.spacing[parsed.value] || hMap[parsed.value] || parsed.value
|
|
44
|
-
return { 'max-height': value } as Record<string, string>
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// Ring utilities
|
|
49
|
-
export const ringRule: UtilityRule = (parsed, config) => {
|
|
50
|
-
if (parsed.utility === 'ring') {
|
|
51
|
-
// Handle ring-inset
|
|
52
|
-
if (parsed.value === 'inset') {
|
|
53
|
-
return { '--hw-ring-inset': 'inset' } as Record<string, string>
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// Check if this is a ring color (e.g., ring-sky-500)
|
|
57
|
-
if (parsed.value) {
|
|
58
|
-
const parts = parsed.value.split('-')
|
|
59
|
-
if (parts.length >= 2) {
|
|
60
|
-
const colorName = parts.slice(0, -1).join('-')
|
|
61
|
-
const shade = parts[parts.length - 1]
|
|
62
|
-
const colorValue = config.theme.colors[colorName]
|
|
63
|
-
if (typeof colorValue === 'object' && colorValue[shade]) {
|
|
64
|
-
return { '--hw-ring-color': colorValue[shade] } as Record<string, string>
|
|
65
|
-
}
|
|
66
|
-
// Also check if it's a direct color value (like custom colors)
|
|
67
|
-
if (config.theme.colors[parsed.value]) {
|
|
68
|
-
return { '--hw-ring-color': config.theme.colors[parsed.value] } as Record<string, string>
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// Handle ring width
|
|
74
|
-
const widths: Record<string, string> = {
|
|
75
|
-
0: '0',
|
|
76
|
-
1: '1px',
|
|
77
|
-
2: '2px',
|
|
78
|
-
4: '4px',
|
|
79
|
-
8: '8px',
|
|
80
|
-
DEFAULT: '3px',
|
|
81
|
-
}
|
|
82
|
-
const width = parsed.value ? widths[parsed.value] || parsed.value : widths.DEFAULT
|
|
83
|
-
return {
|
|
84
|
-
'--hw-ring-offset-shadow': 'var(--hw-ring-inset) 0 0 0 var(--hw-ring-offset-width) var(--hw-ring-offset-color)',
|
|
85
|
-
'--hw-ring-shadow': `var(--hw-ring-inset) 0 0 0 calc(${width} + var(--hw-ring-offset-width)) var(--hw-ring-color)`,
|
|
86
|
-
'box-shadow': 'var(--hw-ring-offset-shadow), var(--hw-ring-shadow), var(--hw-shadow, 0 0 #0000)',
|
|
87
|
-
} as Record<string, string>
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
if (parsed.utility === 'ring-offset' && parsed.value) {
|
|
91
|
-
// First check if it's a width value
|
|
92
|
-
const widths: Record<string, string> = {
|
|
93
|
-
0: '0px',
|
|
94
|
-
1: '1px',
|
|
95
|
-
2: '2px',
|
|
96
|
-
4: '4px',
|
|
97
|
-
8: '8px',
|
|
98
|
-
}
|
|
99
|
-
if (widths[parsed.value]) {
|
|
100
|
-
return { '--hw-ring-offset-width': widths[parsed.value] } as Record<string, string>
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// Otherwise, treat as a color (e.g., ring-offset-ocean-blue)
|
|
104
|
-
const parts = parsed.value.split('-')
|
|
105
|
-
if (parts.length >= 2) {
|
|
106
|
-
const colorName = parts.slice(0, -1).join('-')
|
|
107
|
-
const shade = parts[parts.length - 1]
|
|
108
|
-
const colorValue = config.theme.colors[colorName]
|
|
109
|
-
if (typeof colorValue === 'object' && colorValue[shade]) {
|
|
110
|
-
return { '--hw-ring-offset-color': colorValue[shade] } as Record<string, string>
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
// Check for direct color (e.g., ring-offset-black)
|
|
114
|
-
const directColor = config.theme.colors[parsed.value]
|
|
115
|
-
if (typeof directColor === 'string') {
|
|
116
|
-
return { '--hw-ring-offset-color': directColor } as Record<string, string>
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// Ring opacity
|
|
121
|
-
if (parsed.utility === 'ring-opacity' && parsed.value) {
|
|
122
|
-
const opacityMap: Record<string, string> = {
|
|
123
|
-
0: '0', 5: '0.05', 10: '0.1', 20: '0.2', 25: '0.25',
|
|
124
|
-
30: '0.3', 40: '0.4', 50: '0.5', 60: '0.6', 70: '0.7',
|
|
125
|
-
75: '0.75', 80: '0.8', 90: '0.9', 95: '0.95', 100: '1',
|
|
126
|
-
}
|
|
127
|
-
return { '--hw-ring-opacity': opacityMap[parsed.value] || parsed.value } as Record<string, string>
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// Border opacity utility
|
|
132
|
-
export const borderOpacityRule: UtilityRule = (parsed) => {
|
|
133
|
-
if (parsed.utility === 'border-opacity' && parsed.value) {
|
|
134
|
-
const opacityMap: Record<string, string> = {
|
|
135
|
-
0: '0', 5: '0.05', 10: '0.1', 20: '0.2', 25: '0.25',
|
|
136
|
-
30: '0.3', 40: '0.4', 50: '0.5', 60: '0.6', 70: '0.7',
|
|
137
|
-
75: '0.75', 80: '0.8', 90: '0.9', 95: '0.95', 100: '1',
|
|
138
|
-
}
|
|
139
|
-
return { '--hw-border-opacity': opacityMap[parsed.value] || parsed.value } as Record<string, string>
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// Space utilities (child spacing)
|
|
144
|
-
export const spaceRule: UtilityRule = (parsed, config) => {
|
|
145
|
-
if (parsed.utility === 'space-x' && parsed.value) {
|
|
146
|
-
let spacing: string
|
|
147
|
-
if (parsed.value.startsWith('-')) {
|
|
148
|
-
const positiveValue = parsed.value.slice(1)
|
|
149
|
-
const baseSpacing = config.theme.spacing[positiveValue]
|
|
150
|
-
spacing = baseSpacing ? `-${baseSpacing}` : parsed.value
|
|
151
|
-
}
|
|
152
|
-
else {
|
|
153
|
-
spacing = config.theme.spacing[parsed.value] || parsed.value
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
return {
|
|
157
|
-
properties: {
|
|
158
|
-
'--hw-space-x-reverse': '0',
|
|
159
|
-
'margin-right': `calc(${spacing} * var(--hw-space-x-reverse))`,
|
|
160
|
-
'margin-left': `calc(${spacing} * calc(1 - var(--hw-space-x-reverse)))`,
|
|
161
|
-
} as Record<string, string>,
|
|
162
|
-
childSelector: '> :not([hidden]) ~ :not([hidden])',
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
if (parsed.utility === 'space-y' && parsed.value) {
|
|
167
|
-
let spacing: string
|
|
168
|
-
if (parsed.value.startsWith('-')) {
|
|
169
|
-
const positiveValue = parsed.value.slice(1)
|
|
170
|
-
const baseSpacing = config.theme.spacing[positiveValue]
|
|
171
|
-
spacing = baseSpacing ? `-${baseSpacing}` : parsed.value
|
|
172
|
-
}
|
|
173
|
-
else {
|
|
174
|
-
spacing = config.theme.spacing[parsed.value] || parsed.value
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
return {
|
|
178
|
-
properties: {
|
|
179
|
-
'--hw-space-y-reverse': '0',
|
|
180
|
-
'margin-top': `calc(${spacing} * calc(1 - var(--hw-space-y-reverse)))`,
|
|
181
|
-
'margin-bottom': `calc(${spacing} * var(--hw-space-y-reverse))`,
|
|
182
|
-
} as Record<string, string>,
|
|
183
|
-
childSelector: '> :not([hidden]) ~ :not([hidden])',
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
// Border style utilities
|
|
189
|
-
export const borderStyleRule: UtilityRule = (parsed) => {
|
|
190
|
-
if (parsed.utility === 'border' && parsed.value) {
|
|
191
|
-
const styles: Record<string, string> = {
|
|
192
|
-
solid: 'solid',
|
|
193
|
-
dashed: 'dashed',
|
|
194
|
-
dotted: 'dotted',
|
|
195
|
-
double: 'double',
|
|
196
|
-
hidden: 'hidden',
|
|
197
|
-
none: 'none',
|
|
198
|
-
}
|
|
199
|
-
if (styles[parsed.value]) {
|
|
200
|
-
return { 'border-style': styles[parsed.value] }
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// Divide utilities (borders between children)
|
|
206
|
-
export const divideRule: UtilityRule = (parsed, config) => {
|
|
207
|
-
// Handle divide styles: divide-solid, divide-dashed, divide-dotted
|
|
208
|
-
if (parsed.utility === 'divide' && parsed.value) {
|
|
209
|
-
const styles: Record<string, string> = {
|
|
210
|
-
solid: 'solid',
|
|
211
|
-
dashed: 'dashed',
|
|
212
|
-
dotted: 'dotted',
|
|
213
|
-
double: 'double',
|
|
214
|
-
none: 'none',
|
|
215
|
-
}
|
|
216
|
-
if (styles[parsed.value]) {
|
|
217
|
-
return {
|
|
218
|
-
properties: {
|
|
219
|
-
'border-style': styles[parsed.value],
|
|
220
|
-
} as Record<string, string>,
|
|
221
|
-
childSelector: '> :not([hidden]) ~ :not([hidden])',
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
if (parsed.utility === 'divide-x') {
|
|
227
|
-
const widths: Record<string, string> = {
|
|
228
|
-
0: '0',
|
|
229
|
-
2: '2px',
|
|
230
|
-
4: '4px',
|
|
231
|
-
8: '8px',
|
|
232
|
-
DEFAULT: '1px',
|
|
233
|
-
}
|
|
234
|
-
const width = parsed.value ? (widths[parsed.value] || parsed.value) : widths.DEFAULT
|
|
235
|
-
|
|
236
|
-
return {
|
|
237
|
-
properties: {
|
|
238
|
-
'--hw-divide-x-reverse': '0',
|
|
239
|
-
'border-right-width': `calc(${width} * var(--hw-divide-x-reverse))`,
|
|
240
|
-
'border-left-width': `calc(${width} * calc(1 - var(--hw-divide-x-reverse)))`,
|
|
241
|
-
} as Record<string, string>,
|
|
242
|
-
childSelector: '> :not([hidden]) ~ :not([hidden])',
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
if (parsed.utility === 'divide-y') {
|
|
247
|
-
const widths: Record<string, string> = {
|
|
248
|
-
0: '0',
|
|
249
|
-
2: '2px',
|
|
250
|
-
4: '4px',
|
|
251
|
-
8: '8px',
|
|
252
|
-
DEFAULT: '1px',
|
|
253
|
-
}
|
|
254
|
-
const width = parsed.value ? (widths[parsed.value] || parsed.value) : widths.DEFAULT
|
|
255
|
-
|
|
256
|
-
return {
|
|
257
|
-
properties: {
|
|
258
|
-
'--hw-divide-y-reverse': '0',
|
|
259
|
-
'border-top-width': `calc(${width} * calc(1 - var(--hw-divide-y-reverse)))`,
|
|
260
|
-
'border-bottom-width': `calc(${width} * var(--hw-divide-y-reverse))`,
|
|
261
|
-
} as Record<string, string>,
|
|
262
|
-
childSelector: '> :not([hidden]) ~ :not([hidden])',
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
if (parsed.utility === 'divide' && parsed.value) {
|
|
267
|
-
// divide-{color}-{shade}
|
|
268
|
-
const parts = parsed.value.split('-')
|
|
269
|
-
if (parts.length >= 2) {
|
|
270
|
-
const colorName = parts.slice(0, -1).join('-')
|
|
271
|
-
const shade = parts[parts.length - 1]
|
|
272
|
-
const colorValue = config.theme.colors[colorName]
|
|
273
|
-
if (typeof colorValue === 'object' && colorValue[shade]) {
|
|
274
|
-
return {
|
|
275
|
-
properties: {
|
|
276
|
-
'border-color': colorValue[shade],
|
|
277
|
-
} as Record<string, string>,
|
|
278
|
-
childSelector: '> :not([hidden]) ~ :not([hidden])',
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
// Gradient color stops
|
|
286
|
-
export const gradientStopsRule: UtilityRule = (parsed, config) => {
|
|
287
|
-
const getColor = (value: string) => {
|
|
288
|
-
// First check if it's a direct color value (e.g., ocean-blue, black, white)
|
|
289
|
-
const directColor = config.theme.colors[value]
|
|
290
|
-
if (typeof directColor === 'string') {
|
|
291
|
-
return directColor
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
// Then check if it's a color-shade combination (e.g., sky-500, blue-gray-200)
|
|
295
|
-
const parts = value.split('-')
|
|
296
|
-
if (parts.length >= 2) {
|
|
297
|
-
const colorName = parts.slice(0, -1).join('-')
|
|
298
|
-
const shade = parts[parts.length - 1]
|
|
299
|
-
const colorValue = config.theme.colors[colorName]
|
|
300
|
-
if (typeof colorValue === 'object' && colorValue[shade]) {
|
|
301
|
-
return colorValue[shade]
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
return value
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
if (parsed.utility === 'from' && parsed.value) {
|
|
308
|
-
const color = getColor(parsed.value)
|
|
309
|
-
return {
|
|
310
|
-
'--hw-gradient-from': color,
|
|
311
|
-
'--hw-gradient-to': 'rgb(255 255 255 / 0)',
|
|
312
|
-
'--hw-gradient-stops': 'var(--hw-gradient-from), var(--hw-gradient-to)',
|
|
313
|
-
} as Record<string, string>
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
if (parsed.utility === 'via' && parsed.value) {
|
|
317
|
-
const color = getColor(parsed.value)
|
|
318
|
-
return {
|
|
319
|
-
'--hw-gradient-to': 'rgb(255 255 255 / 0)',
|
|
320
|
-
'--hw-gradient-stops': `var(--hw-gradient-from), ${color}, var(--hw-gradient-to)`,
|
|
321
|
-
} as Record<string, string>
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
if (parsed.utility === 'to' && parsed.value) {
|
|
325
|
-
const color = getColor(parsed.value)
|
|
326
|
-
return {
|
|
327
|
-
'--hw-gradient-to': color,
|
|
328
|
-
'--hw-gradient-stops': 'var(--hw-gradient-from), var(--hw-gradient-to)',
|
|
329
|
-
} as Record<string, string>
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
// Flex order
|
|
334
|
-
export const flexOrderRule: UtilityRule = (parsed) => {
|
|
335
|
-
if (parsed.utility === 'order' && parsed.value) {
|
|
336
|
-
const orders: Record<string, string> = {
|
|
337
|
-
first: '-9999',
|
|
338
|
-
last: '9999',
|
|
339
|
-
none: '0',
|
|
340
|
-
1: '1',
|
|
341
|
-
2: '2',
|
|
342
|
-
3: '3',
|
|
343
|
-
4: '4',
|
|
344
|
-
5: '5',
|
|
345
|
-
6: '6',
|
|
346
|
-
7: '7',
|
|
347
|
-
8: '8',
|
|
348
|
-
9: '9',
|
|
349
|
-
10: '10',
|
|
350
|
-
11: '11',
|
|
351
|
-
12: '12',
|
|
352
|
-
}
|
|
353
|
-
return { order: orders[parsed.value] || parsed.value }
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
// Flex basis
|
|
358
|
-
export const flexBasisRule: UtilityRule = (parsed, config) => {
|
|
359
|
-
if (parsed.utility === 'basis' && parsed.value) {
|
|
360
|
-
// Handle fractions
|
|
361
|
-
if (parsed.value.includes('/')) {
|
|
362
|
-
const [num, denom] = parsed.value.split('/').map(Number)
|
|
363
|
-
return { 'flex-basis': `${(num / denom) * 100}%` }
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
const bases: Record<string, string> = {
|
|
367
|
-
auto: 'auto',
|
|
368
|
-
full: '100%',
|
|
369
|
-
0: '0',
|
|
370
|
-
}
|
|
371
|
-
return { 'flex-basis': bases[parsed.value] || config.theme.spacing[parsed.value] || parsed.value }
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
// Justify/Align self
|
|
376
|
-
export const justifySelfRule: UtilityRule = (parsed) => {
|
|
377
|
-
if (parsed.utility === 'justify-self') {
|
|
378
|
-
const values: Record<string, string> = {
|
|
379
|
-
auto: 'auto',
|
|
380
|
-
start: 'start',
|
|
381
|
-
end: 'end',
|
|
382
|
-
center: 'center',
|
|
383
|
-
stretch: 'stretch',
|
|
384
|
-
}
|
|
385
|
-
return parsed.value ? { 'justify-self': values[parsed.value] || parsed.value } : undefined
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
export const alignSelfRule: UtilityRule = (parsed) => {
|
|
390
|
-
if (parsed.utility === 'self') {
|
|
391
|
-
const values: Record<string, string> = {
|
|
392
|
-
auto: 'auto',
|
|
393
|
-
start: 'flex-start',
|
|
394
|
-
end: 'flex-end',
|
|
395
|
-
center: 'center',
|
|
396
|
-
stretch: 'stretch',
|
|
397
|
-
baseline: 'baseline',
|
|
398
|
-
}
|
|
399
|
-
return parsed.value ? { 'align-self': values[parsed.value] || parsed.value } : undefined
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
// Container utility with responsive max-widths
|
|
404
|
-
export const containerRule: UtilityRule = (parsed, config) => {
|
|
405
|
-
if (parsed.utility === 'container') {
|
|
406
|
-
// container without value - centered container with responsive max-width
|
|
407
|
-
if (!parsed.value) {
|
|
408
|
-
// Use clamp for modern responsive max-width behavior
|
|
409
|
-
// Max-width scales with breakpoints: sm=640, md=768, lg=1024, xl=1280, 2xl=1536
|
|
410
|
-
const xl = config.theme.screens['xl'] || '1280px'
|
|
411
|
-
return {
|
|
412
|
-
'width': '100%',
|
|
413
|
-
'margin-left': 'auto',
|
|
414
|
-
'margin-right': 'auto',
|
|
415
|
-
'max-width': xl,
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
// container-{breakpoint} for specific max-widths
|
|
420
|
-
const breakpointMap: Record<string, string> = {
|
|
421
|
-
'sm': config.theme.screens['sm'] || '640px',
|
|
422
|
-
'md': config.theme.screens['md'] || '768px',
|
|
423
|
-
'lg': config.theme.screens['lg'] || '1024px',
|
|
424
|
-
'xl': config.theme.screens['xl'] || '1280px',
|
|
425
|
-
'2xl': config.theme.screens['2xl'] || '1536px',
|
|
426
|
-
'full': '100%',
|
|
427
|
-
'prose': '65ch',
|
|
428
|
-
'3xl': '1920px',
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
if (breakpointMap[parsed.value]) {
|
|
432
|
-
return {
|
|
433
|
-
'width': '100%',
|
|
434
|
-
'margin-left': 'auto',
|
|
435
|
-
'margin-right': 'auto',
|
|
436
|
-
'max-width': breakpointMap[parsed.value],
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
// Arbitrary value support: container-[800px]
|
|
441
|
-
if (parsed.arbitrary) {
|
|
442
|
-
return {
|
|
443
|
-
'width': '100%',
|
|
444
|
-
'margin-left': 'auto',
|
|
445
|
-
'margin-right': 'auto',
|
|
446
|
-
'max-width': parsed.value,
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
// Arbitrary properties
|
|
453
|
-
export const arbitraryPropertyRule: UtilityRule = (parsed) => {
|
|
454
|
-
// Only handle true arbitrary properties: [color:red], [mask-type:alpha]
|
|
455
|
-
// NOT arbitrary values like w-[100px]
|
|
456
|
-
const rawWithoutImportant = parsed.raw.replace(/^!/, '')
|
|
457
|
-
if (parsed.arbitrary && parsed.utility && parsed.value && rawWithoutImportant.startsWith('[')) {
|
|
458
|
-
// Arbitrary properties start with [ and have the pattern [prop:value]
|
|
459
|
-
return { [parsed.utility]: parsed.value }
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
export const advancedRules: UtilityRule[] = [
|
|
464
|
-
minMaxSizingRule,
|
|
465
|
-
ringRule,
|
|
466
|
-
borderOpacityRule,
|
|
467
|
-
borderStyleRule,
|
|
468
|
-
spaceRule,
|
|
469
|
-
divideRule,
|
|
470
|
-
gradientStopsRule,
|
|
471
|
-
flexOrderRule,
|
|
472
|
-
flexBasisRule,
|
|
473
|
-
justifySelfRule,
|
|
474
|
-
alignSelfRule,
|
|
475
|
-
containerRule,
|
|
476
|
-
arbitraryPropertyRule,
|
|
477
|
-
]
|