@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/bin/cli.ts
DELETED
|
@@ -1,365 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bun
|
|
2
|
-
import type { CrosswindConfig } from '../src/types'
|
|
3
|
-
import { existsSync, watch } from 'node:fs'
|
|
4
|
-
import { unlink } from 'node:fs/promises'
|
|
5
|
-
import process from 'node:process'
|
|
6
|
-
import { CLI } from '@stacksjs/clapp'
|
|
7
|
-
import { version } from '../package.json'
|
|
8
|
-
import { build, buildAndWrite } from '../src/build'
|
|
9
|
-
import { config } from '../src/config'
|
|
10
|
-
import { tailwindPreflight } from '../src/preflight'
|
|
11
|
-
|
|
12
|
-
const cli = new CLI('crosswind')
|
|
13
|
-
|
|
14
|
-
interface GlobalOptions {
|
|
15
|
-
verbose?: boolean
|
|
16
|
-
config?: string
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
interface BuildOptions extends GlobalOptions {
|
|
20
|
-
output?: string
|
|
21
|
-
minify?: boolean
|
|
22
|
-
watch?: boolean
|
|
23
|
-
content?: string
|
|
24
|
-
noPreflight?: boolean
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
interface InitOptions {
|
|
28
|
-
force?: boolean
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
interface AnalyzeOptions extends GlobalOptions {
|
|
32
|
-
json?: boolean
|
|
33
|
-
top?: number
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Load custom config if specified
|
|
38
|
-
*/
|
|
39
|
-
async function loadCustomConfig(configPath?: string): Promise<CrosswindConfig> {
|
|
40
|
-
if (configPath) {
|
|
41
|
-
if (!existsSync(configPath)) {
|
|
42
|
-
console.error(`❌ Config file not found: ${configPath}`)
|
|
43
|
-
process.exit(1)
|
|
44
|
-
}
|
|
45
|
-
try {
|
|
46
|
-
const customConfig = await import(configPath)
|
|
47
|
-
return { ...config, ...(customConfig.default || customConfig) }
|
|
48
|
-
}
|
|
49
|
-
catch (error) {
|
|
50
|
-
console.error(`❌ Failed to load config file: ${configPath}`)
|
|
51
|
-
console.error(error)
|
|
52
|
-
process.exit(1)
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
return config
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Merge CLI options with config
|
|
60
|
-
*/
|
|
61
|
-
function mergeConfig(baseConfig: CrosswindConfig, options: BuildOptions): CrosswindConfig {
|
|
62
|
-
return {
|
|
63
|
-
...baseConfig,
|
|
64
|
-
output: options.output || baseConfig.output,
|
|
65
|
-
minify: options.minify ?? baseConfig.minify,
|
|
66
|
-
content: options.content ? [options.content] : baseConfig.content,
|
|
67
|
-
verbose: options.verbose ?? baseConfig.verbose,
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Run the build process
|
|
73
|
-
*/
|
|
74
|
-
async function runBuild(buildConfig: CrosswindConfig, options: BuildOptions): Promise<void> {
|
|
75
|
-
try {
|
|
76
|
-
const startMsg = options.verbose ? '🚀 Building CSS (verbose mode)...' : '🚀 Building CSS...'
|
|
77
|
-
console.log(startMsg)
|
|
78
|
-
|
|
79
|
-
if (options.verbose) {
|
|
80
|
-
console.log(`📂 Content patterns: ${buildConfig.content.join(', ')}`)
|
|
81
|
-
console.log(`📝 Output: ${buildConfig.output}`)
|
|
82
|
-
console.log(`🗜️ Minify: ${buildConfig.minify ? 'Yes' : 'No'}`)
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const result = await buildAndWrite(buildConfig)
|
|
86
|
-
|
|
87
|
-
console.log(`✅ Built ${result.classes.size} classes in ${result.duration.toFixed(2)}ms`)
|
|
88
|
-
console.log(`📝 Output: ${buildConfig.output}`)
|
|
89
|
-
|
|
90
|
-
// Show compile class stats if enabled
|
|
91
|
-
if (result.compiledClasses && result.compiledClasses.size > 0) {
|
|
92
|
-
console.log(`🔨 Compiled ${result.compiledClasses.size} class groups`)
|
|
93
|
-
if (result.transformedFiles) {
|
|
94
|
-
console.log(`📝 Transformed ${result.transformedFiles.size} files`)
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
if (options.verbose) {
|
|
98
|
-
console.log(`\n📦 Compiled classes:`)
|
|
99
|
-
for (const [, { className, utilities }] of result.compiledClasses) {
|
|
100
|
-
console.log(` ${className} ← ${utilities.join(' ')}`)
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
if (options.verbose && result.classes.size > 0) {
|
|
106
|
-
const classesArray = Array.from(result.classes).sort()
|
|
107
|
-
console.log(`\n📋 Classes found (${result.classes.size}):`)
|
|
108
|
-
classesArray.forEach(cls => console.log(` - ${cls}`))
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// Show size info
|
|
112
|
-
if (existsSync(buildConfig.output)) {
|
|
113
|
-
const file = Bun.file(buildConfig.output)
|
|
114
|
-
const sizeKB = (file.size / 1024).toFixed(2)
|
|
115
|
-
console.log(`📦 File size: ${sizeKB} KB`)
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
catch (error) {
|
|
119
|
-
console.error('❌ Build failed:', error)
|
|
120
|
-
if (options.verbose && error instanceof Error) {
|
|
121
|
-
console.error(error.stack)
|
|
122
|
-
}
|
|
123
|
-
process.exit(1)
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Setup file watching
|
|
129
|
-
*/
|
|
130
|
-
function setupWatch(buildConfig: CrosswindConfig, options: BuildOptions): void {
|
|
131
|
-
console.log('👀 Watching for changes...')
|
|
132
|
-
|
|
133
|
-
// Watch content directories
|
|
134
|
-
const watchDirs = new Set<string>()
|
|
135
|
-
for (const pattern of buildConfig.content) {
|
|
136
|
-
const dir = pattern.split('**')[0] || '.'
|
|
137
|
-
watchDirs.add(dir)
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
for (const dir of watchDirs) {
|
|
141
|
-
watch(dir, { recursive: true }, async (eventType, filename) => {
|
|
142
|
-
if (filename && /\.(?:html|js|ts|jsx|tsx|stx)$/.test(filename)) {
|
|
143
|
-
console.log(`\n📝 ${filename} changed, rebuilding...`)
|
|
144
|
-
await runBuild(buildConfig, options)
|
|
145
|
-
}
|
|
146
|
-
})
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
console.log(`\n👀 Watching: ${Array.from(watchDirs).join(', ')}`)
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// Build command
|
|
153
|
-
cli
|
|
154
|
-
.command('build', 'Build CSS from content files')
|
|
155
|
-
.option('--output <path>', 'Output CSS file path')
|
|
156
|
-
.option('--minify', 'Minify CSS output')
|
|
157
|
-
.option('--watch', 'Watch for file changes')
|
|
158
|
-
.option('--content <pattern>', 'Content file pattern (can override config)')
|
|
159
|
-
.option('--config <path>', 'Path to config file')
|
|
160
|
-
.option('--verbose', 'Show detailed output')
|
|
161
|
-
.option('--no-preflight', 'Skip preflight CSS')
|
|
162
|
-
.example('crosswind build')
|
|
163
|
-
.example('crosswind build --output ./dist/styles.css')
|
|
164
|
-
.example('crosswind build --minify --watch')
|
|
165
|
-
.example('crosswind build --verbose')
|
|
166
|
-
.example('crosswind build --config ./custom.config.ts')
|
|
167
|
-
.action(async (options: BuildOptions) => {
|
|
168
|
-
const baseConfig = await loadCustomConfig(options.config)
|
|
169
|
-
const buildConfig = mergeConfig(baseConfig, options)
|
|
170
|
-
|
|
171
|
-
await runBuild(buildConfig, options)
|
|
172
|
-
|
|
173
|
-
if (options.watch) {
|
|
174
|
-
setupWatch(buildConfig, options)
|
|
175
|
-
}
|
|
176
|
-
})
|
|
177
|
-
|
|
178
|
-
// Watch command (alias for build --watch)
|
|
179
|
-
cli
|
|
180
|
-
.command('watch', 'Build and watch for changes')
|
|
181
|
-
.option('--output <path>', 'Output CSS file path')
|
|
182
|
-
.option('--minify', 'Minify CSS output')
|
|
183
|
-
.option('--content <pattern>', 'Content file pattern')
|
|
184
|
-
.option('--config <path>', 'Path to config file')
|
|
185
|
-
.option('--verbose', 'Show detailed output')
|
|
186
|
-
.example('crosswind watch')
|
|
187
|
-
.example('crosswind watch --output ./dist/styles.css')
|
|
188
|
-
.example('crosswind watch --verbose')
|
|
189
|
-
.action(async (options: BuildOptions) => {
|
|
190
|
-
const baseConfig = await loadCustomConfig(options.config)
|
|
191
|
-
const buildConfig = mergeConfig(baseConfig, options)
|
|
192
|
-
|
|
193
|
-
await runBuild(buildConfig, options)
|
|
194
|
-
setupWatch(buildConfig, options)
|
|
195
|
-
})
|
|
196
|
-
|
|
197
|
-
// Init command - Create a config file
|
|
198
|
-
cli
|
|
199
|
-
.command('init', 'Create a crosswind.config.ts file')
|
|
200
|
-
.option('--force', 'Overwrite existing config file')
|
|
201
|
-
.example('crosswind init')
|
|
202
|
-
.example('crosswind init --force')
|
|
203
|
-
.action(async (options: InitOptions) => {
|
|
204
|
-
const configPath = './crosswind.config.ts'
|
|
205
|
-
|
|
206
|
-
if (existsSync(configPath) && !options.force) {
|
|
207
|
-
console.error('❌ Config file already exists. Use --force to overwrite.')
|
|
208
|
-
process.exit(1)
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
const defaultConfig = `import type { CrosswindOptions } from '@cwcss/crosswind'
|
|
212
|
-
|
|
213
|
-
const config = {
|
|
214
|
-
content: ['./src/**/*.{html,js,ts,jsx,tsx}'],
|
|
215
|
-
output: './dist/crosswind.css',
|
|
216
|
-
minify: false,
|
|
217
|
-
watch: false,
|
|
218
|
-
} satisfies CrosswindOptions
|
|
219
|
-
|
|
220
|
-
export default config
|
|
221
|
-
`
|
|
222
|
-
|
|
223
|
-
try {
|
|
224
|
-
await Bun.write(configPath, defaultConfig)
|
|
225
|
-
console.log('✅ Created crosswind.config.ts')
|
|
226
|
-
console.log('\nNext steps:')
|
|
227
|
-
console.log(' 1. Update the content paths in crosswind.config.ts')
|
|
228
|
-
console.log(' 2. Run: crosswind build')
|
|
229
|
-
}
|
|
230
|
-
catch (error) {
|
|
231
|
-
console.error('❌ Failed to create config file:', error)
|
|
232
|
-
process.exit(1)
|
|
233
|
-
}
|
|
234
|
-
})
|
|
235
|
-
|
|
236
|
-
// Analyze command - Show statistics
|
|
237
|
-
cli
|
|
238
|
-
.command('analyze', 'Analyze utility class usage')
|
|
239
|
-
.option('--config <path>', 'Path to config file')
|
|
240
|
-
.option('--verbose', 'Show detailed output')
|
|
241
|
-
.option('--json', 'Output as JSON')
|
|
242
|
-
.option('--top <n>', 'Show top N most used classes', { default: 10 })
|
|
243
|
-
.example('crosswind analyze')
|
|
244
|
-
.example('crosswind analyze --top 20')
|
|
245
|
-
.example('crosswind analyze --json')
|
|
246
|
-
.action(async (options: AnalyzeOptions) => {
|
|
247
|
-
try {
|
|
248
|
-
const baseConfig = await loadCustomConfig(options.config)
|
|
249
|
-
|
|
250
|
-
if (!options.json) {
|
|
251
|
-
console.log('🔍 Analyzing utility classes...\n')
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
const result = await build(baseConfig)
|
|
255
|
-
|
|
256
|
-
// Group classes by utility type
|
|
257
|
-
const utilityGroups = new Map<string, string[]>()
|
|
258
|
-
for (const cls of result.classes) {
|
|
259
|
-
const utility = cls.split('-')[0].split(':').pop() || 'other'
|
|
260
|
-
if (!utilityGroups.has(utility)) {
|
|
261
|
-
utilityGroups.set(utility, [])
|
|
262
|
-
}
|
|
263
|
-
utilityGroups.get(utility)!.push(cls)
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
const stats = {
|
|
267
|
-
totalClasses: result.classes.size,
|
|
268
|
-
buildTime: result.duration,
|
|
269
|
-
outputSize: existsSync(baseConfig.output) ? Bun.file(baseConfig.output).size : 0,
|
|
270
|
-
utilityGroups: Object.fromEntries(
|
|
271
|
-
Array.from(utilityGroups.entries())
|
|
272
|
-
.map(([key, value]) => [key, value.length] as [string, number])
|
|
273
|
-
.sort((a, b) => (b[1] as number) - (a[1] as number)),
|
|
274
|
-
),
|
|
275
|
-
topClasses: Array.from(result.classes).slice(0, options.top || 10),
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
if (options.json) {
|
|
279
|
-
console.log(JSON.stringify(stats, null, 2))
|
|
280
|
-
}
|
|
281
|
-
else {
|
|
282
|
-
console.log(`📊 Total classes: ${stats.totalClasses}`)
|
|
283
|
-
console.log(`⏱️ Build time: ${stats.buildTime.toFixed(2)}ms`)
|
|
284
|
-
console.log(`📦 Output size: ${(stats.outputSize / 1024).toFixed(2)} KB\n`)
|
|
285
|
-
|
|
286
|
-
console.log(`🏷️ Utility groups (top ${options.top}):`)
|
|
287
|
-
const topGroups = Object.entries(stats.utilityGroups).slice(0, options.top || 10)
|
|
288
|
-
for (const [utility, count] of topGroups) {
|
|
289
|
-
console.log(` ${utility.padEnd(20)} ${count} classes`)
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
if (options.verbose) {
|
|
293
|
-
console.log(`\n📋 All classes:`)
|
|
294
|
-
for (const cls of Array.from(result.classes).sort()) {
|
|
295
|
-
console.log(` - ${cls}`)
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
catch (error) {
|
|
301
|
-
console.error('❌ Analysis failed:', error)
|
|
302
|
-
process.exit(1)
|
|
303
|
-
}
|
|
304
|
-
})
|
|
305
|
-
|
|
306
|
-
// Clean command - Remove output file
|
|
307
|
-
cli
|
|
308
|
-
.command('clean', 'Remove the output CSS file')
|
|
309
|
-
.option('--config <path>', 'Path to config file')
|
|
310
|
-
.example('crosswind clean')
|
|
311
|
-
.action(async (options: GlobalOptions) => {
|
|
312
|
-
try {
|
|
313
|
-
const baseConfig = await loadCustomConfig(options.config)
|
|
314
|
-
|
|
315
|
-
if (!existsSync(baseConfig.output)) {
|
|
316
|
-
console.log('ℹ️ Output file does not exist')
|
|
317
|
-
return
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
await unlink(baseConfig.output)
|
|
321
|
-
console.log(`✅ Removed ${baseConfig.output}`)
|
|
322
|
-
}
|
|
323
|
-
catch (error) {
|
|
324
|
-
console.error('❌ Failed to remove output file:', error)
|
|
325
|
-
process.exit(1)
|
|
326
|
-
}
|
|
327
|
-
})
|
|
328
|
-
|
|
329
|
-
// Preflight command - Generate just the preflight CSS
|
|
330
|
-
cli
|
|
331
|
-
.command('preflight', 'Generate preflight CSS only')
|
|
332
|
-
.option('--output <path>', 'Output CSS file path', { default: './preflight.css' })
|
|
333
|
-
.example('crosswind preflight')
|
|
334
|
-
.example('crosswind preflight --output ./reset.css')
|
|
335
|
-
.action(async (options: { output?: string }) => {
|
|
336
|
-
try {
|
|
337
|
-
const outputPath = options.output || './preflight.css'
|
|
338
|
-
const preflightCSS = tailwindPreflight.getCSS()
|
|
339
|
-
|
|
340
|
-
await Bun.write(outputPath, preflightCSS)
|
|
341
|
-
console.log(`✅ Generated preflight CSS`)
|
|
342
|
-
console.log(`📝 Output: ${outputPath}`)
|
|
343
|
-
|
|
344
|
-
const file = Bun.file(outputPath)
|
|
345
|
-
const sizeKB = (file.size / 1024).toFixed(2)
|
|
346
|
-
console.log(`📦 File size: ${sizeKB} KB`)
|
|
347
|
-
}
|
|
348
|
-
catch (error) {
|
|
349
|
-
console.error('❌ Failed to generate preflight CSS:', error)
|
|
350
|
-
process.exit(1)
|
|
351
|
-
}
|
|
352
|
-
})
|
|
353
|
-
|
|
354
|
-
// Version command
|
|
355
|
-
cli
|
|
356
|
-
.command('version', 'Show the version of Crosswind')
|
|
357
|
-
.action(() => {
|
|
358
|
-
console.log(version)
|
|
359
|
-
})
|
|
360
|
-
|
|
361
|
-
cli.version(version)
|
|
362
|
-
cli.help()
|
|
363
|
-
|
|
364
|
-
// Parse arguments
|
|
365
|
-
cli.parse()
|
package/bin/crosswind
DELETED
|
Binary file
|
package/bin/headwind
DELETED
|
Binary file
|
package/build.ts
DELETED
package/crosswind.config.ts
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>Crosswind - Comprehensive Example</title>
|
|
7
|
-
</head>
|
|
8
|
-
<body>
|
|
9
|
-
<!-- Layout Utilities -->
|
|
10
|
-
<div class="relative top-4 z-10 aspect-square">
|
|
11
|
-
<div class="absolute inset-0 overflow-hidden">Content</div>
|
|
12
|
-
</div>
|
|
13
|
-
|
|
14
|
-
<!-- Grid Utilities -->
|
|
15
|
-
<div class="grid grid-cols-3 gap-4">
|
|
16
|
-
<div class="col-span-2">Span 2</div>
|
|
17
|
-
<div>Cell</div>
|
|
18
|
-
</div>
|
|
19
|
-
|
|
20
|
-
<!-- Typography -->
|
|
21
|
-
<div class="uppercase italic underline whitespace-nowrap truncate">
|
|
22
|
-
Styled Text
|
|
23
|
-
</div>
|
|
24
|
-
|
|
25
|
-
<!-- Transforms -->
|
|
26
|
-
<div class="scale-150 rotate-45 translate-x-4 skew-x-12">
|
|
27
|
-
Transformed
|
|
28
|
-
</div>
|
|
29
|
-
|
|
30
|
-
<!-- Transitions -->
|
|
31
|
-
<button class="transition-all duration-300 ease-in-out hover:opacity-50">
|
|
32
|
-
Animated Button
|
|
33
|
-
</button>
|
|
34
|
-
|
|
35
|
-
<!-- Filters -->
|
|
36
|
-
<div class="blur-sm grayscale-100 brightness-150">
|
|
37
|
-
Filtered Content
|
|
38
|
-
</div>
|
|
39
|
-
|
|
40
|
-
<!-- Interactivity -->
|
|
41
|
-
<div class="cursor-pointer select-none pointer-events-auto resize-both">
|
|
42
|
-
Interactive
|
|
43
|
-
</div>
|
|
44
|
-
|
|
45
|
-
<!-- Arbitrary Values -->
|
|
46
|
-
<div class="w-[250px] p-[2.5rem] bg-[#ff6b6b]">
|
|
47
|
-
Custom Values
|
|
48
|
-
</div>
|
|
49
|
-
|
|
50
|
-
<!-- Important Modifier -->
|
|
51
|
-
<div class="!text-white !bg-black !p-8">
|
|
52
|
-
Important Styles
|
|
53
|
-
</div>
|
|
54
|
-
|
|
55
|
-
<!-- SVG -->
|
|
56
|
-
<svg class="fill-current stroke-current">
|
|
57
|
-
<circle cx="50" cy="50" r="40" />
|
|
58
|
-
</svg>
|
|
59
|
-
|
|
60
|
-
<!-- Table -->
|
|
61
|
-
<table class="border-collapse table-fixed">
|
|
62
|
-
<tr><td>Cell</td></tr>
|
|
63
|
-
</table>
|
|
64
|
-
|
|
65
|
-
<!-- Scroll -->
|
|
66
|
-
<div class="scroll-smooth scroll-p-4 snap-y">
|
|
67
|
-
Scrollable
|
|
68
|
-
</div>
|
|
69
|
-
</body>
|
|
70
|
-
</html>
|
package/example/index.html
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>Crosswind Example</title>
|
|
7
|
-
</head>
|
|
8
|
-
<body>
|
|
9
|
-
<div class="flex flex-col items-center justify-center h-screen bg-gray-100">
|
|
10
|
-
<h1 class="text-4xl font-bold text-gray-900 mb-4">
|
|
11
|
-
Welcome to Crosswind
|
|
12
|
-
</h1>
|
|
13
|
-
<p class="text-lg text-gray-600 mb-8">
|
|
14
|
-
A Bun-powered CSS utility framework
|
|
15
|
-
</p>
|
|
16
|
-
<button class="px-6 py-3 bg-blue-500 text-white rounded-lg hover:bg-blue-600 focus:outline-none">
|
|
17
|
-
Get Started
|
|
18
|
-
</button>
|
|
19
|
-
</div>
|
|
20
|
-
</body>
|
|
21
|
-
</html>
|
package/example/output.css
DELETED
|
@@ -1,236 +0,0 @@
|
|
|
1
|
-
.flex {
|
|
2
|
-
display: flex;
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
.flex-col {
|
|
6
|
-
flex-direction: column;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
.items-center {
|
|
10
|
-
align-items: center;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
.justify-center {
|
|
14
|
-
justify-content: center;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
.h-screen {
|
|
18
|
-
height: 100vh;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
.bg-gray-100 {
|
|
22
|
-
background-color: #f3f4f6;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
.text-4xl {
|
|
26
|
-
font-size: 2.25rem;
|
|
27
|
-
line-height: 2.5rem;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
.font-bold {
|
|
31
|
-
font-weight: 700;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
.text-gray-900 {
|
|
35
|
-
color: #111827;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
.mb-4 {
|
|
39
|
-
margin-bottom: 1rem;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
.text-lg {
|
|
43
|
-
font-size: 1.125rem;
|
|
44
|
-
line-height: 1.75rem;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
.text-gray-600 {
|
|
48
|
-
color: #4b5563;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
.mb-8 {
|
|
52
|
-
margin-bottom: 2rem;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
.px-6 {
|
|
56
|
-
padding-left: 1.5rem;
|
|
57
|
-
padding-right: 1.5rem;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
.py-3 {
|
|
61
|
-
padding-top: 0.75rem;
|
|
62
|
-
padding-bottom: 0.75rem;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
.bg-blue-500 {
|
|
66
|
-
background-color: blue-500;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
.text-white {
|
|
70
|
-
color: #fff;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
.rounded-lg {
|
|
74
|
-
border-radius: 0.5rem;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
.hover\:bg-blue-600:hover {
|
|
78
|
-
background-color: blue-600;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
.focus\:outline-none:focus {
|
|
82
|
-
outline-width: none;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
.relative {
|
|
86
|
-
position: relative;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
.top-4 {
|
|
90
|
-
top: 1rem;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
.z-10 {
|
|
94
|
-
z-index: 10;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
.aspect-square {
|
|
98
|
-
aspect-ratio: 1 / 1;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
.absolute {
|
|
102
|
-
position: absolute;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
.inset-0 {
|
|
106
|
-
top: 0;
|
|
107
|
-
right: 0;
|
|
108
|
-
bottom: 0;
|
|
109
|
-
left: 0;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
.overflow-hidden {
|
|
113
|
-
overflow: hidden;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
.grid {
|
|
117
|
-
display: grid;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
.grid-cols-3 {
|
|
121
|
-
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
.gap-4 {
|
|
125
|
-
gap: 1rem;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
.col-span-2 {
|
|
129
|
-
grid-column: span 2 / span 2;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
.uppercase {
|
|
133
|
-
text-transform: uppercase;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
.italic {
|
|
137
|
-
font-style: italic;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
.underline {
|
|
141
|
-
text-decoration-line: underline;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
.whitespace-nowrap {
|
|
145
|
-
white-space: nowrap;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
.truncate {
|
|
149
|
-
overflow: hidden;
|
|
150
|
-
text-overflow: ellipsis;
|
|
151
|
-
white-space: nowrap;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
.scale-150 {
|
|
155
|
-
transform: scale(1.5);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
.rotate-45 {
|
|
159
|
-
transform: rotate(45deg);
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
.translate-x-4 {
|
|
163
|
-
transform: translateX(1rem);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
.skew-x-12 {
|
|
167
|
-
transform: skewX(12deg);
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
.transition-all {
|
|
171
|
-
transition-property: all;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
.duration-300 {
|
|
175
|
-
transition-duration: 300ms;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
.ease-in-out {
|
|
179
|
-
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
.hover\:opacity-50:hover {
|
|
183
|
-
opacity: 0.5;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
.blur-sm {
|
|
187
|
-
filter: blur(4px);
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
.grayscale-100 {
|
|
191
|
-
filter: grayscale(1);
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
.brightness-150 {
|
|
195
|
-
filter: brightness(1.5);
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
.cursor-pointer {
|
|
199
|
-
cursor: pointer;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
.select-none {
|
|
203
|
-
user-select: none;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
.pointer-events-auto {
|
|
207
|
-
pointer-events: auto;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
.fill-current {
|
|
211
|
-
fill: currentColor;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
.stroke-current {
|
|
215
|
-
stroke: currentColor;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
.border-collapse {
|
|
219
|
-
border-collapse: collapse;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
.table-fixed {
|
|
223
|
-
table-layout: fixed;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
.scroll-smooth {
|
|
227
|
-
scroll-behavior: smooth;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
.scroll-p-4 {
|
|
231
|
-
scroll-padding: 1rem;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
.snap-y {
|
|
235
|
-
scroll-snap-type: y mandatory;
|
|
236
|
-
}
|