@cwcss/crosswind 0.1.5 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +52 -0
  3. package/dist/bin/cli.js +14615 -0
  4. package/dist/build.d.ts +24 -0
  5. package/dist/config.d.ts +5 -0
  6. package/dist/generator.d.ts +31 -0
  7. package/dist/index.d.ts +10 -0
  8. package/dist/parser.d.ts +42 -0
  9. package/dist/plugin.d.ts +22 -0
  10. package/dist/preflight-forms.d.ts +5 -0
  11. package/dist/preflight.d.ts +2 -0
  12. package/dist/rules-advanced.d.ts +27 -0
  13. package/dist/rules-effects.d.ts +25 -0
  14. package/dist/rules-forms.d.ts +7 -0
  15. package/dist/rules-grid.d.ts +13 -0
  16. package/dist/rules-interactivity.d.ts +41 -0
  17. package/dist/rules-layout.d.ts +26 -0
  18. package/dist/rules-transforms.d.ts +33 -0
  19. package/dist/rules-typography.d.ts +41 -0
  20. package/dist/rules.d.ts +39 -0
  21. package/dist/scanner.d.ts +18 -0
  22. package/dist/src/index.js +12848 -0
  23. package/dist/transformer-compile-class.d.ts +37 -0
  24. package/{src/types.ts → dist/types.d.ts} +17 -86
  25. package/package.json +2 -16
  26. package/PLUGIN.md +0 -235
  27. package/benchmark/framework-comparison.bench.ts +0 -850
  28. package/bin/cli.ts +0 -365
  29. package/bin/crosswind +0 -0
  30. package/bin/headwind +0 -0
  31. package/build.ts +0 -8
  32. package/crosswind.config.ts +0 -9
  33. package/example/comprehensive.html +0 -70
  34. package/example/index.html +0 -21
  35. package/example/output.css +0 -236
  36. package/examples/plugin/README.md +0 -112
  37. package/examples/plugin/build.ts +0 -32
  38. package/examples/plugin/src/index.html +0 -34
  39. package/examples/plugin/src/index.ts +0 -7
  40. package/headwind +0 -2
  41. package/src/build.ts +0 -101
  42. package/src/config.ts +0 -529
  43. package/src/generator.ts +0 -2173
  44. package/src/index.ts +0 -10
  45. package/src/parser.ts +0 -1471
  46. package/src/plugin.ts +0 -118
  47. package/src/preflight-forms.ts +0 -229
  48. package/src/preflight.ts +0 -388
  49. package/src/rules-advanced.ts +0 -477
  50. package/src/rules-effects.ts +0 -461
  51. package/src/rules-forms.ts +0 -103
  52. package/src/rules-grid.ts +0 -241
  53. package/src/rules-interactivity.ts +0 -525
  54. package/src/rules-layout.ts +0 -385
  55. package/src/rules-transforms.ts +0 -412
  56. package/src/rules-typography.ts +0 -486
  57. package/src/rules.ts +0 -809
  58. package/src/scanner.ts +0 -84
  59. package/src/transformer-compile-class.ts +0 -275
  60. package/test/advanced-features.test.ts +0 -911
  61. package/test/arbitrary.test.ts +0 -396
  62. package/test/attributify.test.ts +0 -592
  63. package/test/bracket-syntax.test.ts +0 -1133
  64. package/test/build.test.ts +0 -99
  65. package/test/colors.test.ts +0 -934
  66. package/test/flexbox.test.ts +0 -669
  67. package/test/generator.test.ts +0 -597
  68. package/test/grid.test.ts +0 -584
  69. package/test/layout.test.ts +0 -404
  70. package/test/modifiers.test.ts +0 -417
  71. package/test/parser.test.ts +0 -564
  72. package/test/performance-regression.test.ts +0 -376
  73. package/test/performance.test.ts +0 -568
  74. package/test/plugin.test.ts +0 -160
  75. package/test/scanner.test.ts +0 -94
  76. package/test/sizing.test.ts +0 -481
  77. package/test/spacing.test.ts +0 -394
  78. package/test/transformer-compile-class.test.ts +0 -287
  79. package/test/transforms.test.ts +0 -448
  80. package/test/typography.test.ts +0 -632
  81. package/test/variants-form-states.test.ts +0 -225
  82. package/test/variants-group-peer.test.ts +0 -66
  83. package/test/variants-media.test.ts +0 -213
  84. package/test/variants-positional.test.ts +0 -58
  85. package/test/variants-pseudo-elements.test.ts +0 -47
  86. package/test/variants-state.test.ts +0 -62
  87. package/tsconfig.json +0 -18
@@ -1,486 +0,0 @@
1
- import type { UtilityRule } from './rules'
2
-
3
- // Typography utilities
4
-
5
- export const fontFamilyRule: UtilityRule = (parsed, config) => {
6
- if (parsed.utility === 'font' && parsed.value) {
7
- const family = config.theme.fontFamily[parsed.value]
8
- if (family) {
9
- return { 'font-family': family.join(', ') }
10
- }
11
- }
12
- }
13
-
14
- export const fontSmoothingRule: UtilityRule = (parsed) => {
15
- const values: Record<string, Record<string, string>> = {
16
- 'antialiased': {
17
- '-webkit-font-smoothing': 'antialiased',
18
- '-moz-osx-font-smoothing': 'grayscale',
19
- },
20
- 'subpixel-antialiased': {
21
- '-webkit-font-smoothing': 'auto',
22
- '-moz-osx-font-smoothing': 'auto',
23
- },
24
- }
25
- return values[parsed.raw]
26
- }
27
-
28
- export const fontStyleRule: UtilityRule = (parsed) => {
29
- const styles: Record<string, string> = {
30
- 'italic': 'italic',
31
- 'not-italic': 'normal',
32
- }
33
- return styles[parsed.raw] ? { 'font-style': styles[parsed.raw] } : undefined
34
- }
35
-
36
- export const fontStretchRule: UtilityRule = (parsed) => {
37
- if (parsed.utility === 'font-stretch') {
38
- const stretches = ['ultra-condensed', 'extra-condensed', 'condensed', 'semi-condensed', 'normal', 'semi-expanded', 'expanded', 'extra-expanded', 'ultra-expanded']
39
- return parsed.value && stretches.includes(parsed.value) ? { 'font-stretch': parsed.value } : undefined
40
- }
41
- }
42
-
43
- export const fontVariantNumericRule: UtilityRule = (parsed) => {
44
- const variants: Record<string, string> = {
45
- 'normal-nums': 'normal',
46
- 'ordinal': 'ordinal',
47
- 'slashed-zero': 'slashed-zero',
48
- 'lining-nums': 'lining-nums',
49
- 'oldstyle-nums': 'oldstyle-nums',
50
- 'proportional-nums': 'proportional-nums',
51
- 'tabular-nums': 'tabular-nums',
52
- 'diagonal-fractions': 'diagonal-fractions',
53
- 'stacked-fractions': 'stacked-fractions',
54
- }
55
- return variants[parsed.raw] ? { 'font-variant-numeric': variants[parsed.raw] } : undefined
56
- }
57
-
58
- export const letterSpacingRule: UtilityRule = (parsed) => {
59
- if (parsed.utility === 'tracking') {
60
- const values: Record<string, string> = {
61
- tighter: '-0.05em',
62
- tight: '-0.025em',
63
- normal: '0em',
64
- wide: '0.025em',
65
- wider: '0.05em',
66
- widest: '0.1em',
67
- }
68
- if (!parsed.value) {
69
- return undefined
70
- }
71
- // Handle negative values
72
- if (parsed.value.startsWith('-')) {
73
- const positiveValue = parsed.value.slice(1)
74
- return { 'letter-spacing': `-${values[positiveValue] || positiveValue}` }
75
- }
76
- return { 'letter-spacing': values[parsed.value] || parsed.value }
77
- }
78
- }
79
-
80
- export const lineClampRule: UtilityRule = (parsed) => {
81
- if (parsed.utility === 'line-clamp' && parsed.value) {
82
- return {
83
- 'overflow': 'hidden',
84
- 'display': '-webkit-box',
85
- '-webkit-box-orient': 'vertical',
86
- '-webkit-line-clamp': parsed.value,
87
- }
88
- }
89
- }
90
-
91
- export const listStyleImageRule: UtilityRule = (parsed) => {
92
- if (parsed.utility === 'list-image' && parsed.value) {
93
- return { 'list-style-image': parsed.value === 'none' ? 'none' : `url(${parsed.value})` }
94
- }
95
- }
96
-
97
- export const listStylePositionRule: UtilityRule = (parsed) => {
98
- const positions: Record<string, string> = {
99
- 'list-inside': 'inside',
100
- 'list-outside': 'outside',
101
- }
102
- return positions[parsed.raw] ? { 'list-style-position': positions[parsed.raw] } : undefined
103
- }
104
-
105
- export const listStyleTypeRule: UtilityRule = (parsed) => {
106
- if (parsed.utility === 'list') {
107
- const types: Record<string, string> = {
108
- none: 'none',
109
- disc: 'disc',
110
- decimal: 'decimal',
111
- }
112
- return parsed.value ? { 'list-style-type': types[parsed.value] || parsed.value } : undefined
113
- }
114
- }
115
-
116
- export const textDecorationRule: UtilityRule = (parsed, config) => {
117
- const decorations: Record<string, string> = {
118
- 'underline': 'underline',
119
- 'overline': 'overline',
120
- 'line-through': 'line-through',
121
- 'no-underline': 'none',
122
- }
123
- if (decorations[parsed.raw]) {
124
- return { 'text-decoration-line': decorations[parsed.raw] } as Record<string, string>
125
- }
126
-
127
- if (parsed.utility === 'decoration' && parsed.value) {
128
- const styles: Record<string, string> = {
129
- solid: 'solid',
130
- double: 'double',
131
- dotted: 'dotted',
132
- dashed: 'dashed',
133
- wavy: 'wavy',
134
- }
135
-
136
- // Check if it's a style
137
- if (styles[parsed.value]) {
138
- return { 'text-decoration-style': styles[parsed.value] } as Record<string, string>
139
- }
140
-
141
- // Check if it's a thickness
142
- const thicknesses: Record<string, string> = {
143
- 'auto': 'auto',
144
- 'from-font': 'from-font',
145
- '0': '0px',
146
- '1': '1px',
147
- '2': '2px',
148
- '4': '4px',
149
- '8': '8px',
150
- }
151
- if (thicknesses[parsed.value]) {
152
- return { 'text-decoration-thickness': thicknesses[parsed.value] } as Record<string, string>
153
- }
154
-
155
- // Handle arbitrary thickness
156
- if (parsed.arbitrary) {
157
- return { 'text-decoration-thickness': parsed.value } as Record<string, string>
158
- }
159
-
160
- // Otherwise treat it as a color: decoration-blue-500
161
- const parts = parsed.value.split('-')
162
- if (parts.length === 2) {
163
- const [colorName, shade] = parts
164
- const colorValue = config.theme.colors[colorName]
165
- if (typeof colorValue === 'object' && colorValue[shade]) {
166
- return { 'text-decoration-color': colorValue[shade] } as Record<string, string>
167
- }
168
- }
169
-
170
- // Direct color
171
- const directColor = config.theme.colors[parsed.value]
172
- if (typeof directColor === 'string') {
173
- return { 'text-decoration-color': directColor } as Record<string, string>
174
- }
175
-
176
- // Fallback
177
- return { 'text-decoration-color': parsed.value } as Record<string, string>
178
- }
179
-
180
- return undefined
181
- }
182
-
183
- export const underlineOffsetRule: UtilityRule = (parsed) => {
184
- if (parsed.utility === 'underline-offset' && parsed.value) {
185
- const offsets: Record<string, string> = {
186
- auto: 'auto',
187
- 0: '0px',
188
- 1: '1px',
189
- 2: '2px',
190
- 4: '4px',
191
- 8: '8px',
192
- }
193
- return { 'text-underline-offset': offsets[parsed.value] || parsed.value }
194
- }
195
- }
196
-
197
- export const textTransformRule: UtilityRule = (parsed) => {
198
- const transforms: Record<string, string> = {
199
- 'uppercase': 'uppercase',
200
- 'lowercase': 'lowercase',
201
- 'capitalize': 'capitalize',
202
- 'normal-case': 'none',
203
- }
204
- return transforms[parsed.raw] ? { 'text-transform': transforms[parsed.raw] } : undefined
205
- }
206
-
207
- export const textOverflowRule: UtilityRule = (parsed) => {
208
- const overflows: Record<string, Record<string, string>> = {
209
- 'truncate': {
210
- 'overflow': 'hidden',
211
- 'text-overflow': 'ellipsis',
212
- 'white-space': 'nowrap',
213
- },
214
- 'text-ellipsis': { 'text-overflow': 'ellipsis' },
215
- 'text-clip': { 'text-overflow': 'clip' },
216
- }
217
- return overflows[parsed.raw]
218
- }
219
-
220
- export const textWrapRule: UtilityRule = (parsed) => {
221
- const wraps: Record<string, string> = {
222
- 'text-wrap': 'wrap',
223
- 'text-nowrap': 'nowrap',
224
- 'text-balance': 'balance',
225
- 'text-pretty': 'pretty',
226
- }
227
- return wraps[parsed.raw] ? { 'text-wrap': wraps[parsed.raw] } : undefined
228
- }
229
-
230
- export const textIndentRule: UtilityRule = (parsed, config) => {
231
- if (parsed.utility === 'indent' && parsed.value) {
232
- // Handle negative values
233
- if (parsed.value.startsWith('-')) {
234
- const positiveValue = parsed.value.slice(1)
235
- const spacing = config.theme.spacing[positiveValue] || positiveValue
236
- return { 'text-indent': `-${spacing}` }
237
- }
238
- return { 'text-indent': config.theme.spacing[parsed.value] || parsed.value }
239
- }
240
- }
241
-
242
- export const verticalAlignRule: UtilityRule = (parsed) => {
243
- const aligns: Record<string, string> = {
244
- 'align-baseline': 'baseline',
245
- 'align-top': 'top',
246
- 'align-middle': 'middle',
247
- 'align-bottom': 'bottom',
248
- 'align-text-top': 'text-top',
249
- 'align-text-bottom': 'text-bottom',
250
- 'align-sub': 'sub',
251
- 'align-super': 'super',
252
- }
253
- return aligns[parsed.raw] ? { 'vertical-align': aligns[parsed.raw] } : undefined
254
- }
255
-
256
- export const whiteSpaceRule: UtilityRule = (parsed) => {
257
- const spaces: Record<string, string> = {
258
- 'whitespace-normal': 'normal',
259
- 'whitespace-nowrap': 'nowrap',
260
- 'whitespace-pre': 'pre',
261
- 'whitespace-pre-line': 'pre-line',
262
- 'whitespace-pre-wrap': 'pre-wrap',
263
- 'whitespace-break-spaces': 'break-spaces',
264
- }
265
- return spaces[parsed.raw] ? { 'white-space': spaces[parsed.raw] } : undefined
266
- }
267
-
268
- export const wordBreakRule: UtilityRule = (parsed) => {
269
- if (parsed.raw === 'break-normal') {
270
- return {
271
- 'overflow-wrap': 'normal',
272
- 'word-break': 'normal',
273
- } as Record<string, string>
274
- }
275
- if (parsed.raw === 'break-words') {
276
- return { 'overflow-wrap': 'break-word' } as Record<string, string>
277
- }
278
- const breaks: Record<string, string> = {
279
- 'break-all': 'break-all',
280
- 'break-keep': 'keep-all',
281
- }
282
- return breaks[parsed.raw] ? { 'word-break': breaks[parsed.raw] } : undefined
283
- }
284
-
285
- export const overflowWrapRule: UtilityRule = (parsed) => {
286
- const wraps: Record<string, string> = {
287
- 'overflow-wrap-normal': 'normal',
288
- 'overflow-wrap-break': 'break-word',
289
- 'overflow-wrap-anywhere': 'anywhere',
290
- }
291
- return wraps[parsed.raw] ? { 'overflow-wrap': wraps[parsed.raw] } : undefined
292
- }
293
-
294
- export const hyphensRule: UtilityRule = (parsed) => {
295
- const values: Record<string, string> = {
296
- 'hyphens-none': 'none',
297
- 'hyphens-manual': 'manual',
298
- 'hyphens-auto': 'auto',
299
- }
300
- return values[parsed.raw] ? { hyphens: values[parsed.raw] } : undefined
301
- }
302
-
303
- export const contentRule: UtilityRule = (parsed) => {
304
- if (parsed.utility === 'content' && parsed.value) {
305
- const values: Record<string, string> = {
306
- none: 'none',
307
- }
308
- // If value is already quoted or is a special value, use as-is
309
- if (values[parsed.value] || parsed.value.startsWith('"') || parsed.value.startsWith('\'')) {
310
- return { content: values[parsed.value] || parsed.value }
311
- }
312
- // Otherwise wrap in quotes
313
- return { content: `"${parsed.value}"` }
314
- }
315
- }
316
-
317
- export const lineHeightRule: UtilityRule = (parsed, _config) => {
318
- if (parsed.utility === 'leading') {
319
- if (!parsed.value) {
320
- return undefined
321
- }
322
-
323
- const lineHeights: Record<string, string> = {
324
- none: '1',
325
- tight: '1.25',
326
- snug: '1.375',
327
- normal: '1.5',
328
- relaxed: '1.625',
329
- loose: '2',
330
- 3: '.75rem',
331
- 4: '1rem',
332
- 5: '1.25rem',
333
- 6: '1.5rem',
334
- 7: '1.75rem',
335
- 8: '2rem',
336
- 9: '2.25rem',
337
- 10: '2.5rem',
338
- }
339
-
340
- return { 'line-height': lineHeights[parsed.value] || parsed.value }
341
- }
342
- }
343
-
344
- // Writing mode
345
- export const writingModeRule: UtilityRule = (parsed) => {
346
- const values: Record<string, string> = {
347
- 'writing-horizontal-tb': 'horizontal-tb',
348
- 'writing-vertical-rl': 'vertical-rl',
349
- 'writing-vertical-lr': 'vertical-lr',
350
- }
351
- return values[parsed.raw] ? { 'writing-mode': values[parsed.raw] } : undefined
352
- }
353
-
354
- // Text orientation
355
- export const textOrientationRule: UtilityRule = (parsed) => {
356
- const values: Record<string, string> = {
357
- 'text-orientation-mixed': 'mixed',
358
- 'text-orientation-upright': 'upright',
359
- 'text-orientation-sideways': 'sideways',
360
- }
361
- return values[parsed.raw] ? { 'text-orientation': values[parsed.raw] } : undefined
362
- }
363
-
364
- // Direction (ltr/rtl)
365
- export const directionRule: UtilityRule = (parsed) => {
366
- const values: Record<string, string> = {
367
- 'direction-ltr': 'ltr',
368
- 'direction-rtl': 'rtl',
369
- }
370
- return values[parsed.raw] ? { direction: values[parsed.raw] } : undefined
371
- }
372
-
373
- // Text emphasis
374
- export const textEmphasisRule: UtilityRule = (parsed) => {
375
- if (parsed.utility === 'text-emphasis' && parsed.value) {
376
- const styles: Record<string, string> = {
377
- 'none': 'none',
378
- 'filled': 'filled',
379
- 'open': 'open',
380
- 'dot': 'dot',
381
- 'circle': 'circle',
382
- 'double-circle': 'double-circle',
383
- 'triangle': 'triangle',
384
- 'sesame': 'sesame',
385
- }
386
- return { 'text-emphasis': styles[parsed.value] || parsed.value }
387
- }
388
- }
389
-
390
- // Text emphasis color
391
- export const textEmphasisColorRule: UtilityRule = (parsed, config) => {
392
- if (parsed.utility === 'text-emphasis-color' && parsed.value) {
393
- const parts = parsed.value.split('-')
394
- if (parts.length === 2) {
395
- const [colorName, shade] = parts
396
- const colorValue = config.theme.colors[colorName]
397
- if (typeof colorValue === 'object' && colorValue[shade]) {
398
- return { 'text-emphasis-color': colorValue[shade] }
399
- }
400
- }
401
- const directColor = config.theme.colors[parsed.value]
402
- if (typeof directColor === 'string') {
403
- return { 'text-emphasis-color': directColor }
404
- }
405
- }
406
- }
407
-
408
- // Word spacing
409
- export const wordSpacingRule: UtilityRule = (parsed, config) => {
410
- if (parsed.utility === 'word-spacing' && parsed.value) {
411
- const values: Record<string, string> = {
412
- 'tighter': '-0.05em',
413
- 'tight': '-0.025em',
414
- 'normal': 'normal',
415
- 'wide': '0.025em',
416
- 'wider': '0.05em',
417
- 'widest': '0.1em',
418
- }
419
- return { 'word-spacing': values[parsed.value] || config.theme.spacing[parsed.value] || parsed.value }
420
- }
421
- }
422
-
423
- // Font variant caps
424
- export const fontVariantCapsRule: UtilityRule = (parsed) => {
425
- const values: Record<string, string> = {
426
- 'small-caps': 'small-caps',
427
- 'all-small-caps': 'all-small-caps',
428
- 'petite-caps': 'petite-caps',
429
- 'all-petite-caps': 'all-petite-caps',
430
- 'unicase': 'unicase',
431
- 'titling-caps': 'titling-caps',
432
- 'normal-caps': 'normal',
433
- }
434
- return values[parsed.raw] ? { 'font-variant-caps': values[parsed.raw] } : undefined
435
- }
436
-
437
- // Font variant ligatures
438
- export const fontVariantLigaturesRule: UtilityRule = (parsed) => {
439
- const values: Record<string, string> = {
440
- 'ligatures-normal': 'normal',
441
- 'ligatures-none': 'none',
442
- 'common-ligatures': 'common-ligatures',
443
- 'no-common-ligatures': 'no-common-ligatures',
444
- 'discretionary-ligatures': 'discretionary-ligatures',
445
- 'no-discretionary-ligatures': 'no-discretionary-ligatures',
446
- 'historical-ligatures': 'historical-ligatures',
447
- 'no-historical-ligatures': 'no-historical-ligatures',
448
- 'contextual': 'contextual',
449
- 'no-contextual': 'no-contextual',
450
- }
451
- return values[parsed.raw] ? { 'font-variant-ligatures': values[parsed.raw] } : undefined
452
- }
453
-
454
- export const typographyRules: UtilityRule[] = [
455
- fontFamilyRule,
456
- fontSmoothingRule,
457
- fontStyleRule,
458
- fontStretchRule,
459
- fontVariantNumericRule,
460
- fontVariantCapsRule,
461
- fontVariantLigaturesRule,
462
- letterSpacingRule,
463
- lineHeightRule,
464
- lineClampRule,
465
- listStyleImageRule,
466
- listStylePositionRule,
467
- listStyleTypeRule,
468
- textDecorationRule,
469
- underlineOffsetRule,
470
- textTransformRule,
471
- textOverflowRule,
472
- textWrapRule,
473
- textIndentRule,
474
- verticalAlignRule,
475
- whiteSpaceRule,
476
- wordBreakRule,
477
- overflowWrapRule,
478
- hyphensRule,
479
- contentRule,
480
- writingModeRule,
481
- textOrientationRule,
482
- directionRule,
483
- textEmphasisRule,
484
- textEmphasisColorRule,
485
- wordSpacingRule,
486
- ]