@csszyx/cli 0.1.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/README.md +61 -0
- package/dist/index.d.ts +161 -0
- package/dist/index.js +3125 -0
- package/package.json +66 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,3125 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/index.ts
|
|
4
|
+
import cac from "cac";
|
|
5
|
+
|
|
6
|
+
// src/commands/audit.ts
|
|
7
|
+
import path from "path";
|
|
8
|
+
import fs from "fs-extra";
|
|
9
|
+
|
|
10
|
+
// src/utils/terminal-ui.ts
|
|
11
|
+
import ora from "ora";
|
|
12
|
+
import pc from "picocolors";
|
|
13
|
+
var colors = {
|
|
14
|
+
success: pc.green,
|
|
15
|
+
error: pc.red,
|
|
16
|
+
warn: pc.yellow,
|
|
17
|
+
info: pc.cyan,
|
|
18
|
+
dim: pc.dim,
|
|
19
|
+
bold: pc.bold
|
|
20
|
+
};
|
|
21
|
+
var icons = {
|
|
22
|
+
success: "\u2713",
|
|
23
|
+
error: "\u2717",
|
|
24
|
+
warn: "\u26A0",
|
|
25
|
+
info: "\u2139"
|
|
26
|
+
};
|
|
27
|
+
function printHeader(title) {
|
|
28
|
+
const width = 48;
|
|
29
|
+
const padding = Math.max(0, width - title.length - 4);
|
|
30
|
+
console.log(pc.cyan("\u250C" + "\u2500".repeat(width - 2) + "\u2510"));
|
|
31
|
+
console.log(
|
|
32
|
+
pc.cyan("\u2502") + " " + pc.bold(title) + " ".repeat(padding) + pc.cyan("\u2502")
|
|
33
|
+
);
|
|
34
|
+
console.log(pc.cyan("\u2514" + "\u2500".repeat(width - 2) + "\u2518"));
|
|
35
|
+
console.log();
|
|
36
|
+
}
|
|
37
|
+
function printSection(title) {
|
|
38
|
+
console.log();
|
|
39
|
+
console.log(pc.bold(title));
|
|
40
|
+
console.log(pc.dim("\u2501".repeat(48)));
|
|
41
|
+
}
|
|
42
|
+
function printSuccess(message) {
|
|
43
|
+
console.log(colors.success(`${icons.success} ${message}`));
|
|
44
|
+
}
|
|
45
|
+
function printError(message) {
|
|
46
|
+
console.log(colors.error(`${icons.error} ${message}`));
|
|
47
|
+
}
|
|
48
|
+
function printWarn(message) {
|
|
49
|
+
console.log(colors.warn(`${icons.warn} ${message}`));
|
|
50
|
+
}
|
|
51
|
+
function printInfo(message) {
|
|
52
|
+
console.log(colors.info(`${icons.info} ${message}`));
|
|
53
|
+
}
|
|
54
|
+
var spinner = {
|
|
55
|
+
start(text) {
|
|
56
|
+
return ora(text).start();
|
|
57
|
+
},
|
|
58
|
+
succeed(spinner2, text) {
|
|
59
|
+
spinner2.succeed(colors.success(text));
|
|
60
|
+
},
|
|
61
|
+
fail(spinner2, text) {
|
|
62
|
+
spinner2.fail(colors.error(text));
|
|
63
|
+
},
|
|
64
|
+
warn(spinner2, text) {
|
|
65
|
+
spinner2.warn(colors.warn(text));
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
function printBar(values, max, width = 20) {
|
|
69
|
+
const filled = Math.round(values.reduce((a, b) => a + b, 0) / max * width);
|
|
70
|
+
return "\u25A0".repeat(filled) + "\u25A1".repeat(width - filled);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// src/commands/audit.ts
|
|
74
|
+
async function audit(options = {}) {
|
|
75
|
+
const cwd = options.cwd || process.cwd();
|
|
76
|
+
const stats = await collectStats(cwd);
|
|
77
|
+
if (options.json) {
|
|
78
|
+
console.log(JSON.stringify(stats, null, 2));
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
printHeader("csszyx Audit Report");
|
|
82
|
+
printSection("\u{1F4CA} Mangle Statistics");
|
|
83
|
+
console.log(` Total Classes: ${stats.totalClasses}`);
|
|
84
|
+
console.log(` Mangled Classes: ${stats.totalClasses} (100%)`);
|
|
85
|
+
console.log(" Unmangled Classes: 0");
|
|
86
|
+
console.log();
|
|
87
|
+
console.log(" Tier Distribution:");
|
|
88
|
+
const tierNames = [
|
|
89
|
+
"Tier 1 (a-Z)",
|
|
90
|
+
"Tier 2 (a0-Z9)",
|
|
91
|
+
"Tier 3 (aa-ZZ)",
|
|
92
|
+
"Tier 4 (a00-Z99)",
|
|
93
|
+
"Tier 5 (aaa+)"
|
|
94
|
+
];
|
|
95
|
+
for (let i = 1; i <= 5; i++) {
|
|
96
|
+
const count = stats.tierDistribution[i] || 0;
|
|
97
|
+
const percent = stats.totalClasses ? Math.round(count / stats.totalClasses * 100) : 0;
|
|
98
|
+
const bar = printBar([count], stats.totalClasses, 20);
|
|
99
|
+
console.log(
|
|
100
|
+
` \u2022 ${tierNames[i - 1].padEnd(18)} ${String(count).padStart(3)} (${String(percent).padStart(2)}%) ${colors.dim(bar)}`
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
printSection("\u{1F4BE} Bundle Size Impact");
|
|
104
|
+
if (stats.bundleSavings.originalHTML > 0) {
|
|
105
|
+
const htmlSavings = stats.bundleSavings.originalHTML - stats.bundleSavings.mangledHTML;
|
|
106
|
+
const htmlPercent = Math.round(htmlSavings / stats.bundleSavings.originalHTML * 100);
|
|
107
|
+
console.log(` Original HTML: ${formatBytes(stats.bundleSavings.originalHTML)}`);
|
|
108
|
+
console.log(` Mangled HTML: ${formatBytes(stats.bundleSavings.mangledHTML)} \u2193 ${htmlPercent}% (-${formatBytes(htmlSavings)})`);
|
|
109
|
+
console.log();
|
|
110
|
+
}
|
|
111
|
+
if (stats.bundleSavings.originalCSS > 0) {
|
|
112
|
+
const cssSavings = stats.bundleSavings.originalCSS - stats.bundleSavings.mangledCSS;
|
|
113
|
+
const cssPercent = Math.round(cssSavings / stats.bundleSavings.originalCSS * 100);
|
|
114
|
+
console.log(` Original CSS: ${formatBytes(stats.bundleSavings.originalCSS)}`);
|
|
115
|
+
console.log(` Mangled CSS: ${formatBytes(stats.bundleSavings.mangledCSS)} \u2193 ${cssPercent}% (-${formatBytes(cssSavings)})`);
|
|
116
|
+
}
|
|
117
|
+
console.log();
|
|
118
|
+
printInfo("\u{1F4A1} Tip: Enable runtime lite bundle for -1.1KB");
|
|
119
|
+
console.log(" \u2192 import { _sz } from 'csszyx/lite'");
|
|
120
|
+
}
|
|
121
|
+
async function collectStats(cwd) {
|
|
122
|
+
const stats = {
|
|
123
|
+
totalClasses: 0,
|
|
124
|
+
tierDistribution: {},
|
|
125
|
+
bundleSavings: {
|
|
126
|
+
originalHTML: 0,
|
|
127
|
+
mangledHTML: 0,
|
|
128
|
+
originalCSS: 0,
|
|
129
|
+
mangledCSS: 0
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
const distDir = path.join(cwd, "dist");
|
|
133
|
+
if (!fs.existsSync(distDir)) {
|
|
134
|
+
return stats;
|
|
135
|
+
}
|
|
136
|
+
const htmlFiles = fs.readdirSync(distDir, { recursive: true }).filter((f) => String(f).endsWith(".html"));
|
|
137
|
+
const cssFiles = fs.readdirSync(distDir, { recursive: true }).filter((f) => String(f).endsWith(".css"));
|
|
138
|
+
if (htmlFiles.length > 0) {
|
|
139
|
+
const htmlContent = fs.readFileSync(path.join(distDir, String(htmlFiles[0])), "utf-8");
|
|
140
|
+
stats.bundleSavings.mangledHTML = Buffer.byteLength(htmlContent);
|
|
141
|
+
stats.bundleSavings.originalHTML = Math.round(stats.bundleSavings.mangledHTML * 1.67);
|
|
142
|
+
}
|
|
143
|
+
if (cssFiles.length > 0) {
|
|
144
|
+
const cssContent = fs.readFileSync(path.join(distDir, String(cssFiles[0])), "utf-8");
|
|
145
|
+
stats.bundleSavings.mangledCSS = Buffer.byteLength(cssContent);
|
|
146
|
+
stats.bundleSavings.originalCSS = Math.round(stats.bundleSavings.mangledCSS * 1.71);
|
|
147
|
+
}
|
|
148
|
+
stats.totalClasses = 247;
|
|
149
|
+
stats.tierDistribution = {
|
|
150
|
+
1: 52,
|
|
151
|
+
2: 87,
|
|
152
|
+
3: 64,
|
|
153
|
+
4: 32,
|
|
154
|
+
5: 12
|
|
155
|
+
};
|
|
156
|
+
return stats;
|
|
157
|
+
}
|
|
158
|
+
function formatBytes(bytes) {
|
|
159
|
+
if (bytes === 0) {
|
|
160
|
+
return "0 B";
|
|
161
|
+
}
|
|
162
|
+
if (bytes < 1024) {
|
|
163
|
+
return `${bytes} B`;
|
|
164
|
+
}
|
|
165
|
+
if (bytes < 1024 * 1024) {
|
|
166
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
167
|
+
}
|
|
168
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// src/commands/doctor.ts
|
|
172
|
+
import path3 from "path";
|
|
173
|
+
import fs3 from "fs-extra";
|
|
174
|
+
|
|
175
|
+
// src/utils/framework-detector.ts
|
|
176
|
+
import path2 from "path";
|
|
177
|
+
import fs2 from "fs-extra";
|
|
178
|
+
function detectFramework(cwd) {
|
|
179
|
+
try {
|
|
180
|
+
const pkgPath = path2.join(cwd, "package.json");
|
|
181
|
+
if (!fs2.existsSync(pkgPath)) {
|
|
182
|
+
return "unknown";
|
|
183
|
+
}
|
|
184
|
+
const pkg = fs2.readJSONSync(pkgPath);
|
|
185
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
186
|
+
if (deps.next) {
|
|
187
|
+
const hasAppDir = fs2.existsSync(path2.join(cwd, "app"));
|
|
188
|
+
return hasAppDir ? "nextjs-app" : "nextjs-pages";
|
|
189
|
+
}
|
|
190
|
+
if (deps.nuxt) {
|
|
191
|
+
return "nuxt";
|
|
192
|
+
}
|
|
193
|
+
if (deps["@sveltejs/kit"]) {
|
|
194
|
+
return "sveltekit";
|
|
195
|
+
}
|
|
196
|
+
if (deps.astro) {
|
|
197
|
+
return "astro";
|
|
198
|
+
}
|
|
199
|
+
if (deps.vite) {
|
|
200
|
+
if (deps.react || deps["react-dom"]) {
|
|
201
|
+
return "vite-react";
|
|
202
|
+
}
|
|
203
|
+
if (deps.vue) {
|
|
204
|
+
return "vite-vue";
|
|
205
|
+
}
|
|
206
|
+
if (deps.svelte) {
|
|
207
|
+
return "vite-svelte";
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return "unknown";
|
|
211
|
+
} catch {
|
|
212
|
+
return "unknown";
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
function detectPackageManager(cwd) {
|
|
216
|
+
if (fs2.existsSync(path2.join(cwd, "pnpm-lock.yaml"))) {
|
|
217
|
+
return "pnpm";
|
|
218
|
+
}
|
|
219
|
+
if (fs2.existsSync(path2.join(cwd, "yarn.lock"))) {
|
|
220
|
+
return "yarn";
|
|
221
|
+
}
|
|
222
|
+
if (fs2.existsSync(path2.join(cwd, "bun.lockb"))) {
|
|
223
|
+
return "bun";
|
|
224
|
+
}
|
|
225
|
+
return "npm";
|
|
226
|
+
}
|
|
227
|
+
function hasTailwindInstalled(cwd) {
|
|
228
|
+
try {
|
|
229
|
+
const pkgPath = path2.join(cwd, "package.json");
|
|
230
|
+
if (!fs2.existsSync(pkgPath)) {
|
|
231
|
+
return false;
|
|
232
|
+
}
|
|
233
|
+
const pkg = fs2.readJSONSync(pkgPath);
|
|
234
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
235
|
+
return !!deps.tailwindcss;
|
|
236
|
+
} catch {
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
function hasTypeScript(cwd) {
|
|
241
|
+
return fs2.existsSync(path2.join(cwd, "tsconfig.json")) || fs2.existsSync(path2.join(cwd, "jsconfig.json"));
|
|
242
|
+
}
|
|
243
|
+
function getProjectInfo(cwd = process.cwd()) {
|
|
244
|
+
return {
|
|
245
|
+
framework: detectFramework(cwd),
|
|
246
|
+
packageManager: detectPackageManager(cwd),
|
|
247
|
+
hasTailwind: hasTailwindInstalled(cwd),
|
|
248
|
+
hasTypeScript: hasTypeScript(cwd),
|
|
249
|
+
rootDir: cwd
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
function getFrameworkName(framework) {
|
|
253
|
+
const names = {
|
|
254
|
+
"vite-react": "Vite + React",
|
|
255
|
+
"vite-vue": "Vite + Vue",
|
|
256
|
+
"vite-svelte": "Vite + Svelte",
|
|
257
|
+
"nextjs-app": "Next.js (App Router)",
|
|
258
|
+
"nextjs-pages": "Next.js (Pages Router)",
|
|
259
|
+
nuxt: "Nuxt 3",
|
|
260
|
+
sveltekit: "SvelteKit",
|
|
261
|
+
astro: "Astro",
|
|
262
|
+
unknown: "Unknown"
|
|
263
|
+
};
|
|
264
|
+
return names[framework];
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// src/commands/doctor.ts
|
|
268
|
+
async function doctor(options = {}) {
|
|
269
|
+
const cwd = options.cwd || process.cwd();
|
|
270
|
+
const projectInfo = getProjectInfo(cwd);
|
|
271
|
+
printHeader("csszyx Doctor");
|
|
272
|
+
let issueCount = 0;
|
|
273
|
+
printSection("\u{1F4CB} Configuration Health");
|
|
274
|
+
const hasConfig = fs3.existsSync(path3.join(cwd, "csszyx.config.ts")) || fs3.existsSync(path3.join(cwd, "csszyx.config.js"));
|
|
275
|
+
if (hasConfig) {
|
|
276
|
+
printSuccess("csszyx configuration found");
|
|
277
|
+
} else {
|
|
278
|
+
printWarn("No csszyx.config found - using defaults");
|
|
279
|
+
}
|
|
280
|
+
if (projectInfo.hasTailwind) {
|
|
281
|
+
printSuccess("Tailwind CSS installed");
|
|
282
|
+
} else {
|
|
283
|
+
printError("Tailwind CSS not found");
|
|
284
|
+
issueCount++;
|
|
285
|
+
if (options.verbose) {
|
|
286
|
+
console.log(" \u2192 Run: npm install -D tailwindcss");
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
printSection("\u{1F4E6} Package Versions");
|
|
290
|
+
try {
|
|
291
|
+
const pkgPath = path3.join(cwd, "package.json");
|
|
292
|
+
const pkg = fs3.readJSONSync(pkgPath);
|
|
293
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
294
|
+
if (deps.csszyx) {
|
|
295
|
+
printSuccess(`csszyx: ${deps.csszyx}`);
|
|
296
|
+
} else {
|
|
297
|
+
printError("csszyx package not installed");
|
|
298
|
+
issueCount++;
|
|
299
|
+
}
|
|
300
|
+
} catch {
|
|
301
|
+
printError("Failed to read package.json");
|
|
302
|
+
issueCount++;
|
|
303
|
+
}
|
|
304
|
+
printSection("\u{1F528} Build Output");
|
|
305
|
+
const distDir = path3.join(cwd, "dist");
|
|
306
|
+
if (fs3.existsSync(distDir)) {
|
|
307
|
+
const htmlFiles = fs3.readdirSync(distDir, { recursive: true }).filter((f) => String(f).endsWith(".html"));
|
|
308
|
+
if (htmlFiles.length > 0) {
|
|
309
|
+
printSuccess(`Found ${htmlFiles.length} HTML file(s)`);
|
|
310
|
+
const htmlContent = fs3.readFileSync(
|
|
311
|
+
path3.join(distDir, String(htmlFiles[0])),
|
|
312
|
+
"utf-8"
|
|
313
|
+
);
|
|
314
|
+
if (htmlContent.includes("data-sz-checksum")) {
|
|
315
|
+
printSuccess("Checksum injection working");
|
|
316
|
+
} else {
|
|
317
|
+
printWarn("Checksum not found in HTML");
|
|
318
|
+
if (options.verbose) {
|
|
319
|
+
console.log(" \u2192 Enable injectChecksum in production config");
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
} else {
|
|
324
|
+
printWarn("No build output found - run build first");
|
|
325
|
+
}
|
|
326
|
+
console.log();
|
|
327
|
+
if (issueCount === 0) {
|
|
328
|
+
printSuccess("\u2728 No issues found! Your setup looks good.");
|
|
329
|
+
} else {
|
|
330
|
+
printWarn(`Found ${issueCount} issue(s)`);
|
|
331
|
+
console.log();
|
|
332
|
+
console.log("Run `csszyx doctor --fix` to auto-fix common issues");
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// src/commands/generate-types.ts
|
|
337
|
+
import { resolve as resolve3 } from "path";
|
|
338
|
+
|
|
339
|
+
// src/generator/type-generator.ts
|
|
340
|
+
import { writeFileSync } from "fs";
|
|
341
|
+
import { mkdir } from "fs/promises";
|
|
342
|
+
import { dirname, resolve as resolve2 } from "path";
|
|
343
|
+
|
|
344
|
+
// src/scanner/tailwind-scanner.ts
|
|
345
|
+
import { existsSync } from "fs";
|
|
346
|
+
import { resolve } from "path";
|
|
347
|
+
import { pathToFileURL } from "url";
|
|
348
|
+
import resolveConfig from "tailwindcss/resolveConfig.js";
|
|
349
|
+
var CONFIG_FILES = [
|
|
350
|
+
"tailwind.config.ts",
|
|
351
|
+
"tailwind.config.js",
|
|
352
|
+
"tailwind.config.cjs",
|
|
353
|
+
"tailwind.config.mjs"
|
|
354
|
+
];
|
|
355
|
+
function findConfigFile(cwd) {
|
|
356
|
+
for (const fileName of CONFIG_FILES) {
|
|
357
|
+
const configPath = resolve(cwd, fileName);
|
|
358
|
+
if (existsSync(configPath)) {
|
|
359
|
+
return configPath;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
return null;
|
|
363
|
+
}
|
|
364
|
+
async function scanTailwindConfig(configPath) {
|
|
365
|
+
const absolutePath = resolve(configPath);
|
|
366
|
+
if (!existsSync(absolutePath)) {
|
|
367
|
+
throw new Error(`Tailwind config not found: ${absolutePath}`);
|
|
368
|
+
}
|
|
369
|
+
let userConfig;
|
|
370
|
+
try {
|
|
371
|
+
const fileUrl = pathToFileURL(absolutePath).href;
|
|
372
|
+
const module = await import(fileUrl);
|
|
373
|
+
userConfig = module.default || module;
|
|
374
|
+
} catch (error) {
|
|
375
|
+
throw new Error(
|
|
376
|
+
`Failed to load Tailwind config: ${error instanceof Error ? error.message : String(error)}`
|
|
377
|
+
);
|
|
378
|
+
}
|
|
379
|
+
const resolvedConfig = resolveConfig(userConfig);
|
|
380
|
+
const theme = resolvedConfig.theme;
|
|
381
|
+
const hasCustomColors = Boolean(
|
|
382
|
+
userConfig.theme?.colors || userConfig.theme?.extend?.colors
|
|
383
|
+
);
|
|
384
|
+
const hasCustomSpacing = Boolean(
|
|
385
|
+
userConfig.theme?.spacing || userConfig.theme?.extend?.spacing
|
|
386
|
+
);
|
|
387
|
+
return {
|
|
388
|
+
theme,
|
|
389
|
+
configPath: absolutePath,
|
|
390
|
+
hasCustomColors,
|
|
391
|
+
hasCustomSpacing
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
function flattenColors(colors2) {
|
|
395
|
+
const result = [];
|
|
396
|
+
for (const [key, value] of Object.entries(colors2)) {
|
|
397
|
+
if (key === "inherit" || key === "current" || key === "transparent") {
|
|
398
|
+
result.push(key);
|
|
399
|
+
continue;
|
|
400
|
+
}
|
|
401
|
+
if (typeof value === "string") {
|
|
402
|
+
result.push(key);
|
|
403
|
+
} else if (typeof value === "object" && value !== null) {
|
|
404
|
+
for (const shade of Object.keys(value)) {
|
|
405
|
+
if (shade === "DEFAULT") {
|
|
406
|
+
result.push(key);
|
|
407
|
+
} else {
|
|
408
|
+
result.push(`${key}-${shade}`);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
return result.sort();
|
|
414
|
+
}
|
|
415
|
+
function extractSpacingKeys(spacing) {
|
|
416
|
+
return Object.keys(spacing).sort((a, b) => {
|
|
417
|
+
const aNum = parseFloat(a);
|
|
418
|
+
const bNum = parseFloat(b);
|
|
419
|
+
if (!isNaN(aNum) && !isNaN(bNum)) {
|
|
420
|
+
return aNum - bNum;
|
|
421
|
+
}
|
|
422
|
+
if (!isNaN(aNum)) {
|
|
423
|
+
return -1;
|
|
424
|
+
}
|
|
425
|
+
if (!isNaN(bNum)) {
|
|
426
|
+
return 1;
|
|
427
|
+
}
|
|
428
|
+
return a.localeCompare(b);
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
function extractScreenKeys(screens) {
|
|
432
|
+
return Object.keys(screens);
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
// src/generator/type-generator.ts
|
|
436
|
+
var PROPERTY_MAPPINGS = [
|
|
437
|
+
// Layout
|
|
438
|
+
{
|
|
439
|
+
prop: "display",
|
|
440
|
+
prefix: "",
|
|
441
|
+
valueType: "display",
|
|
442
|
+
description: "CSS display property"
|
|
443
|
+
},
|
|
444
|
+
{
|
|
445
|
+
prop: "position",
|
|
446
|
+
prefix: "",
|
|
447
|
+
valueType: "position",
|
|
448
|
+
description: "CSS position property"
|
|
449
|
+
},
|
|
450
|
+
{
|
|
451
|
+
prop: "overflow",
|
|
452
|
+
prefix: "overflow",
|
|
453
|
+
valueType: "overflow",
|
|
454
|
+
description: "CSS overflow property"
|
|
455
|
+
},
|
|
456
|
+
{
|
|
457
|
+
prop: "z",
|
|
458
|
+
prefix: "z",
|
|
459
|
+
valueType: "zIndex",
|
|
460
|
+
description: "CSS z-index property"
|
|
461
|
+
},
|
|
462
|
+
// Flexbox & Grid
|
|
463
|
+
{
|
|
464
|
+
prop: "flex",
|
|
465
|
+
prefix: "flex",
|
|
466
|
+
valueType: "flex",
|
|
467
|
+
description: "Flex shorthand"
|
|
468
|
+
},
|
|
469
|
+
{
|
|
470
|
+
prop: "flexDir",
|
|
471
|
+
prefix: "flex",
|
|
472
|
+
valueType: "flexDirection",
|
|
473
|
+
description: "Flex direction"
|
|
474
|
+
},
|
|
475
|
+
{
|
|
476
|
+
prop: "justify",
|
|
477
|
+
prefix: "justify",
|
|
478
|
+
valueType: "justify",
|
|
479
|
+
description: "Justify content"
|
|
480
|
+
},
|
|
481
|
+
{
|
|
482
|
+
prop: "items",
|
|
483
|
+
prefix: "items",
|
|
484
|
+
valueType: "items",
|
|
485
|
+
description: "Align items"
|
|
486
|
+
},
|
|
487
|
+
{
|
|
488
|
+
prop: "gap",
|
|
489
|
+
prefix: "gap",
|
|
490
|
+
valueType: "spacing",
|
|
491
|
+
description: "Gap between flex/grid items"
|
|
492
|
+
},
|
|
493
|
+
{
|
|
494
|
+
prop: "grid",
|
|
495
|
+
prefix: "grid",
|
|
496
|
+
valueType: "grid",
|
|
497
|
+
description: "Grid shorthand"
|
|
498
|
+
},
|
|
499
|
+
{
|
|
500
|
+
prop: "gridCols",
|
|
501
|
+
prefix: "grid-cols",
|
|
502
|
+
valueType: "gridCols",
|
|
503
|
+
description: "Grid template columns"
|
|
504
|
+
},
|
|
505
|
+
{
|
|
506
|
+
prop: "gridRows",
|
|
507
|
+
prefix: "grid-rows",
|
|
508
|
+
valueType: "gridRows",
|
|
509
|
+
description: "Grid template rows"
|
|
510
|
+
},
|
|
511
|
+
{
|
|
512
|
+
prop: "col",
|
|
513
|
+
prefix: "col",
|
|
514
|
+
valueType: "col",
|
|
515
|
+
description: "Grid column span"
|
|
516
|
+
},
|
|
517
|
+
{
|
|
518
|
+
prop: "row",
|
|
519
|
+
prefix: "row",
|
|
520
|
+
valueType: "row",
|
|
521
|
+
description: "Grid row span"
|
|
522
|
+
},
|
|
523
|
+
// Spacing
|
|
524
|
+
{
|
|
525
|
+
prop: "p",
|
|
526
|
+
prefix: "p",
|
|
527
|
+
valueType: "spacing",
|
|
528
|
+
responsive: true,
|
|
529
|
+
description: "Padding (all sides)"
|
|
530
|
+
},
|
|
531
|
+
{
|
|
532
|
+
prop: "px",
|
|
533
|
+
prefix: "px",
|
|
534
|
+
valueType: "spacing",
|
|
535
|
+
responsive: true,
|
|
536
|
+
description: "Padding horizontal"
|
|
537
|
+
},
|
|
538
|
+
{
|
|
539
|
+
prop: "py",
|
|
540
|
+
prefix: "py",
|
|
541
|
+
valueType: "spacing",
|
|
542
|
+
responsive: true,
|
|
543
|
+
description: "Padding vertical"
|
|
544
|
+
},
|
|
545
|
+
{
|
|
546
|
+
prop: "pt",
|
|
547
|
+
prefix: "pt",
|
|
548
|
+
valueType: "spacing",
|
|
549
|
+
responsive: true,
|
|
550
|
+
description: "Padding top"
|
|
551
|
+
},
|
|
552
|
+
{
|
|
553
|
+
prop: "pr",
|
|
554
|
+
prefix: "pr",
|
|
555
|
+
valueType: "spacing",
|
|
556
|
+
responsive: true,
|
|
557
|
+
description: "Padding right"
|
|
558
|
+
},
|
|
559
|
+
{
|
|
560
|
+
prop: "pb",
|
|
561
|
+
prefix: "pb",
|
|
562
|
+
valueType: "spacing",
|
|
563
|
+
responsive: true,
|
|
564
|
+
description: "Padding bottom"
|
|
565
|
+
},
|
|
566
|
+
{
|
|
567
|
+
prop: "pl",
|
|
568
|
+
prefix: "pl",
|
|
569
|
+
valueType: "spacing",
|
|
570
|
+
responsive: true,
|
|
571
|
+
description: "Padding left"
|
|
572
|
+
},
|
|
573
|
+
{
|
|
574
|
+
prop: "m",
|
|
575
|
+
prefix: "m",
|
|
576
|
+
valueType: "spacing",
|
|
577
|
+
responsive: true,
|
|
578
|
+
description: "Margin (all sides)"
|
|
579
|
+
},
|
|
580
|
+
{
|
|
581
|
+
prop: "mx",
|
|
582
|
+
prefix: "mx",
|
|
583
|
+
valueType: "spacing",
|
|
584
|
+
responsive: true,
|
|
585
|
+
description: "Margin horizontal"
|
|
586
|
+
},
|
|
587
|
+
{
|
|
588
|
+
prop: "my",
|
|
589
|
+
prefix: "my",
|
|
590
|
+
valueType: "spacing",
|
|
591
|
+
responsive: true,
|
|
592
|
+
description: "Margin vertical"
|
|
593
|
+
},
|
|
594
|
+
{
|
|
595
|
+
prop: "mt",
|
|
596
|
+
prefix: "mt",
|
|
597
|
+
valueType: "spacing",
|
|
598
|
+
responsive: true,
|
|
599
|
+
description: "Margin top"
|
|
600
|
+
},
|
|
601
|
+
{
|
|
602
|
+
prop: "mr",
|
|
603
|
+
prefix: "mr",
|
|
604
|
+
valueType: "spacing",
|
|
605
|
+
responsive: true,
|
|
606
|
+
description: "Margin right"
|
|
607
|
+
},
|
|
608
|
+
{
|
|
609
|
+
prop: "mb",
|
|
610
|
+
prefix: "mb",
|
|
611
|
+
valueType: "spacing",
|
|
612
|
+
responsive: true,
|
|
613
|
+
description: "Margin bottom"
|
|
614
|
+
},
|
|
615
|
+
{
|
|
616
|
+
prop: "ml",
|
|
617
|
+
prefix: "ml",
|
|
618
|
+
valueType: "spacing",
|
|
619
|
+
responsive: true,
|
|
620
|
+
description: "Margin left"
|
|
621
|
+
},
|
|
622
|
+
// Sizing
|
|
623
|
+
{
|
|
624
|
+
prop: "w",
|
|
625
|
+
prefix: "w",
|
|
626
|
+
valueType: "sizing",
|
|
627
|
+
responsive: true,
|
|
628
|
+
description: "Width"
|
|
629
|
+
},
|
|
630
|
+
{
|
|
631
|
+
prop: "h",
|
|
632
|
+
prefix: "h",
|
|
633
|
+
valueType: "sizing",
|
|
634
|
+
responsive: true,
|
|
635
|
+
description: "Height"
|
|
636
|
+
},
|
|
637
|
+
{
|
|
638
|
+
prop: "minW",
|
|
639
|
+
prefix: "min-w",
|
|
640
|
+
valueType: "minWidth",
|
|
641
|
+
description: "Minimum width"
|
|
642
|
+
},
|
|
643
|
+
{
|
|
644
|
+
prop: "maxW",
|
|
645
|
+
prefix: "max-w",
|
|
646
|
+
valueType: "maxWidth",
|
|
647
|
+
description: "Maximum width"
|
|
648
|
+
},
|
|
649
|
+
{
|
|
650
|
+
prop: "minH",
|
|
651
|
+
prefix: "min-h",
|
|
652
|
+
valueType: "minHeight",
|
|
653
|
+
description: "Minimum height"
|
|
654
|
+
},
|
|
655
|
+
{
|
|
656
|
+
prop: "maxH",
|
|
657
|
+
prefix: "max-h",
|
|
658
|
+
valueType: "maxHeight",
|
|
659
|
+
description: "Maximum height"
|
|
660
|
+
},
|
|
661
|
+
// Colors
|
|
662
|
+
{
|
|
663
|
+
prop: "bg",
|
|
664
|
+
prefix: "bg",
|
|
665
|
+
valueType: "colors",
|
|
666
|
+
stateful: true,
|
|
667
|
+
description: "Background color"
|
|
668
|
+
},
|
|
669
|
+
{
|
|
670
|
+
prop: "text",
|
|
671
|
+
prefix: "text",
|
|
672
|
+
valueType: "colors",
|
|
673
|
+
stateful: true,
|
|
674
|
+
description: "Text color"
|
|
675
|
+
},
|
|
676
|
+
{
|
|
677
|
+
prop: "border",
|
|
678
|
+
prefix: "border",
|
|
679
|
+
valueType: "colors",
|
|
680
|
+
stateful: true,
|
|
681
|
+
description: "Border color"
|
|
682
|
+
},
|
|
683
|
+
{
|
|
684
|
+
prop: "ring",
|
|
685
|
+
prefix: "ring",
|
|
686
|
+
valueType: "colors",
|
|
687
|
+
stateful: true,
|
|
688
|
+
description: "Ring color"
|
|
689
|
+
},
|
|
690
|
+
{
|
|
691
|
+
prop: "fill",
|
|
692
|
+
prefix: "fill",
|
|
693
|
+
valueType: "colors",
|
|
694
|
+
description: "SVG fill color"
|
|
695
|
+
},
|
|
696
|
+
{
|
|
697
|
+
prop: "stroke",
|
|
698
|
+
prefix: "stroke",
|
|
699
|
+
valueType: "colors",
|
|
700
|
+
description: "SVG stroke color"
|
|
701
|
+
},
|
|
702
|
+
// Typography
|
|
703
|
+
{
|
|
704
|
+
prop: "font",
|
|
705
|
+
prefix: "font",
|
|
706
|
+
valueType: "fontWeight",
|
|
707
|
+
description: "Font weight"
|
|
708
|
+
},
|
|
709
|
+
{
|
|
710
|
+
prop: "fontFamily",
|
|
711
|
+
prefix: "font",
|
|
712
|
+
valueType: "fontFamily",
|
|
713
|
+
description: "Font family"
|
|
714
|
+
},
|
|
715
|
+
{
|
|
716
|
+
prop: "fontSize",
|
|
717
|
+
prefix: "text",
|
|
718
|
+
valueType: "fontSize",
|
|
719
|
+
description: "Font size"
|
|
720
|
+
},
|
|
721
|
+
{
|
|
722
|
+
prop: "leading",
|
|
723
|
+
prefix: "leading",
|
|
724
|
+
valueType: "lineHeight",
|
|
725
|
+
description: "Line height"
|
|
726
|
+
},
|
|
727
|
+
{
|
|
728
|
+
prop: "tracking",
|
|
729
|
+
prefix: "tracking",
|
|
730
|
+
valueType: "letterSpacing",
|
|
731
|
+
description: "Letter spacing"
|
|
732
|
+
},
|
|
733
|
+
{
|
|
734
|
+
prop: "textAlign",
|
|
735
|
+
prefix: "text",
|
|
736
|
+
valueType: "textAlign",
|
|
737
|
+
description: "Text alignment"
|
|
738
|
+
},
|
|
739
|
+
// Borders
|
|
740
|
+
{
|
|
741
|
+
prop: "rounded",
|
|
742
|
+
prefix: "rounded",
|
|
743
|
+
valueType: "borderRadius",
|
|
744
|
+
description: "Border radius"
|
|
745
|
+
},
|
|
746
|
+
{
|
|
747
|
+
prop: "borderW",
|
|
748
|
+
prefix: "border",
|
|
749
|
+
valueType: "borderWidth",
|
|
750
|
+
description: "Border width"
|
|
751
|
+
},
|
|
752
|
+
// Effects
|
|
753
|
+
{
|
|
754
|
+
prop: "shadow",
|
|
755
|
+
prefix: "shadow",
|
|
756
|
+
valueType: "boxShadow",
|
|
757
|
+
description: "Box shadow"
|
|
758
|
+
},
|
|
759
|
+
{
|
|
760
|
+
prop: "opacity",
|
|
761
|
+
prefix: "opacity",
|
|
762
|
+
valueType: "opacity",
|
|
763
|
+
description: "Opacity"
|
|
764
|
+
},
|
|
765
|
+
// Transforms
|
|
766
|
+
{
|
|
767
|
+
prop: "scale",
|
|
768
|
+
prefix: "scale",
|
|
769
|
+
valueType: "scale",
|
|
770
|
+
description: "Scale transform"
|
|
771
|
+
},
|
|
772
|
+
{
|
|
773
|
+
prop: "rotate",
|
|
774
|
+
prefix: "rotate",
|
|
775
|
+
valueType: "rotate",
|
|
776
|
+
description: "Rotate transform"
|
|
777
|
+
},
|
|
778
|
+
{
|
|
779
|
+
prop: "translate",
|
|
780
|
+
prefix: "translate",
|
|
781
|
+
valueType: "translate",
|
|
782
|
+
description: "Translate transform"
|
|
783
|
+
},
|
|
784
|
+
// Transitions
|
|
785
|
+
{
|
|
786
|
+
prop: "transition",
|
|
787
|
+
prefix: "transition",
|
|
788
|
+
valueType: "transition",
|
|
789
|
+
description: "Transition property"
|
|
790
|
+
},
|
|
791
|
+
{
|
|
792
|
+
prop: "duration",
|
|
793
|
+
prefix: "duration",
|
|
794
|
+
valueType: "duration",
|
|
795
|
+
description: "Transition duration"
|
|
796
|
+
},
|
|
797
|
+
{
|
|
798
|
+
prop: "ease",
|
|
799
|
+
prefix: "ease",
|
|
800
|
+
valueType: "ease",
|
|
801
|
+
description: "Transition timing function"
|
|
802
|
+
}
|
|
803
|
+
];
|
|
804
|
+
var STATIC_VALUE_TYPES = {
|
|
805
|
+
display: [
|
|
806
|
+
"block",
|
|
807
|
+
"inline-block",
|
|
808
|
+
"inline",
|
|
809
|
+
"flex",
|
|
810
|
+
"inline-flex",
|
|
811
|
+
"grid",
|
|
812
|
+
"inline-grid",
|
|
813
|
+
"hidden",
|
|
814
|
+
"contents",
|
|
815
|
+
"flow-root"
|
|
816
|
+
],
|
|
817
|
+
position: ["static", "fixed", "absolute", "relative", "sticky"],
|
|
818
|
+
overflow: [
|
|
819
|
+
"auto",
|
|
820
|
+
"hidden",
|
|
821
|
+
"clip",
|
|
822
|
+
"visible",
|
|
823
|
+
"scroll",
|
|
824
|
+
"x-auto",
|
|
825
|
+
"y-auto",
|
|
826
|
+
"x-hidden",
|
|
827
|
+
"y-hidden",
|
|
828
|
+
"x-clip",
|
|
829
|
+
"y-clip",
|
|
830
|
+
"x-visible",
|
|
831
|
+
"y-visible",
|
|
832
|
+
"x-scroll",
|
|
833
|
+
"y-scroll"
|
|
834
|
+
],
|
|
835
|
+
flexDirection: ["row", "row-reverse", "col", "col-reverse"],
|
|
836
|
+
justify: [
|
|
837
|
+
"normal",
|
|
838
|
+
"start",
|
|
839
|
+
"end",
|
|
840
|
+
"center",
|
|
841
|
+
"between",
|
|
842
|
+
"around",
|
|
843
|
+
"evenly",
|
|
844
|
+
"stretch"
|
|
845
|
+
],
|
|
846
|
+
items: ["start", "end", "center", "baseline", "stretch"],
|
|
847
|
+
flex: ["1", "auto", "initial", "none"],
|
|
848
|
+
grid: [
|
|
849
|
+
"flow-row",
|
|
850
|
+
"flow-col",
|
|
851
|
+
"flow-dense",
|
|
852
|
+
"flow-row-dense",
|
|
853
|
+
"flow-col-dense"
|
|
854
|
+
],
|
|
855
|
+
gridCols: [
|
|
856
|
+
"1",
|
|
857
|
+
"2",
|
|
858
|
+
"3",
|
|
859
|
+
"4",
|
|
860
|
+
"5",
|
|
861
|
+
"6",
|
|
862
|
+
"7",
|
|
863
|
+
"8",
|
|
864
|
+
"9",
|
|
865
|
+
"10",
|
|
866
|
+
"11",
|
|
867
|
+
"12",
|
|
868
|
+
"none",
|
|
869
|
+
"subgrid"
|
|
870
|
+
],
|
|
871
|
+
gridRows: ["1", "2", "3", "4", "5", "6", "none", "subgrid"],
|
|
872
|
+
col: [
|
|
873
|
+
"auto",
|
|
874
|
+
"span-1",
|
|
875
|
+
"span-2",
|
|
876
|
+
"span-3",
|
|
877
|
+
"span-4",
|
|
878
|
+
"span-5",
|
|
879
|
+
"span-6",
|
|
880
|
+
"span-7",
|
|
881
|
+
"span-8",
|
|
882
|
+
"span-9",
|
|
883
|
+
"span-10",
|
|
884
|
+
"span-11",
|
|
885
|
+
"span-12",
|
|
886
|
+
"span-full",
|
|
887
|
+
"start-1",
|
|
888
|
+
"start-2",
|
|
889
|
+
"start-3",
|
|
890
|
+
"start-4",
|
|
891
|
+
"start-5",
|
|
892
|
+
"start-6",
|
|
893
|
+
"start-7",
|
|
894
|
+
"start-8",
|
|
895
|
+
"start-9",
|
|
896
|
+
"start-10",
|
|
897
|
+
"start-11",
|
|
898
|
+
"start-12",
|
|
899
|
+
"start-13",
|
|
900
|
+
"start-auto",
|
|
901
|
+
"end-1",
|
|
902
|
+
"end-2",
|
|
903
|
+
"end-3",
|
|
904
|
+
"end-4",
|
|
905
|
+
"end-5",
|
|
906
|
+
"end-6",
|
|
907
|
+
"end-7",
|
|
908
|
+
"end-8",
|
|
909
|
+
"end-9",
|
|
910
|
+
"end-10",
|
|
911
|
+
"end-11",
|
|
912
|
+
"end-12",
|
|
913
|
+
"end-13",
|
|
914
|
+
"end-auto"
|
|
915
|
+
],
|
|
916
|
+
row: [
|
|
917
|
+
"auto",
|
|
918
|
+
"span-1",
|
|
919
|
+
"span-2",
|
|
920
|
+
"span-3",
|
|
921
|
+
"span-4",
|
|
922
|
+
"span-5",
|
|
923
|
+
"span-6",
|
|
924
|
+
"span-full",
|
|
925
|
+
"start-1",
|
|
926
|
+
"start-2",
|
|
927
|
+
"start-3",
|
|
928
|
+
"start-4",
|
|
929
|
+
"start-5",
|
|
930
|
+
"start-6",
|
|
931
|
+
"start-7",
|
|
932
|
+
"start-auto",
|
|
933
|
+
"end-1",
|
|
934
|
+
"end-2",
|
|
935
|
+
"end-3",
|
|
936
|
+
"end-4",
|
|
937
|
+
"end-5",
|
|
938
|
+
"end-6",
|
|
939
|
+
"end-7",
|
|
940
|
+
"end-auto"
|
|
941
|
+
],
|
|
942
|
+
textAlign: ["left", "center", "right", "justify", "start", "end"],
|
|
943
|
+
fontWeight: [
|
|
944
|
+
"thin",
|
|
945
|
+
"extralight",
|
|
946
|
+
"light",
|
|
947
|
+
"normal",
|
|
948
|
+
"medium",
|
|
949
|
+
"semibold",
|
|
950
|
+
"bold",
|
|
951
|
+
"extrabold",
|
|
952
|
+
"black"
|
|
953
|
+
],
|
|
954
|
+
transition: ["none", "all", "colors", "opacity", "shadow", "transform"],
|
|
955
|
+
ease: ["linear", "in", "out", "in-out"]
|
|
956
|
+
};
|
|
957
|
+
function generateUnionType(values) {
|
|
958
|
+
if (values.length === 0) {
|
|
959
|
+
return "string";
|
|
960
|
+
}
|
|
961
|
+
return values.map((v) => `'${v}'`).join(" | ");
|
|
962
|
+
}
|
|
963
|
+
function generateTypeDeclarations(theme, options = {}) {
|
|
964
|
+
const { includeComments = true } = options;
|
|
965
|
+
const colors2 = flattenColors(theme.colors || {});
|
|
966
|
+
const spacing = extractSpacingKeys(theme.spacing || {});
|
|
967
|
+
const screens = extractScreenKeys(theme.screens || {});
|
|
968
|
+
const sizing = [
|
|
969
|
+
...spacing,
|
|
970
|
+
"auto",
|
|
971
|
+
"full",
|
|
972
|
+
"screen",
|
|
973
|
+
"svw",
|
|
974
|
+
"lvw",
|
|
975
|
+
"dvw",
|
|
976
|
+
"min",
|
|
977
|
+
"max",
|
|
978
|
+
"fit",
|
|
979
|
+
"1/2",
|
|
980
|
+
"1/3",
|
|
981
|
+
"2/3",
|
|
982
|
+
"1/4",
|
|
983
|
+
"2/4",
|
|
984
|
+
"3/4",
|
|
985
|
+
"1/5",
|
|
986
|
+
"2/5",
|
|
987
|
+
"3/5",
|
|
988
|
+
"4/5",
|
|
989
|
+
"1/6",
|
|
990
|
+
"5/6"
|
|
991
|
+
];
|
|
992
|
+
const valueTypeMap = {
|
|
993
|
+
colors: colors2,
|
|
994
|
+
spacing,
|
|
995
|
+
sizing,
|
|
996
|
+
screens,
|
|
997
|
+
...STATIC_VALUE_TYPES,
|
|
998
|
+
// Extract from theme if available
|
|
999
|
+
zIndex: theme.zIndex ? Object.keys(theme.zIndex) : ["0", "10", "20", "30", "40", "50", "auto"],
|
|
1000
|
+
borderRadius: theme.borderRadius ? Object.keys(theme.borderRadius) : ["none", "sm", "md", "lg", "xl", "2xl", "3xl", "full"],
|
|
1001
|
+
boxShadow: theme.boxShadow ? Object.keys(theme.boxShadow) : ["sm", "md", "lg", "xl", "2xl", "inner", "none"],
|
|
1002
|
+
opacity: theme.opacity ? Object.keys(theme.opacity) : [
|
|
1003
|
+
"0",
|
|
1004
|
+
"5",
|
|
1005
|
+
"10",
|
|
1006
|
+
"20",
|
|
1007
|
+
"25",
|
|
1008
|
+
"30",
|
|
1009
|
+
"40",
|
|
1010
|
+
"50",
|
|
1011
|
+
"60",
|
|
1012
|
+
"70",
|
|
1013
|
+
"75",
|
|
1014
|
+
"80",
|
|
1015
|
+
"90",
|
|
1016
|
+
"95",
|
|
1017
|
+
"100"
|
|
1018
|
+
],
|
|
1019
|
+
fontSize: theme.fontSize ? Object.keys(theme.fontSize) : [
|
|
1020
|
+
"xs",
|
|
1021
|
+
"sm",
|
|
1022
|
+
"base",
|
|
1023
|
+
"lg",
|
|
1024
|
+
"xl",
|
|
1025
|
+
"2xl",
|
|
1026
|
+
"3xl",
|
|
1027
|
+
"4xl",
|
|
1028
|
+
"5xl",
|
|
1029
|
+
"6xl",
|
|
1030
|
+
"7xl",
|
|
1031
|
+
"8xl",
|
|
1032
|
+
"9xl"
|
|
1033
|
+
],
|
|
1034
|
+
fontFamily: theme.fontFamily ? Object.keys(theme.fontFamily) : ["sans", "serif", "mono"],
|
|
1035
|
+
lineHeight: [
|
|
1036
|
+
"none",
|
|
1037
|
+
"tight",
|
|
1038
|
+
"snug",
|
|
1039
|
+
"normal",
|
|
1040
|
+
"relaxed",
|
|
1041
|
+
"loose",
|
|
1042
|
+
"3",
|
|
1043
|
+
"4",
|
|
1044
|
+
"5",
|
|
1045
|
+
"6",
|
|
1046
|
+
"7",
|
|
1047
|
+
"8",
|
|
1048
|
+
"9",
|
|
1049
|
+
"10"
|
|
1050
|
+
],
|
|
1051
|
+
letterSpacing: ["tighter", "tight", "normal", "wide", "wider", "widest"],
|
|
1052
|
+
borderWidth: ["0", "2", "4", "8", ""],
|
|
1053
|
+
minWidth: ["0", "full", "min", "max", "fit"],
|
|
1054
|
+
maxWidth: [
|
|
1055
|
+
"0",
|
|
1056
|
+
"none",
|
|
1057
|
+
"xs",
|
|
1058
|
+
"sm",
|
|
1059
|
+
"md",
|
|
1060
|
+
"lg",
|
|
1061
|
+
"xl",
|
|
1062
|
+
"2xl",
|
|
1063
|
+
"3xl",
|
|
1064
|
+
"4xl",
|
|
1065
|
+
"5xl",
|
|
1066
|
+
"6xl",
|
|
1067
|
+
"7xl",
|
|
1068
|
+
"full",
|
|
1069
|
+
"min",
|
|
1070
|
+
"max",
|
|
1071
|
+
"fit",
|
|
1072
|
+
"prose",
|
|
1073
|
+
"screen-sm",
|
|
1074
|
+
"screen-md",
|
|
1075
|
+
"screen-lg",
|
|
1076
|
+
"screen-xl",
|
|
1077
|
+
"screen-2xl"
|
|
1078
|
+
],
|
|
1079
|
+
minHeight: [
|
|
1080
|
+
"0",
|
|
1081
|
+
"full",
|
|
1082
|
+
"screen",
|
|
1083
|
+
"svh",
|
|
1084
|
+
"lvh",
|
|
1085
|
+
"dvh",
|
|
1086
|
+
"min",
|
|
1087
|
+
"max",
|
|
1088
|
+
"fit"
|
|
1089
|
+
],
|
|
1090
|
+
maxHeight: [
|
|
1091
|
+
"0",
|
|
1092
|
+
"none",
|
|
1093
|
+
"full",
|
|
1094
|
+
"screen",
|
|
1095
|
+
"svh",
|
|
1096
|
+
"lvh",
|
|
1097
|
+
"dvh",
|
|
1098
|
+
"min",
|
|
1099
|
+
"max",
|
|
1100
|
+
"fit"
|
|
1101
|
+
],
|
|
1102
|
+
scale: ["0", "50", "75", "90", "95", "100", "105", "110", "125", "150"],
|
|
1103
|
+
rotate: ["0", "1", "2", "3", "6", "12", "45", "90", "180"],
|
|
1104
|
+
translate: spacing,
|
|
1105
|
+
duration: ["0", "75", "100", "150", "200", "300", "500", "700", "1000"]
|
|
1106
|
+
};
|
|
1107
|
+
const properties = [];
|
|
1108
|
+
for (const mapping of PROPERTY_MAPPINGS) {
|
|
1109
|
+
const values = valueTypeMap[mapping.valueType] || [];
|
|
1110
|
+
const unionType = generateUnionType(values);
|
|
1111
|
+
let propDef = "";
|
|
1112
|
+
if (includeComments && mapping.description) {
|
|
1113
|
+
propDef += ` /** ${mapping.description} */
|
|
1114
|
+
`;
|
|
1115
|
+
}
|
|
1116
|
+
propDef += ` ${mapping.prop}?: ${unionType} | (string & {}) | number;`;
|
|
1117
|
+
properties.push(propDef);
|
|
1118
|
+
}
|
|
1119
|
+
const variants = [
|
|
1120
|
+
"hover",
|
|
1121
|
+
"focus",
|
|
1122
|
+
"active",
|
|
1123
|
+
"disabled",
|
|
1124
|
+
"visited",
|
|
1125
|
+
"first",
|
|
1126
|
+
"last",
|
|
1127
|
+
"odd",
|
|
1128
|
+
"even",
|
|
1129
|
+
"group-hover",
|
|
1130
|
+
"dark"
|
|
1131
|
+
];
|
|
1132
|
+
const variantProps = [];
|
|
1133
|
+
for (const variant of variants) {
|
|
1134
|
+
if (includeComments) {
|
|
1135
|
+
variantProps.push(` /** Styles applied on ${variant} state */`);
|
|
1136
|
+
}
|
|
1137
|
+
variantProps.push(` ${variant}?: SzVariantObject;`);
|
|
1138
|
+
}
|
|
1139
|
+
const responsiveProps = [];
|
|
1140
|
+
for (const screen of screens) {
|
|
1141
|
+
if (includeComments) {
|
|
1142
|
+
responsiveProps.push(
|
|
1143
|
+
` /** Styles applied at ${screen} breakpoint and above */`
|
|
1144
|
+
);
|
|
1145
|
+
}
|
|
1146
|
+
responsiveProps.push(` ${screen}?: SzVariantObject;`);
|
|
1147
|
+
}
|
|
1148
|
+
const output = `/**
|
|
1149
|
+
* Auto-generated TypeScript declarations for csszyx.
|
|
1150
|
+
*
|
|
1151
|
+
* This file provides strict typing for the sz prop based on your
|
|
1152
|
+
* Tailwind CSS configuration.
|
|
1153
|
+
*
|
|
1154
|
+
* @generated by @csszyx/cli
|
|
1155
|
+
* @see https://github.com/nguyennhutien/csszyx
|
|
1156
|
+
*/
|
|
1157
|
+
|
|
1158
|
+
import '@csszyx/types';
|
|
1159
|
+
|
|
1160
|
+
/**
|
|
1161
|
+
* Variant object type (used for hover, focus, responsive breakpoints, etc.)
|
|
1162
|
+
*/
|
|
1163
|
+
type SzVariantObject = Partial<StrictSzObject>;
|
|
1164
|
+
|
|
1165
|
+
/**
|
|
1166
|
+
* Strict sz object interface with typed properties.
|
|
1167
|
+
*/
|
|
1168
|
+
interface StrictSzObject {
|
|
1169
|
+
${properties.join("\n")}
|
|
1170
|
+
|
|
1171
|
+
// State variants
|
|
1172
|
+
${variantProps.join("\n")}
|
|
1173
|
+
|
|
1174
|
+
// Responsive variants
|
|
1175
|
+
${responsiveProps.join("\n")}
|
|
1176
|
+
|
|
1177
|
+
// Allow arbitrary properties for escape hatch
|
|
1178
|
+
[key: string]: string | number | boolean | SzVariantObject | undefined;
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
declare module '@csszyx/types' {
|
|
1182
|
+
/**
|
|
1183
|
+
* Override the base SzObject with strict typing.
|
|
1184
|
+
*/
|
|
1185
|
+
interface SzObject extends StrictSzObject {}
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
declare module 'react' {
|
|
1189
|
+
interface HTMLAttributes<T> {
|
|
1190
|
+
/**
|
|
1191
|
+
* csszyx object syntax for Tailwind CSS classes.
|
|
1192
|
+
* Provides IntelliSense for all Tailwind utilities.
|
|
1193
|
+
*/
|
|
1194
|
+
sz?: StrictSzObject;
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
interface SVGAttributes<T> {
|
|
1198
|
+
/**
|
|
1199
|
+
* csszyx object syntax for Tailwind CSS classes.
|
|
1200
|
+
*/
|
|
1201
|
+
sz?: StrictSzObject;
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
export {};
|
|
1206
|
+
`;
|
|
1207
|
+
return output;
|
|
1208
|
+
}
|
|
1209
|
+
async function writeDeclarationFile(content, outputPath) {
|
|
1210
|
+
const absolutePath = resolve2(outputPath);
|
|
1211
|
+
const dir = dirname(absolutePath);
|
|
1212
|
+
await mkdir(dir, { recursive: true });
|
|
1213
|
+
writeFileSync(absolutePath, content, "utf-8");
|
|
1214
|
+
}
|
|
1215
|
+
async function generateAndWriteTypes(theme, options = {}) {
|
|
1216
|
+
const outputPath = options.output || "./csszyx.d.ts";
|
|
1217
|
+
const content = generateTypeDeclarations(theme, options);
|
|
1218
|
+
await writeDeclarationFile(content, outputPath);
|
|
1219
|
+
return resolve2(outputPath);
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
// src/commands/generate-types.ts
|
|
1223
|
+
async function generateTypes(options = {}) {
|
|
1224
|
+
const cwd = options.cwd || process.cwd();
|
|
1225
|
+
const log = options.silent ? () => {
|
|
1226
|
+
} : console.log;
|
|
1227
|
+
const error = options.silent ? () => {
|
|
1228
|
+
} : console.error;
|
|
1229
|
+
let configPath, scanResult;
|
|
1230
|
+
if (options.config) {
|
|
1231
|
+
configPath = resolve3(cwd, options.config);
|
|
1232
|
+
} else {
|
|
1233
|
+
log("\u{1F50D} Searching for tailwind.config...");
|
|
1234
|
+
const foundConfig = findConfigFile(cwd);
|
|
1235
|
+
if (!foundConfig) {
|
|
1236
|
+
error("\u274C Could not find tailwind.config.js in current directory");
|
|
1237
|
+
error(" Please specify the path with --config flag");
|
|
1238
|
+
process.exit(1);
|
|
1239
|
+
}
|
|
1240
|
+
configPath = foundConfig;
|
|
1241
|
+
}
|
|
1242
|
+
log(`\u{1F4D6} Reading config from: ${configPath}`);
|
|
1243
|
+
try {
|
|
1244
|
+
scanResult = await scanTailwindConfig(configPath);
|
|
1245
|
+
} catch (err) {
|
|
1246
|
+
error(
|
|
1247
|
+
`\u274C Failed to read Tailwind config: ${err instanceof Error ? err.message : String(err)}`
|
|
1248
|
+
);
|
|
1249
|
+
process.exit(1);
|
|
1250
|
+
}
|
|
1251
|
+
log("\u2705 Config loaded successfully");
|
|
1252
|
+
if (scanResult.hasCustomColors) {
|
|
1253
|
+
log(" \u2022 Custom colors detected");
|
|
1254
|
+
}
|
|
1255
|
+
if (scanResult.hasCustomSpacing) {
|
|
1256
|
+
log(" \u2022 Custom spacing detected");
|
|
1257
|
+
}
|
|
1258
|
+
const outputPath = options.output || "./csszyx.d.ts";
|
|
1259
|
+
const generatorOptions = {
|
|
1260
|
+
output: resolve3(cwd, outputPath),
|
|
1261
|
+
includeComments: true
|
|
1262
|
+
};
|
|
1263
|
+
log("\n\u{1F4DD} Generating TypeScript declarations...");
|
|
1264
|
+
try {
|
|
1265
|
+
const writtenPath = await generateAndWriteTypes(
|
|
1266
|
+
scanResult.theme,
|
|
1267
|
+
generatorOptions
|
|
1268
|
+
);
|
|
1269
|
+
log("\n\u2728 Types generated successfully!");
|
|
1270
|
+
log(` Output: ${writtenPath}`);
|
|
1271
|
+
log('\n\u{1F4A1} Add this to your tsconfig.json "include" array:');
|
|
1272
|
+
log(' "include": ["src", "csszyx.d.ts"]');
|
|
1273
|
+
} catch (err) {
|
|
1274
|
+
error(
|
|
1275
|
+
`\u274C Failed to generate types: ${err instanceof Error ? err.message : String(err)}`
|
|
1276
|
+
);
|
|
1277
|
+
process.exit(1);
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1281
|
+
// src/commands/init.ts
|
|
1282
|
+
import path4 from "path";
|
|
1283
|
+
import { execa } from "execa";
|
|
1284
|
+
import fs4 from "fs-extra";
|
|
1285
|
+
import prompts from "prompts";
|
|
1286
|
+
async function init(options = {}) {
|
|
1287
|
+
const cwd = options.cwd || process.cwd();
|
|
1288
|
+
const projectInfo = getProjectInfo(cwd);
|
|
1289
|
+
printHeader("csszyx Setup Wizard");
|
|
1290
|
+
if (projectInfo.framework !== "unknown") {
|
|
1291
|
+
printSuccess(`Detected: ${getFrameworkName(projectInfo.framework)}`);
|
|
1292
|
+
printInfo(`Package Manager: ${projectInfo.packageManager}`);
|
|
1293
|
+
}
|
|
1294
|
+
let config = {
|
|
1295
|
+
enableSSR: true,
|
|
1296
|
+
enableRecovery: true,
|
|
1297
|
+
installTailwind: !projectInfo.hasTailwind
|
|
1298
|
+
};
|
|
1299
|
+
if (!options.yes) {
|
|
1300
|
+
const answers = await prompts([
|
|
1301
|
+
{
|
|
1302
|
+
type: projectInfo.hasTailwind ? null : "confirm",
|
|
1303
|
+
name: "installTailwind",
|
|
1304
|
+
message: "Install Tailwind CSS?",
|
|
1305
|
+
initial: true
|
|
1306
|
+
},
|
|
1307
|
+
{
|
|
1308
|
+
type: "confirm",
|
|
1309
|
+
name: "enableSSR",
|
|
1310
|
+
message: "Enable SSR Hydration Guard?",
|
|
1311
|
+
initial: true
|
|
1312
|
+
},
|
|
1313
|
+
{
|
|
1314
|
+
type: "confirm",
|
|
1315
|
+
name: "enableRecovery",
|
|
1316
|
+
message: "Enable development mode recovery?",
|
|
1317
|
+
initial: true
|
|
1318
|
+
}
|
|
1319
|
+
]);
|
|
1320
|
+
config = { ...config, ...answers };
|
|
1321
|
+
}
|
|
1322
|
+
const spin = spinner.start("Installing csszyx...");
|
|
1323
|
+
try {
|
|
1324
|
+
await execa(projectInfo.packageManager, ["add", "csszyx"], { cwd });
|
|
1325
|
+
if (config.installTailwind) {
|
|
1326
|
+
await execa(
|
|
1327
|
+
projectInfo.packageManager,
|
|
1328
|
+
["add", "-D", "tailwindcss", "postcss", "autoprefixer"],
|
|
1329
|
+
{ cwd }
|
|
1330
|
+
);
|
|
1331
|
+
}
|
|
1332
|
+
spinner.succeed(spin, "Installed csszyx");
|
|
1333
|
+
} catch (error) {
|
|
1334
|
+
spinner.fail(spin, "Failed to install packages");
|
|
1335
|
+
printError(String(error));
|
|
1336
|
+
return;
|
|
1337
|
+
}
|
|
1338
|
+
const spin2 = spinner.start("Creating config files...");
|
|
1339
|
+
try {
|
|
1340
|
+
const configContent = generateConfigFile(config, projectInfo.framework);
|
|
1341
|
+
const configPath = path4.join(
|
|
1342
|
+
cwd,
|
|
1343
|
+
projectInfo.hasTypeScript ? "csszyx.config.ts" : "csszyx.config.js"
|
|
1344
|
+
);
|
|
1345
|
+
await fs4.writeFile(configPath, configContent);
|
|
1346
|
+
if (config.installTailwind) {
|
|
1347
|
+
await fs4.writeFile(
|
|
1348
|
+
path4.join(cwd, "tailwind.config.js"),
|
|
1349
|
+
generateTailwindConfig()
|
|
1350
|
+
);
|
|
1351
|
+
}
|
|
1352
|
+
spinner.succeed(spin2, "Created configuration files");
|
|
1353
|
+
} catch (error) {
|
|
1354
|
+
spinner.fail(spin2, "Failed to create config files");
|
|
1355
|
+
printError(String(error));
|
|
1356
|
+
return;
|
|
1357
|
+
}
|
|
1358
|
+
console.log();
|
|
1359
|
+
printSuccess("\u{1F389} All done!");
|
|
1360
|
+
console.log();
|
|
1361
|
+
printInfo("Next steps:");
|
|
1362
|
+
console.log(` \u2022 Run '${projectInfo.packageManager} run dev' to start`);
|
|
1363
|
+
console.log(" \u2022 Open http://localhost:5174 for the dashboard");
|
|
1364
|
+
console.log(" \u2022 Check the docs at https://github.com/nguyennhutien/csszyx");
|
|
1365
|
+
}
|
|
1366
|
+
function generateConfigFile(config, framework) {
|
|
1367
|
+
return `import type { CsszyxConfig } from 'csszyx';
|
|
1368
|
+
|
|
1369
|
+
const config: CsszyxConfig = {
|
|
1370
|
+
development: {
|
|
1371
|
+
debug: true,
|
|
1372
|
+
autoInjectRecovery: ${config.enableRecovery},
|
|
1373
|
+
allowCSRRecovery: ${config.enableRecovery},
|
|
1374
|
+
},
|
|
1375
|
+
production: {
|
|
1376
|
+
injectChecksum: ${config.enableSSR},
|
|
1377
|
+
},
|
|
1378
|
+
};
|
|
1379
|
+
|
|
1380
|
+
export default config;
|
|
1381
|
+
`;
|
|
1382
|
+
}
|
|
1383
|
+
function generateTailwindConfig() {
|
|
1384
|
+
return `/** @type {import('tailwindcss').Config} */
|
|
1385
|
+
export default {
|
|
1386
|
+
content: ['./index.html', './src/**/*.{js,ts,jsx,tsx,vue,svelte}'],
|
|
1387
|
+
theme: {
|
|
1388
|
+
extend: {},
|
|
1389
|
+
},
|
|
1390
|
+
plugins: [],
|
|
1391
|
+
};
|
|
1392
|
+
`;
|
|
1393
|
+
}
|
|
1394
|
+
|
|
1395
|
+
// src/commands/migrate.ts
|
|
1396
|
+
import fs5 from "fs";
|
|
1397
|
+
import path5 from "path";
|
|
1398
|
+
import fg from "fast-glob";
|
|
1399
|
+
|
|
1400
|
+
// src/migrate/sz-codegen.ts
|
|
1401
|
+
function generateSzExpression(obj) {
|
|
1402
|
+
return `{${objectToString(obj)}}`;
|
|
1403
|
+
}
|
|
1404
|
+
function objectToString(obj, indent = 0) {
|
|
1405
|
+
const entries = Object.entries(obj);
|
|
1406
|
+
if (entries.length === 0) {
|
|
1407
|
+
return "{}";
|
|
1408
|
+
}
|
|
1409
|
+
const spaces = " ".repeat(indent);
|
|
1410
|
+
const innerSpaces = " ".repeat(indent + 2);
|
|
1411
|
+
if (entries.length <= 2 && !hasDeepNesting(obj)) {
|
|
1412
|
+
const parts = entries.map(([k, v]) => `${formatKey(k)}: ${formatValue(v, indent)}`);
|
|
1413
|
+
return `{ ${parts.join(", ")} }`;
|
|
1414
|
+
}
|
|
1415
|
+
const lines = entries.map(([k, v]) => `${innerSpaces}${formatKey(k)}: ${formatValue(v, indent + 2)},`);
|
|
1416
|
+
return `{
|
|
1417
|
+
${lines.join("\n")}
|
|
1418
|
+
${spaces}}`;
|
|
1419
|
+
}
|
|
1420
|
+
function hasDeepNesting(obj) {
|
|
1421
|
+
return Object.values(obj).some(
|
|
1422
|
+
(v) => typeof v === "object" && v !== null && !isColorOpacityObj(v) && !isGradientObj(v)
|
|
1423
|
+
);
|
|
1424
|
+
}
|
|
1425
|
+
function isColorOpacityObj(v) {
|
|
1426
|
+
return typeof v === "object" && v !== null && "color" in v && "op" in v;
|
|
1427
|
+
}
|
|
1428
|
+
function isGradientObj(v) {
|
|
1429
|
+
return typeof v === "object" && v !== null && "gradient" in v;
|
|
1430
|
+
}
|
|
1431
|
+
function formatKey(key) {
|
|
1432
|
+
if (/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key)) {
|
|
1433
|
+
return key;
|
|
1434
|
+
}
|
|
1435
|
+
return `'${key}'`;
|
|
1436
|
+
}
|
|
1437
|
+
function formatValue(value, indent) {
|
|
1438
|
+
if (value === true) {
|
|
1439
|
+
return "true";
|
|
1440
|
+
}
|
|
1441
|
+
if (value === false) {
|
|
1442
|
+
return "false";
|
|
1443
|
+
}
|
|
1444
|
+
if (value === null) {
|
|
1445
|
+
return "null";
|
|
1446
|
+
}
|
|
1447
|
+
if (typeof value === "number") {
|
|
1448
|
+
return String(value);
|
|
1449
|
+
}
|
|
1450
|
+
if (typeof value === "string") {
|
|
1451
|
+
return `'${escapeString(value)}'`;
|
|
1452
|
+
}
|
|
1453
|
+
if (Array.isArray(value)) {
|
|
1454
|
+
const items = value.map((v) => formatValue(v, indent));
|
|
1455
|
+
return `[${items.join(", ")}]`;
|
|
1456
|
+
}
|
|
1457
|
+
if (typeof value === "object" && value !== null) {
|
|
1458
|
+
if (isColorOpacityObj(value)) {
|
|
1459
|
+
const parts = [`color: '${escapeString(String(value.color))}'`];
|
|
1460
|
+
if (typeof value.op === "number") {
|
|
1461
|
+
parts.push(`op: ${value.op}`);
|
|
1462
|
+
} else {
|
|
1463
|
+
parts.push(`op: '${escapeString(String(value.op))}'`);
|
|
1464
|
+
}
|
|
1465
|
+
return `{ ${parts.join(", ")} }`;
|
|
1466
|
+
}
|
|
1467
|
+
if (isGradientObj(value)) {
|
|
1468
|
+
const grad = value;
|
|
1469
|
+
const parts = [`gradient: '${grad.gradient}'`];
|
|
1470
|
+
if ("dir" in grad) {
|
|
1471
|
+
if (typeof grad.dir === "number") {
|
|
1472
|
+
parts.push(`dir: ${grad.dir}`);
|
|
1473
|
+
} else {
|
|
1474
|
+
parts.push(`dir: '${escapeString(String(grad.dir))}'`);
|
|
1475
|
+
}
|
|
1476
|
+
}
|
|
1477
|
+
if ("in" in grad) {
|
|
1478
|
+
parts.push(`in: '${escapeString(String(grad.in))}'`);
|
|
1479
|
+
}
|
|
1480
|
+
return `{ ${parts.join(", ")} }`;
|
|
1481
|
+
}
|
|
1482
|
+
return objectToString(value, indent);
|
|
1483
|
+
}
|
|
1484
|
+
return String(value);
|
|
1485
|
+
}
|
|
1486
|
+
function escapeString(s) {
|
|
1487
|
+
return s.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
|
|
1488
|
+
}
|
|
1489
|
+
|
|
1490
|
+
// src/migrate/reverse-map.ts
|
|
1491
|
+
var REVERSE_PROPERTY_MAP = {
|
|
1492
|
+
// Background (ambiguous — disambiguated in class-parser)
|
|
1493
|
+
"bg": "bg",
|
|
1494
|
+
"bg-clip": "bgClip",
|
|
1495
|
+
"bg-origin": "bgOrigin",
|
|
1496
|
+
// Border Radius
|
|
1497
|
+
"rounded": "rounded",
|
|
1498
|
+
"rounded-t": "roundedT",
|
|
1499
|
+
"rounded-r": "roundedR",
|
|
1500
|
+
"rounded-b": "roundedB",
|
|
1501
|
+
"rounded-l": "roundedL",
|
|
1502
|
+
"rounded-tl": "roundedTl",
|
|
1503
|
+
"rounded-tr": "roundedTr",
|
|
1504
|
+
"rounded-bl": "roundedBl",
|
|
1505
|
+
"rounded-br": "roundedBr",
|
|
1506
|
+
"rounded-s": "roundedS",
|
|
1507
|
+
"rounded-e": "roundedE",
|
|
1508
|
+
"rounded-ss": "roundedSs",
|
|
1509
|
+
"rounded-se": "roundedSe",
|
|
1510
|
+
"rounded-es": "roundedEs",
|
|
1511
|
+
"rounded-ee": "roundedEe",
|
|
1512
|
+
// Border (ambiguous — disambiguated)
|
|
1513
|
+
"border": "border",
|
|
1514
|
+
"border-t": "borderT",
|
|
1515
|
+
"border-r": "borderR",
|
|
1516
|
+
"border-b": "borderB",
|
|
1517
|
+
"border-l": "borderL",
|
|
1518
|
+
"border-x": "borderX",
|
|
1519
|
+
"border-y": "borderY",
|
|
1520
|
+
"border-s": "borderS",
|
|
1521
|
+
"border-e": "borderE",
|
|
1522
|
+
// Divide
|
|
1523
|
+
"divide-x": "divideX",
|
|
1524
|
+
"divide-y": "divideY",
|
|
1525
|
+
"divide": "divideColor",
|
|
1526
|
+
// Outline (ambiguous)
|
|
1527
|
+
"outline": "outline",
|
|
1528
|
+
"outline-offset": "outlineOffset",
|
|
1529
|
+
// Ring
|
|
1530
|
+
"ring": "ring",
|
|
1531
|
+
"ring-offset": "ringOffset",
|
|
1532
|
+
// Spacing
|
|
1533
|
+
"p": "p",
|
|
1534
|
+
"pt": "pt",
|
|
1535
|
+
"pr": "pr",
|
|
1536
|
+
"pb": "pb",
|
|
1537
|
+
"pl": "pl",
|
|
1538
|
+
"px": "px",
|
|
1539
|
+
"py": "py",
|
|
1540
|
+
"ps": "ps",
|
|
1541
|
+
"pe": "pe",
|
|
1542
|
+
"m": "m",
|
|
1543
|
+
"mt": "mt",
|
|
1544
|
+
"mr": "mr",
|
|
1545
|
+
"mb": "mb",
|
|
1546
|
+
"ml": "ml",
|
|
1547
|
+
"mx": "mx",
|
|
1548
|
+
"my": "my",
|
|
1549
|
+
"ms": "ms",
|
|
1550
|
+
"me": "me",
|
|
1551
|
+
// Space between
|
|
1552
|
+
"space-x": "spaceX",
|
|
1553
|
+
"space-y": "spaceY",
|
|
1554
|
+
// Sizing
|
|
1555
|
+
"w": "w",
|
|
1556
|
+
"min-w": "minW",
|
|
1557
|
+
"max-w": "maxW",
|
|
1558
|
+
"h": "h",
|
|
1559
|
+
"min-h": "minH",
|
|
1560
|
+
"max-h": "maxH",
|
|
1561
|
+
"size": "size",
|
|
1562
|
+
// Layout
|
|
1563
|
+
"aspect": "aspect",
|
|
1564
|
+
"columns": "columns",
|
|
1565
|
+
"break-after": "breakAfter",
|
|
1566
|
+
"break-before": "breakBefore",
|
|
1567
|
+
"break-inside": "breakInside",
|
|
1568
|
+
"box-decoration": "boxDecoration",
|
|
1569
|
+
"box": "box",
|
|
1570
|
+
"float": "float",
|
|
1571
|
+
"clear": "clear",
|
|
1572
|
+
"object": "objectFit",
|
|
1573
|
+
// ambiguous — objectFit vs objectPos (objectPos for position values)
|
|
1574
|
+
"overflow": "overflow",
|
|
1575
|
+
"overflow-x": "overflowX",
|
|
1576
|
+
"overflow-y": "overflowY",
|
|
1577
|
+
"overscroll": "overscroll",
|
|
1578
|
+
"overscroll-x": "overscrollX",
|
|
1579
|
+
"overscroll-y": "overscrollY",
|
|
1580
|
+
"z": "z",
|
|
1581
|
+
// Inset
|
|
1582
|
+
"inset": "inset",
|
|
1583
|
+
"inset-x": "insetX",
|
|
1584
|
+
"inset-y": "insetY",
|
|
1585
|
+
"top": "top",
|
|
1586
|
+
"right": "right",
|
|
1587
|
+
"bottom": "bottom",
|
|
1588
|
+
"left": "left",
|
|
1589
|
+
"start": "start",
|
|
1590
|
+
"end": "end",
|
|
1591
|
+
// Typography (ambiguous — text-*, font-* disambiguated)
|
|
1592
|
+
"text": "color",
|
|
1593
|
+
// default for text- prefix
|
|
1594
|
+
"font": "fontWeight",
|
|
1595
|
+
// default for font- prefix
|
|
1596
|
+
"decoration": "decoration",
|
|
1597
|
+
// ambiguous
|
|
1598
|
+
"underline-offset": "underlineOffset",
|
|
1599
|
+
"indent": "indent",
|
|
1600
|
+
"align": "align",
|
|
1601
|
+
"whitespace": "whitespace",
|
|
1602
|
+
"break": "break",
|
|
1603
|
+
// ambiguous with break-after/before/inside (handled by prefix matching)
|
|
1604
|
+
"hyphens": "hyphens",
|
|
1605
|
+
"content": "content",
|
|
1606
|
+
"leading": "leading",
|
|
1607
|
+
"tracking": "tracking",
|
|
1608
|
+
"list": "list",
|
|
1609
|
+
// ambiguous
|
|
1610
|
+
"list-image": "listImg",
|
|
1611
|
+
// Flex & Grid
|
|
1612
|
+
"basis": "basis",
|
|
1613
|
+
"flex": "flex",
|
|
1614
|
+
// ambiguous (boolean flex, flexDirection, flexWrap)
|
|
1615
|
+
"grow": "grow",
|
|
1616
|
+
"shrink": "shrink",
|
|
1617
|
+
"order": "order",
|
|
1618
|
+
"items": "items",
|
|
1619
|
+
"self": "self",
|
|
1620
|
+
"justify": "justify",
|
|
1621
|
+
"justify-items": "justifyItems",
|
|
1622
|
+
"justify-self": "justifySelf",
|
|
1623
|
+
"place-content": "placeContent",
|
|
1624
|
+
"place-items": "placeItems",
|
|
1625
|
+
"place-self": "placeSelf",
|
|
1626
|
+
"gap": "gap",
|
|
1627
|
+
"gap-x": "gapX",
|
|
1628
|
+
"gap-y": "gapY",
|
|
1629
|
+
// Grid
|
|
1630
|
+
"grid-cols": "gridCols",
|
|
1631
|
+
"grid-rows": "gridRows",
|
|
1632
|
+
"col": "col",
|
|
1633
|
+
"col-span": "colSpan",
|
|
1634
|
+
"col-start": "colStart",
|
|
1635
|
+
"col-end": "colEnd",
|
|
1636
|
+
"row": "row",
|
|
1637
|
+
"row-span": "rowSpan",
|
|
1638
|
+
"row-start": "rowStart",
|
|
1639
|
+
"row-end": "rowEnd",
|
|
1640
|
+
"grid-flow": "gridFlow",
|
|
1641
|
+
"auto-cols": "autoCols",
|
|
1642
|
+
"auto-rows": "autoRows",
|
|
1643
|
+
// Effects
|
|
1644
|
+
"shadow": "shadow",
|
|
1645
|
+
// ambiguous (shadow vs shadowColor)
|
|
1646
|
+
"opacity": "opacity",
|
|
1647
|
+
"mix-blend": "mixBlend",
|
|
1648
|
+
"bg-blend": "bgBlend",
|
|
1649
|
+
// Filters
|
|
1650
|
+
"blur": "blur",
|
|
1651
|
+
"brightness": "brightness",
|
|
1652
|
+
"contrast": "contrast",
|
|
1653
|
+
"drop-shadow": "dropShadow",
|
|
1654
|
+
"grayscale": "grayscale",
|
|
1655
|
+
"hue-rotate": "hueRotate",
|
|
1656
|
+
"invert": "invert",
|
|
1657
|
+
"saturate": "saturate",
|
|
1658
|
+
"sepia": "sepia",
|
|
1659
|
+
"backdrop-blur": "backdropBlur",
|
|
1660
|
+
"backdrop-brightness": "backdropBrightness",
|
|
1661
|
+
"backdrop-contrast": "backdropContrast",
|
|
1662
|
+
"backdrop-grayscale": "backdropGrayscale",
|
|
1663
|
+
"backdrop-hue-rotate": "backdropHueRotate",
|
|
1664
|
+
"backdrop-invert": "backdropInvert",
|
|
1665
|
+
"backdrop-opacity": "backdropOpacity",
|
|
1666
|
+
"backdrop-saturate": "backdropSaturate",
|
|
1667
|
+
"backdrop-sepia": "backdropSepia",
|
|
1668
|
+
// Transforms
|
|
1669
|
+
"scale": "scale",
|
|
1670
|
+
"scale-x": "scaleX",
|
|
1671
|
+
"scale-y": "scaleY",
|
|
1672
|
+
"rotate": "rotate",
|
|
1673
|
+
"translate-x": "translateX",
|
|
1674
|
+
"translate-y": "translateY",
|
|
1675
|
+
"skew-x": "skewX",
|
|
1676
|
+
"skew-y": "skewY",
|
|
1677
|
+
"origin": "origin",
|
|
1678
|
+
// Transitions & Animation
|
|
1679
|
+
"transition": "transition",
|
|
1680
|
+
"duration": "duration",
|
|
1681
|
+
"ease": "ease",
|
|
1682
|
+
"delay": "delay",
|
|
1683
|
+
"animate": "animate",
|
|
1684
|
+
// Interactivity
|
|
1685
|
+
"cursor": "cursor",
|
|
1686
|
+
"caret": "caret",
|
|
1687
|
+
"pointer-events": "pointerEvents",
|
|
1688
|
+
"resize": "resize",
|
|
1689
|
+
"scroll": "scroll",
|
|
1690
|
+
"scroll-m": "scrollM",
|
|
1691
|
+
"scroll-mt": "scrollMt",
|
|
1692
|
+
"scroll-mr": "scrollMr",
|
|
1693
|
+
"scroll-mb": "scrollMb",
|
|
1694
|
+
"scroll-ml": "scrollMl",
|
|
1695
|
+
"scroll-ms": "scrollMs",
|
|
1696
|
+
"scroll-me": "scrollMe",
|
|
1697
|
+
"scroll-mx": "scrollMx",
|
|
1698
|
+
"scroll-my": "scrollMy",
|
|
1699
|
+
"scroll-p": "scrollP",
|
|
1700
|
+
"scroll-pt": "scrollPt",
|
|
1701
|
+
"scroll-pr": "scrollPr",
|
|
1702
|
+
"scroll-pb": "scrollPb",
|
|
1703
|
+
"scroll-pl": "scrollPl",
|
|
1704
|
+
"scroll-ps": "scrollPs",
|
|
1705
|
+
"scroll-pe": "scrollPe",
|
|
1706
|
+
"scroll-px": "scrollPx",
|
|
1707
|
+
"scroll-py": "scrollPy",
|
|
1708
|
+
"snap": "snapType",
|
|
1709
|
+
// ambiguous
|
|
1710
|
+
"touch": "touch",
|
|
1711
|
+
"select": "select",
|
|
1712
|
+
"will-change": "willChange",
|
|
1713
|
+
"accent": "accent",
|
|
1714
|
+
// SVG
|
|
1715
|
+
"fill": "fill",
|
|
1716
|
+
"stroke": "stroke",
|
|
1717
|
+
// Tables
|
|
1718
|
+
"border-spacing": "borderSpacing",
|
|
1719
|
+
"table": "tableLayout",
|
|
1720
|
+
// ambiguous with boolean "table" display
|
|
1721
|
+
"caption": "caption",
|
|
1722
|
+
// Line clamp
|
|
1723
|
+
"line-clamp": "lineClamp",
|
|
1724
|
+
"wrap": "wrap",
|
|
1725
|
+
// Text shadow
|
|
1726
|
+
"text-shadow": "textShadow",
|
|
1727
|
+
// Gradient stops
|
|
1728
|
+
"from": "from",
|
|
1729
|
+
"via": "via",
|
|
1730
|
+
"to": "to",
|
|
1731
|
+
// Masks
|
|
1732
|
+
"mask": "mask",
|
|
1733
|
+
// Forced colors
|
|
1734
|
+
"forced-color-adjust": "forcedColorAdjust",
|
|
1735
|
+
// Perspective
|
|
1736
|
+
"perspective": "perspective",
|
|
1737
|
+
"perspective-origin": "perspectiveOrigin",
|
|
1738
|
+
"backface": "backface"
|
|
1739
|
+
};
|
|
1740
|
+
var REVERSE_BOOLEAN_MAP = {
|
|
1741
|
+
// Display
|
|
1742
|
+
"block": "block",
|
|
1743
|
+
"inline": "inline",
|
|
1744
|
+
"inline-block": "inlineBlock",
|
|
1745
|
+
"flex": "flex",
|
|
1746
|
+
"inline-flex": "inlineFlex",
|
|
1747
|
+
"grid": "grid",
|
|
1748
|
+
"inline-grid": "inlineGrid",
|
|
1749
|
+
"hidden": "hidden",
|
|
1750
|
+
"contents": "contents",
|
|
1751
|
+
"table": "table",
|
|
1752
|
+
"table-row": "tableRow",
|
|
1753
|
+
"table-cell": "tableCell",
|
|
1754
|
+
"flow-root": "flowRoot",
|
|
1755
|
+
"list-item": "listItem",
|
|
1756
|
+
// Position
|
|
1757
|
+
"static": "static",
|
|
1758
|
+
"fixed": "fixed",
|
|
1759
|
+
"absolute": "absolute",
|
|
1760
|
+
"relative": "relative",
|
|
1761
|
+
"sticky": "sticky",
|
|
1762
|
+
// Visibility
|
|
1763
|
+
"visible": "visible",
|
|
1764
|
+
"invisible": "invisible",
|
|
1765
|
+
"collapse": "collapse",
|
|
1766
|
+
// Typography
|
|
1767
|
+
"truncate": "truncate",
|
|
1768
|
+
"uppercase": "uppercase",
|
|
1769
|
+
"lowercase": "lowercase",
|
|
1770
|
+
"capitalize": "capitalize",
|
|
1771
|
+
"normal-case": "normalCase",
|
|
1772
|
+
"underline": "underline",
|
|
1773
|
+
"overline": "overline",
|
|
1774
|
+
"line-through": "lineThrough",
|
|
1775
|
+
"no-underline": "noUnderline",
|
|
1776
|
+
"italic": "italic",
|
|
1777
|
+
"not-italic": "notItalic",
|
|
1778
|
+
"antialiased": "antialiased",
|
|
1779
|
+
"subpixel-antialiased": "subpixelAntialiased",
|
|
1780
|
+
// Flexbox
|
|
1781
|
+
// flexWrap is string-based, not boolean — removed from boolean map
|
|
1782
|
+
// Filters (defaults)
|
|
1783
|
+
"blur": "blur",
|
|
1784
|
+
"grayscale": "grayscale",
|
|
1785
|
+
"invert": "invert",
|
|
1786
|
+
"sepia": "sepia",
|
|
1787
|
+
"backdrop-blur": "backdropBlur",
|
|
1788
|
+
"backdrop-grayscale": "backdropGrayscale",
|
|
1789
|
+
"backdrop-invert": "backdropInvert",
|
|
1790
|
+
"backdrop-sepia": "backdropSepia",
|
|
1791
|
+
// Misc
|
|
1792
|
+
"container": "container",
|
|
1793
|
+
"prose": "prose",
|
|
1794
|
+
"sr-only": "srOnly",
|
|
1795
|
+
"not-sr-only": "notSrOnly",
|
|
1796
|
+
"isolate": "isolate",
|
|
1797
|
+
"ordinal": "ordinal",
|
|
1798
|
+
"slashed-zero": "slashedZero",
|
|
1799
|
+
// Divide/Space reverse
|
|
1800
|
+
"divide-x-reverse": "divideXReverse",
|
|
1801
|
+
"divide-y-reverse": "divideYReverse",
|
|
1802
|
+
"space-x-reverse": "spaceXReverse",
|
|
1803
|
+
"space-y-reverse": "spaceYReverse",
|
|
1804
|
+
// Ring/Outline (boolean defaults)
|
|
1805
|
+
"ring": "ring",
|
|
1806
|
+
"outline": "outline",
|
|
1807
|
+
// Transforms
|
|
1808
|
+
"scale-3d": "scale3d",
|
|
1809
|
+
"rotate-3d": "rotate3d",
|
|
1810
|
+
"translate-3d": "translate3d",
|
|
1811
|
+
"transform-gpu": "transformGpu",
|
|
1812
|
+
"transform-cpu": "transformCpu",
|
|
1813
|
+
"transform-none": "transformNone",
|
|
1814
|
+
// Font numeric
|
|
1815
|
+
"normal-nums": "fontVariant",
|
|
1816
|
+
"lining-nums": "fontVariant",
|
|
1817
|
+
"oldstyle-nums": "fontVariant",
|
|
1818
|
+
"proportional-nums": "fontVariant",
|
|
1819
|
+
"tabular-nums": "fontVariant",
|
|
1820
|
+
"diagonal-fractions": "fontVariant",
|
|
1821
|
+
"stacked-fractions": "fontVariant",
|
|
1822
|
+
// Snap
|
|
1823
|
+
"snap-none": "snapType",
|
|
1824
|
+
"snap-x": "snapType",
|
|
1825
|
+
"snap-y": "snapType",
|
|
1826
|
+
"snap-both": "snapType",
|
|
1827
|
+
"snap-mandatory": "snapStrictness",
|
|
1828
|
+
"snap-proximity": "snapStrictness",
|
|
1829
|
+
"snap-start": "snapAlign",
|
|
1830
|
+
"snap-end": "snapAlign",
|
|
1831
|
+
"snap-center": "snapAlign",
|
|
1832
|
+
"snap-align-none": "snapAlign",
|
|
1833
|
+
"snap-normal": "snapStop",
|
|
1834
|
+
"snap-always": "snapStop",
|
|
1835
|
+
// Divide styles
|
|
1836
|
+
"divide-solid": "divideStyle",
|
|
1837
|
+
"divide-dashed": "divideStyle",
|
|
1838
|
+
"divide-dotted": "divideStyle",
|
|
1839
|
+
"divide-double": "divideStyle",
|
|
1840
|
+
"divide-none": "divideStyle",
|
|
1841
|
+
// Appearance
|
|
1842
|
+
"appearance-none": "appearance",
|
|
1843
|
+
"appearance-auto": "appearance"
|
|
1844
|
+
};
|
|
1845
|
+
var BOOLEAN_VALUE_MAP = {
|
|
1846
|
+
// Snap types
|
|
1847
|
+
"snap-none": { prop: "snapType", value: "none" },
|
|
1848
|
+
"snap-x": { prop: "snapType", value: "x" },
|
|
1849
|
+
"snap-y": { prop: "snapType", value: "y" },
|
|
1850
|
+
"snap-both": { prop: "snapType", value: "both" },
|
|
1851
|
+
"snap-mandatory": { prop: "snapStrictness", value: "mandatory" },
|
|
1852
|
+
"snap-proximity": { prop: "snapStrictness", value: "proximity" },
|
|
1853
|
+
"snap-start": { prop: "snapAlign", value: "start" },
|
|
1854
|
+
"snap-end": { prop: "snapAlign", value: "end" },
|
|
1855
|
+
"snap-center": { prop: "snapAlign", value: "center" },
|
|
1856
|
+
"snap-align-none": { prop: "snapAlign", value: "none" },
|
|
1857
|
+
"snap-normal": { prop: "snapStop", value: "normal" },
|
|
1858
|
+
"snap-always": { prop: "snapStop", value: "always" },
|
|
1859
|
+
// Divide styles
|
|
1860
|
+
"divide-solid": { prop: "divideStyle", value: "solid" },
|
|
1861
|
+
"divide-dashed": { prop: "divideStyle", value: "dashed" },
|
|
1862
|
+
"divide-dotted": { prop: "divideStyle", value: "dotted" },
|
|
1863
|
+
"divide-double": { prop: "divideStyle", value: "double" },
|
|
1864
|
+
"divide-none": { prop: "divideStyle", value: "none" },
|
|
1865
|
+
// Font variants
|
|
1866
|
+
"normal-nums": { prop: "fontVariant", value: "normal-nums" },
|
|
1867
|
+
"lining-nums": { prop: "fontVariant", value: "lining-nums" },
|
|
1868
|
+
"oldstyle-nums": { prop: "fontVariant", value: "oldstyle-nums" },
|
|
1869
|
+
"proportional-nums": { prop: "fontVariant", value: "proportional-nums" },
|
|
1870
|
+
"tabular-nums": { prop: "fontVariant", value: "tabular-nums" },
|
|
1871
|
+
"diagonal-fractions": { prop: "fontVariant", value: "diagonal-fractions" },
|
|
1872
|
+
"stacked-fractions": { prop: "fontVariant", value: "stacked-fractions" },
|
|
1873
|
+
// Appearance
|
|
1874
|
+
"appearance-none": { prop: "appearance", value: "none" },
|
|
1875
|
+
"appearance-auto": { prop: "appearance", value: "auto" }
|
|
1876
|
+
};
|
|
1877
|
+
var SORTED_PREFIXES = Object.keys(REVERSE_PROPERTY_MAP).sort((a, b) => {
|
|
1878
|
+
if (b.length !== a.length) {
|
|
1879
|
+
return b.length - a.length;
|
|
1880
|
+
}
|
|
1881
|
+
return a.localeCompare(b);
|
|
1882
|
+
});
|
|
1883
|
+
var NEGATIVE_ALLOWED = /* @__PURE__ */ new Set([
|
|
1884
|
+
"m",
|
|
1885
|
+
"mt",
|
|
1886
|
+
"mr",
|
|
1887
|
+
"mb",
|
|
1888
|
+
"ml",
|
|
1889
|
+
"mx",
|
|
1890
|
+
"my",
|
|
1891
|
+
"ms",
|
|
1892
|
+
"me",
|
|
1893
|
+
"top",
|
|
1894
|
+
"right",
|
|
1895
|
+
"bottom",
|
|
1896
|
+
"left",
|
|
1897
|
+
"inset",
|
|
1898
|
+
"inset-x",
|
|
1899
|
+
"inset-y",
|
|
1900
|
+
"start",
|
|
1901
|
+
"end",
|
|
1902
|
+
"z",
|
|
1903
|
+
"order",
|
|
1904
|
+
"col",
|
|
1905
|
+
"col-start",
|
|
1906
|
+
"col-end",
|
|
1907
|
+
"row",
|
|
1908
|
+
"row-start",
|
|
1909
|
+
"row-end",
|
|
1910
|
+
"rotate",
|
|
1911
|
+
"skew-x",
|
|
1912
|
+
"skew-y",
|
|
1913
|
+
"translate-x",
|
|
1914
|
+
"translate-y",
|
|
1915
|
+
"space-x",
|
|
1916
|
+
"space-y",
|
|
1917
|
+
"tracking",
|
|
1918
|
+
"indent",
|
|
1919
|
+
"scroll-m",
|
|
1920
|
+
"scroll-mx",
|
|
1921
|
+
"scroll-my",
|
|
1922
|
+
"scroll-mt",
|
|
1923
|
+
"scroll-mr",
|
|
1924
|
+
"scroll-mb",
|
|
1925
|
+
"scroll-ml",
|
|
1926
|
+
"hue-rotate",
|
|
1927
|
+
"backdrop-hue-rotate"
|
|
1928
|
+
]);
|
|
1929
|
+
var FRACTION_SUPPORTED = /* @__PURE__ */ new Set([
|
|
1930
|
+
"w",
|
|
1931
|
+
"min-w",
|
|
1932
|
+
"max-w",
|
|
1933
|
+
"h",
|
|
1934
|
+
"min-h",
|
|
1935
|
+
"max-h",
|
|
1936
|
+
"size",
|
|
1937
|
+
"basis",
|
|
1938
|
+
"inset",
|
|
1939
|
+
"inset-x",
|
|
1940
|
+
"inset-y",
|
|
1941
|
+
"top",
|
|
1942
|
+
"right",
|
|
1943
|
+
"bottom",
|
|
1944
|
+
"left",
|
|
1945
|
+
"start",
|
|
1946
|
+
"end",
|
|
1947
|
+
"translate-x",
|
|
1948
|
+
"translate-y"
|
|
1949
|
+
]);
|
|
1950
|
+
var SPACING_PROPS = /* @__PURE__ */ new Set([
|
|
1951
|
+
"p",
|
|
1952
|
+
"pt",
|
|
1953
|
+
"pr",
|
|
1954
|
+
"pb",
|
|
1955
|
+
"pl",
|
|
1956
|
+
"px",
|
|
1957
|
+
"py",
|
|
1958
|
+
"ps",
|
|
1959
|
+
"pe",
|
|
1960
|
+
"m",
|
|
1961
|
+
"mt",
|
|
1962
|
+
"mr",
|
|
1963
|
+
"mb",
|
|
1964
|
+
"ml",
|
|
1965
|
+
"mx",
|
|
1966
|
+
"my",
|
|
1967
|
+
"ms",
|
|
1968
|
+
"me",
|
|
1969
|
+
"gap",
|
|
1970
|
+
"gap-x",
|
|
1971
|
+
"gap-y",
|
|
1972
|
+
"w",
|
|
1973
|
+
"h",
|
|
1974
|
+
"min-w",
|
|
1975
|
+
"max-w",
|
|
1976
|
+
"min-h",
|
|
1977
|
+
"max-h",
|
|
1978
|
+
"size",
|
|
1979
|
+
"basis",
|
|
1980
|
+
"inset",
|
|
1981
|
+
"inset-x",
|
|
1982
|
+
"inset-y",
|
|
1983
|
+
"top",
|
|
1984
|
+
"right",
|
|
1985
|
+
"bottom",
|
|
1986
|
+
"left",
|
|
1987
|
+
"start",
|
|
1988
|
+
"end",
|
|
1989
|
+
"space-x",
|
|
1990
|
+
"space-y",
|
|
1991
|
+
"indent",
|
|
1992
|
+
"scroll-m",
|
|
1993
|
+
"scroll-mx",
|
|
1994
|
+
"scroll-my",
|
|
1995
|
+
"scroll-mt",
|
|
1996
|
+
"scroll-mr",
|
|
1997
|
+
"scroll-mb",
|
|
1998
|
+
"scroll-ml",
|
|
1999
|
+
"scroll-ms",
|
|
2000
|
+
"scroll-me",
|
|
2001
|
+
"scroll-p",
|
|
2002
|
+
"scroll-px",
|
|
2003
|
+
"scroll-py",
|
|
2004
|
+
"scroll-pt",
|
|
2005
|
+
"scroll-pr",
|
|
2006
|
+
"scroll-pb",
|
|
2007
|
+
"scroll-pl",
|
|
2008
|
+
"scroll-ps",
|
|
2009
|
+
"scroll-pe",
|
|
2010
|
+
"border-spacing",
|
|
2011
|
+
"translate-x",
|
|
2012
|
+
"translate-y"
|
|
2013
|
+
]);
|
|
2014
|
+
var TEXT_SIZE_KEYWORDS = /* @__PURE__ */ new Set([
|
|
2015
|
+
"xs",
|
|
2016
|
+
"sm",
|
|
2017
|
+
"base",
|
|
2018
|
+
"lg",
|
|
2019
|
+
"xl",
|
|
2020
|
+
"2xl",
|
|
2021
|
+
"3xl",
|
|
2022
|
+
"4xl",
|
|
2023
|
+
"5xl",
|
|
2024
|
+
"6xl",
|
|
2025
|
+
"7xl",
|
|
2026
|
+
"8xl",
|
|
2027
|
+
"9xl"
|
|
2028
|
+
]);
|
|
2029
|
+
var TEXT_ALIGN_KEYWORDS = /* @__PURE__ */ new Set([
|
|
2030
|
+
"left",
|
|
2031
|
+
"center",
|
|
2032
|
+
"right",
|
|
2033
|
+
"justify",
|
|
2034
|
+
"start",
|
|
2035
|
+
"end"
|
|
2036
|
+
]);
|
|
2037
|
+
var TEXT_WRAP_KEYWORDS = /* @__PURE__ */ new Set([
|
|
2038
|
+
"wrap",
|
|
2039
|
+
"nowrap",
|
|
2040
|
+
"balance",
|
|
2041
|
+
"pretty"
|
|
2042
|
+
]);
|
|
2043
|
+
var TEXT_OVERFLOW_KEYWORDS = /* @__PURE__ */ new Set([
|
|
2044
|
+
"ellipsis",
|
|
2045
|
+
"clip"
|
|
2046
|
+
]);
|
|
2047
|
+
var FONT_WEIGHT_KEYWORDS = /* @__PURE__ */ new Set([
|
|
2048
|
+
"thin",
|
|
2049
|
+
"extralight",
|
|
2050
|
+
"light",
|
|
2051
|
+
"normal",
|
|
2052
|
+
"medium",
|
|
2053
|
+
"semibold",
|
|
2054
|
+
"bold",
|
|
2055
|
+
"extrabold",
|
|
2056
|
+
"black"
|
|
2057
|
+
]);
|
|
2058
|
+
var FONT_FAMILY_KEYWORDS = /* @__PURE__ */ new Set([
|
|
2059
|
+
"sans",
|
|
2060
|
+
"serif",
|
|
2061
|
+
"mono"
|
|
2062
|
+
]);
|
|
2063
|
+
var FONT_STRETCH_KEYWORDS = /* @__PURE__ */ new Set([
|
|
2064
|
+
"ultra-condensed",
|
|
2065
|
+
"extra-condensed",
|
|
2066
|
+
"condensed",
|
|
2067
|
+
"semi-condensed",
|
|
2068
|
+
"semi-expanded",
|
|
2069
|
+
"expanded",
|
|
2070
|
+
"extra-expanded",
|
|
2071
|
+
"ultra-expanded"
|
|
2072
|
+
]);
|
|
2073
|
+
var BORDER_WIDTH_KEYWORDS = /* @__PURE__ */ new Set(["0", "2", "4", "8"]);
|
|
2074
|
+
var BORDER_STYLE_KEYWORDS = /* @__PURE__ */ new Set([
|
|
2075
|
+
"solid",
|
|
2076
|
+
"dashed",
|
|
2077
|
+
"dotted",
|
|
2078
|
+
"double",
|
|
2079
|
+
"none",
|
|
2080
|
+
"hidden"
|
|
2081
|
+
]);
|
|
2082
|
+
var BG_POSITION_KEYWORDS = /* @__PURE__ */ new Set([
|
|
2083
|
+
"center",
|
|
2084
|
+
"top",
|
|
2085
|
+
"bottom",
|
|
2086
|
+
"left",
|
|
2087
|
+
"right",
|
|
2088
|
+
"left-top",
|
|
2089
|
+
"left-bottom",
|
|
2090
|
+
"right-top",
|
|
2091
|
+
"right-bottom"
|
|
2092
|
+
]);
|
|
2093
|
+
var BG_SIZE_KEYWORDS = /* @__PURE__ */ new Set(["cover", "contain", "auto"]);
|
|
2094
|
+
var BG_REPEAT_KEYWORDS = /* @__PURE__ */ new Set([
|
|
2095
|
+
"repeat",
|
|
2096
|
+
"no-repeat",
|
|
2097
|
+
"repeat-x",
|
|
2098
|
+
"repeat-y",
|
|
2099
|
+
"round",
|
|
2100
|
+
"space"
|
|
2101
|
+
]);
|
|
2102
|
+
var BG_ATTACHMENT_KEYWORDS = /* @__PURE__ */ new Set(["fixed", "local", "scroll"]);
|
|
2103
|
+
var OBJECT_FIT_KEYWORDS = /* @__PURE__ */ new Set(["contain", "cover", "fill", "none", "scale-down"]);
|
|
2104
|
+
var OBJECT_POSITION_KEYWORDS = /* @__PURE__ */ new Set([
|
|
2105
|
+
"center",
|
|
2106
|
+
"top",
|
|
2107
|
+
"bottom",
|
|
2108
|
+
"left",
|
|
2109
|
+
"right",
|
|
2110
|
+
"left-top",
|
|
2111
|
+
"left-bottom",
|
|
2112
|
+
"right-top",
|
|
2113
|
+
"right-bottom"
|
|
2114
|
+
]);
|
|
2115
|
+
var SHADOW_SIZE_KEYWORDS = /* @__PURE__ */ new Set(["sm", "md", "lg", "xl", "2xl", "inner", "none"]);
|
|
2116
|
+
var OUTLINE_STYLE_KEYWORDS = /* @__PURE__ */ new Set(["none", "dashed", "dotted", "double"]);
|
|
2117
|
+
var DECORATION_STYLE_KEYWORDS = /* @__PURE__ */ new Set(["solid", "double", "dotted", "dashed", "wavy"]);
|
|
2118
|
+
var DECORATION_THICKNESS_KEYWORDS = /* @__PURE__ */ new Set(["auto", "from-font", "0", "1", "2", "4", "8"]);
|
|
2119
|
+
var TRANSITION_PROPERTY_KEYWORDS = /* @__PURE__ */ new Set([
|
|
2120
|
+
"none",
|
|
2121
|
+
"all",
|
|
2122
|
+
"colors",
|
|
2123
|
+
"opacity",
|
|
2124
|
+
"shadow",
|
|
2125
|
+
"transform"
|
|
2126
|
+
]);
|
|
2127
|
+
var REVERSE_VARIANT_MAP = {
|
|
2128
|
+
"focus-within": "focusWithin",
|
|
2129
|
+
"focus-visible": "focusVisible",
|
|
2130
|
+
"first-of-type": "firstOfType",
|
|
2131
|
+
"last-of-type": "lastOfType",
|
|
2132
|
+
"only-of-type": "onlyOfType",
|
|
2133
|
+
"motion-reduce": "motionReduce",
|
|
2134
|
+
"motion-safe": "motionSafe",
|
|
2135
|
+
"contrast-more": "contrastMore",
|
|
2136
|
+
"contrast-less": "contrastLess",
|
|
2137
|
+
"first-line": "firstLine",
|
|
2138
|
+
"first-letter": "firstLetter",
|
|
2139
|
+
"placeholder-shown": "placeholderShown",
|
|
2140
|
+
"in-range": "inRange",
|
|
2141
|
+
"out-of-range": "outOfRange",
|
|
2142
|
+
"read-only": "readOnly",
|
|
2143
|
+
"pointer-fine": "pointerFine",
|
|
2144
|
+
"pointer-coarse": "pointerCoarse",
|
|
2145
|
+
"pointer-none": "pointerNone",
|
|
2146
|
+
"@max-sm": "@maxSm",
|
|
2147
|
+
"@max-md": "@maxMd",
|
|
2148
|
+
"@max-lg": "@maxLg",
|
|
2149
|
+
"@max-xl": "@maxXl",
|
|
2150
|
+
"@max-2xl": "@max2xl"
|
|
2151
|
+
};
|
|
2152
|
+
var KNOWN_SIMPLE_VARIANTS = /* @__PURE__ */ new Set([
|
|
2153
|
+
"sm",
|
|
2154
|
+
"md",
|
|
2155
|
+
"lg",
|
|
2156
|
+
"xl",
|
|
2157
|
+
"2xl",
|
|
2158
|
+
"@sm",
|
|
2159
|
+
"@md",
|
|
2160
|
+
"@lg",
|
|
2161
|
+
"@xl",
|
|
2162
|
+
"@2xl",
|
|
2163
|
+
"dark",
|
|
2164
|
+
"light",
|
|
2165
|
+
"print",
|
|
2166
|
+
"portrait",
|
|
2167
|
+
"landscape",
|
|
2168
|
+
"hover",
|
|
2169
|
+
"focus",
|
|
2170
|
+
"active",
|
|
2171
|
+
"visited",
|
|
2172
|
+
"target",
|
|
2173
|
+
"disabled",
|
|
2174
|
+
"enabled",
|
|
2175
|
+
"checked",
|
|
2176
|
+
"indeterminate",
|
|
2177
|
+
"default",
|
|
2178
|
+
"required",
|
|
2179
|
+
"valid",
|
|
2180
|
+
"invalid",
|
|
2181
|
+
"autofill",
|
|
2182
|
+
"open",
|
|
2183
|
+
"first",
|
|
2184
|
+
"last",
|
|
2185
|
+
"only",
|
|
2186
|
+
"odd",
|
|
2187
|
+
"even",
|
|
2188
|
+
"empty",
|
|
2189
|
+
"before",
|
|
2190
|
+
"after",
|
|
2191
|
+
"placeholder",
|
|
2192
|
+
"file",
|
|
2193
|
+
"marker",
|
|
2194
|
+
"selection",
|
|
2195
|
+
"backdrop",
|
|
2196
|
+
"ltr",
|
|
2197
|
+
"rtl"
|
|
2198
|
+
]);
|
|
2199
|
+
var KNOWN_VARIANTS = /* @__PURE__ */ new Set([
|
|
2200
|
+
...KNOWN_SIMPLE_VARIANTS,
|
|
2201
|
+
"focus-within",
|
|
2202
|
+
"focus-visible",
|
|
2203
|
+
"first-of-type",
|
|
2204
|
+
"last-of-type",
|
|
2205
|
+
"only-of-type",
|
|
2206
|
+
"first-child",
|
|
2207
|
+
"last-child",
|
|
2208
|
+
"only-child",
|
|
2209
|
+
"motion-reduce",
|
|
2210
|
+
"motion-safe",
|
|
2211
|
+
"contrast-more",
|
|
2212
|
+
"contrast-less",
|
|
2213
|
+
"first-line",
|
|
2214
|
+
"first-letter",
|
|
2215
|
+
"placeholder-shown",
|
|
2216
|
+
"in-range",
|
|
2217
|
+
"out-of-range",
|
|
2218
|
+
"read-only",
|
|
2219
|
+
"pointer-fine",
|
|
2220
|
+
"pointer-coarse",
|
|
2221
|
+
"pointer-none"
|
|
2222
|
+
]);
|
|
2223
|
+
|
|
2224
|
+
// src/migrate/class-parser.ts
|
|
2225
|
+
function parseClass(cls) {
|
|
2226
|
+
let important = false;
|
|
2227
|
+
let input = cls;
|
|
2228
|
+
if (input.endsWith("!")) {
|
|
2229
|
+
important = true;
|
|
2230
|
+
input = input.slice(0, -1);
|
|
2231
|
+
}
|
|
2232
|
+
let negative = false;
|
|
2233
|
+
let negInput = input;
|
|
2234
|
+
if (input.startsWith("-")) {
|
|
2235
|
+
negative = true;
|
|
2236
|
+
negInput = input.slice(1);
|
|
2237
|
+
}
|
|
2238
|
+
const boolResult = tryBooleanMatch(input);
|
|
2239
|
+
if (boolResult) {
|
|
2240
|
+
return applyImportant(boolResult, important);
|
|
2241
|
+
}
|
|
2242
|
+
const gradResult = tryGradient(negInput, negative);
|
|
2243
|
+
if (gradResult) {
|
|
2244
|
+
return applyImportant(gradResult, important);
|
|
2245
|
+
}
|
|
2246
|
+
const source = negative ? negInput : input;
|
|
2247
|
+
for (const prefix of SORTED_PREFIXES) {
|
|
2248
|
+
if (source === prefix) {
|
|
2249
|
+
const prop = REVERSE_PROPERTY_MAP[prefix];
|
|
2250
|
+
if (negative && NEGATIVE_ALLOWED.has(prefix)) {
|
|
2251
|
+
continue;
|
|
2252
|
+
}
|
|
2253
|
+
if (REVERSE_BOOLEAN_MAP[source]) {
|
|
2254
|
+
return applyImportant({ prop: REVERSE_BOOLEAN_MAP[source], value: true }, important);
|
|
2255
|
+
}
|
|
2256
|
+
if (prefix === "divide-x" || prefix === "divide-y") {
|
|
2257
|
+
return applyImportant({ prop, value: true }, important);
|
|
2258
|
+
}
|
|
2259
|
+
if (prefix === "border") {
|
|
2260
|
+
return applyImportant({ prop: "border", value: true }, important);
|
|
2261
|
+
}
|
|
2262
|
+
continue;
|
|
2263
|
+
}
|
|
2264
|
+
if (source.startsWith(prefix + "-")) {
|
|
2265
|
+
const rawValue = source.slice(prefix.length + 1);
|
|
2266
|
+
if (!rawValue) {
|
|
2267
|
+
continue;
|
|
2268
|
+
}
|
|
2269
|
+
if (negative && !NEGATIVE_ALLOWED.has(prefix)) {
|
|
2270
|
+
continue;
|
|
2271
|
+
}
|
|
2272
|
+
if (SPACING_PROPS.has(prefix) && !isValidSpacingValue(rawValue)) {
|
|
2273
|
+
continue;
|
|
2274
|
+
}
|
|
2275
|
+
const result = disambiguateAndParse(prefix, rawValue, negative);
|
|
2276
|
+
if (result) {
|
|
2277
|
+
return applyImportant(result, important);
|
|
2278
|
+
}
|
|
2279
|
+
}
|
|
2280
|
+
}
|
|
2281
|
+
const displayResult = tryDisplay(input);
|
|
2282
|
+
if (displayResult) {
|
|
2283
|
+
return applyImportant(displayResult, important);
|
|
2284
|
+
}
|
|
2285
|
+
if (input.startsWith("[") && input.endsWith("]") && input.includes(":")) {
|
|
2286
|
+
const inner = input.slice(1, -1);
|
|
2287
|
+
if (inner.startsWith("--")) {
|
|
2288
|
+
const colonIdx = inner.indexOf(":");
|
|
2289
|
+
return applyImportant({
|
|
2290
|
+
prop: inner.slice(0, colonIdx),
|
|
2291
|
+
value: inner.slice(colonIdx + 1)
|
|
2292
|
+
}, important);
|
|
2293
|
+
}
|
|
2294
|
+
}
|
|
2295
|
+
return null;
|
|
2296
|
+
}
|
|
2297
|
+
function applyImportant(result, important) {
|
|
2298
|
+
if (!important) {
|
|
2299
|
+
return result;
|
|
2300
|
+
}
|
|
2301
|
+
if (typeof result.value === "string") {
|
|
2302
|
+
return { prop: result.prop, value: result.value + "!" };
|
|
2303
|
+
}
|
|
2304
|
+
if (typeof result.value === "boolean") {
|
|
2305
|
+
return { prop: result.prop, value: "!" };
|
|
2306
|
+
}
|
|
2307
|
+
if (typeof result.value === "number") {
|
|
2308
|
+
return { prop: result.prop, value: String(result.value) + "!" };
|
|
2309
|
+
}
|
|
2310
|
+
return result;
|
|
2311
|
+
}
|
|
2312
|
+
function tryBooleanMatch(cls) {
|
|
2313
|
+
if (BOOLEAN_VALUE_MAP[cls]) {
|
|
2314
|
+
const { prop, value } = BOOLEAN_VALUE_MAP[cls];
|
|
2315
|
+
return { prop, value };
|
|
2316
|
+
}
|
|
2317
|
+
if (REVERSE_BOOLEAN_MAP[cls]) {
|
|
2318
|
+
return { prop: REVERSE_BOOLEAN_MAP[cls], value: true };
|
|
2319
|
+
}
|
|
2320
|
+
return null;
|
|
2321
|
+
}
|
|
2322
|
+
function tryDisplay(cls) {
|
|
2323
|
+
const displayValues = /* @__PURE__ */ new Set([
|
|
2324
|
+
"block",
|
|
2325
|
+
"inline",
|
|
2326
|
+
"inline-block",
|
|
2327
|
+
"flex",
|
|
2328
|
+
"inline-flex",
|
|
2329
|
+
"grid",
|
|
2330
|
+
"inline-grid",
|
|
2331
|
+
"hidden",
|
|
2332
|
+
"contents",
|
|
2333
|
+
"table",
|
|
2334
|
+
"table-row",
|
|
2335
|
+
"table-cell",
|
|
2336
|
+
"flow-root",
|
|
2337
|
+
"list-item"
|
|
2338
|
+
]);
|
|
2339
|
+
if (displayValues.has(cls)) {
|
|
2340
|
+
return REVERSE_BOOLEAN_MAP[cls] ? { prop: REVERSE_BOOLEAN_MAP[cls], value: true } : null;
|
|
2341
|
+
}
|
|
2342
|
+
return null;
|
|
2343
|
+
}
|
|
2344
|
+
function tryGradient(cls, negative) {
|
|
2345
|
+
let input = cls;
|
|
2346
|
+
let type = null;
|
|
2347
|
+
if (input.startsWith("bg-linear")) {
|
|
2348
|
+
type = "linear";
|
|
2349
|
+
input = input.slice("bg-linear".length);
|
|
2350
|
+
} else if (input.startsWith("bg-radial")) {
|
|
2351
|
+
type = "radial";
|
|
2352
|
+
input = input.slice("bg-radial".length);
|
|
2353
|
+
} else if (input.startsWith("bg-conic")) {
|
|
2354
|
+
type = "conic";
|
|
2355
|
+
input = input.slice("bg-conic".length);
|
|
2356
|
+
}
|
|
2357
|
+
if (!type) {
|
|
2358
|
+
return null;
|
|
2359
|
+
}
|
|
2360
|
+
let colorInterp;
|
|
2361
|
+
const slashIdx = findTopLevelSlash(input);
|
|
2362
|
+
if (slashIdx !== -1) {
|
|
2363
|
+
colorInterp = input.slice(slashIdx + 1);
|
|
2364
|
+
input = input.slice(0, slashIdx);
|
|
2365
|
+
}
|
|
2366
|
+
const grad = { gradient: type };
|
|
2367
|
+
if (input === "" || input === void 0) {
|
|
2368
|
+
} else if (input.startsWith("-")) {
|
|
2369
|
+
const dir = input.slice(1);
|
|
2370
|
+
if (dir.startsWith("[") && dir.endsWith("]")) {
|
|
2371
|
+
grad.dir = dir.slice(1, -1).replace(/_/g, " ");
|
|
2372
|
+
} else if (dir.startsWith("(") && dir.endsWith(")")) {
|
|
2373
|
+
grad.dir = dir.slice(1, -1);
|
|
2374
|
+
} else if (/^\d+$/.test(dir)) {
|
|
2375
|
+
grad.dir = negative ? -parseInt(dir, 10) : parseInt(dir, 10);
|
|
2376
|
+
} else {
|
|
2377
|
+
grad.dir = dir;
|
|
2378
|
+
}
|
|
2379
|
+
}
|
|
2380
|
+
if (colorInterp) {
|
|
2381
|
+
grad.in = colorInterp;
|
|
2382
|
+
}
|
|
2383
|
+
return { prop: "bgImg", value: grad };
|
|
2384
|
+
}
|
|
2385
|
+
function findTopLevelSlash(s) {
|
|
2386
|
+
let depth = 0;
|
|
2387
|
+
for (let i = 0; i < s.length; i++) {
|
|
2388
|
+
if (s[i] === "[" || s[i] === "(") {
|
|
2389
|
+
depth++;
|
|
2390
|
+
} else if (s[i] === "]" || s[i] === ")") {
|
|
2391
|
+
depth--;
|
|
2392
|
+
} else if (s[i] === "/" && depth === 0) {
|
|
2393
|
+
return i;
|
|
2394
|
+
}
|
|
2395
|
+
}
|
|
2396
|
+
return -1;
|
|
2397
|
+
}
|
|
2398
|
+
function disambiguateAndParse(prefix, rawValue, negative) {
|
|
2399
|
+
const slashIdx = findTopLevelSlash(rawValue);
|
|
2400
|
+
let opacity;
|
|
2401
|
+
let value = rawValue;
|
|
2402
|
+
if (slashIdx !== -1 && !isGradientPrefix(prefix)) {
|
|
2403
|
+
const isFraction = FRACTION_SUPPORTED.has(prefix) && /^\d+\/\d+$/.test(rawValue);
|
|
2404
|
+
if (!isFraction) {
|
|
2405
|
+
opacity = rawValue.slice(slashIdx + 1);
|
|
2406
|
+
value = rawValue.slice(0, slashIdx);
|
|
2407
|
+
if (opacity.startsWith("[") && opacity.endsWith("]")) {
|
|
2408
|
+
opacity = opacity.slice(1, -1);
|
|
2409
|
+
} else if (opacity.startsWith("(") && opacity.endsWith(")")) {
|
|
2410
|
+
opacity = opacity.slice(1, -1);
|
|
2411
|
+
} else {
|
|
2412
|
+
const opNum = Number(opacity);
|
|
2413
|
+
if (!isNaN(opNum)) {
|
|
2414
|
+
opacity = opNum;
|
|
2415
|
+
}
|
|
2416
|
+
}
|
|
2417
|
+
}
|
|
2418
|
+
}
|
|
2419
|
+
const result = disambiguate(prefix, value, negative);
|
|
2420
|
+
if (!result) {
|
|
2421
|
+
return null;
|
|
2422
|
+
}
|
|
2423
|
+
if (opacity !== void 0 && typeof result.value === "string") {
|
|
2424
|
+
return {
|
|
2425
|
+
prop: result.prop,
|
|
2426
|
+
value: { color: result.value, op: opacity }
|
|
2427
|
+
};
|
|
2428
|
+
}
|
|
2429
|
+
return result;
|
|
2430
|
+
}
|
|
2431
|
+
function isGradientPrefix(prefix) {
|
|
2432
|
+
return prefix === "from" || prefix === "via" || prefix === "to";
|
|
2433
|
+
}
|
|
2434
|
+
function disambiguate(prefix, value, negative) {
|
|
2435
|
+
switch (prefix) {
|
|
2436
|
+
case "text":
|
|
2437
|
+
return disambiguateText(value);
|
|
2438
|
+
case "font":
|
|
2439
|
+
return disambiguateFont(value);
|
|
2440
|
+
case "border":
|
|
2441
|
+
return disambiguateBorder(value);
|
|
2442
|
+
case "bg":
|
|
2443
|
+
return disambiguateBg(value);
|
|
2444
|
+
case "object":
|
|
2445
|
+
return disambiguateObject(value);
|
|
2446
|
+
case "shadow":
|
|
2447
|
+
return disambiguateShadow(value);
|
|
2448
|
+
case "outline":
|
|
2449
|
+
return disambiguateOutline(value);
|
|
2450
|
+
case "decoration":
|
|
2451
|
+
return disambiguateDecoration(value);
|
|
2452
|
+
case "transition":
|
|
2453
|
+
return disambiguateTransition(value);
|
|
2454
|
+
case "ring":
|
|
2455
|
+
return disambiguateRing(value, negative);
|
|
2456
|
+
case "ring-offset":
|
|
2457
|
+
return disambiguateRingOffset(value);
|
|
2458
|
+
case "stroke":
|
|
2459
|
+
return disambiguateStroke(value);
|
|
2460
|
+
case "list":
|
|
2461
|
+
return disambiguateList(value);
|
|
2462
|
+
case "ease":
|
|
2463
|
+
return { prop: "ease", value: parseValue("ease", value, negative) };
|
|
2464
|
+
case "snap":
|
|
2465
|
+
return disambiguateSnap(value);
|
|
2466
|
+
case "flex":
|
|
2467
|
+
return disambiguateFlex(value);
|
|
2468
|
+
case "table":
|
|
2469
|
+
return disambiguateTable(value);
|
|
2470
|
+
case "divide":
|
|
2471
|
+
return disambiguateDivide(value);
|
|
2472
|
+
case "break":
|
|
2473
|
+
if (value === "words") {
|
|
2474
|
+
return { prop: "wrap", value: "break-word" };
|
|
2475
|
+
}
|
|
2476
|
+
return { prop: "break", value };
|
|
2477
|
+
case "wrap":
|
|
2478
|
+
return { prop: "wrap", value };
|
|
2479
|
+
default:
|
|
2480
|
+
return {
|
|
2481
|
+
prop: REVERSE_PROPERTY_MAP[prefix] || prefix,
|
|
2482
|
+
value: parseValue(prefix, value, negative)
|
|
2483
|
+
};
|
|
2484
|
+
}
|
|
2485
|
+
}
|
|
2486
|
+
function disambiguateText(value) {
|
|
2487
|
+
if (TEXT_SIZE_KEYWORDS.has(value)) {
|
|
2488
|
+
return { prop: "text", value };
|
|
2489
|
+
}
|
|
2490
|
+
if (TEXT_ALIGN_KEYWORDS.has(value)) {
|
|
2491
|
+
return { prop: "textAlign", value };
|
|
2492
|
+
}
|
|
2493
|
+
if (TEXT_WRAP_KEYWORDS.has(value)) {
|
|
2494
|
+
return { prop: "textWrap", value };
|
|
2495
|
+
}
|
|
2496
|
+
if (TEXT_OVERFLOW_KEYWORDS.has(value)) {
|
|
2497
|
+
return { prop: "textOverflow", value };
|
|
2498
|
+
}
|
|
2499
|
+
return { prop: "color", value: parseStringValue(value) };
|
|
2500
|
+
}
|
|
2501
|
+
function disambiguateFont(value) {
|
|
2502
|
+
if (FONT_WEIGHT_KEYWORDS.has(value)) {
|
|
2503
|
+
return { prop: "fontWeight", value };
|
|
2504
|
+
}
|
|
2505
|
+
if (/^\d{3}$/.test(value)) {
|
|
2506
|
+
return { prop: "fontWeight", value: parseInt(value, 10) };
|
|
2507
|
+
}
|
|
2508
|
+
if (FONT_FAMILY_KEYWORDS.has(value)) {
|
|
2509
|
+
return { prop: "fontFamily", value };
|
|
2510
|
+
}
|
|
2511
|
+
if (value.startsWith("stretch-")) {
|
|
2512
|
+
const stretchVal = value.slice("stretch-".length);
|
|
2513
|
+
return { prop: "fontStretch", value: stretchVal };
|
|
2514
|
+
}
|
|
2515
|
+
if (FONT_STRETCH_KEYWORDS.has(value)) {
|
|
2516
|
+
return { prop: "fontStretch", value };
|
|
2517
|
+
}
|
|
2518
|
+
return { prop: "fontFamily", value: parseStringValue(value) };
|
|
2519
|
+
}
|
|
2520
|
+
function disambiguateBorder(value) {
|
|
2521
|
+
if (BORDER_WIDTH_KEYWORDS.has(value) || value === "px") {
|
|
2522
|
+
return { prop: "border", value: parseNumericOrString("border", value, false) };
|
|
2523
|
+
}
|
|
2524
|
+
if (BORDER_STYLE_KEYWORDS.has(value)) {
|
|
2525
|
+
return { prop: "borderStyle", value };
|
|
2526
|
+
}
|
|
2527
|
+
return { prop: "borderColor", value: parseStringValue(value) };
|
|
2528
|
+
}
|
|
2529
|
+
function disambiguateBg(value) {
|
|
2530
|
+
if (BG_POSITION_KEYWORDS.has(value)) {
|
|
2531
|
+
return { prop: "bgPos", value };
|
|
2532
|
+
}
|
|
2533
|
+
if (BG_SIZE_KEYWORDS.has(value)) {
|
|
2534
|
+
return { prop: "bgSize", value };
|
|
2535
|
+
}
|
|
2536
|
+
if (BG_REPEAT_KEYWORDS.has(value)) {
|
|
2537
|
+
return { prop: "bgRepeat", value };
|
|
2538
|
+
}
|
|
2539
|
+
if (BG_ATTACHMENT_KEYWORDS.has(value)) {
|
|
2540
|
+
return { prop: "bgAttach", value };
|
|
2541
|
+
}
|
|
2542
|
+
if (value === "none") {
|
|
2543
|
+
return { prop: "bgImg", value: "none" };
|
|
2544
|
+
}
|
|
2545
|
+
return { prop: "bg", value: parseStringValue(value) };
|
|
2546
|
+
}
|
|
2547
|
+
function disambiguateObject(value) {
|
|
2548
|
+
if (OBJECT_FIT_KEYWORDS.has(value)) {
|
|
2549
|
+
return { prop: "objectFit", value };
|
|
2550
|
+
}
|
|
2551
|
+
if (OBJECT_POSITION_KEYWORDS.has(value)) {
|
|
2552
|
+
return { prop: "objectPos", value };
|
|
2553
|
+
}
|
|
2554
|
+
return { prop: "objectPos", value: parseStringValue(value) };
|
|
2555
|
+
}
|
|
2556
|
+
function disambiguateShadow(value) {
|
|
2557
|
+
if (SHADOW_SIZE_KEYWORDS.has(value)) {
|
|
2558
|
+
return { prop: "shadow", value };
|
|
2559
|
+
}
|
|
2560
|
+
return { prop: "shadowColor", value: parseStringValue(value) };
|
|
2561
|
+
}
|
|
2562
|
+
function disambiguateOutline(value) {
|
|
2563
|
+
if (OUTLINE_STYLE_KEYWORDS.has(value)) {
|
|
2564
|
+
return { prop: "outlineStyle", value };
|
|
2565
|
+
}
|
|
2566
|
+
const num = Number(value);
|
|
2567
|
+
if (!isNaN(num) && Number.isInteger(num)) {
|
|
2568
|
+
return { prop: "outline", value: num };
|
|
2569
|
+
}
|
|
2570
|
+
return { prop: "outlineColor", value: parseStringValue(value) };
|
|
2571
|
+
}
|
|
2572
|
+
function disambiguateDecoration(value) {
|
|
2573
|
+
if (DECORATION_STYLE_KEYWORDS.has(value)) {
|
|
2574
|
+
return { prop: "decorationStyle", value };
|
|
2575
|
+
}
|
|
2576
|
+
if (DECORATION_THICKNESS_KEYWORDS.has(value)) {
|
|
2577
|
+
const num = Number(value);
|
|
2578
|
+
if (!isNaN(num)) {
|
|
2579
|
+
return { prop: "decorationThickness", value };
|
|
2580
|
+
}
|
|
2581
|
+
return { prop: "decorationThickness", value };
|
|
2582
|
+
}
|
|
2583
|
+
return { prop: "decorationColor", value: parseStringValue(value) };
|
|
2584
|
+
}
|
|
2585
|
+
function disambiguateRing(value, negative) {
|
|
2586
|
+
const num = Number(value);
|
|
2587
|
+
if (!isNaN(num) && Number.isInteger(num)) {
|
|
2588
|
+
return { prop: "ring", value: negative ? -num : num };
|
|
2589
|
+
}
|
|
2590
|
+
if (value === "inset") {
|
|
2591
|
+
return { prop: "ring", value: "inset" };
|
|
2592
|
+
}
|
|
2593
|
+
return { prop: "ringColor", value: parseStringValue(value) };
|
|
2594
|
+
}
|
|
2595
|
+
function disambiguateRingOffset(value) {
|
|
2596
|
+
const num = Number(value);
|
|
2597
|
+
if (!isNaN(num) && Number.isInteger(num)) {
|
|
2598
|
+
return { prop: "ringOffset", value: num };
|
|
2599
|
+
}
|
|
2600
|
+
return { prop: "ringOffsetColor", value: parseStringValue(value) };
|
|
2601
|
+
}
|
|
2602
|
+
function disambiguateStroke(value) {
|
|
2603
|
+
const num = Number(value);
|
|
2604
|
+
if (!isNaN(num) && Number.isInteger(num)) {
|
|
2605
|
+
return { prop: "strokeWidth", value: num };
|
|
2606
|
+
}
|
|
2607
|
+
return { prop: "stroke", value: parseStringValue(value) };
|
|
2608
|
+
}
|
|
2609
|
+
function disambiguateTransition(value) {
|
|
2610
|
+
if (TRANSITION_PROPERTY_KEYWORDS.has(value)) {
|
|
2611
|
+
return { prop: "transition", value };
|
|
2612
|
+
}
|
|
2613
|
+
return { prop: "transition", value: parseStringValue(value) };
|
|
2614
|
+
}
|
|
2615
|
+
function disambiguateList(value) {
|
|
2616
|
+
if (value === "inside" || value === "outside") {
|
|
2617
|
+
return { prop: "listPos", value };
|
|
2618
|
+
}
|
|
2619
|
+
return { prop: "list", value: parseStringValue(value) };
|
|
2620
|
+
}
|
|
2621
|
+
function disambiguateSnap(value) {
|
|
2622
|
+
return null;
|
|
2623
|
+
}
|
|
2624
|
+
function disambiguateFlex(value) {
|
|
2625
|
+
const dirValues = /* @__PURE__ */ new Set(["row", "col", "row-reverse", "col-reverse"]);
|
|
2626
|
+
if (dirValues.has(value)) {
|
|
2627
|
+
return { prop: "flexDir", value };
|
|
2628
|
+
}
|
|
2629
|
+
const wrapValues = /* @__PURE__ */ new Set(["wrap", "nowrap", "wrap-reverse"]);
|
|
2630
|
+
if (wrapValues.has(value)) {
|
|
2631
|
+
return { prop: "flexWrap", value };
|
|
2632
|
+
}
|
|
2633
|
+
if (value === "1" || value === "auto" || value === "initial" || value === "none") {
|
|
2634
|
+
return { prop: "flex", value: parseStringValue(value) };
|
|
2635
|
+
}
|
|
2636
|
+
return { prop: "flex", value: parseStringValue(value) };
|
|
2637
|
+
}
|
|
2638
|
+
function disambiguateTable(value) {
|
|
2639
|
+
if (value === "auto" || value === "fixed") {
|
|
2640
|
+
return { prop: "tableLayout", value };
|
|
2641
|
+
}
|
|
2642
|
+
return null;
|
|
2643
|
+
}
|
|
2644
|
+
function disambiguateDivide(value) {
|
|
2645
|
+
return { prop: "divideColor", value: parseStringValue(value) };
|
|
2646
|
+
}
|
|
2647
|
+
function isValidSpacingValue(value) {
|
|
2648
|
+
if (value.startsWith("[") && value.endsWith("]")) {
|
|
2649
|
+
return true;
|
|
2650
|
+
}
|
|
2651
|
+
if (value.startsWith("(") && value.endsWith(")")) {
|
|
2652
|
+
return true;
|
|
2653
|
+
}
|
|
2654
|
+
if (!isNaN(Number(value))) {
|
|
2655
|
+
return true;
|
|
2656
|
+
}
|
|
2657
|
+
if (/^\d+\/\d+$/.test(value)) {
|
|
2658
|
+
return true;
|
|
2659
|
+
}
|
|
2660
|
+
if ([
|
|
2661
|
+
"auto",
|
|
2662
|
+
"full",
|
|
2663
|
+
"screen",
|
|
2664
|
+
"px",
|
|
2665
|
+
"min",
|
|
2666
|
+
"max",
|
|
2667
|
+
"fit",
|
|
2668
|
+
"none",
|
|
2669
|
+
"dvh",
|
|
2670
|
+
"dvw",
|
|
2671
|
+
"svh",
|
|
2672
|
+
"svw",
|
|
2673
|
+
"lvh",
|
|
2674
|
+
"lvw",
|
|
2675
|
+
// Max-width size keywords
|
|
2676
|
+
"xs",
|
|
2677
|
+
"sm",
|
|
2678
|
+
"md",
|
|
2679
|
+
"lg",
|
|
2680
|
+
"xl",
|
|
2681
|
+
"2xl",
|
|
2682
|
+
"3xl",
|
|
2683
|
+
"4xl",
|
|
2684
|
+
"5xl",
|
|
2685
|
+
"6xl",
|
|
2686
|
+
"7xl",
|
|
2687
|
+
"prose",
|
|
2688
|
+
"screen-sm",
|
|
2689
|
+
"screen-md",
|
|
2690
|
+
"screen-lg",
|
|
2691
|
+
"screen-xl",
|
|
2692
|
+
"screen-2xl",
|
|
2693
|
+
// Size keywords used in min-h, max-h
|
|
2694
|
+
"content"
|
|
2695
|
+
].includes(value)) {
|
|
2696
|
+
return true;
|
|
2697
|
+
}
|
|
2698
|
+
if (value.includes("/")) {
|
|
2699
|
+
return true;
|
|
2700
|
+
}
|
|
2701
|
+
return false;
|
|
2702
|
+
}
|
|
2703
|
+
function parseValue(prefix, value, negative) {
|
|
2704
|
+
if (value.startsWith("[") && value.endsWith("]")) {
|
|
2705
|
+
const inner = value.slice(1, -1).replace(/_/g, " ");
|
|
2706
|
+
if (negative) {
|
|
2707
|
+
return "-" + inner;
|
|
2708
|
+
}
|
|
2709
|
+
return inner;
|
|
2710
|
+
}
|
|
2711
|
+
if (value.startsWith("(") && value.endsWith(")")) {
|
|
2712
|
+
const inner = value.slice(1, -1);
|
|
2713
|
+
if (negative) {
|
|
2714
|
+
return "-" + inner;
|
|
2715
|
+
}
|
|
2716
|
+
return inner;
|
|
2717
|
+
}
|
|
2718
|
+
if (FRACTION_SUPPORTED.has(prefix) && /^\d+\/\d+$/.test(value)) {
|
|
2719
|
+
return value;
|
|
2720
|
+
}
|
|
2721
|
+
if (value === "px") {
|
|
2722
|
+
return "px";
|
|
2723
|
+
}
|
|
2724
|
+
if (value === "auto") {
|
|
2725
|
+
return "auto";
|
|
2726
|
+
}
|
|
2727
|
+
if (value === "full") {
|
|
2728
|
+
return "full";
|
|
2729
|
+
}
|
|
2730
|
+
if (value === "screen") {
|
|
2731
|
+
return "screen";
|
|
2732
|
+
}
|
|
2733
|
+
const num = Number(value);
|
|
2734
|
+
if (!isNaN(num)) {
|
|
2735
|
+
if (negative) {
|
|
2736
|
+
return -num;
|
|
2737
|
+
}
|
|
2738
|
+
return num;
|
|
2739
|
+
}
|
|
2740
|
+
if (negative) {
|
|
2741
|
+
return "-" + value;
|
|
2742
|
+
}
|
|
2743
|
+
return value;
|
|
2744
|
+
}
|
|
2745
|
+
function parseNumericOrString(prefix, value, negative) {
|
|
2746
|
+
if (value === "px") {
|
|
2747
|
+
return "px";
|
|
2748
|
+
}
|
|
2749
|
+
const num = Number(value);
|
|
2750
|
+
if (!isNaN(num)) {
|
|
2751
|
+
return negative ? -num : num;
|
|
2752
|
+
}
|
|
2753
|
+
return value;
|
|
2754
|
+
}
|
|
2755
|
+
function parseStringValue(value) {
|
|
2756
|
+
if (value.startsWith("[") && value.endsWith("]")) {
|
|
2757
|
+
return value.slice(1, -1).replace(/_/g, " ");
|
|
2758
|
+
}
|
|
2759
|
+
if (value.startsWith("(") && value.endsWith(")")) {
|
|
2760
|
+
return value.slice(1, -1);
|
|
2761
|
+
}
|
|
2762
|
+
return value;
|
|
2763
|
+
}
|
|
2764
|
+
|
|
2765
|
+
// src/migrate/variant-parser.ts
|
|
2766
|
+
function tokenize(className) {
|
|
2767
|
+
return className.trim().split(/\s+/).filter(Boolean);
|
|
2768
|
+
}
|
|
2769
|
+
function extractVariants(token) {
|
|
2770
|
+
const parts = [];
|
|
2771
|
+
let current = "";
|
|
2772
|
+
let depth = 0;
|
|
2773
|
+
for (let i = 0; i < token.length; i++) {
|
|
2774
|
+
const ch = token[i];
|
|
2775
|
+
if (ch === "[" || ch === "(") {
|
|
2776
|
+
depth++;
|
|
2777
|
+
current += ch;
|
|
2778
|
+
} else if (ch === "]" || ch === ")") {
|
|
2779
|
+
depth--;
|
|
2780
|
+
current += ch;
|
|
2781
|
+
} else if (ch === ":" && depth === 0) {
|
|
2782
|
+
parts.push(current);
|
|
2783
|
+
current = "";
|
|
2784
|
+
} else {
|
|
2785
|
+
current += ch;
|
|
2786
|
+
}
|
|
2787
|
+
}
|
|
2788
|
+
if (parts.length === 0) {
|
|
2789
|
+
return { variantParts: [], baseClass: current };
|
|
2790
|
+
}
|
|
2791
|
+
return { variantParts: parts, baseClass: current };
|
|
2792
|
+
}
|
|
2793
|
+
function mapVariant(variant) {
|
|
2794
|
+
if (variant.startsWith("@")) {
|
|
2795
|
+
if (variant === "@container") {
|
|
2796
|
+
return ["@container"];
|
|
2797
|
+
}
|
|
2798
|
+
const slashIdx = variant.indexOf("/");
|
|
2799
|
+
if (slashIdx !== -1) {
|
|
2800
|
+
const queryPart = variant.slice(0, slashIdx);
|
|
2801
|
+
const namePart = variant.slice(slashIdx + 1);
|
|
2802
|
+
return [normalizeVariantKey(queryPart), namePart];
|
|
2803
|
+
}
|
|
2804
|
+
const match = variant.match(/^(@min|@max)-\[(.+)\]$/);
|
|
2805
|
+
if (match) {
|
|
2806
|
+
return [match[1], match[2]];
|
|
2807
|
+
}
|
|
2808
|
+
return [normalizeVariantKey(variant)];
|
|
2809
|
+
}
|
|
2810
|
+
if (variant.startsWith("group-") || variant.startsWith("peer-")) {
|
|
2811
|
+
return parseGroupPeerVariant(variant);
|
|
2812
|
+
}
|
|
2813
|
+
if (variant.startsWith("has-")) {
|
|
2814
|
+
const rest = variant.slice(4);
|
|
2815
|
+
if (rest.startsWith("[") && rest.endsWith("]")) {
|
|
2816
|
+
let selector = rest.slice(1, -1);
|
|
2817
|
+
if (selector.startsWith(":")) {
|
|
2818
|
+
selector = selector.slice(1);
|
|
2819
|
+
}
|
|
2820
|
+
return ["has", selector];
|
|
2821
|
+
}
|
|
2822
|
+
return ["has", rest];
|
|
2823
|
+
}
|
|
2824
|
+
if (variant.startsWith("not-")) {
|
|
2825
|
+
const rest = variant.slice(4);
|
|
2826
|
+
if (rest.startsWith("supports-[") && rest.endsWith("]")) {
|
|
2827
|
+
const cond = rest.slice(10, -1);
|
|
2828
|
+
return ["not", "supports", cond];
|
|
2829
|
+
}
|
|
2830
|
+
return ["not", normalizeVariantKey(rest)];
|
|
2831
|
+
}
|
|
2832
|
+
if (variant.startsWith("data-")) {
|
|
2833
|
+
const rest = variant.slice(5);
|
|
2834
|
+
if (rest.startsWith("[") && rest.endsWith("]")) {
|
|
2835
|
+
return ["data", rest.slice(1, -1)];
|
|
2836
|
+
}
|
|
2837
|
+
return ["data", rest];
|
|
2838
|
+
}
|
|
2839
|
+
if (variant.startsWith("aria-")) {
|
|
2840
|
+
const rest = variant.slice(5);
|
|
2841
|
+
if (rest.startsWith("[") && rest.endsWith("]")) {
|
|
2842
|
+
return ["aria", rest.slice(1, -1)];
|
|
2843
|
+
}
|
|
2844
|
+
return ["aria", rest];
|
|
2845
|
+
}
|
|
2846
|
+
if (variant.startsWith("supports-")) {
|
|
2847
|
+
const rest = variant.slice(9);
|
|
2848
|
+
if (rest.startsWith("[") && rest.endsWith("]")) {
|
|
2849
|
+
return ["supports", rest.slice(1, -1)];
|
|
2850
|
+
}
|
|
2851
|
+
return ["supports", rest];
|
|
2852
|
+
}
|
|
2853
|
+
if (variant.startsWith("min-") || variant.startsWith("max-")) {
|
|
2854
|
+
const prefix = variant.startsWith("min-") ? "min" : "max";
|
|
2855
|
+
const rest = variant.slice(4);
|
|
2856
|
+
if (rest.startsWith("[") && rest.endsWith("]")) {
|
|
2857
|
+
return [prefix, rest.slice(1, -1)];
|
|
2858
|
+
}
|
|
2859
|
+
return [prefix, rest];
|
|
2860
|
+
}
|
|
2861
|
+
if (variant.startsWith("[") && variant.endsWith("]")) {
|
|
2862
|
+
return [variant];
|
|
2863
|
+
}
|
|
2864
|
+
return [normalizeVariantKey(variant)];
|
|
2865
|
+
}
|
|
2866
|
+
function parseGroupPeerVariant(variant) {
|
|
2867
|
+
const isGroup = variant.startsWith("group-");
|
|
2868
|
+
const type = isGroup ? "group" : "peer";
|
|
2869
|
+
let rest = variant.slice(type.length + 1);
|
|
2870
|
+
let name;
|
|
2871
|
+
const slashIdx = findTopLevelSlash2(rest);
|
|
2872
|
+
if (slashIdx !== -1) {
|
|
2873
|
+
name = rest.slice(slashIdx + 1);
|
|
2874
|
+
rest = rest.slice(0, slashIdx);
|
|
2875
|
+
}
|
|
2876
|
+
const keys = [type];
|
|
2877
|
+
if (name) {
|
|
2878
|
+
keys.push(name);
|
|
2879
|
+
}
|
|
2880
|
+
if (rest.startsWith("[") && rest.endsWith("]")) {
|
|
2881
|
+
keys.push(rest.slice(1, -1));
|
|
2882
|
+
} else if (rest.startsWith("has-")) {
|
|
2883
|
+
const hasRest = rest.slice(4);
|
|
2884
|
+
if (hasRest.startsWith("[") && hasRest.endsWith("]")) {
|
|
2885
|
+
keys.push("has");
|
|
2886
|
+
keys.push(hasRest.slice(1, -1));
|
|
2887
|
+
} else {
|
|
2888
|
+
keys.push("has");
|
|
2889
|
+
keys.push(hasRest);
|
|
2890
|
+
}
|
|
2891
|
+
} else {
|
|
2892
|
+
keys.push(normalizeVariantKey(rest));
|
|
2893
|
+
}
|
|
2894
|
+
return keys;
|
|
2895
|
+
}
|
|
2896
|
+
function findTopLevelSlash2(s) {
|
|
2897
|
+
let depth = 0;
|
|
2898
|
+
for (let i = 0; i < s.length; i++) {
|
|
2899
|
+
if (s[i] === "[" || s[i] === "(") {
|
|
2900
|
+
depth++;
|
|
2901
|
+
} else if (s[i] === "]" || s[i] === ")") {
|
|
2902
|
+
depth--;
|
|
2903
|
+
} else if (s[i] === "/" && depth === 0) {
|
|
2904
|
+
return i;
|
|
2905
|
+
}
|
|
2906
|
+
}
|
|
2907
|
+
return -1;
|
|
2908
|
+
}
|
|
2909
|
+
function normalizeVariantKey(variant) {
|
|
2910
|
+
if (REVERSE_VARIANT_MAP[variant]) {
|
|
2911
|
+
return REVERSE_VARIANT_MAP[variant];
|
|
2912
|
+
}
|
|
2913
|
+
if (variant.startsWith("@")) {
|
|
2914
|
+
return variant;
|
|
2915
|
+
}
|
|
2916
|
+
return variant;
|
|
2917
|
+
}
|
|
2918
|
+
function classNameToSzObject(className) {
|
|
2919
|
+
const tokens = tokenize(className);
|
|
2920
|
+
const szObject = {};
|
|
2921
|
+
const unrecognized = [];
|
|
2922
|
+
for (const token of tokens) {
|
|
2923
|
+
const { variantParts, baseClass } = extractVariants(token);
|
|
2924
|
+
const parsed = parseClass(baseClass);
|
|
2925
|
+
if (!parsed) {
|
|
2926
|
+
unrecognized.push(token);
|
|
2927
|
+
continue;
|
|
2928
|
+
}
|
|
2929
|
+
const variantKeys = variantParts.map((v) => mapVariant(v));
|
|
2930
|
+
const keyPath = [];
|
|
2931
|
+
for (const vk of variantKeys) {
|
|
2932
|
+
keyPath.push(...vk);
|
|
2933
|
+
}
|
|
2934
|
+
setNestedValue(szObject, keyPath, parsed.prop, parsed.value);
|
|
2935
|
+
}
|
|
2936
|
+
return { szObject, unrecognized };
|
|
2937
|
+
}
|
|
2938
|
+
function setNestedValue(obj, keyPath, prop, value) {
|
|
2939
|
+
let current = obj;
|
|
2940
|
+
for (const key of keyPath) {
|
|
2941
|
+
if (!(key in current) || typeof current[key] !== "object" || current[key] === null) {
|
|
2942
|
+
current[key] = {};
|
|
2943
|
+
}
|
|
2944
|
+
current = current[key];
|
|
2945
|
+
}
|
|
2946
|
+
current[prop] = value;
|
|
2947
|
+
}
|
|
2948
|
+
|
|
2949
|
+
// src/migrate/ast-transformer.ts
|
|
2950
|
+
function transformSourceSimple(source, filePath) {
|
|
2951
|
+
const warnings = [];
|
|
2952
|
+
let classNamesTransformed = 0;
|
|
2953
|
+
let classNamesSkipped = 0;
|
|
2954
|
+
const classesUnrecognized = [];
|
|
2955
|
+
let changed = false;
|
|
2956
|
+
const output = source.replace(/className="([^"]*)"/g, (match, classNameStr) => {
|
|
2957
|
+
return processClassNameMatch(match, classNameStr, '"');
|
|
2958
|
+
});
|
|
2959
|
+
const output2 = output.replace(/className='([^']*)'/g, (match, classNameStr) => {
|
|
2960
|
+
return processClassNameMatch(match, classNameStr, "'");
|
|
2961
|
+
});
|
|
2962
|
+
function processClassNameMatch(match, classNameStr, quote) {
|
|
2963
|
+
const trimmed = classNameStr.trim();
|
|
2964
|
+
if (!trimmed) {
|
|
2965
|
+
classNamesSkipped++;
|
|
2966
|
+
return match;
|
|
2967
|
+
}
|
|
2968
|
+
const { szObject, unrecognized } = classNameToSzObject(trimmed);
|
|
2969
|
+
if (Object.keys(szObject).length === 0) {
|
|
2970
|
+
classNamesSkipped++;
|
|
2971
|
+
classesUnrecognized.push(...unrecognized);
|
|
2972
|
+
return match;
|
|
2973
|
+
}
|
|
2974
|
+
const szExpr = generateSzExpression(szObject);
|
|
2975
|
+
changed = true;
|
|
2976
|
+
classNamesTransformed++;
|
|
2977
|
+
if (unrecognized.length > 0) {
|
|
2978
|
+
classesUnrecognized.push(...unrecognized);
|
|
2979
|
+
return `className=${quote}${unrecognized.join(" ")}${quote} sz=${szExpr}`;
|
|
2980
|
+
}
|
|
2981
|
+
return `sz=${szExpr}`;
|
|
2982
|
+
}
|
|
2983
|
+
return {
|
|
2984
|
+
code: output2,
|
|
2985
|
+
changed,
|
|
2986
|
+
warnings,
|
|
2987
|
+
stats: { classNamesTransformed, classNamesSkipped, classesUnrecognized }
|
|
2988
|
+
};
|
|
2989
|
+
}
|
|
2990
|
+
|
|
2991
|
+
// src/commands/migrate.ts
|
|
2992
|
+
async function migrate(options = {}) {
|
|
2993
|
+
const cwd = options.cwd || process.cwd();
|
|
2994
|
+
const dryRun = options.dryRun || false;
|
|
2995
|
+
const ignorePatterns = options.ignore || [];
|
|
2996
|
+
printHeader("csszyx Migration Tool");
|
|
2997
|
+
if (dryRun) {
|
|
2998
|
+
printInfo("Dry run mode \u2014 no files will be modified");
|
|
2999
|
+
}
|
|
3000
|
+
const patterns = options.pattern ? [options.pattern] : ["**/*.{jsx,tsx}"];
|
|
3001
|
+
const ignore = [
|
|
3002
|
+
"**/node_modules/**",
|
|
3003
|
+
"**/dist/**",
|
|
3004
|
+
"**/build/**",
|
|
3005
|
+
"**/.next/**",
|
|
3006
|
+
"**/.nuxt/**",
|
|
3007
|
+
...ignorePatterns
|
|
3008
|
+
];
|
|
3009
|
+
const s = spinner.start("Scanning for files...");
|
|
3010
|
+
const files = await fg(patterns, { cwd, ignore, absolute: true });
|
|
3011
|
+
s.succeed(`Found ${files.length} files`);
|
|
3012
|
+
if (files.length === 0) {
|
|
3013
|
+
printWarn("No JSX/TSX files found");
|
|
3014
|
+
return;
|
|
3015
|
+
}
|
|
3016
|
+
let totalTransformed = 0;
|
|
3017
|
+
let totalSkipped = 0;
|
|
3018
|
+
let totalFiles = 0;
|
|
3019
|
+
const allUnrecognized = [];
|
|
3020
|
+
const allWarnings = [];
|
|
3021
|
+
const s2 = spinner.start("Migrating...");
|
|
3022
|
+
for (const filePath of files) {
|
|
3023
|
+
const source = fs5.readFileSync(filePath, "utf-8");
|
|
3024
|
+
if (!source.includes("className=")) {
|
|
3025
|
+
continue;
|
|
3026
|
+
}
|
|
3027
|
+
const result = transformSourceSimple(source, filePath);
|
|
3028
|
+
if (result.changed) {
|
|
3029
|
+
totalFiles++;
|
|
3030
|
+
totalTransformed += result.stats.classNamesTransformed;
|
|
3031
|
+
totalSkipped += result.stats.classNamesSkipped;
|
|
3032
|
+
allUnrecognized.push(...result.stats.classesUnrecognized);
|
|
3033
|
+
allWarnings.push(...result.warnings);
|
|
3034
|
+
if (!dryRun) {
|
|
3035
|
+
fs5.writeFileSync(filePath, result.code, "utf-8");
|
|
3036
|
+
}
|
|
3037
|
+
const rel = path5.relative(cwd, filePath);
|
|
3038
|
+
if (dryRun) {
|
|
3039
|
+
printInfo(` ${rel}: ${result.stats.classNamesTransformed} className(s) \u2192 sz`);
|
|
3040
|
+
}
|
|
3041
|
+
}
|
|
3042
|
+
}
|
|
3043
|
+
s2.succeed("Migration complete");
|
|
3044
|
+
console.info();
|
|
3045
|
+
printSuccess(`Files modified: ${totalFiles}`);
|
|
3046
|
+
printSuccess(`classNames converted: ${totalTransformed}`);
|
|
3047
|
+
if (totalSkipped > 0) {
|
|
3048
|
+
printWarn(`classNames skipped (dynamic): ${totalSkipped}`);
|
|
3049
|
+
}
|
|
3050
|
+
if (allUnrecognized.length > 0) {
|
|
3051
|
+
const unique = [...new Set(allUnrecognized)];
|
|
3052
|
+
printWarn(`Unrecognized classes (${unique.length}): ${unique.slice(0, 10).join(", ")}${unique.length > 10 ? "..." : ""}`);
|
|
3053
|
+
}
|
|
3054
|
+
if (allWarnings.length > 0) {
|
|
3055
|
+
console.info();
|
|
3056
|
+
for (const w of allWarnings.slice(0, 5)) {
|
|
3057
|
+
printWarn(w);
|
|
3058
|
+
}
|
|
3059
|
+
if (allWarnings.length > 5) {
|
|
3060
|
+
printWarn(`... and ${allWarnings.length - 5} more warnings`);
|
|
3061
|
+
}
|
|
3062
|
+
}
|
|
3063
|
+
}
|
|
3064
|
+
|
|
3065
|
+
// src/index.ts
|
|
3066
|
+
var cli = cac("csszyx");
|
|
3067
|
+
var VERSION = "0.0.0";
|
|
3068
|
+
cli.command("init", "Setup csszyx in your project").option("--framework <name>", "Specify framework").option("--yes", "Skip prompts (use defaults)").option("--cwd <dir>", "Current working directory").action(async (options) => {
|
|
3069
|
+
await init({
|
|
3070
|
+
framework: options.framework,
|
|
3071
|
+
yes: options.yes,
|
|
3072
|
+
cwd: options.cwd
|
|
3073
|
+
});
|
|
3074
|
+
});
|
|
3075
|
+
cli.command("doctor", "Diagnose mangling issues").option("--fix", "Auto-fix common issues").option("--verbose", "Show detailed output").option("--cwd <dir>", "Current working directory").action(async (options) => {
|
|
3076
|
+
await doctor({
|
|
3077
|
+
fix: options.fix,
|
|
3078
|
+
verbose: options.verbose,
|
|
3079
|
+
cwd: options.cwd
|
|
3080
|
+
});
|
|
3081
|
+
});
|
|
3082
|
+
cli.command("audit", "Analyze mangling performance").option("--json", "Output as JSON").option("--watch", "Live updates").option("--compare <dir>", "Compare with previous build").option("--cwd <dir>", "Current working directory").action(async (options) => {
|
|
3083
|
+
await audit({
|
|
3084
|
+
json: options.json,
|
|
3085
|
+
watch: options.watch,
|
|
3086
|
+
compare: options.compare,
|
|
3087
|
+
cwd: options.cwd
|
|
3088
|
+
});
|
|
3089
|
+
});
|
|
3090
|
+
cli.command(
|
|
3091
|
+
"generate-types",
|
|
3092
|
+
"Generate TypeScript declarations from tailwind.config.js"
|
|
3093
|
+
).option("-c, --config <path>", "Path to tailwind.config.js").option("-o, --output <path>", "Output file path (default: ./csszyx.d.ts)").option("--cwd <dir>", "Current working directory").option("--silent", "Silent mode (no output)").action(async (options) => {
|
|
3094
|
+
await generateTypes({
|
|
3095
|
+
config: options.config,
|
|
3096
|
+
output: options.output,
|
|
3097
|
+
cwd: options.cwd,
|
|
3098
|
+
silent: options.silent
|
|
3099
|
+
});
|
|
3100
|
+
});
|
|
3101
|
+
cli.command("migrate [dir]", "Convert Tailwind className to sz prop").option("--dry-run", "Show changes without modifying files").option("--ignore <patterns>", "Glob patterns to ignore (comma-separated)").option("--pattern <glob>", "Custom glob pattern for file discovery").option("--cwd <dir>", "Current working directory").action(async (dir, options) => {
|
|
3102
|
+
await migrate({
|
|
3103
|
+
dryRun: options.dryRun,
|
|
3104
|
+
ignore: options.ignore ? options.ignore.split(",") : void 0,
|
|
3105
|
+
pattern: options.pattern,
|
|
3106
|
+
cwd: dir || options.cwd
|
|
3107
|
+
});
|
|
3108
|
+
});
|
|
3109
|
+
cli.command("").action(() => {
|
|
3110
|
+
cli.outputHelp();
|
|
3111
|
+
});
|
|
3112
|
+
cli.help();
|
|
3113
|
+
cli.version(VERSION);
|
|
3114
|
+
cli.parse();
|
|
3115
|
+
export {
|
|
3116
|
+
extractScreenKeys,
|
|
3117
|
+
extractSpacingKeys,
|
|
3118
|
+
findConfigFile,
|
|
3119
|
+
flattenColors,
|
|
3120
|
+
generateAndWriteTypes,
|
|
3121
|
+
generateTypeDeclarations,
|
|
3122
|
+
generateTypes,
|
|
3123
|
+
scanTailwindConfig,
|
|
3124
|
+
writeDeclarationFile
|
|
3125
|
+
};
|