@csszyx/compiler 0.3.0 → 0.4.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/dist/chunk-3RG5ZIWI.js +10 -0
- package/dist/color-var.cjs +38 -0
- package/dist/color-var.d.cts +18 -0
- package/dist/color-var.d.ts +18 -0
- package/dist/color-var.js +15 -0
- package/dist/index.cjs +737 -114
- package/dist/index.d.cts +110 -26
- package/dist/index.d.ts +110 -26
- package/dist/index.js +736 -120
- package/package.json +14 -4
package/dist/index.cjs
CHANGED
|
@@ -30,12 +30,16 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
+
BOOLEAN_SHORTHANDS: () => BOOLEAN_SHORTHANDS,
|
|
33
34
|
COLOR_PROPERTIES: () => COLOR_PROPERTIES,
|
|
34
35
|
CsszyxCompiler: () => CsszyxCompiler,
|
|
35
36
|
DEFAULT_COMPILER_OPTIONS: () => DEFAULT_COMPILER_OPTIONS,
|
|
37
|
+
KNOWN_VARIANTS: () => KNOWN_VARIANTS,
|
|
36
38
|
ManifestBuilder: () => ManifestBuilder,
|
|
37
39
|
PROPERTY_CATEGORY_MAP: () => PROPERTY_CATEGORY_MAP,
|
|
40
|
+
PROPERTY_MAP: () => PROPERTY_MAP,
|
|
38
41
|
PropertyCategory: () => PropertyCategory,
|
|
42
|
+
SUGGESTION_MAP: () => SUGGESTION_MAP,
|
|
39
43
|
VERSION: () => VERSION,
|
|
40
44
|
buildParentMap: () => buildParentMap,
|
|
41
45
|
createRecoveryToken: () => createRecoveryToken,
|
|
@@ -230,7 +234,8 @@ var PROPERTY_CATEGORY_MAP = {
|
|
|
230
234
|
skewY: 4 /* ANGLE */,
|
|
231
235
|
// ---- DURATION ----
|
|
232
236
|
duration: 5 /* DURATION */,
|
|
233
|
-
delay: 5 /* DURATION
|
|
237
|
+
delay: 5 /* DURATION */,
|
|
238
|
+
animationDelay: 5 /* DURATION */
|
|
234
239
|
};
|
|
235
240
|
function getPropertyCategory(property) {
|
|
236
241
|
return PROPERTY_CATEGORY_MAP[property] ?? 7 /* PASSTHROUGH */;
|
|
@@ -274,6 +279,9 @@ function isValidColorString(value) {
|
|
|
274
279
|
if (/^[a-zA-Z][a-zA-Z0-9]*(-[a-zA-Z0-9]+)*-\d+$/.test(value)) {
|
|
275
280
|
return true;
|
|
276
281
|
}
|
|
282
|
+
if (/^[a-zA-Z][a-zA-Z0-9]*(-[a-zA-Z][a-zA-Z0-9]*)*$/.test(value)) {
|
|
283
|
+
return true;
|
|
284
|
+
}
|
|
277
285
|
return false;
|
|
278
286
|
}
|
|
279
287
|
function hasSlashOpacity(value) {
|
|
@@ -376,11 +384,13 @@ var PROPERTY_MAP = {
|
|
|
376
384
|
outlineColor: "outline",
|
|
377
385
|
outlineOffset: "outline-offset",
|
|
378
386
|
outlineStyle: "outline",
|
|
379
|
-
// Ring (
|
|
387
|
+
// Ring (v4: outset ring + inset ring)
|
|
380
388
|
ring: "ring",
|
|
381
389
|
ringColor: "ring",
|
|
382
390
|
ringOffset: "ring-offset",
|
|
383
391
|
ringOffsetColor: "ring-offset",
|
|
392
|
+
insetRing: "inset-ring",
|
|
393
|
+
insetRingColor: "inset-ring",
|
|
384
394
|
// Spacing (canonical shorthand only)
|
|
385
395
|
p: "p",
|
|
386
396
|
pt: "pt",
|
|
@@ -560,6 +570,7 @@ var PROPERTY_MAP = {
|
|
|
560
570
|
rotateX: "rotate-x",
|
|
561
571
|
rotateY: "rotate-y",
|
|
562
572
|
rotateZ: "rotate-z",
|
|
573
|
+
translate: "translate",
|
|
563
574
|
translateX: "translate-x",
|
|
564
575
|
translateY: "translate-y",
|
|
565
576
|
translateZ: "translate-z",
|
|
@@ -578,6 +589,8 @@ var PROPERTY_MAP = {
|
|
|
578
589
|
ease: "ease",
|
|
579
590
|
delay: "delay",
|
|
580
591
|
animate: "animate",
|
|
592
|
+
animationDelay: "animation-delay",
|
|
593
|
+
// animation-delay — distinct from transition delay
|
|
581
594
|
// Masks
|
|
582
595
|
mask: "mask",
|
|
583
596
|
maskSize: "mask-size",
|
|
@@ -984,13 +997,7 @@ var BOOLEAN_SHORTHANDS = /* @__PURE__ */ new Set([
|
|
|
984
997
|
// Ring (v3 future)
|
|
985
998
|
"ring",
|
|
986
999
|
// Outline
|
|
987
|
-
"outline"
|
|
988
|
-
// Transforms
|
|
989
|
-
"scale3d",
|
|
990
|
-
"rotate3d",
|
|
991
|
-
"translate3d",
|
|
992
|
-
"transformGpu",
|
|
993
|
-
"transformCpu"
|
|
1000
|
+
"outline"
|
|
994
1001
|
]);
|
|
995
1002
|
var BOOLEAN_TO_CLASS = {
|
|
996
1003
|
inlineBlock: "inline-block",
|
|
@@ -1023,9 +1030,6 @@ var BOOLEAN_TO_CLASS = {
|
|
|
1023
1030
|
diagonalFractions: "diagonal-fractions",
|
|
1024
1031
|
stackedFractions: "stacked-fractions",
|
|
1025
1032
|
// Transforms
|
|
1026
|
-
scale3d: "scale-3d",
|
|
1027
|
-
rotate3d: "rotate-3d",
|
|
1028
|
-
translate3d: "translate-3d",
|
|
1029
1033
|
transformGpu: "transform-gpu",
|
|
1030
1034
|
transformCpu: "transform-cpu",
|
|
1031
1035
|
// Misc
|
|
@@ -1092,6 +1096,7 @@ var NEGATIVE_ALLOWED = /* @__PURE__ */ new Set([
|
|
|
1092
1096
|
"scale-z",
|
|
1093
1097
|
"skew-x",
|
|
1094
1098
|
"skew-y",
|
|
1099
|
+
"translate",
|
|
1095
1100
|
"translate-x",
|
|
1096
1101
|
"translate-y",
|
|
1097
1102
|
"translate-z",
|
|
@@ -1118,7 +1123,10 @@ function handleImportant(value) {
|
|
|
1118
1123
|
}
|
|
1119
1124
|
function formatOpacity(op) {
|
|
1120
1125
|
if (typeof op === "number") {
|
|
1121
|
-
|
|
1126
|
+
if (Number.isInteger(op * 2)) {
|
|
1127
|
+
return String(op);
|
|
1128
|
+
}
|
|
1129
|
+
return `[${op}]`;
|
|
1122
1130
|
}
|
|
1123
1131
|
if (typeof op === "string") {
|
|
1124
1132
|
if (op.startsWith("--")) {
|
|
@@ -1135,7 +1143,8 @@ function normalizeArbitraryVariant(key) {
|
|
|
1135
1143
|
return key.replace(/\s+/g, "");
|
|
1136
1144
|
}
|
|
1137
1145
|
function normalizeArbitraryValue(value) {
|
|
1138
|
-
|
|
1146
|
+
const stripped = value.startsWith("[") && value.endsWith("]") ? value.slice(1, -1) : value;
|
|
1147
|
+
return stripped.trim().replace(/\s+/g, "_");
|
|
1139
1148
|
}
|
|
1140
1149
|
var FRACTION_SUPPORTED_PROPS = /* @__PURE__ */ new Set([
|
|
1141
1150
|
// Sizing (both rawKey and resolved key forms)
|
|
@@ -1173,6 +1182,7 @@ var FRACTION_SUPPORTED_PROPS = /* @__PURE__ */ new Set([
|
|
|
1173
1182
|
"start",
|
|
1174
1183
|
"end",
|
|
1175
1184
|
// Translate
|
|
1185
|
+
"translate",
|
|
1176
1186
|
"translate-x",
|
|
1177
1187
|
"translateX",
|
|
1178
1188
|
"translate-y",
|
|
@@ -1181,21 +1191,22 @@ var FRACTION_SUPPORTED_PROPS = /* @__PURE__ */ new Set([
|
|
|
1181
1191
|
"aspect"
|
|
1182
1192
|
]);
|
|
1183
1193
|
function needsArbitraryBrackets(value) {
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1194
|
+
const v = value.startsWith("[") && value.endsWith("]") ? value.slice(1, -1) : value;
|
|
1195
|
+
return /^\d+(\.\d+)?(px|rem|em|%|vh|vw|ch|dvh|dvw|svh|svw|lvh|lvw|cqw|cqh|deg|rad|turn|grad|ms|s|fr)$/.test(v) || // Positive units
|
|
1196
|
+
/^-\d+(\.\d+)?(px|rem|em|%|vh|vw|ch|dvh|dvw|svh|svw|lvh|lvw|cqw|cqh|deg|rad|turn|grad|ms|s|fr)$/.test(v) || // Negative units like -1px, -2rem
|
|
1197
|
+
/^\.\d+(px|rem|em|%|vh|vw|ch)?$/.test(v) || // Values starting with . like .25em
|
|
1198
|
+
/^-\.\d+(px|rem|em|%|vh|vw|ch)?$/.test(v) || // Negative values starting with -. like -.25em
|
|
1199
|
+
v.startsWith("#") || // Hex colors
|
|
1200
|
+
v.startsWith("rgb") || // RGB colors
|
|
1201
|
+
v.startsWith("hsl") || // HSL colors
|
|
1202
|
+
v.includes("calc(") || // Calculations
|
|
1203
|
+
v.includes("var(") || // CSS variables (old syntax)
|
|
1204
|
+
v.includes("attr(") || // attr() function
|
|
1205
|
+
v.includes("url(") || // URLs
|
|
1206
|
+
v.includes("clamp(") || // Clamp
|
|
1207
|
+
v.includes("min(") || // Min
|
|
1208
|
+
v.includes("max(") || // Max
|
|
1209
|
+
v.includes(" ");
|
|
1199
1210
|
}
|
|
1200
1211
|
var LIST_STYLE_STANDARD = /* @__PURE__ */ new Set(["none", "disc", "decimal"]);
|
|
1201
1212
|
var FONT_STRETCH_KEYWORDS = /* @__PURE__ */ new Set([
|
|
@@ -1209,11 +1220,12 @@ var FONT_STRETCH_KEYWORDS = /* @__PURE__ */ new Set([
|
|
|
1209
1220
|
"extra-expanded",
|
|
1210
1221
|
"ultra-expanded"
|
|
1211
1222
|
]);
|
|
1212
|
-
|
|
1213
|
-
"
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
]);
|
|
1223
|
+
function camelToKebab(prop) {
|
|
1224
|
+
if (prop.startsWith("--")) {
|
|
1225
|
+
return prop;
|
|
1226
|
+
}
|
|
1227
|
+
return prop.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
|
|
1228
|
+
}
|
|
1217
1229
|
function getVariantPrefix(key) {
|
|
1218
1230
|
if (VARIANT_MAP[key]) {
|
|
1219
1231
|
return VARIANT_MAP[key];
|
|
@@ -1239,6 +1251,32 @@ function handleGroupPeer(type, nestedObj, prefix) {
|
|
|
1239
1251
|
}
|
|
1240
1252
|
continue;
|
|
1241
1253
|
}
|
|
1254
|
+
if (nestedKey === "data" && typeof nestedValue === "object") {
|
|
1255
|
+
for (const [attr, attrValue] of Object.entries(nestedValue)) {
|
|
1256
|
+
if (attrValue === null || attrValue === void 0 || attrValue === false) {
|
|
1257
|
+
continue;
|
|
1258
|
+
}
|
|
1259
|
+
const variantPrefix = `${prefix}${type}-data-[${attr}]:`;
|
|
1260
|
+
const result = transform(attrValue, variantPrefix);
|
|
1261
|
+
if (result.className) {
|
|
1262
|
+
classes.push(result.className);
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1265
|
+
continue;
|
|
1266
|
+
}
|
|
1267
|
+
if (nestedKey === "aria" && typeof nestedValue === "object") {
|
|
1268
|
+
for (const [attr, attrValue] of Object.entries(nestedValue)) {
|
|
1269
|
+
if (attrValue === null || attrValue === void 0 || attrValue === false) {
|
|
1270
|
+
continue;
|
|
1271
|
+
}
|
|
1272
|
+
const variantPrefix = ARIA_STATES.has(attr) ? `${prefix}${type}-aria-${attr}:` : `${prefix}${type}-aria-[${attr}]:`;
|
|
1273
|
+
const result = transform(attrValue, variantPrefix);
|
|
1274
|
+
if (result.className) {
|
|
1275
|
+
classes.push(result.className);
|
|
1276
|
+
}
|
|
1277
|
+
}
|
|
1278
|
+
continue;
|
|
1279
|
+
}
|
|
1242
1280
|
const isVariant = KNOWN_VARIANTS.has(nestedKey) || KNOWN_VARIANTS.has(getVariantPrefix(nestedKey));
|
|
1243
1281
|
const isArbitrary = nestedKey.startsWith(".") || nestedKey.startsWith("#") || nestedKey.startsWith("[") || nestedKey.startsWith(":");
|
|
1244
1282
|
if (isArbitrary) {
|
|
@@ -1259,6 +1297,33 @@ function handleGroupPeer(type, nestedObj, prefix) {
|
|
|
1259
1297
|
if (stateValue === null || stateValue === void 0 || stateValue === false) {
|
|
1260
1298
|
continue;
|
|
1261
1299
|
}
|
|
1300
|
+
if (state === "data" && typeof stateValue === "object") {
|
|
1301
|
+
for (const [attr, attrValue] of Object.entries(stateValue)) {
|
|
1302
|
+
if (attrValue === null || attrValue === void 0 || attrValue === false) {
|
|
1303
|
+
continue;
|
|
1304
|
+
}
|
|
1305
|
+
const variantPrefix2 = `${prefix}${type}-data-[${attr}]/${nestedKey}:`;
|
|
1306
|
+
const result2 = transform(attrValue, variantPrefix2);
|
|
1307
|
+
if (result2.className) {
|
|
1308
|
+
classes.push(result2.className);
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
continue;
|
|
1312
|
+
}
|
|
1313
|
+
if (state === "aria" && typeof stateValue === "object") {
|
|
1314
|
+
for (const [attr, attrValue] of Object.entries(stateValue)) {
|
|
1315
|
+
if (attrValue === null || attrValue === void 0 || attrValue === false) {
|
|
1316
|
+
continue;
|
|
1317
|
+
}
|
|
1318
|
+
const ariaSegment = ARIA_STATES.has(attr) ? `aria-${attr}` : `aria-[${attr}]`;
|
|
1319
|
+
const variantPrefix2 = `${prefix}${type}-${ariaSegment}/${nestedKey}:`;
|
|
1320
|
+
const result2 = transform(attrValue, variantPrefix2);
|
|
1321
|
+
if (result2.className) {
|
|
1322
|
+
classes.push(result2.className);
|
|
1323
|
+
}
|
|
1324
|
+
}
|
|
1325
|
+
continue;
|
|
1326
|
+
}
|
|
1262
1327
|
const mappedState = getVariantPrefix(state);
|
|
1263
1328
|
const variantPrefix = `${prefix}${type}-${mappedState}/${nestedKey}:`;
|
|
1264
1329
|
const result = transform(stateValue, variantPrefix);
|
|
@@ -1380,6 +1445,18 @@ function transform(szProp, prefix = "", mangleMap) {
|
|
|
1380
1445
|
if (value === null || value === void 0) {
|
|
1381
1446
|
continue;
|
|
1382
1447
|
}
|
|
1448
|
+
if (rawKey === "css") {
|
|
1449
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
1450
|
+
for (const [cssProp, cssVal] of Object.entries(value)) {
|
|
1451
|
+
if (cssVal === null || cssVal === void 0) {
|
|
1452
|
+
continue;
|
|
1453
|
+
}
|
|
1454
|
+
const kebab = camelToKebab(cssProp);
|
|
1455
|
+
classes.push(`${prefix}[${kebab}:${normalizeArbitraryValue(String(cssVal))}]`);
|
|
1456
|
+
}
|
|
1457
|
+
}
|
|
1458
|
+
continue;
|
|
1459
|
+
}
|
|
1383
1460
|
if (rawKey.startsWith("@") && typeof value === "string") {
|
|
1384
1461
|
const mappedKey = VARIANT_MAP[rawKey] || rawKey;
|
|
1385
1462
|
classes.push(`${prefix}${mappedKey}/${value}`);
|
|
@@ -1450,10 +1527,11 @@ function transform(szProp, prefix = "", mangleMap) {
|
|
|
1450
1527
|
classes.push(`${prefix}${rawKey}/${value}`);
|
|
1451
1528
|
continue;
|
|
1452
1529
|
}
|
|
1453
|
-
if (typeof value === "object" && value !== null && !Array.isArray(value) && "color" in value) {
|
|
1530
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value) && rawKey in PROPERTY_MAP && "color" in value) {
|
|
1454
1531
|
const colorObj = value;
|
|
1455
1532
|
const twPrefix = PROPERTY_MAP[rawKey] || rawKey.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
|
|
1456
|
-
const
|
|
1533
|
+
const rawColorBase = String(colorObj.color);
|
|
1534
|
+
const colorBase = rawColorBase.startsWith("--") ? `(${rawColorBase})` : needsArbitraryBrackets(rawColorBase) ? `[${normalizeArbitraryValue(rawColorBase)}]` : normalizeArbitraryValue(rawColorBase);
|
|
1457
1535
|
if (colorObj.op !== void 0) {
|
|
1458
1536
|
const opStr = formatOpacity(colorObj.op);
|
|
1459
1537
|
classes.push(`${prefix}${twPrefix}-${colorBase}/${opStr}`);
|
|
@@ -1812,7 +1890,7 @@ function transform(szProp, prefix = "", mangleMap) {
|
|
|
1812
1890
|
}
|
|
1813
1891
|
if (rawKey === "decorationThickness" || rawKey === "textDecorationThickness") {
|
|
1814
1892
|
if (needsArbitraryBrackets(value)) {
|
|
1815
|
-
className += `decoration-[${value}]`;
|
|
1893
|
+
className += `decoration-[${normalizeArbitraryValue(value)}]`;
|
|
1816
1894
|
} else if (value.startsWith("--")) {
|
|
1817
1895
|
className += `decoration-(${value})`;
|
|
1818
1896
|
} else {
|
|
@@ -1863,7 +1941,9 @@ function transform(szProp, prefix = "", mangleMap) {
|
|
|
1863
1941
|
if (rawKey === "brightness" || rawKey === "contrast" || rawKey === "saturate" || rawKey === "scale" || rawKey === "backdropBrightness" || rawKey === "backdropContrast" || rawKey === "backdropSaturate") {
|
|
1864
1942
|
const prop = rawKey.startsWith("backdrop") ? `backdrop-${rawKey.slice(8).toLowerCase()}` : rawKey;
|
|
1865
1943
|
const sValue = String(value);
|
|
1866
|
-
if (sValue
|
|
1944
|
+
if (sValue === "3d" && rawKey === "scale") {
|
|
1945
|
+
classes.push(`${prefix}scale-3d`);
|
|
1946
|
+
} else if (sValue.startsWith("--")) {
|
|
1867
1947
|
classes.push(`${prop}-(${sValue})`);
|
|
1868
1948
|
} else {
|
|
1869
1949
|
classes.push(`${prop}-[${sValue}]`);
|
|
@@ -1903,38 +1983,53 @@ function transform(szProp, prefix = "", mangleMap) {
|
|
|
1903
1983
|
if (rawKey === "bgImg") {
|
|
1904
1984
|
const v = String(value).trim();
|
|
1905
1985
|
if (v === "none") {
|
|
1906
|
-
classes.push(
|
|
1986
|
+
classes.push(`${prefix}bg-none`);
|
|
1907
1987
|
continue;
|
|
1908
1988
|
}
|
|
1909
1989
|
const vNorm = v.startsWith("-") ? v.slice(1) : v;
|
|
1990
|
+
if (vNorm.startsWith("repeating-")) {
|
|
1991
|
+
classes.push(`${prefix}bg-[${normalizeArbitraryValue(v)}]`);
|
|
1992
|
+
continue;
|
|
1993
|
+
}
|
|
1910
1994
|
if (vNorm.startsWith("linear-") || vNorm.startsWith("radial") || vNorm.startsWith("conic") || vNorm.startsWith("gradient-to-")) {
|
|
1911
1995
|
const vMapped = vNorm.startsWith("gradient-to-") ? vNorm.replace("gradient-to-", "linear-to-") : vNorm;
|
|
1912
1996
|
if (v.startsWith("-")) {
|
|
1913
|
-
classes.push(
|
|
1997
|
+
classes.push(`${prefix}-bg-${vMapped}`);
|
|
1914
1998
|
} else {
|
|
1915
|
-
classes.push(
|
|
1999
|
+
classes.push(`${prefix}bg-${vMapped}`);
|
|
1916
2000
|
}
|
|
1917
2001
|
continue;
|
|
1918
2002
|
}
|
|
1919
2003
|
if (v.startsWith("--")) {
|
|
1920
|
-
classes.push(
|
|
2004
|
+
classes.push(`${prefix}bg-(image:${v})`);
|
|
1921
2005
|
continue;
|
|
1922
2006
|
}
|
|
1923
2007
|
if (v.startsWith("url(")) {
|
|
1924
|
-
classes.push(
|
|
2008
|
+
classes.push(`${prefix}bg-[${v}]`);
|
|
1925
2009
|
continue;
|
|
1926
2010
|
}
|
|
1927
|
-
classes.push(
|
|
2011
|
+
classes.push(`${prefix}bg-[url(${v})]`);
|
|
1928
2012
|
continue;
|
|
1929
2013
|
}
|
|
1930
2014
|
if (rawKey === "bgPos") {
|
|
1931
2015
|
const sVal = String(value);
|
|
1932
2016
|
if (sVal.startsWith("--")) {
|
|
1933
|
-
classes.push(
|
|
2017
|
+
classes.push(`${prefix}bg-(${sVal})`);
|
|
1934
2018
|
} else if (sVal.includes("_") || needsArbitraryBrackets(sVal)) {
|
|
1935
|
-
classes.push(
|
|
2019
|
+
classes.push(`${prefix}bg-[${normalizeArbitraryValue(sVal)}]`);
|
|
1936
2020
|
} else {
|
|
1937
|
-
classes.push(
|
|
2021
|
+
classes.push(`${prefix}bg-${sVal}`);
|
|
2022
|
+
}
|
|
2023
|
+
continue;
|
|
2024
|
+
}
|
|
2025
|
+
if (rawKey === "bgSize") {
|
|
2026
|
+
const sVal = String(value);
|
|
2027
|
+
if (sVal === "auto" || sVal === "cover" || sVal === "contain") {
|
|
2028
|
+
classes.push(`${prefix}bg-${sVal}`);
|
|
2029
|
+
} else if (sVal.startsWith("--")) {
|
|
2030
|
+
classes.push(`${prefix}bg-size-(${sVal})`);
|
|
2031
|
+
} else {
|
|
2032
|
+
classes.push(`${prefix}bg-size-[${normalizeArbitraryValue(sVal)}]`);
|
|
1938
2033
|
}
|
|
1939
2034
|
continue;
|
|
1940
2035
|
}
|
|
@@ -1960,7 +2055,8 @@ function transform(szProp, prefix = "", mangleMap) {
|
|
|
1960
2055
|
} else if (value === "no-repeat") {
|
|
1961
2056
|
className += "bg-no-repeat";
|
|
1962
2057
|
} else {
|
|
1963
|
-
|
|
2058
|
+
const suffix = value.startsWith("repeat-") ? value.slice(7) : value;
|
|
2059
|
+
className += `bg-repeat-${suffix}`;
|
|
1964
2060
|
}
|
|
1965
2061
|
classes.push(className);
|
|
1966
2062
|
continue;
|
|
@@ -1990,16 +2086,19 @@ function transform(szProp, prefix = "", mangleMap) {
|
|
|
1990
2086
|
classes.push(className);
|
|
1991
2087
|
continue;
|
|
1992
2088
|
}
|
|
1993
|
-
if (rawKey === "
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
2089
|
+
if (rawKey === "alignContent") {
|
|
2090
|
+
className += `content-${value}`;
|
|
2091
|
+
classes.push(className);
|
|
2092
|
+
continue;
|
|
2093
|
+
}
|
|
2094
|
+
if (rawKey === "content") {
|
|
2095
|
+
if (value === "none") {
|
|
2096
|
+
className += "content-none";
|
|
1997
2097
|
} else if (value.startsWith("--")) {
|
|
1998
2098
|
className += `content-(${value})`;
|
|
1999
|
-
} else if (!["none", "empty"].includes(value)) {
|
|
2000
|
-
className += `content-[${value}]`;
|
|
2001
2099
|
} else {
|
|
2002
|
-
|
|
2100
|
+
const inner = value.startsWith('"') && value.endsWith('"') && value.length >= 2 ? `'${value.slice(1, -1)}'` : value;
|
|
2101
|
+
className += `content-[${inner}]`;
|
|
2003
2102
|
}
|
|
2004
2103
|
classes.push(className);
|
|
2005
2104
|
continue;
|
|
@@ -2052,16 +2151,12 @@ function transform(szProp, prefix = "", mangleMap) {
|
|
|
2052
2151
|
const sVal = String(value);
|
|
2053
2152
|
const prop = PROPERTY_MAP[rawKey] || rawKey;
|
|
2054
2153
|
if (needsArbitraryBrackets(sVal) || sVal.includes("(") || sVal.includes("_") || sVal.includes("%")) {
|
|
2055
|
-
classes.push(`${prop}-[${normalizeArbitraryValue(sVal)}]`);
|
|
2154
|
+
classes.push(`${className}${prop}-[${normalizeArbitraryValue(sVal)}]`);
|
|
2056
2155
|
continue;
|
|
2057
2156
|
}
|
|
2058
2157
|
}
|
|
2059
2158
|
if (rawKey === "transformStyle") {
|
|
2060
|
-
|
|
2061
|
-
className += "transform-3d";
|
|
2062
|
-
} else {
|
|
2063
|
-
className += `transform-${value}`;
|
|
2064
|
-
}
|
|
2159
|
+
className += `transform-${value}`;
|
|
2065
2160
|
classes.push(className);
|
|
2066
2161
|
continue;
|
|
2067
2162
|
}
|
|
@@ -2072,7 +2167,7 @@ function transform(szProp, prefix = "", mangleMap) {
|
|
|
2072
2167
|
} else if (value.startsWith("--")) {
|
|
2073
2168
|
className += `perspective-(${value})`;
|
|
2074
2169
|
} else if (needsArbitraryBrackets(value)) {
|
|
2075
|
-
className += `perspective-[${value}]`;
|
|
2170
|
+
className += `perspective-[${normalizeArbitraryValue(value)}]`;
|
|
2076
2171
|
} else {
|
|
2077
2172
|
className += `perspective-${value}`;
|
|
2078
2173
|
}
|
|
@@ -2096,7 +2191,7 @@ function transform(szProp, prefix = "", mangleMap) {
|
|
|
2096
2191
|
}
|
|
2097
2192
|
}
|
|
2098
2193
|
if (process.env.NODE_ENV !== "production" && typeof window === "undefined") {
|
|
2099
|
-
const isKnown = PROPERTY_MAP[rawKey] || BOOLEAN_SHORTHANDS.has(rawKey) || SNAP_DIRECT_MAP[rawKey] ||
|
|
2194
|
+
const isKnown = PROPERTY_MAP[rawKey] || BOOLEAN_SHORTHANDS.has(rawKey) || SNAP_DIRECT_MAP[rawKey] || rawKey === "fromPos" || rawKey === "viaPos" || rawKey === "toPos" || rawKey.startsWith("--") || rawKey.startsWith("[") || rawKey.startsWith("@") || // Variants that fell through (e.g. empty object)
|
|
2100
2195
|
KNOWN_VARIANTS.has(rawKey) || // Groups/Peers
|
|
2101
2196
|
rawKey === "group" || rawKey === "peer" || // Special variant objects
|
|
2102
2197
|
rawKey === "has" || rawKey === "not" || rawKey === "data" || rawKey === "aria" || rawKey === "supports" || rawKey === "min" || rawKey === "max";
|
|
@@ -2123,6 +2218,11 @@ function transform(szProp, prefix = "", mangleMap) {
|
|
|
2123
2218
|
classes.push(className);
|
|
2124
2219
|
continue;
|
|
2125
2220
|
}
|
|
2221
|
+
if (rawKey === "animationDelay") {
|
|
2222
|
+
const ms = typeof value === "number" ? `${value}ms` : String(value);
|
|
2223
|
+
classes.push(`${className}[animation-delay:${ms}]`);
|
|
2224
|
+
continue;
|
|
2225
|
+
}
|
|
2126
2226
|
if (typeof value === "number") {
|
|
2127
2227
|
if (value < 0 && NEGATIVE_ALLOWED.has(key)) {
|
|
2128
2228
|
className += `-${key}-${Math.abs(value)}`;
|
|
@@ -2135,15 +2235,6 @@ function transform(szProp, prefix = "", mangleMap) {
|
|
|
2135
2235
|
if (typeof value === "string") {
|
|
2136
2236
|
const { value: cleanValue, important } = handleImportant(value);
|
|
2137
2237
|
let finalValue = cleanValue;
|
|
2138
|
-
if (NEEDS_ARBITRARY_PROPERTY.has(key)) {
|
|
2139
|
-
const arbitraryProp = `[${key}:${finalValue}]`;
|
|
2140
|
-
className += arbitraryProp;
|
|
2141
|
-
if (important) {
|
|
2142
|
-
className += "!";
|
|
2143
|
-
}
|
|
2144
|
-
classes.push(className);
|
|
2145
|
-
continue;
|
|
2146
|
-
}
|
|
2147
2238
|
if (finalValue.startsWith("--")) {
|
|
2148
2239
|
const typeHint = CSS_VAR_TYPE_HINTS[rawKey];
|
|
2149
2240
|
if (typeHint) {
|
|
@@ -2177,7 +2268,7 @@ function transform(szProp, prefix = "", mangleMap) {
|
|
|
2177
2268
|
}
|
|
2178
2269
|
}
|
|
2179
2270
|
let mergedClasses = classes;
|
|
2180
|
-
const textSizePattern = /^((?:[a-z0-9\-[\]@/:]*:)*)text-(
|
|
2271
|
+
const textSizePattern = /^((?:[a-z0-9\-[\]@/:]*:)*)text-(xs|sm|base|lg|[2-9]?xl|\[.+\]|\(.+\))$/;
|
|
2181
2272
|
const leadingPattern = /^((?:[a-z0-9\-[\]@/:]*:)*)leading-(.+)$/;
|
|
2182
2273
|
const textEntries = [];
|
|
2183
2274
|
const leadingEntries = [];
|
|
@@ -2194,11 +2285,15 @@ function transform(szProp, prefix = "", mangleMap) {
|
|
|
2194
2285
|
}
|
|
2195
2286
|
if (textEntries.length > 0 && leadingEntries.length > 0) {
|
|
2196
2287
|
const removeIndices = /* @__PURE__ */ new Set();
|
|
2288
|
+
const consumedLeading = /* @__PURE__ */ new Set();
|
|
2197
2289
|
for (const te of textEntries) {
|
|
2198
|
-
const matchingLeading = leadingEntries.find(
|
|
2290
|
+
const matchingLeading = leadingEntries.find(
|
|
2291
|
+
(le) => le.prefix === te.prefix && !consumedLeading.has(le.index)
|
|
2292
|
+
);
|
|
2199
2293
|
if (matchingLeading) {
|
|
2200
2294
|
mergedClasses[te.index] = `${te.prefix}text-${te.size}/${matchingLeading.value}`;
|
|
2201
2295
|
removeIndices.add(matchingLeading.index);
|
|
2296
|
+
consumedLeading.add(matchingLeading.index);
|
|
2202
2297
|
}
|
|
2203
2298
|
}
|
|
2204
2299
|
if (removeIndices.size > 0) {
|
|
@@ -2228,11 +2323,14 @@ function normalizeClassName(className) {
|
|
|
2228
2323
|
// src/transform.ts
|
|
2229
2324
|
function transformSourceCode(source) {
|
|
2230
2325
|
let usesRuntime = false;
|
|
2326
|
+
let usesMerge = false;
|
|
2231
2327
|
let usesColorVar = false;
|
|
2232
2328
|
let transformed = false;
|
|
2233
2329
|
const collectedClasses = /* @__PURE__ */ new Set();
|
|
2330
|
+
const rawClassNames = /* @__PURE__ */ new Set();
|
|
2331
|
+
const diagnostics = [];
|
|
2234
2332
|
if (!source.includes("sz")) {
|
|
2235
|
-
return { code: source, transformed: false, usesRuntime: false, usesColorVar: false, classes: collectedClasses };
|
|
2333
|
+
return { code: source, transformed: false, usesRuntime: false, usesMerge: false, usesColorVar: false, classes: collectedClasses, rawClassNames, diagnostics };
|
|
2236
2334
|
}
|
|
2237
2335
|
try {
|
|
2238
2336
|
const result = babel.transformSync(source, {
|
|
@@ -2256,7 +2354,7 @@ function transformSourceCode(source) {
|
|
|
2256
2354
|
if (t.isStringLiteral(val)) {
|
|
2257
2355
|
for (const c of val.value.split(/\s+/)) {
|
|
2258
2356
|
if (c) {
|
|
2259
|
-
|
|
2357
|
+
rawClassNames.add(c);
|
|
2260
2358
|
}
|
|
2261
2359
|
}
|
|
2262
2360
|
}
|
|
@@ -2266,6 +2364,99 @@ function transformSourceCode(source) {
|
|
|
2266
2364
|
return;
|
|
2267
2365
|
}
|
|
2268
2366
|
const value = path.node.value;
|
|
2367
|
+
let existingClassNameNode = null;
|
|
2368
|
+
let existingClassExpr = null;
|
|
2369
|
+
let existingStyleNode = null;
|
|
2370
|
+
let existingStyleExpr = null;
|
|
2371
|
+
if (path.parentPath?.isJSXOpeningElement()) {
|
|
2372
|
+
for (const attr of path.parentPath.node.attributes) {
|
|
2373
|
+
if (t.isJSXAttribute(attr) && t.isJSXIdentifier(attr.name)) {
|
|
2374
|
+
const aName = attr.name;
|
|
2375
|
+
if (aName.name === "className" || aName.name === "class") {
|
|
2376
|
+
existingClassNameNode = attr;
|
|
2377
|
+
const aVal = attr.value;
|
|
2378
|
+
if (t.isStringLiteral(aVal)) {
|
|
2379
|
+
existingClassExpr = aVal;
|
|
2380
|
+
} else if (t.isJSXExpressionContainer(aVal)) {
|
|
2381
|
+
if (t.isExpression(aVal.expression)) {
|
|
2382
|
+
existingClassExpr = aVal.expression;
|
|
2383
|
+
}
|
|
2384
|
+
}
|
|
2385
|
+
} else if (aName.name === "style") {
|
|
2386
|
+
existingStyleNode = attr;
|
|
2387
|
+
const aVal = attr.value;
|
|
2388
|
+
if (t.isJSXExpressionContainer(aVal)) {
|
|
2389
|
+
if (t.isExpression(aVal.expression)) {
|
|
2390
|
+
existingStyleExpr = aVal.expression;
|
|
2391
|
+
}
|
|
2392
|
+
} else if (t.isStringLiteral(aVal)) {
|
|
2393
|
+
existingStyleExpr = aVal;
|
|
2394
|
+
}
|
|
2395
|
+
}
|
|
2396
|
+
}
|
|
2397
|
+
}
|
|
2398
|
+
}
|
|
2399
|
+
const createMergedClassNameValue = (szExpr) => {
|
|
2400
|
+
if (!existingClassExpr) {
|
|
2401
|
+
return t.isStringLiteral(szExpr) ? szExpr : t.jsxExpressionContainer(szExpr);
|
|
2402
|
+
}
|
|
2403
|
+
if (existingClassNameNode && path.parentPath?.isJSXOpeningElement()) {
|
|
2404
|
+
path.parentPath.node.attributes = path.parentPath.node.attributes.filter(
|
|
2405
|
+
(a) => a !== existingClassNameNode
|
|
2406
|
+
);
|
|
2407
|
+
existingClassNameNode = null;
|
|
2408
|
+
}
|
|
2409
|
+
if (t.isStringLiteral(existingClassExpr) && t.isStringLiteral(szExpr)) {
|
|
2410
|
+
const merged = `${existingClassExpr.value} ${szExpr.value}`.trim();
|
|
2411
|
+
return t.stringLiteral(merged);
|
|
2412
|
+
}
|
|
2413
|
+
usesRuntime = true;
|
|
2414
|
+
usesMerge = true;
|
|
2415
|
+
return t.jsxExpressionContainer(
|
|
2416
|
+
t.callExpression(t.identifier("_szMerge"), [existingClassExpr, szExpr])
|
|
2417
|
+
);
|
|
2418
|
+
};
|
|
2419
|
+
const mergeAndInjectStyle = (newStyleProps) => {
|
|
2420
|
+
if (newStyleProps.length === 0) {
|
|
2421
|
+
return;
|
|
2422
|
+
}
|
|
2423
|
+
if (!path.parentPath?.isJSXOpeningElement()) {
|
|
2424
|
+
return;
|
|
2425
|
+
}
|
|
2426
|
+
if (existingStyleNode && existingStyleExpr) {
|
|
2427
|
+
path.parentPath.node.attributes = path.parentPath.node.attributes.filter(
|
|
2428
|
+
(a) => a !== existingStyleNode
|
|
2429
|
+
);
|
|
2430
|
+
existingStyleNode = null;
|
|
2431
|
+
if (t.isObjectExpression(existingStyleExpr)) {
|
|
2432
|
+
existingStyleExpr.properties.push(...newStyleProps);
|
|
2433
|
+
path.parentPath.node.attributes.push(
|
|
2434
|
+
t.jsxAttribute(t.jsxIdentifier("style"), t.jsxExpressionContainer(existingStyleExpr))
|
|
2435
|
+
);
|
|
2436
|
+
} else if (t.isStringLiteral(existingStyleExpr)) {
|
|
2437
|
+
const parsedOldProps = parseStyleStringToObjectExpr(existingStyleExpr.value).properties;
|
|
2438
|
+
path.parentPath.node.attributes.push(
|
|
2439
|
+
t.jsxAttribute(t.jsxIdentifier("style"), t.jsxExpressionContainer(
|
|
2440
|
+
t.objectExpression([...parsedOldProps, ...newStyleProps])
|
|
2441
|
+
))
|
|
2442
|
+
);
|
|
2443
|
+
} else {
|
|
2444
|
+
const mergedStyle = t.objectExpression([
|
|
2445
|
+
t.spreadElement(existingStyleExpr),
|
|
2446
|
+
...newStyleProps
|
|
2447
|
+
]);
|
|
2448
|
+
path.parentPath.node.attributes.push(
|
|
2449
|
+
t.jsxAttribute(t.jsxIdentifier("style"), t.jsxExpressionContainer(mergedStyle))
|
|
2450
|
+
);
|
|
2451
|
+
}
|
|
2452
|
+
} else {
|
|
2453
|
+
path.parentPath.node.attributes.push(
|
|
2454
|
+
t.jsxAttribute(t.jsxIdentifier("style"), t.jsxExpressionContainer(t.objectExpression(newStyleProps)))
|
|
2455
|
+
);
|
|
2456
|
+
existingStyleExpr = t.objectExpression(newStyleProps);
|
|
2457
|
+
existingStyleNode = path.parentPath.node.attributes[path.parentPath.node.attributes.length - 1];
|
|
2458
|
+
}
|
|
2459
|
+
};
|
|
2269
2460
|
if (t.isStringLiteral(value)) {
|
|
2270
2461
|
path.node.name.name = "className";
|
|
2271
2462
|
for (const c of value.value.split(/\s+/)) {
|
|
@@ -2273,13 +2464,16 @@ function transformSourceCode(source) {
|
|
|
2273
2464
|
collectedClasses.add(c);
|
|
2274
2465
|
}
|
|
2275
2466
|
}
|
|
2467
|
+
path.node.value = createMergedClassNameValue(value);
|
|
2276
2468
|
transformed = true;
|
|
2277
2469
|
return;
|
|
2278
2470
|
}
|
|
2279
2471
|
if (t.isJSXExpressionContainer(value)) {
|
|
2280
2472
|
const expression = value.expression;
|
|
2281
2473
|
if (t.isObjectExpression(expression)) {
|
|
2282
|
-
const
|
|
2474
|
+
const getBinding = (name) => path.scope.getBinding(name);
|
|
2475
|
+
const flatExpression = resolveObjectSpreads(expression, getBinding) ?? expression;
|
|
2476
|
+
const staticObject = evaluateStaticObject(flatExpression);
|
|
2283
2477
|
if (staticObject !== null) {
|
|
2284
2478
|
const { className, attributes } = transform(staticObject);
|
|
2285
2479
|
for (const c of className.split(/\s+/)) {
|
|
@@ -2288,22 +2482,35 @@ function transformSourceCode(source) {
|
|
|
2288
2482
|
}
|
|
2289
2483
|
}
|
|
2290
2484
|
path.node.name.name = "className";
|
|
2291
|
-
path.node.value = t.stringLiteral(className);
|
|
2485
|
+
path.node.value = createMergedClassNameValue(t.stringLiteral(className));
|
|
2292
2486
|
Object.entries(attributes).forEach(([key, val]) => {
|
|
2293
2487
|
if (path.parentPath?.isJSXOpeningElement()) {
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2488
|
+
if (key === "style") {
|
|
2489
|
+
const newProps = parseStyleStringToObjectExpr(val).properties;
|
|
2490
|
+
mergeAndInjectStyle(newProps);
|
|
2491
|
+
} else {
|
|
2492
|
+
path.parentPath.node.attributes.push(
|
|
2493
|
+
t.jsxAttribute(
|
|
2494
|
+
t.jsxIdentifier(key),
|
|
2495
|
+
t.stringLiteral(val)
|
|
2496
|
+
)
|
|
2497
|
+
);
|
|
2498
|
+
}
|
|
2300
2499
|
}
|
|
2301
2500
|
});
|
|
2302
2501
|
transformed = true;
|
|
2303
2502
|
return;
|
|
2304
2503
|
}
|
|
2305
|
-
const
|
|
2306
|
-
if (
|
|
2504
|
+
const hoisted = tryHoistConditionalSpread(expression, getBinding);
|
|
2505
|
+
if (hoisted !== null) {
|
|
2506
|
+
path.node.name.name = "className";
|
|
2507
|
+
path.node.value = createMergedClassNameValue(hoisted);
|
|
2508
|
+
collectFromExpr(hoisted, collectedClasses);
|
|
2509
|
+
transformed = true;
|
|
2510
|
+
return;
|
|
2511
|
+
}
|
|
2512
|
+
const partial = evaluatePartialObject(flatExpression);
|
|
2513
|
+
if (partial !== null && !partial.hasSpread && (partial.dynamicProps.size > 0 || partial.conditionalClasses.length > 0)) {
|
|
2307
2514
|
const staticClasses = [];
|
|
2308
2515
|
if (Object.keys(partial.staticProps).length > 0) {
|
|
2309
2516
|
const { className: sc } = transform(partial.staticProps);
|
|
@@ -2324,23 +2531,28 @@ function transformSourceCode(source) {
|
|
|
2324
2531
|
)
|
|
2325
2532
|
);
|
|
2326
2533
|
}
|
|
2327
|
-
const
|
|
2328
|
-
for (const c of
|
|
2534
|
+
const baseClasses = [...staticClasses, ...partial.rawClasses, ...cssVarClasses].join(" ");
|
|
2535
|
+
for (const c of baseClasses.split(/\s+/)) {
|
|
2329
2536
|
if (c) {
|
|
2330
2537
|
collectedClasses.add(c);
|
|
2331
2538
|
}
|
|
2332
2539
|
}
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
)
|
|
2341
|
-
|
|
2342
|
-
|
|
2540
|
+
for (const cc of partial.conditionalClasses) {
|
|
2541
|
+
for (const c of cc.consequent.split(/\s+/)) {
|
|
2542
|
+
if (c) {
|
|
2543
|
+
collectedClasses.add(c);
|
|
2544
|
+
}
|
|
2545
|
+
}
|
|
2546
|
+
for (const c of cc.alternate.split(/\s+/)) {
|
|
2547
|
+
if (c) {
|
|
2548
|
+
collectedClasses.add(c);
|
|
2549
|
+
}
|
|
2550
|
+
}
|
|
2343
2551
|
}
|
|
2552
|
+
const classExpr = partial.conditionalClasses.length > 0 ? buildConditionalClassExpr(baseClasses, partial.conditionalClasses) : t.stringLiteral(baseClasses);
|
|
2553
|
+
path.node.name.name = "className";
|
|
2554
|
+
path.node.value = createMergedClassNameValue(classExpr);
|
|
2555
|
+
mergeAndInjectStyle(styleProps);
|
|
2344
2556
|
if (partial.usesColorVar) {
|
|
2345
2557
|
usesColorVar = true;
|
|
2346
2558
|
}
|
|
@@ -2353,18 +2565,19 @@ function transformSourceCode(source) {
|
|
|
2353
2565
|
if (binding && binding.path.isVariableDeclarator()) {
|
|
2354
2566
|
const init2 = binding.path.node.init;
|
|
2355
2567
|
if (init2) {
|
|
2356
|
-
const
|
|
2568
|
+
const gbIdent = (name) => path.scope.getBinding(name);
|
|
2569
|
+
const resolved = tryStaticTransformNode(init2, gbIdent);
|
|
2357
2570
|
if (resolved !== null) {
|
|
2358
2571
|
path.node.name.name = "className";
|
|
2359
2572
|
if (t.isStringLiteral(resolved)) {
|
|
2360
|
-
path.node.value = resolved;
|
|
2573
|
+
path.node.value = createMergedClassNameValue(resolved);
|
|
2361
2574
|
for (const c of resolved.value.split(/\s+/)) {
|
|
2362
2575
|
if (c) {
|
|
2363
2576
|
collectedClasses.add(c);
|
|
2364
2577
|
}
|
|
2365
2578
|
}
|
|
2366
2579
|
} else {
|
|
2367
|
-
value
|
|
2580
|
+
path.node.value = createMergedClassNameValue(resolved);
|
|
2368
2581
|
collectFromExpr(resolved, collectedClasses);
|
|
2369
2582
|
}
|
|
2370
2583
|
transformed = true;
|
|
@@ -2374,33 +2587,267 @@ function transformSourceCode(source) {
|
|
|
2374
2587
|
}
|
|
2375
2588
|
}
|
|
2376
2589
|
if (t.isConditionalExpression(expression)) {
|
|
2377
|
-
const
|
|
2590
|
+
const gbCond = (name) => path.scope.getBinding(name);
|
|
2591
|
+
const resolved = tryStaticTransformNode(expression, gbCond);
|
|
2378
2592
|
if (resolved !== null) {
|
|
2379
2593
|
path.node.name.name = "className";
|
|
2380
2594
|
if (t.isStringLiteral(resolved)) {
|
|
2381
|
-
path.node.value = resolved;
|
|
2595
|
+
path.node.value = createMergedClassNameValue(resolved);
|
|
2382
2596
|
for (const c of resolved.value.split(/\s+/)) {
|
|
2383
2597
|
if (c) {
|
|
2384
2598
|
collectedClasses.add(c);
|
|
2385
2599
|
}
|
|
2386
2600
|
}
|
|
2387
2601
|
} else {
|
|
2388
|
-
value
|
|
2602
|
+
path.node.value = createMergedClassNameValue(resolved);
|
|
2389
2603
|
collectFromExpr(resolved, collectedClasses);
|
|
2390
2604
|
}
|
|
2391
2605
|
transformed = true;
|
|
2392
2606
|
return;
|
|
2393
2607
|
}
|
|
2394
2608
|
}
|
|
2609
|
+
if (t.isArrayExpression(expression)) {
|
|
2610
|
+
const parts = [];
|
|
2611
|
+
let hasRuntime = false;
|
|
2612
|
+
const getBindingForArray = (name) => path.scope.getBinding(name);
|
|
2613
|
+
for (const element of expression.elements) {
|
|
2614
|
+
if (element === null) {
|
|
2615
|
+
continue;
|
|
2616
|
+
}
|
|
2617
|
+
if (t.isBooleanLiteral(element) && !element.value) {
|
|
2618
|
+
continue;
|
|
2619
|
+
}
|
|
2620
|
+
if (t.isNullLiteral(element)) {
|
|
2621
|
+
continue;
|
|
2622
|
+
}
|
|
2623
|
+
if (t.isIdentifier(element) && element.name === "undefined") {
|
|
2624
|
+
continue;
|
|
2625
|
+
}
|
|
2626
|
+
if (t.isLogicalExpression(element) && element.operator === "&&") {
|
|
2627
|
+
const resolved2 = tryStaticTransformNode(element.right, getBindingForArray);
|
|
2628
|
+
if (resolved2 !== null && t.isStringLiteral(resolved2)) {
|
|
2629
|
+
if (resolved2.value) {
|
|
2630
|
+
parts.push(t.logicalExpression("&&", element.left, resolved2));
|
|
2631
|
+
for (const c of resolved2.value.split(/\s+/)) {
|
|
2632
|
+
if (c) {
|
|
2633
|
+
collectedClasses.add(c);
|
|
2634
|
+
}
|
|
2635
|
+
}
|
|
2636
|
+
hasRuntime = true;
|
|
2637
|
+
}
|
|
2638
|
+
continue;
|
|
2639
|
+
}
|
|
2640
|
+
parts.push(element);
|
|
2641
|
+
hasRuntime = true;
|
|
2642
|
+
continue;
|
|
2643
|
+
}
|
|
2644
|
+
const resolved = tryStaticTransformNode(element, getBindingForArray);
|
|
2645
|
+
if (resolved !== null) {
|
|
2646
|
+
if (t.isStringLiteral(resolved)) {
|
|
2647
|
+
if (resolved.value) {
|
|
2648
|
+
parts.push(resolved);
|
|
2649
|
+
for (const c of resolved.value.split(/\s+/)) {
|
|
2650
|
+
if (c) {
|
|
2651
|
+
collectedClasses.add(c);
|
|
2652
|
+
}
|
|
2653
|
+
}
|
|
2654
|
+
}
|
|
2655
|
+
} else {
|
|
2656
|
+
parts.push(resolved);
|
|
2657
|
+
collectFromExpr(resolved, collectedClasses);
|
|
2658
|
+
hasRuntime = true;
|
|
2659
|
+
}
|
|
2660
|
+
} else {
|
|
2661
|
+
parts.push(element);
|
|
2662
|
+
hasRuntime = true;
|
|
2663
|
+
}
|
|
2664
|
+
}
|
|
2665
|
+
path.node.name.name = "className";
|
|
2666
|
+
if (parts.length === 0) {
|
|
2667
|
+
path.node.value = createMergedClassNameValue(t.stringLiteral(""));
|
|
2668
|
+
} else if (!hasRuntime) {
|
|
2669
|
+
const merged = parts.map((p) => p.value).filter(Boolean).join(" ");
|
|
2670
|
+
path.node.value = createMergedClassNameValue(t.stringLiteral(merged));
|
|
2671
|
+
} else {
|
|
2672
|
+
if (existingClassExpr) {
|
|
2673
|
+
parts.unshift(existingClassExpr);
|
|
2674
|
+
if (existingClassNameNode && path.parentPath?.isJSXOpeningElement()) {
|
|
2675
|
+
path.parentPath.node.attributes = path.parentPath.node.attributes.filter(
|
|
2676
|
+
(a) => a !== existingClassNameNode
|
|
2677
|
+
);
|
|
2678
|
+
existingClassNameNode = null;
|
|
2679
|
+
}
|
|
2680
|
+
}
|
|
2681
|
+
const szCall2 = t.callExpression(
|
|
2682
|
+
t.identifier("_szMerge"),
|
|
2683
|
+
parts
|
|
2684
|
+
);
|
|
2685
|
+
path.node.value = t.jsxExpressionContainer(szCall2);
|
|
2686
|
+
usesMerge = true;
|
|
2687
|
+
usesRuntime = true;
|
|
2688
|
+
}
|
|
2689
|
+
transformed = true;
|
|
2690
|
+
return;
|
|
2691
|
+
}
|
|
2692
|
+
const loc = expression.loc;
|
|
2693
|
+
const lineCol = loc ? `${loc.start.line}:${loc.start.column + 1}` : "?";
|
|
2694
|
+
let reason, suggestion;
|
|
2695
|
+
if (t.isCallExpression(expression)) {
|
|
2696
|
+
const callee = expression.callee;
|
|
2697
|
+
const name = t.isIdentifier(callee) ? callee.name : t.isMemberExpression(callee) && t.isIdentifier(callee.property) ? callee.property.name : "?";
|
|
2698
|
+
reason = `function call \`${name}()\` result is unknown at build time`;
|
|
2699
|
+
suggestion = "If it returns static variants \u2192 convert to szv(). If it depends on runtime data \u2192 use dynamic().";
|
|
2700
|
+
} else if (t.isIdentifier(expression)) {
|
|
2701
|
+
reason = `identifier \`${expression.name}\` could not be resolved to a static value`;
|
|
2702
|
+
suggestion = "Make sure it's a module-level or function-body const with a literal object value. For variant-based styling \u2192 szv(). For true runtime values \u2192 dynamic().";
|
|
2703
|
+
} else if (t.isMemberExpression(expression)) {
|
|
2704
|
+
reason = "member expression is not statically resolvable";
|
|
2705
|
+
suggestion = "Extract the value to a module-level const. For variant-based styling \u2192 szv(). For true runtime values \u2192 dynamic().";
|
|
2706
|
+
} else {
|
|
2707
|
+
reason = `expression of type \`${expression.type}\` is not statically analyzable`;
|
|
2708
|
+
suggestion = "Use a literal sz object or a module-level const. For variant-based styling \u2192 szv(). For true runtime values \u2192 dynamic().";
|
|
2709
|
+
}
|
|
2710
|
+
diagnostics.push(`sz fallback at ${lineCol}: ${reason}.
|
|
2711
|
+
Suggestion: ${suggestion}`);
|
|
2395
2712
|
path.node.name.name = "className";
|
|
2396
2713
|
const szCall = t.callExpression(
|
|
2397
2714
|
t.identifier("_sz"),
|
|
2398
2715
|
[expression]
|
|
2399
2716
|
);
|
|
2400
|
-
value
|
|
2717
|
+
path.node.value = createMergedClassNameValue(szCall);
|
|
2401
2718
|
usesRuntime = true;
|
|
2402
2719
|
transformed = true;
|
|
2403
2720
|
}
|
|
2721
|
+
},
|
|
2722
|
+
// ── szv catalog extraction ────────────────────────────────────────
|
|
2723
|
+
// When the compiler sees `const X = szv({...})` with a static config,
|
|
2724
|
+
// it emits a no-op catalog array so Tailwind JIT can scan all variant
|
|
2725
|
+
// class strings — even when szv is called at runtime with dynamic args.
|
|
2726
|
+
VariableDeclarator(path) {
|
|
2727
|
+
const init2 = path.node.init;
|
|
2728
|
+
if (!t.isCallExpression(init2)) {
|
|
2729
|
+
return;
|
|
2730
|
+
}
|
|
2731
|
+
if (!t.isIdentifier(init2.callee) || init2.callee.name !== "szv") {
|
|
2732
|
+
return;
|
|
2733
|
+
}
|
|
2734
|
+
if (init2.arguments.length === 0) {
|
|
2735
|
+
return;
|
|
2736
|
+
}
|
|
2737
|
+
if (!t.isIdentifier(path.node.id)) {
|
|
2738
|
+
return;
|
|
2739
|
+
}
|
|
2740
|
+
const configArg = init2.arguments[0];
|
|
2741
|
+
if (!t.isObjectExpression(configArg)) {
|
|
2742
|
+
return;
|
|
2743
|
+
}
|
|
2744
|
+
const config = evaluateStaticObject(configArg);
|
|
2745
|
+
if (!config) {
|
|
2746
|
+
return;
|
|
2747
|
+
}
|
|
2748
|
+
const base = config.base ?? {};
|
|
2749
|
+
const variants = config.variants ?? {};
|
|
2750
|
+
const classStrings = [];
|
|
2751
|
+
const baseResult = transform(base);
|
|
2752
|
+
const baseCls = typeof baseResult === "string" ? baseResult : baseResult.className;
|
|
2753
|
+
if (baseCls) {
|
|
2754
|
+
classStrings.push(baseCls);
|
|
2755
|
+
}
|
|
2756
|
+
for (const variantValues of Object.values(variants)) {
|
|
2757
|
+
for (const variantObj of Object.values(variantValues)) {
|
|
2758
|
+
if (!variantObj || typeof variantObj !== "object") {
|
|
2759
|
+
continue;
|
|
2760
|
+
}
|
|
2761
|
+
const merged = { ...base, ...variantObj };
|
|
2762
|
+
const result2 = transform(merged);
|
|
2763
|
+
const cls = typeof result2 === "string" ? result2 : result2.className;
|
|
2764
|
+
if (cls) {
|
|
2765
|
+
classStrings.push(cls);
|
|
2766
|
+
}
|
|
2767
|
+
}
|
|
2768
|
+
}
|
|
2769
|
+
if (classStrings.length === 0) {
|
|
2770
|
+
return;
|
|
2771
|
+
}
|
|
2772
|
+
for (const combined of classStrings) {
|
|
2773
|
+
for (const c of combined.split(/\s+/)) {
|
|
2774
|
+
if (c) {
|
|
2775
|
+
collectedClasses.add(c);
|
|
2776
|
+
}
|
|
2777
|
+
}
|
|
2778
|
+
}
|
|
2779
|
+
const catalogDecl = t.variableDeclaration("const", [
|
|
2780
|
+
t.variableDeclarator(
|
|
2781
|
+
t.identifier(`_szv_catalog_${path.node.id.name}`),
|
|
2782
|
+
t.arrayExpression(classStrings.map((s) => t.stringLiteral(s)))
|
|
2783
|
+
)
|
|
2784
|
+
]);
|
|
2785
|
+
const parentPath = path.parentPath;
|
|
2786
|
+
if (parentPath && t.isVariableDeclaration(parentPath.node)) {
|
|
2787
|
+
parentPath.insertAfter(catalogDecl);
|
|
2788
|
+
transformed = true;
|
|
2789
|
+
}
|
|
2790
|
+
},
|
|
2791
|
+
// ── dynamic() literal extraction ──────────────────────────────────
|
|
2792
|
+
// Detects `dynamic({...})` and `dynamic(CONST_IDENTIFIER)` calls
|
|
2793
|
+
// with statically-analyzable arguments and adds the resulting
|
|
2794
|
+
// class tokens to collectedClasses so prescanAndWriteClasses()
|
|
2795
|
+
// includes them in csszyx-classes.html for Tailwind to scan.
|
|
2796
|
+
// This means dynamic() with static/const args works in Astro SSR
|
|
2797
|
+
// without needing client:* directives.
|
|
2798
|
+
CallExpression(path) {
|
|
2799
|
+
const callee = path.node.callee;
|
|
2800
|
+
if (!t.isIdentifier(callee) || callee.name !== "dynamic") {
|
|
2801
|
+
return;
|
|
2802
|
+
}
|
|
2803
|
+
if (path.node.arguments.length === 0) {
|
|
2804
|
+
return;
|
|
2805
|
+
}
|
|
2806
|
+
const arg = path.node.arguments[0];
|
|
2807
|
+
if (t.isObjectExpression(arg)) {
|
|
2808
|
+
const staticObj = evaluateStaticObject(arg);
|
|
2809
|
+
if (!staticObj) {
|
|
2810
|
+
return;
|
|
2811
|
+
}
|
|
2812
|
+
const { className } = transform(staticObj);
|
|
2813
|
+
for (const c of className.split(/\s+/)) {
|
|
2814
|
+
if (c) {
|
|
2815
|
+
collectedClasses.add(c);
|
|
2816
|
+
}
|
|
2817
|
+
}
|
|
2818
|
+
return;
|
|
2819
|
+
}
|
|
2820
|
+
let argExpr = arg;
|
|
2821
|
+
while (t.isTSAsExpression(argExpr) || t.isTSSatisfiesExpression(argExpr)) {
|
|
2822
|
+
argExpr = argExpr.expression;
|
|
2823
|
+
}
|
|
2824
|
+
if (t.isIdentifier(argExpr)) {
|
|
2825
|
+
const binding = path.scope.getBinding(argExpr.name);
|
|
2826
|
+
if (!binding) {
|
|
2827
|
+
return;
|
|
2828
|
+
}
|
|
2829
|
+
const declarator = binding.path.node;
|
|
2830
|
+
if (!t.isVariableDeclarator(declarator) || !declarator.init) {
|
|
2831
|
+
return;
|
|
2832
|
+
}
|
|
2833
|
+
let initExpr = declarator.init;
|
|
2834
|
+
while (t.isTSAsExpression(initExpr) || t.isTSSatisfiesExpression(initExpr)) {
|
|
2835
|
+
initExpr = initExpr.expression;
|
|
2836
|
+
}
|
|
2837
|
+
if (!t.isObjectExpression(initExpr)) {
|
|
2838
|
+
return;
|
|
2839
|
+
}
|
|
2840
|
+
const staticObj = evaluateStaticObject(initExpr);
|
|
2841
|
+
if (!staticObj) {
|
|
2842
|
+
return;
|
|
2843
|
+
}
|
|
2844
|
+
const { className } = transform(staticObj);
|
|
2845
|
+
for (const c of className.split(/\s+/)) {
|
|
2846
|
+
if (c) {
|
|
2847
|
+
collectedClasses.add(c);
|
|
2848
|
+
}
|
|
2849
|
+
}
|
|
2850
|
+
}
|
|
2404
2851
|
}
|
|
2405
2852
|
}
|
|
2406
2853
|
};
|
|
@@ -2411,29 +2858,72 @@ function transformSourceCode(source) {
|
|
|
2411
2858
|
code: result?.code || source,
|
|
2412
2859
|
transformed,
|
|
2413
2860
|
usesRuntime,
|
|
2861
|
+
usesMerge,
|
|
2414
2862
|
usesColorVar,
|
|
2415
|
-
classes: collectedClasses
|
|
2863
|
+
classes: collectedClasses,
|
|
2864
|
+
rawClassNames,
|
|
2865
|
+
diagnostics
|
|
2416
2866
|
};
|
|
2417
2867
|
} catch (e) {
|
|
2418
2868
|
console.warn("[csszyx] AST transform failed, falling back to original code:", e);
|
|
2419
|
-
return { code: source, transformed: false, usesRuntime: false, usesColorVar: false, classes: collectedClasses };
|
|
2869
|
+
return { code: source, transformed: false, usesRuntime: false, usesMerge: false, usesColorVar: false, classes: collectedClasses, rawClassNames, diagnostics };
|
|
2870
|
+
}
|
|
2871
|
+
}
|
|
2872
|
+
function parseStyleStringToObjectExpr(styleStr) {
|
|
2873
|
+
const props = styleStr.split(";").map((s) => s.trim()).filter(Boolean);
|
|
2874
|
+
const objProps = [];
|
|
2875
|
+
for (const prop of props) {
|
|
2876
|
+
const idx = prop.indexOf(":");
|
|
2877
|
+
if (idx > -1) {
|
|
2878
|
+
const k = prop.slice(0, idx).trim();
|
|
2879
|
+
const v = prop.slice(idx + 1).trim();
|
|
2880
|
+
let keyNode;
|
|
2881
|
+
if (k.startsWith("--")) {
|
|
2882
|
+
keyNode = t.stringLiteral(k);
|
|
2883
|
+
} else {
|
|
2884
|
+
const camel = k.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
|
|
2885
|
+
keyNode = t.identifier(camel);
|
|
2886
|
+
}
|
|
2887
|
+
objProps.push(t.objectProperty(keyNode, t.stringLiteral(v)));
|
|
2888
|
+
}
|
|
2420
2889
|
}
|
|
2890
|
+
return t.objectExpression(objProps);
|
|
2421
2891
|
}
|
|
2422
|
-
function tryStaticTransformNode(node) {
|
|
2892
|
+
function tryStaticTransformNode(node, getBinding) {
|
|
2893
|
+
if (t.isTSAsExpression(node) || t.isTSSatisfiesExpression(node)) {
|
|
2894
|
+
return tryStaticTransformNode(node.expression, getBinding);
|
|
2895
|
+
}
|
|
2423
2896
|
if (t.isObjectExpression(node)) {
|
|
2424
|
-
const
|
|
2897
|
+
const resolved = getBinding ? resolveObjectSpreads(node, getBinding) ?? node : node;
|
|
2898
|
+
const staticObj = evaluateStaticObject(resolved);
|
|
2425
2899
|
if (staticObj !== null) {
|
|
2426
2900
|
const { className } = transform(staticObj);
|
|
2427
2901
|
return t.stringLiteral(className);
|
|
2428
2902
|
}
|
|
2903
|
+
if (getBinding) {
|
|
2904
|
+
const hoisted = tryHoistConditionalSpread(node, getBinding);
|
|
2905
|
+
if (hoisted !== null) {
|
|
2906
|
+
return hoisted;
|
|
2907
|
+
}
|
|
2908
|
+
}
|
|
2429
2909
|
return null;
|
|
2430
2910
|
}
|
|
2431
2911
|
if (t.isStringLiteral(node)) {
|
|
2432
2912
|
return node;
|
|
2433
2913
|
}
|
|
2914
|
+
if (t.isIdentifier(node) && getBinding) {
|
|
2915
|
+
const binding = getBinding(node.name);
|
|
2916
|
+
if (binding && binding.path.isVariableDeclarator()) {
|
|
2917
|
+
const init2 = binding.path.node.init;
|
|
2918
|
+
if (init2) {
|
|
2919
|
+
return tryStaticTransformNode(init2, getBinding);
|
|
2920
|
+
}
|
|
2921
|
+
}
|
|
2922
|
+
return null;
|
|
2923
|
+
}
|
|
2434
2924
|
if (t.isConditionalExpression(node)) {
|
|
2435
|
-
const consequent = tryStaticTransformNode(node.consequent);
|
|
2436
|
-
const alternate = tryStaticTransformNode(node.alternate);
|
|
2925
|
+
const consequent = tryStaticTransformNode(node.consequent, getBinding);
|
|
2926
|
+
const alternate = tryStaticTransformNode(node.alternate, getBinding);
|
|
2437
2927
|
if (consequent !== null && alternate !== null) {
|
|
2438
2928
|
return t.conditionalExpression(node.test, consequent, alternate);
|
|
2439
2929
|
}
|
|
@@ -2441,6 +2931,39 @@ function tryStaticTransformNode(node) {
|
|
|
2441
2931
|
}
|
|
2442
2932
|
return null;
|
|
2443
2933
|
}
|
|
2934
|
+
function tryHoistConditionalSpread(node, getBinding) {
|
|
2935
|
+
let conditionalSpreadIdx = -1;
|
|
2936
|
+
let conditionalExpr = null;
|
|
2937
|
+
for (let i = 0; i < node.properties.length; i++) {
|
|
2938
|
+
const prop = node.properties[i];
|
|
2939
|
+
if (!t.isSpreadElement(prop)) {
|
|
2940
|
+
continue;
|
|
2941
|
+
}
|
|
2942
|
+
if (t.isConditionalExpression(prop.argument)) {
|
|
2943
|
+
if (conditionalSpreadIdx !== -1) {
|
|
2944
|
+
return null;
|
|
2945
|
+
}
|
|
2946
|
+
conditionalSpreadIdx = i;
|
|
2947
|
+
conditionalExpr = prop.argument;
|
|
2948
|
+
} else {
|
|
2949
|
+
return null;
|
|
2950
|
+
}
|
|
2951
|
+
}
|
|
2952
|
+
if (conditionalSpreadIdx === -1 || conditionalExpr === null) {
|
|
2953
|
+
return null;
|
|
2954
|
+
}
|
|
2955
|
+
const otherProps = node.properties.filter((_, i) => i !== conditionalSpreadIdx);
|
|
2956
|
+
const mkObj = (branch) => t.objectExpression([t.spreadElement(branch), ...otherProps]);
|
|
2957
|
+
const resolvedA = tryStaticTransformNode(mkObj(conditionalExpr.consequent), getBinding);
|
|
2958
|
+
const resolvedB = tryStaticTransformNode(mkObj(conditionalExpr.alternate), getBinding);
|
|
2959
|
+
if (!resolvedA || !resolvedB) {
|
|
2960
|
+
return null;
|
|
2961
|
+
}
|
|
2962
|
+
if (!t.isStringLiteral(resolvedA) || !t.isStringLiteral(resolvedB)) {
|
|
2963
|
+
return null;
|
|
2964
|
+
}
|
|
2965
|
+
return t.conditionalExpression(conditionalExpr.test, resolvedA, resolvedB);
|
|
2966
|
+
}
|
|
2444
2967
|
function evaluateStaticObject(node) {
|
|
2445
2968
|
const result = {};
|
|
2446
2969
|
for (const prop of node.properties) {
|
|
@@ -2455,6 +2978,8 @@ function evaluateStaticObject(node) {
|
|
|
2455
2978
|
key = prop.key.name;
|
|
2456
2979
|
} else if (t.isStringLiteral(prop.key)) {
|
|
2457
2980
|
key = prop.key.value;
|
|
2981
|
+
} else if (t.isNumericLiteral(prop.key)) {
|
|
2982
|
+
key = String(prop.key.value);
|
|
2458
2983
|
} else {
|
|
2459
2984
|
return null;
|
|
2460
2985
|
}
|
|
@@ -2479,10 +3004,82 @@ function evaluateStaticObject(node) {
|
|
|
2479
3004
|
}
|
|
2480
3005
|
return result;
|
|
2481
3006
|
}
|
|
3007
|
+
function resolveObjectSpreads(node, getBinding) {
|
|
3008
|
+
const newProps = [];
|
|
3009
|
+
for (const prop of node.properties) {
|
|
3010
|
+
if (!t.isSpreadElement(prop)) {
|
|
3011
|
+
if (t.isObjectProperty(prop) && t.isObjectExpression(prop.value)) {
|
|
3012
|
+
const resolvedValue = resolveObjectSpreads(prop.value, getBinding);
|
|
3013
|
+
if (resolvedValue === null) {
|
|
3014
|
+
return null;
|
|
3015
|
+
}
|
|
3016
|
+
newProps.push(t.objectProperty(prop.key, resolvedValue, prop.computed, prop.shorthand));
|
|
3017
|
+
} else {
|
|
3018
|
+
newProps.push(prop);
|
|
3019
|
+
}
|
|
3020
|
+
continue;
|
|
3021
|
+
}
|
|
3022
|
+
const arg = prop.argument;
|
|
3023
|
+
if (!t.isIdentifier(arg)) {
|
|
3024
|
+
return null;
|
|
3025
|
+
}
|
|
3026
|
+
const binding = getBinding(arg.name);
|
|
3027
|
+
if (!binding || !binding.path.isVariableDeclarator()) {
|
|
3028
|
+
return null;
|
|
3029
|
+
}
|
|
3030
|
+
let init2 = binding.path.node.init;
|
|
3031
|
+
if (t.isTSAsExpression(init2) || t.isTSSatisfiesExpression(init2)) {
|
|
3032
|
+
init2 = init2.expression;
|
|
3033
|
+
}
|
|
3034
|
+
if (!t.isObjectExpression(init2)) {
|
|
3035
|
+
return null;
|
|
3036
|
+
}
|
|
3037
|
+
const inner = resolveObjectSpreads(init2, getBinding);
|
|
3038
|
+
if (inner === null) {
|
|
3039
|
+
return null;
|
|
3040
|
+
}
|
|
3041
|
+
newProps.push(...inner.properties);
|
|
3042
|
+
}
|
|
3043
|
+
return t.objectExpression(newProps);
|
|
3044
|
+
}
|
|
3045
|
+
function extractStaticLiteralValue(node) {
|
|
3046
|
+
if (t.isStringLiteral(node)) {
|
|
3047
|
+
return node.value;
|
|
3048
|
+
}
|
|
3049
|
+
if (t.isNumericLiteral(node)) {
|
|
3050
|
+
return node.value;
|
|
3051
|
+
}
|
|
3052
|
+
if (t.isBooleanLiteral(node)) {
|
|
3053
|
+
return node.value;
|
|
3054
|
+
}
|
|
3055
|
+
if (t.isUnaryExpression(node) && node.operator === "-" && t.isNumericLiteral(node.argument)) {
|
|
3056
|
+
return -node.argument.value;
|
|
3057
|
+
}
|
|
3058
|
+
return null;
|
|
3059
|
+
}
|
|
3060
|
+
function buildConditionalClassExpr(baseClasses, conditionalClasses) {
|
|
3061
|
+
if (conditionalClasses.length === 0) {
|
|
3062
|
+
return t.stringLiteral(baseClasses);
|
|
3063
|
+
}
|
|
3064
|
+
const makeCondExpr = (cc) => t.conditionalExpression(cc.test, t.stringLiteral(cc.consequent), t.stringLiteral(cc.alternate));
|
|
3065
|
+
if (conditionalClasses.length === 1 && !baseClasses) {
|
|
3066
|
+
return makeCondExpr(conditionalClasses[0]);
|
|
3067
|
+
}
|
|
3068
|
+
const quasis = [];
|
|
3069
|
+
const exprs = [];
|
|
3070
|
+
for (let i = 0; i < conditionalClasses.length; i++) {
|
|
3071
|
+
const prefix = i === 0 ? baseClasses ? baseClasses + " " : "" : " ";
|
|
3072
|
+
quasis.push(t.templateElement({ raw: prefix, cooked: prefix }, false));
|
|
3073
|
+
exprs.push(makeCondExpr(conditionalClasses[i]));
|
|
3074
|
+
}
|
|
3075
|
+
quasis.push(t.templateElement({ raw: "", cooked: "" }, true));
|
|
3076
|
+
return t.templateLiteral(quasis, exprs);
|
|
3077
|
+
}
|
|
2482
3078
|
function evaluatePartialObject(node, variantChain = "") {
|
|
2483
3079
|
const staticProps = {};
|
|
2484
3080
|
const dynamicProps = /* @__PURE__ */ new Map();
|
|
2485
3081
|
const rawClasses = [];
|
|
3082
|
+
const conditionalClasses = [];
|
|
2486
3083
|
let usesColorVar = false;
|
|
2487
3084
|
for (const prop of node.properties) {
|
|
2488
3085
|
if (t.isSpreadElement(prop)) {
|
|
@@ -2499,6 +3096,8 @@ function evaluatePartialObject(node, variantChain = "") {
|
|
|
2499
3096
|
key = prop.key.name;
|
|
2500
3097
|
} else if (t.isStringLiteral(prop.key)) {
|
|
2501
3098
|
key = prop.key.value;
|
|
3099
|
+
} else if (t.isNumericLiteral(prop.key)) {
|
|
3100
|
+
key = String(prop.key.value);
|
|
2502
3101
|
} else {
|
|
2503
3102
|
return null;
|
|
2504
3103
|
}
|
|
@@ -2541,7 +3140,7 @@ function evaluatePartialObject(node, variantChain = "") {
|
|
|
2541
3140
|
staticProps[key] = { color: colorStr, op: opVal };
|
|
2542
3141
|
} else if (t.isExpression(opProp.value)) {
|
|
2543
3142
|
const variantPfx = variantChain ? `${variantChain}:` : "";
|
|
2544
|
-
rawClasses.push(`${variantPfx}${twPrefix}-${colorStr}/
|
|
3143
|
+
rawClasses.push(`${variantPfx}${twPrefix}-${colorStr}/(${opVarName})`);
|
|
2545
3144
|
dynamicProps.set(uniqueKey, {
|
|
2546
3145
|
expression: opProp.value,
|
|
2547
3146
|
category: 3 /* UNITLESS */,
|
|
@@ -2580,6 +3179,7 @@ function evaluatePartialObject(node, variantChain = "") {
|
|
|
2580
3179
|
dynamicProps.set(k, v);
|
|
2581
3180
|
}
|
|
2582
3181
|
rawClasses.push(...nestedResult.rawClasses);
|
|
3182
|
+
conditionalClasses.push(...nestedResult.conditionalClasses);
|
|
2583
3183
|
if (nestedResult.usesColorVar) {
|
|
2584
3184
|
usesColorVar = true;
|
|
2585
3185
|
}
|
|
@@ -2588,6 +3188,25 @@ function evaluatePartialObject(node, variantChain = "") {
|
|
|
2588
3188
|
}
|
|
2589
3189
|
}
|
|
2590
3190
|
}
|
|
3191
|
+
} else if (t.isConditionalExpression(value)) {
|
|
3192
|
+
const consVal = extractStaticLiteralValue(value.consequent);
|
|
3193
|
+
const altVal = extractStaticLiteralValue(value.alternate);
|
|
3194
|
+
if (consVal !== null && altVal !== null) {
|
|
3195
|
+
const { className: classA } = transform({ [key]: consVal });
|
|
3196
|
+
const { className: classB } = transform({ [key]: altVal });
|
|
3197
|
+
const vPfx = variantChain ? getVariantPrefix(variantChain) + ":" : "";
|
|
3198
|
+
const prefixed = (cls) => vPfx ? cls.split(/\s+/).filter(Boolean).map((c) => vPfx + c).join(" ") : cls;
|
|
3199
|
+
conditionalClasses.push({ test: value.test, consequent: prefixed(classA), alternate: prefixed(classB) });
|
|
3200
|
+
} else {
|
|
3201
|
+
const twPrefix = PROPERTY_MAP[key] || key.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
|
|
3202
|
+
const category = getPropertyCategory(key);
|
|
3203
|
+
const varName = getCSSVariableName(key, variantChain || void 0);
|
|
3204
|
+
const uniqueKey = variantChain ? `${variantChain}-${key}` : key;
|
|
3205
|
+
if (COLOR_PROPERTIES.has(key)) {
|
|
3206
|
+
usesColorVar = true;
|
|
3207
|
+
}
|
|
3208
|
+
dynamicProps.set(uniqueKey, { expression: value, category, varName, twPrefix, variantChain: variantChain || "" });
|
|
3209
|
+
}
|
|
2591
3210
|
} else if (t.isExpression(value)) {
|
|
2592
3211
|
const twPrefix = PROPERTY_MAP[key] || key.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
|
|
2593
3212
|
const category = getPropertyCategory(key);
|
|
@@ -2607,7 +3226,7 @@ function evaluatePartialObject(node, variantChain = "") {
|
|
|
2607
3226
|
return null;
|
|
2608
3227
|
}
|
|
2609
3228
|
}
|
|
2610
|
-
return { staticProps, dynamicProps, rawClasses, hasSpread: false, usesColorVar };
|
|
3229
|
+
return { staticProps, dynamicProps, rawClasses, conditionalClasses, hasSpread: false, usesColorVar };
|
|
2611
3230
|
}
|
|
2612
3231
|
function generateStyleValueExpression(info) {
|
|
2613
3232
|
const { expression, category } = info;
|
|
@@ -2670,7 +3289,7 @@ function collectFromExpr(node, classes) {
|
|
|
2670
3289
|
function buildCSSVarClassName(info) {
|
|
2671
3290
|
const { twPrefix, varName, variantChain } = info;
|
|
2672
3291
|
const variantPrefix = variantChain ? `${getVariantPrefix(variantChain)}:` : "";
|
|
2673
|
-
return `${variantPrefix}${twPrefix}-
|
|
3292
|
+
return `${variantPrefix}${twPrefix}-(${varName})`;
|
|
2674
3293
|
}
|
|
2675
3294
|
|
|
2676
3295
|
// src/compiler.ts
|
|
@@ -3136,12 +3755,16 @@ function mergeOptions(options = {}) {
|
|
|
3136
3755
|
}
|
|
3137
3756
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3138
3757
|
0 && (module.exports = {
|
|
3758
|
+
BOOLEAN_SHORTHANDS,
|
|
3139
3759
|
COLOR_PROPERTIES,
|
|
3140
3760
|
CsszyxCompiler,
|
|
3141
3761
|
DEFAULT_COMPILER_OPTIONS,
|
|
3762
|
+
KNOWN_VARIANTS,
|
|
3142
3763
|
ManifestBuilder,
|
|
3143
3764
|
PROPERTY_CATEGORY_MAP,
|
|
3765
|
+
PROPERTY_MAP,
|
|
3144
3766
|
PropertyCategory,
|
|
3767
|
+
SUGGESTION_MAP,
|
|
3145
3768
|
VERSION,
|
|
3146
3769
|
buildParentMap,
|
|
3147
3770
|
createRecoveryToken,
|