@cwcss/crosswind 0.1.6 → 0.2.1

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/README.md CHANGED
@@ -1,390 +1,596 @@
1
- <p align="center"><img src=".github/art/cover.jpg" alt="Social Card of this repo"></p>
1
+ # @cwcss/crosswind
2
2
 
3
- [![npm version][npm-version-src]][npm-version-href]
4
- [![GitHub Actions][github-actions-src]][github-actions-href]
5
- [![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/)
6
- <!-- [![npm downloads][npm-downloads-src]][npm-downloads-href] -->
7
- <!-- [![Codecov][codecov-src]][codecov-href] -->
3
+ A performant utility-first CSS engine, compatible with Tailwind CSS. Built with TypeScript and optimized for Bun.
8
4
 
9
- # crosswind
10
-
11
- A blazingly fast, utility-first CSS framework built with Bun. Crosswind generates only the CSS you need by scanning your files for utility classes, providing Tailwind CSS-compatible utilities with exceptional performance.
12
-
13
- ## Features
14
-
15
- - ⚡️**Blazingly Fast**- Built with Bun for exceptional performance (1000+ utilities in <10ms)
16
- - 🎯**On-Demand Generation**- Only generates CSS for utilities you actually use
17
- - 🎨**Tailwind-Compatible**- Familiar utility classes and syntax
18
- - 💪**Fully Typed**- Complete TypeScript support with type-safe configuration
19
- - 🔧**Highly Configurable**- Customize theme, colors, spacing, variants, and more
20
- - 📦**Zero Runtime Dependencies**- Minimal footprint, maximum performance
21
- - 🔥**Hot Reload**- Watch mode for instant rebuilds during development
22
- - 🎭**Variant Support**- Responsive, state (hover, focus, etc.), dark mode, and custom variants
23
- - ✨**Modern CSS Features**- Grid, Flexbox, animations, transforms, filters, and more
24
- - 🔨**Class Compilation**- Optimize HTML by compiling utility groups into single class names
25
- - 🧪**Thoroughly Tested**- 1300+ tests including comprehensive performance benchmarks
26
- - 🚀**Production Ready**- Minification, preflight CSS, and optimized builds
27
- - ⌨️**CLI & API**- Use via command line or programmatic API
28
-
29
- ## Get Started
30
-
31
- ### Installation
5
+ ## Installation
32
6
 
33
7
  ```bash
34
- bun add crosswind
35
-
36
- # or
37
-
38
- npm install crosswind
39
- ```### Quick Start
40
-
41
- 1.**Initialize Crosswind**:```bash
42
-
43
- # Create a config file
44
-
45
- bunx crosswind init
46
-
47
- ```This creates a`crosswind.config.ts`file:```typescript
48
- import type { CrosswindOptions } from 'crosswind'
49
-
50
- export default {
51
- content: ['./src/**/*.{html,js,ts,jsx,tsx}'],
52
- output: './dist/crosswind.css',
53
- minify: false,
54
- } satisfies CrosswindOptions
55
- ```1.**Add utility classes to your HTML**:```html
56
-
57
- <div class="flex items-center justify-between p-4 bg-blue-500 text-white rounded-lg shadow-md hover:bg-blue-600">
58
- <h1 class="text-2xl font-bold">Hello Crosswind!</h1>
59
- </div>
60
-
61
- ```1.**Build your CSS**:```bash
8
+ bun add @cwcss/crosswind
9
+ ```
62
10
 
63
- # Build once
11
+ ## Quick Start
64
12
 
65
- bunx crosswind build
13
+ ### Programmatic API
66
14
 
67
- # Build and watch for changes
15
+ ```typescript
16
+ import { CSSGenerator, defaultConfig } from '@cwcss/crosswind'
68
17
 
69
- bunx crosswind watch
18
+ const gen = new CSSGenerator(defaultConfig)
19
+ gen.generate('flex')
20
+ gen.generate('items-center')
21
+ gen.generate('gap-4')
22
+ gen.generate('p-8')
23
+ gen.generate('bg-blue-500')
24
+ gen.generate('text-white')
25
+ gen.generate('rounded-lg')
26
+ gen.generate('hover:bg-blue-600')
27
+ gen.generate('dark:bg-gray-900')
70
28
 
71
- # Build with options
29
+ const css = gen.toCSS(true) // true = include preflight
30
+ ```
72
31
 
73
- bunx crosswind build --output ./dist/styles.css --minify
74
- ```### Programmatic API
32
+ ### Build API
75
33
 
76
- You can also use Crosswind programmatically:```typescript
77
- import { build } from 'crosswind'
34
+ ```typescript
35
+ import { build } from '@cwcss/crosswind'
78
36
 
79
37
  const result = await build({
80
- content: ['./src/**/*.html'],
38
+ content: ['./src/**/*.html', './src/**/*.tsx'],
81
39
  output: './dist/styles.css',
82
40
  minify: true,
83
41
  })
42
+ ```
84
43
 
85
- console.log(`Generated ${result.classes.size} classes in ${result.duration}ms`)
44
+ ### CLI
86
45
 
87
- ```## CLI Commands
46
+ ```bash
47
+ crosswind build
48
+ crosswind build --watch
49
+ crosswind build --minify
50
+ ```
88
51
 
89
- Crosswind provides a comprehensive CLI:```bash
90
- crosswind build # Build CSS once
91
- crosswind watch # Build and watch for changes
92
- crosswind init # Create config file
93
- crosswind analyze # Analyze utility class usage
94
- crosswind clean # Remove output CSS file
95
- crosswind preflight # Generate preflight CSS only
96
- crosswind --version # Show version
97
- crosswind --help # Show help
98
- ```## Configuration
52
+ ## Configuration
99
53
 
100
- Crosswind supports extensive configuration options:```typescript
101
- import type { CrosswindOptions } from 'crosswind'
54
+ Create a `crosswind.config.ts` in your project root:
102
55
 
103
- export default {
104
- // Content sources to scan for utility classes
105
- content: ['./src/**/*.{html,js,ts,jsx,tsx}'],
56
+ ```typescript
57
+ import type { CrosswindConfig } from '@cwcss/crosswind'
106
58
 
107
- // Output CSS file path
59
+ export default {
60
+ content: ['./src/**/*.{html,tsx,stx}'],
108
61
  output: './dist/styles.css',
109
-
110
- // Minify output CSS
111
62
  minify: false,
112
63
 
113
- // Enable watch mode
114
- watch: false,
115
-
116
- // Enable verbose logging
117
- verbose: false,
118
-
119
- // Theme customization
120
64
  theme: {
121
- colors: {
122
- primary: '#3b82f6',
123
- secondary: '#10b981',
124
- // ... extend or override default colors
125
- },
126
- spacing: {
127
- // ... customize spacing scale
65
+ extend: {
66
+ colors: {
67
+ brand: {
68
+ 50: '#eff6ff',
69
+ 500: '#3b82f6',
70
+ 900: '#1e3a5a',
71
+ },
72
+ },
73
+ spacing: {
74
+ '18': '4.5rem',
75
+ '112': '28rem',
76
+ },
128
77
  },
129
- fontSize: {
130
- // ... customize font sizes
131
- },
132
- // ... and more
133
78
  },
134
79
 
135
- // Shortcuts (utility aliases)
136
- shortcuts: {
137
- btn: 'px-4 py-2 rounded bg-blue-500 text-white hover:bg-blue-600',
138
- card: 'p-6 bg-white rounded-lg shadow-md',
139
- },
140
-
141
- // Custom variants
142
- variants: {
143
- // ... configure breakpoints, states, etc.
144
- },
145
-
146
- // Safelist (always include these classes)
147
- safelist: ['bg-red-500', 'text-green-500'],
80
+ safelist: ['bg-brand-500', 'text-white'],
81
+ blocklist: ['opacity-0'],
82
+ } satisfies Partial<CrosswindConfig>
83
+ ```
148
84
 
149
- // Blocklist (never include these classes)
150
- blocklist: ['debug-*'],
85
+ ### Theme
86
+
87
+ The default theme includes Tailwind-compatible values for:
88
+
89
+ - **colors** - Full color palette (slate, gray, zinc, red, orange, yellow, green, blue, indigo, purple, pink, etc.) with 50-950 shades in oklch
90
+ - **spacing** - 0 through 96, plus `px` (1px), fractional values
91
+ - **fontSize** - xs through 9xl with line-height pairs
92
+ - **fontFamily** - sans, serif, mono
93
+ - **screens** - sm (640px), md (768px), lg (1024px), xl (1280px), 2xl (1536px)
94
+ - **borderRadius** - none, sm, DEFAULT, md, lg, xl, 2xl, 3xl, full
95
+ - **boxShadow** - sm, DEFAULT, md, lg, xl, 2xl, inner, none
96
+
97
+ All theme values can be extended or overridden via `theme.extend`.
98
+
99
+ ## Utilities
100
+
101
+ ### Layout
102
+
103
+ | Utility | CSS |
104
+ |---------|-----|
105
+ | `block`, `inline-block`, `flex`, `grid`, `hidden` | `display: *` |
106
+ | `static`, `fixed`, `absolute`, `relative`, `sticky` | `position: *` |
107
+ | `top-*`, `right-*`, `bottom-*`, `left-*`, `inset-*` | Positioning |
108
+ | `z-*` | `z-index` |
109
+ | `overflow-*`, `overflow-x-*`, `overflow-y-*` | Overflow |
110
+ | `float-*`, `clear-*` | Float & clear (includes logical `start`/`end`) |
111
+ | `isolate`, `isolation-auto` | Isolation |
112
+ | `object-cover`, `object-contain`, `object-fill`, `object-none` | Object fit |
113
+ | `object-top`, `object-center`, `object-bottom`, etc. | Object position |
114
+ | `columns-*` | Multi-column layout |
115
+ | `break-before-*`, `break-after-*`, `break-inside-*` | Break behavior |
116
+ | `box-border`, `box-content` | Box sizing |
117
+ | `aspect-auto`, `aspect-square`, `aspect-video` | Aspect ratio |
118
+ | `visible`, `invisible`, `collapse` | Visibility |
119
+
120
+ ### Flexbox
121
+
122
+ | Utility | CSS |
123
+ |---------|-----|
124
+ | `flex-row`, `flex-col`, `flex-row-reverse`, `flex-col-reverse` | Direction |
125
+ | `flex-wrap`, `flex-nowrap`, `flex-wrap-reverse` | Wrap |
126
+ | `flex-1`, `flex-auto`, `flex-initial`, `flex-none` | Flex shorthand |
127
+ | `grow`, `grow-0`, `shrink`, `shrink-0` | Grow & shrink |
128
+ | `basis-*` | Flex basis (supports fractions: `basis-1/2`) |
129
+ | `justify-*`, `items-*`, `self-*` | Alignment |
130
+ | `justify-items-*`, `justify-self-*` | Justify items/self |
131
+ | `content-*` | Align content |
132
+ | `order-*`, `order-first`, `order-last`, `order-none` | Order |
133
+
134
+ ### Grid
135
+
136
+ | Utility | CSS |
137
+ |---------|-----|
138
+ | `grid-cols-*`, `grid-rows-*` | Template columns/rows (1-12, none, subgrid) |
139
+ | `col-span-*`, `col-start-*`, `col-end-*` | Column placement |
140
+ | `row-span-*`, `row-start-*`, `row-end-*` | Row placement |
141
+ | `grid-flow-row`, `grid-flow-col`, `grid-flow-dense` | Auto flow |
142
+ | `auto-cols-*`, `auto-rows-*` | Auto columns/rows |
143
+ | `gap-*`, `gap-x-*`, `gap-y-*` | Gap |
144
+ | `place-content-*`, `place-items-*`, `place-self-*` | Place shortcuts |
145
+
146
+ Arbitrary grid templates use underscore-to-space conversion:
151
147
 
152
- // Custom rules
153
- rules: [],
148
+ ```html
149
+ <div class="grid grid-cols-[120px_1fr_200px]">
150
+ <!-- grid-template-columns: 120px 1fr 200px -->
151
+ ```
154
152
 
155
- // Preflight CSS (normalize/reset styles)
156
- preflights: [],
153
+ ### Spacing
157
154
 
158
- // Presets
159
- presets: [],
160
- } satisfies CrosswindOptions
155
+ | Utility | CSS |
156
+ |---------|-----|
157
+ | `p-*`, `px-*`, `py-*`, `pt-*`, `pr-*`, `pb-*`, `pl-*` | Padding |
158
+ | `ps-*`, `pe-*` | Padding inline start/end (logical) |
159
+ | `m-*`, `mx-*`, `my-*`, `mt-*`, `mr-*`, `mb-*`, `ml-*` | Margin |
160
+ | `ms-*`, `me-*` | Margin inline start/end (logical) |
161
+ | `space-x-*`, `space-y-*` | Space between children |
161
162
 
162
- ```For more configuration options, see the [Configuration Guide](https://crosswind.stacksjs.org/config).
163
+ Negative values supported: `-m-4`, `-translate-x-1`.
163
164
 
164
- ## Available Utilities
165
+ ### Sizing
165
166
 
166
- Crosswind provides a comprehensive set of utility classes compatible with Tailwind CSS:
167
+ | Utility | CSS |
168
+ |---------|-----|
169
+ | `w-*`, `h-*` | Width & height |
170
+ | `size-*` | Width + height shorthand |
171
+ | `min-w-*`, `max-w-*`, `min-h-*`, `max-h-*` | Min/max sizing |
167
172
 
168
- -**Layout**: display, position, overflow, z-index, etc.
169
- -**Flexbox & Grid**: flex, grid, gap, align, justify, etc.
170
- -**Spacing**: margin, padding with full scale support
171
- -**Sizing**: width, height, min/max sizes
172
- -**Typography**: font family, size, weight, line height, text alignment, etc.
173
- -**Backgrounds**: colors, gradients, images, position, size
174
- -**Borders**: width, color, radius, style
175
- -**Effects**: shadow, opacity, blend modes, filters
176
- -**Transforms**: translate, rotate, scale, skew
177
- -**Transitions & Animations**: duration, timing, delay
178
- -**Interactivity**: cursor, pointer events, user select, scroll behavior
179
- -**Advanced**: mask utilities, backdrop filters, ring utilities
173
+ Values: spacing scale, `auto`, `full` (100%), `screen` (100vw/vh), `min`, `max`, `fit`, fractions (`w-1/2`).
180
174
 
181
- ### Variants
175
+ ### Colors
182
176
 
183
- -**Responsive**:`sm:`, `md:`, `lg:`, `xl:`, `2xl:`-**State**:`hover:`, `focus:`, `active:`, `disabled:`, `visited:`, `checked:`-**Pseudo-elements**:`before:`, `after:`, `placeholder:`, `selection:`-**Group/Peer**:`group-hover:`, `peer-focus:`-**Dark mode**:`dark:`-**Positional**:`first:`, `last:`, `odd:`, `even:`-**Important**:`!`prefix (e.g.,`!text-red-500`)
177
+ All color utilities support opacity modifiers:
184
178
 
185
- ### Arbitrary Values
179
+ ```html
180
+ <!-- Integer opacity (0-100 scale) -->
181
+ <div class="bg-blue-500/50"> <!-- 50% opacity -->
182
+ <div class="text-white/75"> <!-- 75% opacity -->
183
+ <div class="border-black/10"> <!-- 10% opacity -->
184
+
185
+ <!-- Arbitrary opacity (0-1 scale) -->
186
+ <div class="bg-white/[0.04]"> <!-- 4% opacity -->
187
+ <div class="text-black/[0.87]"> <!-- 87% opacity -->
188
+ ```
186
189
 
187
- Crosswind supports arbitrary values for maximum flexibility:
190
+ | Utility | CSS |
191
+ |---------|-----|
192
+ | `bg-*` | Background color |
193
+ | `text-*` | Text color |
194
+ | `border-*` | Border color |
195
+ | `ring-*` | Ring color |
196
+ | `divide-*` | Divide color (supports opacity: `divide-white/10`) |
197
+ | `placeholder-*` | Placeholder color |
198
+ | `accent-*` | Accent color |
199
+ | `caret-*` | Caret color |
200
+ | `fill-*`, `stroke-*` | SVG fill & stroke |
201
+
202
+ Special values: `current` (currentColor), `transparent`, `inherit`, `white`, `black`.
203
+
204
+ ### Typography
205
+
206
+ | Utility | CSS |
207
+ |---------|-----|
208
+ | `text-xs` through `text-9xl` | Font size |
209
+ | `font-thin` through `font-black` | Font weight |
210
+ | `font-sans`, `font-serif`, `font-mono` | Font family |
211
+ | `italic`, `not-italic` | Font style |
212
+ | `tracking-*` | Letter spacing |
213
+ | `leading-*` | Line height |
214
+ | `text-left`, `text-center`, `text-right`, `text-justify` | Alignment |
215
+ | `uppercase`, `lowercase`, `capitalize`, `normal-case` | Text transform |
216
+ | `underline`, `overline`, `line-through`, `no-underline` | Decoration |
217
+ | `decoration-*` | Decoration style, color, thickness |
218
+ | `truncate`, `text-ellipsis`, `text-clip` | Text overflow |
219
+ | `text-wrap`, `text-nowrap`, `text-balance`, `text-pretty` | Text wrap |
220
+ | `line-clamp-*` | Line clamp |
221
+ | `indent-*` | Text indent |
222
+ | `antialiased`, `subpixel-antialiased` | Font smoothing |
223
+ | `tabular-nums`, `lining-nums`, `oldstyle-nums`, etc. | Font variant numeric |
224
+ | `hyphens-none`, `hyphens-manual`, `hyphens-auto` | Hyphens |
225
+ | `whitespace-*` | White space |
226
+ | `break-normal`, `break-words`, `break-all` | Word break |
227
+
228
+ ### Borders
229
+
230
+ | Utility | CSS |
231
+ |---------|-----|
232
+ | `border`, `border-0`, `border-2`, `border-4`, `border-8` | Border width |
233
+ | `border-t`, `border-r`, `border-b`, `border-l` | Side borders |
234
+ | `border-s`, `border-e` | Logical side borders (inline-start/end) |
235
+ | `border-x`, `border-y` | Axis borders |
236
+ | `border-solid`, `border-dashed`, `border-dotted`, `border-double`, `border-none` | Style |
237
+ | `rounded-*` | Border radius |
238
+ | `rounded-s-*`, `rounded-e-*` | Logical border radius |
239
+ | `rounded-ss-*`, `rounded-se-*`, `rounded-es-*`, `rounded-ee-*` | Corner-specific logical radius |
240
+ | `outline-*` | Outline width, style, color |
241
+ | `outline-offset-*` | Outline offset |
242
+ | `ring-*`, `ring-offset-*` | Ring |
243
+ | `divide-x`, `divide-y` | Divide width |
244
+ | `divide-*` | Divide color, style, opacity |
245
+
246
+ ### Effects & Filters
247
+
248
+ | Utility | CSS |
249
+ |---------|-----|
250
+ | `shadow-*` | Box shadow |
251
+ | `shadow-{color}` | Shadow color |
252
+ | `opacity-*` | Opacity (0-100) |
253
+ | `mix-blend-*` | Mix blend mode |
254
+ | `bg-blend-*` | Background blend mode |
255
+ | `blur-*`, `brightness-*`, `contrast-*`, `grayscale-*` | Filters |
256
+ | `invert-*`, `saturate-*`, `sepia-*`, `hue-rotate-*` | Filters |
257
+ | `drop-shadow-*` | Drop shadow filter |
258
+ | `backdrop-blur-*`, `backdrop-brightness-*`, etc. | Backdrop filters |
259
+
260
+ ### Backgrounds & Gradients
261
+
262
+ | Utility | CSS |
263
+ |---------|-----|
264
+ | `bg-fixed`, `bg-local`, `bg-scroll` | Background attachment |
265
+ | `bg-clip-border`, `bg-clip-padding`, `bg-clip-content`, `bg-clip-text` | Background clip |
266
+ | `bg-top`, `bg-center`, `bg-bottom`, etc. | Background position |
267
+ | `bg-repeat`, `bg-no-repeat`, `bg-repeat-x`, `bg-repeat-y` | Background repeat |
268
+ | `bg-auto`, `bg-cover`, `bg-contain` | Background size |
269
+
270
+ **Linear gradients:**
188
271
 
189
272
  ```html
273
+ <div class="bg-gradient-to-r from-blue-500 via-purple-500 to-pink-500">
274
+ ```
190
275
 
191
- <div class="w-[500px] h-[calc(100vh-4rem)] bg-[#1da1f2] text-[clamp(1rem,5vw,3rem)]">
192
- Custom values!
193
- </div>
276
+ Directions: `bg-gradient-to-{t,tr,r,br,b,bl,l,tl}`.
194
277
 
195
- ```### Compile Class (HTML Optimization)
278
+ **Radial gradients:**
196
279
 
197
- Optimize your HTML by compiling utility groups into single class names:```html
198
- <!-- Before -->
199
- <div class=":hw: flex items-center justify-between px-4 py-2 bg-white rounded-lg shadow-md">
200
- Content
201
- </div>
280
+ ```html
281
+ <div class="bg-radial from-white to-blue-500">
282
+ <div class="bg-radial-at-t from-yellow-200 to-orange-500">
283
+ ```
202
284
 
203
- <!-- After build -->
204
- <div class="hw-2k9d3a">
205
- Content
206
- </div>
207
- ```This reduces HTML file size by up to 60%. Learn more in the [Compile Class documentation](https://crosswind.stacksjs.org/features/compile-class).
285
+ Positions: `bg-radial-at-{t,tr,r,br,b,bl,l,tl,c}`.
208
286
 
209
- ## Testing
287
+ **Conic gradients:**
210
288
 
211
- Crosswind includes a comprehensive test suite with 1300+ tests:```bash
289
+ ```html
290
+ <div class="bg-conic from-red-500 via-yellow-500 to-green-500">
291
+ <div class="bg-conic-from-r from-blue-500 to-purple-500">
292
+ ```
212
293
 
213
- # Run all tests
294
+ Starting angles: `bg-conic-from-{t,tr,r,br,b,bl,l,tl}`.
295
+
296
+ ### Transforms & Transitions
297
+
298
+ | Utility | CSS |
299
+ |---------|-----|
300
+ | `scale-*`, `scale-x-*`, `scale-y-*` | Scale |
301
+ | `rotate-*` | Rotate |
302
+ | `translate-x-*`, `translate-y-*` | Translate |
303
+ | `skew-x-*`, `skew-y-*` | Skew |
304
+ | `origin-*` | Transform origin |
305
+ | `transition`, `transition-all`, `transition-colors`, `transition-opacity`, `transition-shadow`, `transition-transform` | Transition property |
306
+ | `duration-*` | Transition duration |
307
+ | `ease-linear`, `ease-in`, `ease-out`, `ease-in-out` | Timing function |
308
+ | `delay-*` | Transition delay |
309
+ | `animate-spin`, `animate-ping`, `animate-pulse`, `animate-bounce`, `animate-none` | Animation |
310
+ | `perspective-*` | 3D perspective |
311
+ | `backface-visible`, `backface-hidden` | Backface visibility |
312
+
313
+ ### Interactivity
314
+
315
+ | Utility | CSS |
316
+ |---------|-----|
317
+ | `cursor-*` | Cursor style |
318
+ | `pointer-events-none`, `pointer-events-auto` | Pointer events |
319
+ | `resize`, `resize-x`, `resize-y`, `resize-none` | Resize |
320
+ | `select-none`, `select-text`, `select-all`, `select-auto` | User select |
321
+ | `scroll-auto`, `scroll-smooth` | Scroll behavior |
322
+ | `scroll-m-*`, `scroll-p-*` | Scroll margin/padding |
323
+ | `snap-x`, `snap-y`, `snap-both`, `snap-mandatory`, `snap-proximity` | Scroll snap |
324
+ | `snap-start`, `snap-end`, `snap-center`, `snap-align-none` | Snap align |
325
+ | `touch-auto`, `touch-none`, `touch-manipulation`, `touch-pan-*` | Touch action |
326
+ | `will-change-auto`, `will-change-scroll`, `will-change-contents`, `will-change-transform` | Will change |
327
+ | `appearance-none`, `appearance-auto` | Appearance |
328
+ | `scrollbar-auto`, `scrollbar-thin`, `scrollbar-none` | Scrollbar width |
329
+
330
+ ### Content
214
331
 
215
- bun test
332
+ ```html
333
+ <div class="before:content-['*'] before:text-red-500">Required</div>
334
+ <div class="before:content-empty before:block before:h-4"></div>
335
+ <div class="after:content-[attr(data-count)]"></div>
336
+ ```
216
337
 
217
- # Run specific test files
338
+ | Utility | CSS |
339
+ |---------|-----|
340
+ | `content-none` | `content: none` |
341
+ | `content-empty` | `content: ""` |
342
+ | `content-['text']` | `content: 'text'` |
343
+ | `content-[attr(data-*)]` | `content: attr(data-*)` |
218
344
 
219
- bun test test/performance.test.ts
345
+ ### SVG
220
346
 
221
- # Run tests in watch mode
347
+ | Utility | CSS |
348
+ |---------|-----|
349
+ | `fill-none`, `fill-current`, `fill-{color}` | Fill |
350
+ | `stroke-none`, `stroke-current`, `stroke-{color}` | Stroke color |
351
+ | `stroke-0`, `stroke-1`, `stroke-2` | Stroke width |
222
352
 
223
- bun test --watch
353
+ ### Tables
224
354
 
225
- ```### Test Coverage
355
+ | Utility | CSS |
356
+ |---------|-----|
357
+ | `border-collapse`, `border-separate` | Border collapse |
358
+ | `border-spacing-*` | Border spacing |
359
+ | `table-auto`, `table-fixed` | Table layout |
360
+ | `caption-top`, `caption-bottom` | Caption side |
226
361
 
227
- -**Core Functionality**: Parser, generator, scanner, builder
228
- -**Utilities**: Layout, typography, colors, spacing, grid, flexbox
229
- -**Variants**: Responsive, state, pseudo-elements, combinations
230
- -**Advanced Features**: Shortcuts, custom rules, arbitrary values
231
- -**Performance**: Benchmarks for generation speed and memory efficiency
232
- -**Edge Cases**: Invalid inputs, complex nesting, duplicate handling
362
+ ## Variants
233
363
 
234
- ## Performance
364
+ ### Pseudo-class Variants
235
365
 
236
- Crosswind is designed for speed. We've benchmarked against other popular utility-first CSS frameworks to demonstrate our performance advantages.
366
+ ```html
367
+ <div class="hover:bg-blue-600 focus:ring-2 active:scale-95">
368
+ <div class="first:mt-0 last:mb-0 odd:bg-gray-50 even:bg-white">
369
+ <div class="disabled:opacity-50 checked:bg-blue-500 required:border-red-500">
370
+ <div class="focus-within:ring-2 focus-visible:outline-2">
371
+ <div class="visited:text-purple-600 target:ring-2">
372
+ <div class="open:rotate-180 empty:hidden">
373
+ <div class="valid:border-green-500 invalid:border-red-500 read-only:opacity-75">
374
+ <div class="autofill:bg-yellow-50 indeterminate:bg-gray-300">
375
+ ```
237
376
 
238
- ### Benchmark Results
377
+ ### Negation Variants
239
378
 
240
- Our comprehensive benchmark suite (20 tests) compares Crosswind with UnoCSS, Tailwind CSS v3, and Tailwind CSS v4.
379
+ ```html
380
+ <div class="not-first:mt-4 not-last:mb-4">
381
+ <div class="not-disabled:cursor-pointer not-empty:block">
382
+ <div class="not-checked:bg-gray-100 not-only:border-b">
383
+ <div class="not-first-of-type:pt-4 not-last-of-type:pb-4">
384
+ ```
241
385
 
242
- | Scenario | Crosswind | UnoCSS | Tailwind v3 | Tailwind v4 | Winner |
243
- |----------|----------|--------|-------------|-------------|--------|
244
- |**Simple Utilities**(10 classes) |**2.75µs**| 31.58µs | 14.32ms | 46.47ms | Crosswind ⚡ |
245
- |**Complex Utilities**(11 classes) |**8.61µs**| 43.77µs | 14.25ms | 39.26ms | Crosswind ⚡ |
246
- |**Arbitrary Values**(10 classes) |**41.71µs**| 64.44µs | 15.52ms | - | Crosswind ⚡ |
247
- |**Real-world Components**(~60 classes) |**25.26µs**| 97.71µs | 16.12ms | 45.07ms | Crosswind ⚡ |
248
- |**Large Scale**(500 classes) |**94.89µs**| 201.30µs | 14.51ms | 40.06ms | Crosswind ⚡ |
249
- |**CSS Output**(1000 values) |**1.50ms**| 115.59ms | 16.03ms | - | Crosswind ⚡ |
250
- |**Color Utilities**(330 classes) |**100.85µs**| 526.82µs | 12.89ms | 37.27ms | Crosswind ⚡ |
251
- |**Responsive**(500 classes) |**100.16µs**| 211.39µs | 12.86ms | 41.07ms | Crosswind ⚡ |
252
- |**Interactive States**(440 classes) |**260.75µs**| 1.16ms | 13.84ms | 38.06ms | Crosswind ⚡ |
253
- |**Duplicate Handling**(6000 items) |**43.19µs**| 1.81ms | 18.47ms | 48.11ms | Crosswind ⚡ |
254
- |**Typography**(50 classes) |**16.06µs**| 94.37µs | 14.37ms | 39.33ms | Crosswind ⚡ |
255
- |**Flexbox**(50 classes) |**13.77µs**| 88.62µs | 13.04ms | 42.38ms | Crosswind ⚡ |
256
- |**Grid**(55 classes) |**59.89µs**| 118.31µs | 15.10ms | 39.00ms | Crosswind ⚡ |
257
- |**Stacked Variants**(40 classes) |**73.43µs**| 148.79µs | 15.65ms | 41.11ms | Crosswind ⚡ |
258
- |**Transforms**(55 classes) |**78.39µs**| 100.85µs | 13.76ms | 44.34ms | Crosswind ⚡ |
259
- |**Transitions**(30 classes) |**12.96µs**| 66.47µs | 14.38ms | 36.46ms | Crosswind ⚡ |
260
- |**Border & Ring**(45 classes) |**12.55µs**| 90.45µs | 10.52ms | 40.58ms | Crosswind ⚡ |
261
- |**Shadow & Effects**(35 classes) |**6.92µs**| 62.12µs | 10.89ms | 36.62ms | Crosswind ⚡ |
262
- |**Incremental Generation**(200 classes) |**73.91µs**| 196.35µs | 14.07ms | 35.58ms | Crosswind ⚡ |
263
- |**Full Project**(~800 classes) |**649.87µs**| 1.38ms | 14.41ms | - | Crosswind ⚡ |
386
+ ### Pseudo-element Variants
264
387
 
265
- ### Highlights
388
+ ```html
389
+ <div class="before:content-[''] before:block before:h-4">
390
+ <div class="after:content-['*'] after:text-red-500">
391
+ <li class="marker:text-blue-500">Item</li>
392
+ <input class="placeholder:text-gray-400">
393
+ <p class="selection:bg-blue-200">Selectable text</p>
394
+ <input class="file:bg-blue-50 file:border-0" type="file">
395
+ ```
266
396
 
267
- -**Crosswind wins 20/20 benchmarks**vs all competitors
268
- -**Simple utilities**: 11x faster than UnoCSS, 5,200x faster than Tailwind v3
269
- -**Typography**: 6x faster than UnoCSS
270
- -**Flexbox**: 6.4x faster than UnoCSS
271
- -**Shadow & Effects**: 9x faster than UnoCSS
272
- -**Border & Ring**: 7x faster than UnoCSS
273
- -**Color utilities**: 5x faster than UnoCSS
274
- -**Interactive states**: 4.5x faster than UnoCSS
275
- -**Duplicate handling**: 42x faster than UnoCSS
276
- -**CSS output generation**: 77x faster than UnoCSS
277
- -**Full project simulation**: 2.1x faster than UnoCSS, 22x faster than Tailwind v3
397
+ ### Responsive Variants
278
398
 
279
- ### Running Benchmarks
399
+ ```html
400
+ <div class="p-4 sm:p-6 md:p-8 lg:p-12 xl:p-16 2xl:p-20">
401
+ ```
280
402
 
281
- You can run the benchmarks yourself to see the performance on your hardware:```bash
403
+ | Variant | Breakpoint |
404
+ |---------|-----------|
405
+ | `sm:` | 640px |
406
+ | `md:` | 768px |
407
+ | `lg:` | 1024px |
408
+ | `xl:` | 1280px |
409
+ | `2xl:` | 1536px |
282
410
 
283
- # Run the comprehensive benchmark suite
411
+ ### Dark & Light Mode
284
412
 
285
- bun run benchmark
413
+ ```html
414
+ <div class="bg-white dark:bg-gray-900 light:bg-gray-50">
415
+ <div class="text-gray-900 dark:text-white">
416
+ ```
286
417
 
287
- # Or run from the packages/crosswind directory
418
+ Uses class-based strategy (`.dark`/`.light` parent class).
288
419
 
289
- cd packages/crosswind
290
- bun run benchmark
291
- ```All benchmarks use [Mitata](https://github.com/evanwashere/mitata) for accurate measurements and run on Bun runtime. Results may vary based on your hardware.
420
+ ### Group & Peer Variants
292
421
 
293
- ## Development
422
+ ```html
423
+ <!-- Group: parent state affects children -->
424
+ <div class="group">
425
+ <p class="group-hover:text-blue-500">Hovering parent</p>
426
+ <p class="group-focus:ring-2">Parent focused</p>
427
+ <p class="group-has-[:checked]:bg-blue-50">Parent has checked input</p>
428
+ </div>
294
429
 
295
- To contribute to Crosswind development:```bash
430
+ <!-- Named groups (for nesting) -->
431
+ <div class="group/card">
432
+ <div class="group/button">
433
+ <span class="group-hover/card:text-blue-500">Card hovered</span>
434
+ </div>
435
+ </div>
296
436
 
297
- # Clone the repository
437
+ <!-- Peer: sibling state affects element -->
438
+ <input class="peer" />
439
+ <p class="peer-invalid:text-red-500">Error message</p>
440
+ <p class="peer-has-[:checked]:text-green-500">Checked sibling</p>
441
+ ```
298
442
 
299
- git clone <https://github.com/cwcss/crosswind.git>
300
- cd crosswind
443
+ ### has: Variant
301
444
 
302
- # Install dependencies
445
+ ```html
446
+ <div class="has-[:focus]:ring-2"> <!-- :has(:focus) -->
447
+ <div class="has-[input:checked]:bg-blue-50"> <!-- :has(input:checked) -->
448
+ <div class="has-[>img]:p-4"> <!-- :has(>img) -->
449
+ ```
303
450
 
304
- bun install
451
+ ### aria-* Variants
305
452
 
306
- # Run tests
453
+ ```html
454
+ <div class="aria-disabled:opacity-50"> <!-- [aria-disabled="true"] -->
455
+ <div class="aria-expanded:rotate-180"> <!-- [aria-expanded="true"] -->
456
+ <div class="aria-[sort=ascending]:text-blue-500"> <!-- [aria-sort=ascending] -->
457
+ ```
307
458
 
308
- bun test
459
+ ### data-* Variants
309
460
 
310
- # Run tests in watch mode
461
+ ```html
462
+ <div class="data-loading:opacity-50"> <!-- [data-loading] -->
463
+ <div class="data-[state=active]:bg-white"> <!-- [data-state=active] -->
464
+ <div class="data-[theme=dark]:bg-black"> <!-- [data-theme=dark] -->
465
+ ```
311
466
 
312
- bun test --watch
467
+ ### Media Query Variants
313
468
 
314
- # Run performance benchmarks
469
+ ```html
470
+ <div class="landscape:flex-row portrait:flex-col">
471
+ <div class="motion-safe:animate-bounce motion-reduce:animate-none">
472
+ <div class="contrast-more:border-2 contrast-less:border-0">
473
+ <div class="forced-colors:border print:hidden">
474
+ ```
315
475
 
316
- bun test test/performance.test.ts
476
+ Media variants stack with responsive variants:
317
477
 
318
- # Type check
478
+ ```html
479
+ <div class="lg:landscape:flex-row">
480
+ <!-- @media (min-width: 1024px) and (orientation: landscape) -->
481
+ ```
319
482
 
320
- bun run typecheck
483
+ ### @supports Variant
321
484
 
322
- # Build the package
485
+ ```html
486
+ <div class="supports-[display:grid]:grid">
487
+ <div class="supports-[backdrop-filter:blur(0)]:backdrop-blur-sm">
488
+ ```
323
489
 
324
- bun run build
490
+ ### Container Queries
325
491
 
492
+ ```html
493
+ <div class="@container">
494
+ <div class="@sm:flex @md:grid @lg:grid-cols-3">
495
+ </div>
326
496
  ```
327
497
 
328
- ## Documentation
498
+ ### Direction Variants
329
499
 
330
- For comprehensive documentation, visit [crosswind.stacksjs.org](https://crosswind.stacksjs.org)
500
+ ```html
501
+ <div class="rtl:text-right ltr:text-left">
502
+ ```
331
503
 
332
- - [Installation Guide](https://crosswind.stacksjs.org/install)
333
- - [Usage Guide](https://crosswind.stacksjs.org/usage)
334
- - [Configuration](https://crosswind.stacksjs.org/config)
335
- - [CLI Reference](https://crosswind.stacksjs.org/features/cli)
336
- - [API Reference](https://crosswind.stacksjs.org/api-reference)
504
+ ## Arbitrary Values
337
505
 
338
- ## Changelog
506
+ Use brackets for any CSS value:
339
507
 
340
- Please see our [releases](https://github.com/cwcss/crosswind/releases) page for more information on what has changed recently.
508
+ ```html
509
+ <div class="w-[350px] h-[calc(100vh-4rem)] p-[clamp(1rem,3vw,2rem)]">
510
+ <div class="text-[#1a1a1a] bg-[rgb(255,0,0)] border-[oklch(50%_0.2_240)]">
511
+ <div class="grid-cols-[120px_1fr_200px]"> <!-- underscores become spaces -->
512
+ <div class="text-[clamp(1rem,3vw,2rem)]">
513
+ <div class="font-[600]">
514
+ <div class="tracking-[0.2em]">
515
+ <div class="leading-[1.7]">
516
+ ```
341
517
 
342
- ## Contributing
518
+ ### Arbitrary Properties
343
519
 
344
- Please see [CONTRIBUTING](.github/CONTRIBUTING.md) for details.
520
+ ```html
521
+ <div class="[mask-type:luminance]">
522
+ <div class="[text-wrap:balance]">
523
+ ```
345
524
 
346
- We welcome contributions! Whether it's:
525
+ ### Type Hints
347
526
 
348
- - 🐛 Bug reports and fixes
349
- - ✨ New utility classes or features
350
- - 📝 Documentation improvements
351
- - ⚡️ Performance optimizations
352
- - 🧪 Additional test coverage
527
+ ```html
528
+ <div class="text-[color:var(--brand)]">
529
+ <div class="text-[length:var(--size)]">
530
+ ```
353
531
 
354
- ## Community
532
+ ## Important Modifier
355
533
 
356
- For help, discussion about best practices, or any other conversation that would benefit from being searchable:
534
+ Prefix with `!` to apply `!important`:
357
535
 
358
- [Discussions on GitHub](https://github.com/cwcss/crosswind/discussions)
536
+ ```html
537
+ <div class="!p-4 !text-red-500">
538
+ ```
359
539
 
360
- For casual chit-chat with others using this package:
540
+ ## Presets
361
541
 
362
- [Join the Stacks Discord Server](https://discord.gg/stacksjs)
542
+ ```typescript
543
+ import type { Preset } from '@cwcss/crosswind'
363
544
 
364
- ## Postcardware
545
+ const myPreset: Preset = {
546
+ name: 'my-preset',
547
+ theme: {
548
+ extend: {
549
+ colors: {
550
+ brand: '#3b82f6',
551
+ },
552
+ },
553
+ },
554
+ shortcuts: {
555
+ btn: 'px-4 py-2 rounded font-semibold',
556
+ },
557
+ }
365
558
 
366
- “Software that is free, but hopes for a postcard.” We love receiving postcards from around the world showing where Stacks is being used! We showcase them on our website too.
559
+ export default {
560
+ presets: [myPreset],
561
+ }
562
+ ```
367
563
 
368
- Our address: Stacks.js, 12665 Village Ln #2306, Playa Vista, CA 90094, United States 🌎
564
+ ## Shortcuts
369
565
 
370
- ## Sponsors
566
+ Define reusable class combinations:
371
567
 
372
- We would like to extend our thanks to the following sponsors for funding Stacks development. If you are interested in becoming a sponsor, please reach out to us.
568
+ ```typescript
569
+ export default {
570
+ shortcuts: {
571
+ 'btn': 'px-4 py-2 rounded-lg font-semibold transition-colors',
572
+ 'btn-primary': 'btn bg-blue-500 text-white hover:bg-blue-600',
573
+ 'card': 'rounded-xl border border-gray-200 p-6 shadow-sm',
574
+ },
575
+ }
576
+ ```
373
577
 
374
- - [JetBrains](https://www.jetbrains.com/)
375
- - [The Solana Foundation](https://solana.com/)
578
+ ## Performance
376
579
 
377
- ## License
580
+ Crosswind uses several optimizations for fast CSS generation:
378
581
 
379
- The MIT License (MIT). Please see [LICENSE](LICENSE.md) for more information.
582
+ - **O(1) static utility map** for ~80% of common utilities (display, flex, grid, transitions, etc.)
583
+ - **Pre-computed color map** with flat cache for instant color lookups
584
+ - **Class-level caching** prevents duplicate generation
585
+ - **Selector caching** avoids rebuilding selectors with variants
586
+ - **Media query caching** for responsive and feature variants
587
+ - **Negative match cache** to skip known-unmatched utilities
380
588
 
381
- Made with 💙
589
+ Benchmarks (1000 utilities):
590
+ - Simple utilities: ~0.7ms
591
+ - Complex utilities: ~4.5ms
592
+ - Arbitrary values: ~0.6ms
382
593
 
383
- <!-- Badges -->
384
- [npm-version-src]: <https://img.shields.io/npm/v/crosswind?style=flat-square>
385
- [npm-version-href]: <https://npmjs.com/package/crosswind>
386
- [github-actions-src]: <https://img.shields.io/github/actions/workflow/status/cwcss/crosswind/ci.yml?style=flat-square&branch=main>
387
- [github-actions-href]: <https://github.com/cwcss/crosswind/actions?query=workflow%3Aci>
594
+ ## License
388
595
 
389
- <!-- [codecov-src]: <https://img.shields.io/codecov/c/gh/cwcss/crosswind/main?style=flat-square>
390
- [codecov-href]: <https://codecov.io/gh/cwcss/crosswind> -->
596
+ MIT