@csszyx/compiler 0.2.0 → 0.3.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # @csszyx/compiler
2
2
 
3
- TypeScript compiler package for csszyx - handles JSX transformation, recovery token generation, and manifest creation.
3
+ TypeScript compiler package for CSSzyx - handles JSX transformation, recovery token generation, and manifest creation.
4
4
 
5
5
  ## Features
6
6
 
@@ -83,7 +83,7 @@ const manifest = builder.build();
83
83
 
84
84
  #### `transform(szProp: SzObject, prefix?: string): string`
85
85
 
86
- Transforms a csszyx sz object into a Tailwind CSS className string.
86
+ Transforms a CSSzyx sz object into a Tailwind CSS className string.
87
87
 
88
88
  #### `isValidSzProp(szProp: unknown): boolean`
89
89
 
package/dist/index.cjs CHANGED
@@ -463,6 +463,7 @@ var PROPERTY_MAP = {
463
463
  color: "text",
464
464
  text: "text",
465
465
  fontWeight: "font",
466
+ weight: "font",
466
467
  fontFamily: "font",
467
468
  fontStretch: "font-stretch",
468
469
  textAlign: "text",
@@ -554,9 +555,14 @@ var PROPERTY_MAP = {
554
555
  scale: "scale",
555
556
  scaleX: "scale-x",
556
557
  scaleY: "scale-y",
558
+ scaleZ: "scale-z",
557
559
  rotate: "rotate",
560
+ rotateX: "rotate-x",
561
+ rotateY: "rotate-y",
562
+ rotateZ: "rotate-z",
558
563
  translateX: "translate-x",
559
564
  translateY: "translate-y",
565
+ translateZ: "translate-z",
560
566
  skewX: "skew-x",
561
567
  skewY: "skew-y",
562
568
  origin: "origin",
@@ -564,6 +570,7 @@ var PROPERTY_MAP = {
564
570
  perspective: "perspective",
565
571
  perspectiveOrigin: "perspective-origin",
566
572
  transformStyle: "transform",
573
+ transform: "transform",
567
574
  // Transitions & Animation
568
575
  transition: "transition",
569
576
  transitionBehavior: "transition",
@@ -581,6 +588,8 @@ var PROPERTY_MAP = {
581
588
  cursor: "cursor",
582
589
  caret: "caret",
583
590
  pointerEvents: "pointer-events",
591
+ fieldSizing: "field-sizing",
592
+ scheme: "scheme",
584
593
  resize: "resize",
585
594
  scroll: "scroll",
586
595
  scrollM: "scroll-m",
@@ -954,6 +963,7 @@ var BOOLEAN_SHORTHANDS = /* @__PURE__ */ new Set([
954
963
  // Misc
955
964
  "container",
956
965
  "prose",
966
+ "proseInvert",
957
967
  "srOnly",
958
968
  "notSrOnly",
959
969
  "isolate",
@@ -980,8 +990,7 @@ var BOOLEAN_SHORTHANDS = /* @__PURE__ */ new Set([
980
990
  "rotate3d",
981
991
  "translate3d",
982
992
  "transformGpu",
983
- "transformCpu",
984
- "transformNone"
993
+ "transformCpu"
985
994
  ]);
986
995
  var BOOLEAN_TO_CLASS = {
987
996
  inlineBlock: "inline-block",
@@ -1019,7 +1028,8 @@ var BOOLEAN_TO_CLASS = {
1019
1028
  translate3d: "translate-3d",
1020
1029
  transformGpu: "transform-gpu",
1021
1030
  transformCpu: "transform-cpu",
1022
- transformNone: "transform-none"
1031
+ // Misc
1032
+ proseInvert: "prose-invert"
1023
1033
  };
1024
1034
  var SNAP_DIRECT_MAP = {
1025
1035
  snapAlign: {
@@ -1076,10 +1086,16 @@ var NEGATIVE_ALLOWED = /* @__PURE__ */ new Set([
1076
1086
  "row-start",
1077
1087
  "row-end",
1078
1088
  "rotate",
1089
+ "rotate-x",
1090
+ "rotate-y",
1091
+ "rotate-z",
1092
+ "scale-z",
1079
1093
  "skew-x",
1080
1094
  "skew-y",
1081
1095
  "translate-x",
1082
1096
  "translate-y",
1097
+ "translate-z",
1098
+ "mask",
1083
1099
  "space-x",
1084
1100
  "space-y",
1085
1101
  "tracking",
@@ -1119,7 +1135,7 @@ function normalizeArbitraryVariant(key) {
1119
1135
  return key.replace(/\s+/g, "");
1120
1136
  }
1121
1137
  function normalizeArbitraryValue(value) {
1122
- return value.trim().replace(/\s*([+*/(),:])\s*/g, "$1").replace(/\s+/g, "_");
1138
+ return value.trim().replace(/\s+/g, "_");
1123
1139
  }
1124
1140
  var FRACTION_SUPPORTED_PROPS = /* @__PURE__ */ new Set([
1125
1141
  // Sizing (both rawKey and resolved key forms)
@@ -1160,11 +1176,15 @@ var FRACTION_SUPPORTED_PROPS = /* @__PURE__ */ new Set([
1160
1176
  "translate-x",
1161
1177
  "translateX",
1162
1178
  "translate-y",
1163
- "translateY"
1179
+ "translateY",
1180
+ // Aspect
1181
+ "aspect"
1164
1182
  ]);
1165
1183
  function needsArbitraryBrackets(value) {
1166
- 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(value) || // Units
1184
+ 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(value) || // Positive units
1185
+ /^-\d+(\.\d+)?(px|rem|em|%|vh|vw|ch|dvh|dvw|svh|svw|lvh|lvw|cqw|cqh|deg|rad|turn|grad|ms|s|fr)$/.test(value) || // Negative units like -1px, -2rem
1167
1186
  /^\.\d+(px|rem|em|%|vh|vw|ch)?$/.test(value) || // Values starting with . like .25em
1187
+ /^-\.\d+(px|rem|em|%|vh|vw|ch)?$/.test(value) || // Negative values starting with -. like -.25em
1168
1188
  value.startsWith("#") || // Hex colors
1169
1189
  value.startsWith("rgb") || // RGB colors
1170
1190
  value.startsWith("hsl") || // HSL colors
@@ -1616,12 +1636,13 @@ function transform(szProp, prefix = "", mangleMap) {
1616
1636
  }
1617
1637
  let className = prefix;
1618
1638
  if (rawKey === "willChange" && typeof value === "string") {
1619
- if (value === "scroll") {
1620
- classes.push(`${prefix}will-change-scroll-position`);
1639
+ const WILL_CHANGE_KEYWORDS = /* @__PURE__ */ new Set(["auto", "scroll", "contents", "transform"]);
1640
+ if (WILL_CHANGE_KEYWORDS.has(value)) {
1641
+ classes.push(`${prefix}will-change-${value}`);
1621
1642
  } else if (value.startsWith("--")) {
1622
1643
  classes.push(`${prefix}will-change-(${value})`);
1623
1644
  } else {
1624
- classes.push(`${prefix}will-change-${value}`);
1645
+ classes.push(`${prefix}will-change-[${normalizeArbitraryValue(value)}]`);
1625
1646
  }
1626
1647
  continue;
1627
1648
  }
@@ -1735,10 +1756,10 @@ function transform(szProp, prefix = "", mangleMap) {
1735
1756
  continue;
1736
1757
  }
1737
1758
  if (rawKey === "textOverflow") {
1738
- if (value === "ellipsis") {
1739
- classes.push(`${prefix}truncate`);
1740
- } else {
1759
+ if (value === "ellipsis" || value === "clip") {
1741
1760
  classes.push(`${prefix}text-${value}`);
1761
+ } else {
1762
+ classes.push(`${prefix}text-[${value}]`);
1742
1763
  }
1743
1764
  continue;
1744
1765
  }
@@ -1806,8 +1827,13 @@ function transform(szProp, prefix = "", mangleMap) {
1806
1827
  className += `font-${sValue}`;
1807
1828
  } else if (sValue.startsWith("--")) {
1808
1829
  className += `font-stretch-(${sValue})`;
1809
- } else if (/^\d+%$/.test(sValue)) {
1810
- className += `font-stretch-${sValue}`;
1830
+ } else if (/^\d+(\.\d+)?%$/.test(sValue)) {
1831
+ const valNum = parseFloat(sValue);
1832
+ if (sValue.includes(".") || !Number.isInteger(valNum)) {
1833
+ className += `font-stretch-[${sValue}]`;
1834
+ } else {
1835
+ className += `font-stretch-${sValue}`;
1836
+ }
1811
1837
  } else {
1812
1838
  className += `font-stretch-[${sValue}]`;
1813
1839
  }
@@ -1928,6 +1954,17 @@ function transform(szProp, prefix = "", mangleMap) {
1928
1954
  classes.push(className);
1929
1955
  continue;
1930
1956
  }
1957
+ if (rawKey === "bgRepeat" || rawKey === "backgroundRepeat") {
1958
+ if (value === "repeat") {
1959
+ className += "bg-repeat";
1960
+ } else if (value === "no-repeat") {
1961
+ className += "bg-no-repeat";
1962
+ } else {
1963
+ className += `bg-repeat-${value}`;
1964
+ }
1965
+ classes.push(className);
1966
+ continue;
1967
+ }
1931
1968
  if (rawKey === "maskSize") {
1932
1969
  className += `mask-${value}`;
1933
1970
  classes.push(className);
@@ -1953,8 +1990,11 @@ function transform(szProp, prefix = "", mangleMap) {
1953
1990
  classes.push(className);
1954
1991
  continue;
1955
1992
  }
1956
- if (rawKey === "content") {
1957
- if (value.startsWith("--")) {
1993
+ if (rawKey === "content" || rawKey === "alignContent") {
1994
+ const ALIGN_CONTENT_KEYWORDS = /* @__PURE__ */ new Set(["normal", "center", "start", "end", "between", "around", "evenly", "baseline", "stretch"]);
1995
+ if (ALIGN_CONTENT_KEYWORDS.has(value)) {
1996
+ className += `content-${value}`;
1997
+ } else if (value.startsWith("--")) {
1958
1998
  className += `content-(${value})`;
1959
1999
  } else if (!["none", "empty"].includes(value)) {
1960
2000
  className += `content-[${value}]`;
@@ -2104,7 +2144,6 @@ function transform(szProp, prefix = "", mangleMap) {
2104
2144
  classes.push(className);
2105
2145
  continue;
2106
2146
  }
2107
- const isAspectRatio = key === "aspect" && /^\d+\/\d+$/.test(finalValue);
2108
2147
  if (finalValue.startsWith("--")) {
2109
2148
  const typeHint = CSS_VAR_TYPE_HINTS[rawKey];
2110
2149
  if (typeHint) {
@@ -2118,10 +2157,19 @@ function transform(szProp, prefix = "", mangleMap) {
2118
2157
  if (!FRACTION_SUPPORTED_PROPS.has(rawKey)) {
2119
2158
  finalValue = `[${finalValue}]`;
2120
2159
  }
2121
- } else if (needsArbitraryBrackets(finalValue) || isAspectRatio || /^\d+\.\d+%$/.test(finalValue)) {
2160
+ } else if (key === "aspect" && /^[0-9]+(?:\.[0-9]+)?\/[0-9]+(?:\.[0-9]+)?$/.test(finalValue)) {
2161
+ if (finalValue === "auto" || finalValue === "square" || finalValue === "video" || /^\d+\/\d+$/.test(finalValue)) {
2162
+ } else {
2163
+ finalValue = `[${finalValue}]`;
2164
+ }
2165
+ } else if (needsArbitraryBrackets(finalValue) || /^\d+\.\d+%$/.test(finalValue)) {
2122
2166
  finalValue = `[${normalizeArbitraryValue(finalValue)}]`;
2123
2167
  }
2124
- className += `${key}-${finalValue}`;
2168
+ if (finalValue.startsWith("-") && NEGATIVE_ALLOWED.has(key)) {
2169
+ className = `-${prefix}${key}-${finalValue.substring(1)}`;
2170
+ } else {
2171
+ className += `${key}-${finalValue}`;
2172
+ }
2125
2173
  if (important) {
2126
2174
  className += "!";
2127
2175
  }
@@ -2182,8 +2230,9 @@ function transformSourceCode(source) {
2182
2230
  let usesRuntime = false;
2183
2231
  let usesColorVar = false;
2184
2232
  let transformed = false;
2233
+ const collectedClasses = /* @__PURE__ */ new Set();
2185
2234
  if (!source.includes("sz")) {
2186
- return { code: source, transformed: false, usesRuntime: false, usesColorVar: false };
2235
+ return { code: source, transformed: false, usesRuntime: false, usesColorVar: false, classes: collectedClasses };
2187
2236
  }
2188
2237
  try {
2189
2238
  const result = babel.transformSync(source, {
@@ -2201,12 +2250,29 @@ function transformSourceCode(source) {
2201
2250
  return {
2202
2251
  visitor: {
2203
2252
  JSXAttribute(path) {
2204
- if (path.node.name.name !== "sz") {
2253
+ const attrName = t.isJSXIdentifier(path.node.name) ? path.node.name.name : "";
2254
+ if (attrName === "className" || attrName === "class") {
2255
+ const val = path.node.value;
2256
+ if (t.isStringLiteral(val)) {
2257
+ for (const c of val.value.split(/\s+/)) {
2258
+ if (c) {
2259
+ collectedClasses.add(c);
2260
+ }
2261
+ }
2262
+ }
2263
+ return;
2264
+ }
2265
+ if (attrName !== "sz") {
2205
2266
  return;
2206
2267
  }
2207
2268
  const value = path.node.value;
2208
2269
  if (t.isStringLiteral(value)) {
2209
2270
  path.node.name.name = "className";
2271
+ for (const c of value.value.split(/\s+/)) {
2272
+ if (c) {
2273
+ collectedClasses.add(c);
2274
+ }
2275
+ }
2210
2276
  transformed = true;
2211
2277
  return;
2212
2278
  }
@@ -2216,6 +2282,11 @@ function transformSourceCode(source) {
2216
2282
  const staticObject = evaluateStaticObject(expression);
2217
2283
  if (staticObject !== null) {
2218
2284
  const { className, attributes } = transform(staticObject);
2285
+ for (const c of className.split(/\s+/)) {
2286
+ if (c) {
2287
+ collectedClasses.add(c);
2288
+ }
2289
+ }
2219
2290
  path.node.name.name = "className";
2220
2291
  path.node.value = t.stringLiteral(className);
2221
2292
  Object.entries(attributes).forEach(([key, val]) => {
@@ -2254,6 +2325,11 @@ function transformSourceCode(source) {
2254
2325
  );
2255
2326
  }
2256
2327
  const allClasses = [...staticClasses, ...partial.rawClasses, ...cssVarClasses].join(" ");
2328
+ for (const c of allClasses.split(/\s+/)) {
2329
+ if (c) {
2330
+ collectedClasses.add(c);
2331
+ }
2332
+ }
2257
2333
  path.node.name.name = "className";
2258
2334
  path.node.value = t.stringLiteral(allClasses);
2259
2335
  if (styleProps.length > 0 && path.parentPath?.isJSXOpeningElement()) {
@@ -2282,8 +2358,14 @@ function transformSourceCode(source) {
2282
2358
  path.node.name.name = "className";
2283
2359
  if (t.isStringLiteral(resolved)) {
2284
2360
  path.node.value = resolved;
2361
+ for (const c of resolved.value.split(/\s+/)) {
2362
+ if (c) {
2363
+ collectedClasses.add(c);
2364
+ }
2365
+ }
2285
2366
  } else {
2286
2367
  value.expression = resolved;
2368
+ collectFromExpr(resolved, collectedClasses);
2287
2369
  }
2288
2370
  transformed = true;
2289
2371
  return;
@@ -2297,8 +2379,14 @@ function transformSourceCode(source) {
2297
2379
  path.node.name.name = "className";
2298
2380
  if (t.isStringLiteral(resolved)) {
2299
2381
  path.node.value = resolved;
2382
+ for (const c of resolved.value.split(/\s+/)) {
2383
+ if (c) {
2384
+ collectedClasses.add(c);
2385
+ }
2386
+ }
2300
2387
  } else {
2301
2388
  value.expression = resolved;
2389
+ collectFromExpr(resolved, collectedClasses);
2302
2390
  }
2303
2391
  transformed = true;
2304
2392
  return;
@@ -2323,11 +2411,12 @@ function transformSourceCode(source) {
2323
2411
  code: result?.code || source,
2324
2412
  transformed,
2325
2413
  usesRuntime,
2326
- usesColorVar
2414
+ usesColorVar,
2415
+ classes: collectedClasses
2327
2416
  };
2328
2417
  } catch (e) {
2329
2418
  console.warn("[csszyx] AST transform failed, falling back to original code:", e);
2330
- return { code: source, transformed: false, usesRuntime: false, usesColorVar: false };
2419
+ return { code: source, transformed: false, usesRuntime: false, usesColorVar: false, classes: collectedClasses };
2331
2420
  }
2332
2421
  }
2333
2422
  function tryStaticTransformNode(node) {
@@ -2566,6 +2655,18 @@ function generateStyleValueExpression(info) {
2566
2655
  );
2567
2656
  }
2568
2657
  }
2658
+ function collectFromExpr(node, classes) {
2659
+ if (t.isStringLiteral(node)) {
2660
+ for (const c of node.value.split(/\s+/)) {
2661
+ if (c) {
2662
+ classes.add(c);
2663
+ }
2664
+ }
2665
+ } else if (t.isConditionalExpression(node)) {
2666
+ collectFromExpr(node.consequent, classes);
2667
+ collectFromExpr(node.alternate, classes);
2668
+ }
2669
+ }
2569
2670
  function buildCSSVarClassName(info) {
2570
2671
  const { twPrefix, varName, variantChain } = info;
2571
2672
  const variantPrefix = variantChain ? `${getVariantPrefix(variantChain)}:` : "";
package/dist/index.d.cts CHANGED
@@ -61,6 +61,7 @@ declare function transformSourceCode(source: string): {
61
61
  transformed: boolean;
62
62
  usesRuntime: boolean;
63
63
  usesColorVar: boolean;
64
+ classes: Set<string>;
64
65
  };
65
66
 
66
67
  /**
@@ -606,6 +607,8 @@ interface LayoutProps {
606
607
  container?: boolean;
607
608
  /** Boolean sugar for prose */
608
609
  prose?: boolean;
610
+ /** Boolean sugar for prose-invert (requires @tailwindcss/typography plugin) */
611
+ proseInvert?: boolean;
609
612
  /** @see https://tailwindcss.com/docs/float */
610
613
  float?: 'right' | 'left' | 'start' | 'end' | 'none';
611
614
  /** @see https://tailwindcss.com/docs/clear */
@@ -1066,15 +1069,25 @@ interface TransformProps {
1066
1069
  scale?: 0 | 50 | 75 | 90 | 95 | 100 | 105 | 110 | 125 | 150 | 200 | number | (string & {});
1067
1070
  scaleX?: TransformProps['scale'];
1068
1071
  scaleY?: TransformProps['scale'];
1072
+ /** @see https://tailwindcss.com/docs/scale (Z-axis, 3D) */
1073
+ scaleZ?: TransformProps['scale'];
1069
1074
  /** Boolean sugar for 3D scale */
1070
1075
  scale3d?: boolean;
1071
1076
  /** @see https://tailwindcss.com/docs/rotate */
1072
1077
  rotate?: 0 | 1 | 2 | 3 | 6 | 12 | 45 | 90 | 180 | number | (string & {});
1078
+ /** @see https://tailwindcss.com/docs/rotate (X-axis, 3D) */
1079
+ rotateX?: TransformProps['rotate'];
1080
+ /** @see https://tailwindcss.com/docs/rotate (Y-axis, 3D) */
1081
+ rotateY?: TransformProps['rotate'];
1082
+ /** @see https://tailwindcss.com/docs/rotate (Z-axis, 3D) */
1083
+ rotateZ?: TransformProps['rotate'];
1073
1084
  /** Boolean sugar for 3D rotate */
1074
1085
  rotate3d?: boolean;
1075
1086
  /** @see https://tailwindcss.com/docs/translate */
1076
1087
  translateX?: SpacingValue | FractionValue;
1077
1088
  translateY?: SpacingValue | FractionValue;
1089
+ /** @see https://tailwindcss.com/docs/translate (Z-axis, 3D) */
1090
+ translateZ?: SpacingValue;
1078
1091
  /** Boolean sugar for 3D translate */
1079
1092
  translate3d?: boolean;
1080
1093
  /** @see https://tailwindcss.com/docs/skew */
@@ -1085,7 +1098,8 @@ interface TransformProps {
1085
1098
  /** Transform rendering hints */
1086
1099
  transformGpu?: boolean;
1087
1100
  transformCpu?: boolean;
1088
- transformNone?: boolean;
1101
+ /** @see https://tailwindcss.com/docs/transform */
1102
+ transform?: 'none';
1089
1103
  /** @see https://tailwindcss.com/docs/perspective */
1090
1104
  perspective?: 'none' | (string & {});
1091
1105
  perspectiveOrigin?: (string & {});
@@ -1121,6 +1135,10 @@ interface InteractivityProps {
1121
1135
  caret?: 'auto' | ColorPropValue;
1122
1136
  /** @see https://tailwindcss.com/docs/pointer-events */
1123
1137
  pointerEvents?: 'none' | 'auto';
1138
+ /** @see https://tailwindcss.com/docs/field-sizing */
1139
+ fieldSizing?: 'fixed' | 'content';
1140
+ /** @see https://tailwindcss.com/docs/color-scheme */
1141
+ scheme?: 'normal' | 'dark' | 'light' | 'light-dark' | 'only-dark' | 'only-light';
1124
1142
  /** @see https://tailwindcss.com/docs/resize */
1125
1143
  resize?: 'none' | 'y' | 'x' | boolean;
1126
1144
  /** @see https://tailwindcss.com/docs/scroll-behavior */
package/dist/index.d.ts CHANGED
@@ -61,6 +61,7 @@ declare function transformSourceCode(source: string): {
61
61
  transformed: boolean;
62
62
  usesRuntime: boolean;
63
63
  usesColorVar: boolean;
64
+ classes: Set<string>;
64
65
  };
65
66
 
66
67
  /**
@@ -606,6 +607,8 @@ interface LayoutProps {
606
607
  container?: boolean;
607
608
  /** Boolean sugar for prose */
608
609
  prose?: boolean;
610
+ /** Boolean sugar for prose-invert (requires @tailwindcss/typography plugin) */
611
+ proseInvert?: boolean;
609
612
  /** @see https://tailwindcss.com/docs/float */
610
613
  float?: 'right' | 'left' | 'start' | 'end' | 'none';
611
614
  /** @see https://tailwindcss.com/docs/clear */
@@ -1066,15 +1069,25 @@ interface TransformProps {
1066
1069
  scale?: 0 | 50 | 75 | 90 | 95 | 100 | 105 | 110 | 125 | 150 | 200 | number | (string & {});
1067
1070
  scaleX?: TransformProps['scale'];
1068
1071
  scaleY?: TransformProps['scale'];
1072
+ /** @see https://tailwindcss.com/docs/scale (Z-axis, 3D) */
1073
+ scaleZ?: TransformProps['scale'];
1069
1074
  /** Boolean sugar for 3D scale */
1070
1075
  scale3d?: boolean;
1071
1076
  /** @see https://tailwindcss.com/docs/rotate */
1072
1077
  rotate?: 0 | 1 | 2 | 3 | 6 | 12 | 45 | 90 | 180 | number | (string & {});
1078
+ /** @see https://tailwindcss.com/docs/rotate (X-axis, 3D) */
1079
+ rotateX?: TransformProps['rotate'];
1080
+ /** @see https://tailwindcss.com/docs/rotate (Y-axis, 3D) */
1081
+ rotateY?: TransformProps['rotate'];
1082
+ /** @see https://tailwindcss.com/docs/rotate (Z-axis, 3D) */
1083
+ rotateZ?: TransformProps['rotate'];
1073
1084
  /** Boolean sugar for 3D rotate */
1074
1085
  rotate3d?: boolean;
1075
1086
  /** @see https://tailwindcss.com/docs/translate */
1076
1087
  translateX?: SpacingValue | FractionValue;
1077
1088
  translateY?: SpacingValue | FractionValue;
1089
+ /** @see https://tailwindcss.com/docs/translate (Z-axis, 3D) */
1090
+ translateZ?: SpacingValue;
1078
1091
  /** Boolean sugar for 3D translate */
1079
1092
  translate3d?: boolean;
1080
1093
  /** @see https://tailwindcss.com/docs/skew */
@@ -1085,7 +1098,8 @@ interface TransformProps {
1085
1098
  /** Transform rendering hints */
1086
1099
  transformGpu?: boolean;
1087
1100
  transformCpu?: boolean;
1088
- transformNone?: boolean;
1101
+ /** @see https://tailwindcss.com/docs/transform */
1102
+ transform?: 'none';
1089
1103
  /** @see https://tailwindcss.com/docs/perspective */
1090
1104
  perspective?: 'none' | (string & {});
1091
1105
  perspectiveOrigin?: (string & {});
@@ -1121,6 +1135,10 @@ interface InteractivityProps {
1121
1135
  caret?: 'auto' | ColorPropValue;
1122
1136
  /** @see https://tailwindcss.com/docs/pointer-events */
1123
1137
  pointerEvents?: 'none' | 'auto';
1138
+ /** @see https://tailwindcss.com/docs/field-sizing */
1139
+ fieldSizing?: 'fixed' | 'content';
1140
+ /** @see https://tailwindcss.com/docs/color-scheme */
1141
+ scheme?: 'normal' | 'dark' | 'light' | 'light-dark' | 'only-dark' | 'only-light';
1124
1142
  /** @see https://tailwindcss.com/docs/resize */
1125
1143
  resize?: 'none' | 'y' | 'x' | boolean;
1126
1144
  /** @see https://tailwindcss.com/docs/scroll-behavior */
package/dist/index.js CHANGED
@@ -411,6 +411,7 @@ var PROPERTY_MAP = {
411
411
  color: "text",
412
412
  text: "text",
413
413
  fontWeight: "font",
414
+ weight: "font",
414
415
  fontFamily: "font",
415
416
  fontStretch: "font-stretch",
416
417
  textAlign: "text",
@@ -502,9 +503,14 @@ var PROPERTY_MAP = {
502
503
  scale: "scale",
503
504
  scaleX: "scale-x",
504
505
  scaleY: "scale-y",
506
+ scaleZ: "scale-z",
505
507
  rotate: "rotate",
508
+ rotateX: "rotate-x",
509
+ rotateY: "rotate-y",
510
+ rotateZ: "rotate-z",
506
511
  translateX: "translate-x",
507
512
  translateY: "translate-y",
513
+ translateZ: "translate-z",
508
514
  skewX: "skew-x",
509
515
  skewY: "skew-y",
510
516
  origin: "origin",
@@ -512,6 +518,7 @@ var PROPERTY_MAP = {
512
518
  perspective: "perspective",
513
519
  perspectiveOrigin: "perspective-origin",
514
520
  transformStyle: "transform",
521
+ transform: "transform",
515
522
  // Transitions & Animation
516
523
  transition: "transition",
517
524
  transitionBehavior: "transition",
@@ -529,6 +536,8 @@ var PROPERTY_MAP = {
529
536
  cursor: "cursor",
530
537
  caret: "caret",
531
538
  pointerEvents: "pointer-events",
539
+ fieldSizing: "field-sizing",
540
+ scheme: "scheme",
532
541
  resize: "resize",
533
542
  scroll: "scroll",
534
543
  scrollM: "scroll-m",
@@ -902,6 +911,7 @@ var BOOLEAN_SHORTHANDS = /* @__PURE__ */ new Set([
902
911
  // Misc
903
912
  "container",
904
913
  "prose",
914
+ "proseInvert",
905
915
  "srOnly",
906
916
  "notSrOnly",
907
917
  "isolate",
@@ -928,8 +938,7 @@ var BOOLEAN_SHORTHANDS = /* @__PURE__ */ new Set([
928
938
  "rotate3d",
929
939
  "translate3d",
930
940
  "transformGpu",
931
- "transformCpu",
932
- "transformNone"
941
+ "transformCpu"
933
942
  ]);
934
943
  var BOOLEAN_TO_CLASS = {
935
944
  inlineBlock: "inline-block",
@@ -967,7 +976,8 @@ var BOOLEAN_TO_CLASS = {
967
976
  translate3d: "translate-3d",
968
977
  transformGpu: "transform-gpu",
969
978
  transformCpu: "transform-cpu",
970
- transformNone: "transform-none"
979
+ // Misc
980
+ proseInvert: "prose-invert"
971
981
  };
972
982
  var SNAP_DIRECT_MAP = {
973
983
  snapAlign: {
@@ -1024,10 +1034,16 @@ var NEGATIVE_ALLOWED = /* @__PURE__ */ new Set([
1024
1034
  "row-start",
1025
1035
  "row-end",
1026
1036
  "rotate",
1037
+ "rotate-x",
1038
+ "rotate-y",
1039
+ "rotate-z",
1040
+ "scale-z",
1027
1041
  "skew-x",
1028
1042
  "skew-y",
1029
1043
  "translate-x",
1030
1044
  "translate-y",
1045
+ "translate-z",
1046
+ "mask",
1031
1047
  "space-x",
1032
1048
  "space-y",
1033
1049
  "tracking",
@@ -1067,7 +1083,7 @@ function normalizeArbitraryVariant(key) {
1067
1083
  return key.replace(/\s+/g, "");
1068
1084
  }
1069
1085
  function normalizeArbitraryValue(value) {
1070
- return value.trim().replace(/\s*([+*/(),:])\s*/g, "$1").replace(/\s+/g, "_");
1086
+ return value.trim().replace(/\s+/g, "_");
1071
1087
  }
1072
1088
  var FRACTION_SUPPORTED_PROPS = /* @__PURE__ */ new Set([
1073
1089
  // Sizing (both rawKey and resolved key forms)
@@ -1108,11 +1124,15 @@ var FRACTION_SUPPORTED_PROPS = /* @__PURE__ */ new Set([
1108
1124
  "translate-x",
1109
1125
  "translateX",
1110
1126
  "translate-y",
1111
- "translateY"
1127
+ "translateY",
1128
+ // Aspect
1129
+ "aspect"
1112
1130
  ]);
1113
1131
  function needsArbitraryBrackets(value) {
1114
- 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(value) || // Units
1132
+ 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(value) || // Positive units
1133
+ /^-\d+(\.\d+)?(px|rem|em|%|vh|vw|ch|dvh|dvw|svh|svw|lvh|lvw|cqw|cqh|deg|rad|turn|grad|ms|s|fr)$/.test(value) || // Negative units like -1px, -2rem
1115
1134
  /^\.\d+(px|rem|em|%|vh|vw|ch)?$/.test(value) || // Values starting with . like .25em
1135
+ /^-\.\d+(px|rem|em|%|vh|vw|ch)?$/.test(value) || // Negative values starting with -. like -.25em
1116
1136
  value.startsWith("#") || // Hex colors
1117
1137
  value.startsWith("rgb") || // RGB colors
1118
1138
  value.startsWith("hsl") || // HSL colors
@@ -1564,12 +1584,13 @@ function transform(szProp, prefix = "", mangleMap) {
1564
1584
  }
1565
1585
  let className = prefix;
1566
1586
  if (rawKey === "willChange" && typeof value === "string") {
1567
- if (value === "scroll") {
1568
- classes.push(`${prefix}will-change-scroll-position`);
1587
+ const WILL_CHANGE_KEYWORDS = /* @__PURE__ */ new Set(["auto", "scroll", "contents", "transform"]);
1588
+ if (WILL_CHANGE_KEYWORDS.has(value)) {
1589
+ classes.push(`${prefix}will-change-${value}`);
1569
1590
  } else if (value.startsWith("--")) {
1570
1591
  classes.push(`${prefix}will-change-(${value})`);
1571
1592
  } else {
1572
- classes.push(`${prefix}will-change-${value}`);
1593
+ classes.push(`${prefix}will-change-[${normalizeArbitraryValue(value)}]`);
1573
1594
  }
1574
1595
  continue;
1575
1596
  }
@@ -1683,10 +1704,10 @@ function transform(szProp, prefix = "", mangleMap) {
1683
1704
  continue;
1684
1705
  }
1685
1706
  if (rawKey === "textOverflow") {
1686
- if (value === "ellipsis") {
1687
- classes.push(`${prefix}truncate`);
1688
- } else {
1707
+ if (value === "ellipsis" || value === "clip") {
1689
1708
  classes.push(`${prefix}text-${value}`);
1709
+ } else {
1710
+ classes.push(`${prefix}text-[${value}]`);
1690
1711
  }
1691
1712
  continue;
1692
1713
  }
@@ -1754,8 +1775,13 @@ function transform(szProp, prefix = "", mangleMap) {
1754
1775
  className += `font-${sValue}`;
1755
1776
  } else if (sValue.startsWith("--")) {
1756
1777
  className += `font-stretch-(${sValue})`;
1757
- } else if (/^\d+%$/.test(sValue)) {
1758
- className += `font-stretch-${sValue}`;
1778
+ } else if (/^\d+(\.\d+)?%$/.test(sValue)) {
1779
+ const valNum = parseFloat(sValue);
1780
+ if (sValue.includes(".") || !Number.isInteger(valNum)) {
1781
+ className += `font-stretch-[${sValue}]`;
1782
+ } else {
1783
+ className += `font-stretch-${sValue}`;
1784
+ }
1759
1785
  } else {
1760
1786
  className += `font-stretch-[${sValue}]`;
1761
1787
  }
@@ -1876,6 +1902,17 @@ function transform(szProp, prefix = "", mangleMap) {
1876
1902
  classes.push(className);
1877
1903
  continue;
1878
1904
  }
1905
+ if (rawKey === "bgRepeat" || rawKey === "backgroundRepeat") {
1906
+ if (value === "repeat") {
1907
+ className += "bg-repeat";
1908
+ } else if (value === "no-repeat") {
1909
+ className += "bg-no-repeat";
1910
+ } else {
1911
+ className += `bg-repeat-${value}`;
1912
+ }
1913
+ classes.push(className);
1914
+ continue;
1915
+ }
1879
1916
  if (rawKey === "maskSize") {
1880
1917
  className += `mask-${value}`;
1881
1918
  classes.push(className);
@@ -1901,8 +1938,11 @@ function transform(szProp, prefix = "", mangleMap) {
1901
1938
  classes.push(className);
1902
1939
  continue;
1903
1940
  }
1904
- if (rawKey === "content") {
1905
- if (value.startsWith("--")) {
1941
+ if (rawKey === "content" || rawKey === "alignContent") {
1942
+ const ALIGN_CONTENT_KEYWORDS = /* @__PURE__ */ new Set(["normal", "center", "start", "end", "between", "around", "evenly", "baseline", "stretch"]);
1943
+ if (ALIGN_CONTENT_KEYWORDS.has(value)) {
1944
+ className += `content-${value}`;
1945
+ } else if (value.startsWith("--")) {
1906
1946
  className += `content-(${value})`;
1907
1947
  } else if (!["none", "empty"].includes(value)) {
1908
1948
  className += `content-[${value}]`;
@@ -2052,7 +2092,6 @@ function transform(szProp, prefix = "", mangleMap) {
2052
2092
  classes.push(className);
2053
2093
  continue;
2054
2094
  }
2055
- const isAspectRatio = key === "aspect" && /^\d+\/\d+$/.test(finalValue);
2056
2095
  if (finalValue.startsWith("--")) {
2057
2096
  const typeHint = CSS_VAR_TYPE_HINTS[rawKey];
2058
2097
  if (typeHint) {
@@ -2066,10 +2105,19 @@ function transform(szProp, prefix = "", mangleMap) {
2066
2105
  if (!FRACTION_SUPPORTED_PROPS.has(rawKey)) {
2067
2106
  finalValue = `[${finalValue}]`;
2068
2107
  }
2069
- } else if (needsArbitraryBrackets(finalValue) || isAspectRatio || /^\d+\.\d+%$/.test(finalValue)) {
2108
+ } else if (key === "aspect" && /^[0-9]+(?:\.[0-9]+)?\/[0-9]+(?:\.[0-9]+)?$/.test(finalValue)) {
2109
+ if (finalValue === "auto" || finalValue === "square" || finalValue === "video" || /^\d+\/\d+$/.test(finalValue)) {
2110
+ } else {
2111
+ finalValue = `[${finalValue}]`;
2112
+ }
2113
+ } else if (needsArbitraryBrackets(finalValue) || /^\d+\.\d+%$/.test(finalValue)) {
2070
2114
  finalValue = `[${normalizeArbitraryValue(finalValue)}]`;
2071
2115
  }
2072
- className += `${key}-${finalValue}`;
2116
+ if (finalValue.startsWith("-") && NEGATIVE_ALLOWED.has(key)) {
2117
+ className = `-${prefix}${key}-${finalValue.substring(1)}`;
2118
+ } else {
2119
+ className += `${key}-${finalValue}`;
2120
+ }
2073
2121
  if (important) {
2074
2122
  className += "!";
2075
2123
  }
@@ -2130,8 +2178,9 @@ function transformSourceCode(source) {
2130
2178
  let usesRuntime = false;
2131
2179
  let usesColorVar = false;
2132
2180
  let transformed = false;
2181
+ const collectedClasses = /* @__PURE__ */ new Set();
2133
2182
  if (!source.includes("sz")) {
2134
- return { code: source, transformed: false, usesRuntime: false, usesColorVar: false };
2183
+ return { code: source, transformed: false, usesRuntime: false, usesColorVar: false, classes: collectedClasses };
2135
2184
  }
2136
2185
  try {
2137
2186
  const result = babel.transformSync(source, {
@@ -2149,12 +2198,29 @@ function transformSourceCode(source) {
2149
2198
  return {
2150
2199
  visitor: {
2151
2200
  JSXAttribute(path) {
2152
- if (path.node.name.name !== "sz") {
2201
+ const attrName = t.isJSXIdentifier(path.node.name) ? path.node.name.name : "";
2202
+ if (attrName === "className" || attrName === "class") {
2203
+ const val = path.node.value;
2204
+ if (t.isStringLiteral(val)) {
2205
+ for (const c of val.value.split(/\s+/)) {
2206
+ if (c) {
2207
+ collectedClasses.add(c);
2208
+ }
2209
+ }
2210
+ }
2211
+ return;
2212
+ }
2213
+ if (attrName !== "sz") {
2153
2214
  return;
2154
2215
  }
2155
2216
  const value = path.node.value;
2156
2217
  if (t.isStringLiteral(value)) {
2157
2218
  path.node.name.name = "className";
2219
+ for (const c of value.value.split(/\s+/)) {
2220
+ if (c) {
2221
+ collectedClasses.add(c);
2222
+ }
2223
+ }
2158
2224
  transformed = true;
2159
2225
  return;
2160
2226
  }
@@ -2164,6 +2230,11 @@ function transformSourceCode(source) {
2164
2230
  const staticObject = evaluateStaticObject(expression);
2165
2231
  if (staticObject !== null) {
2166
2232
  const { className, attributes } = transform(staticObject);
2233
+ for (const c of className.split(/\s+/)) {
2234
+ if (c) {
2235
+ collectedClasses.add(c);
2236
+ }
2237
+ }
2167
2238
  path.node.name.name = "className";
2168
2239
  path.node.value = t.stringLiteral(className);
2169
2240
  Object.entries(attributes).forEach(([key, val]) => {
@@ -2202,6 +2273,11 @@ function transformSourceCode(source) {
2202
2273
  );
2203
2274
  }
2204
2275
  const allClasses = [...staticClasses, ...partial.rawClasses, ...cssVarClasses].join(" ");
2276
+ for (const c of allClasses.split(/\s+/)) {
2277
+ if (c) {
2278
+ collectedClasses.add(c);
2279
+ }
2280
+ }
2205
2281
  path.node.name.name = "className";
2206
2282
  path.node.value = t.stringLiteral(allClasses);
2207
2283
  if (styleProps.length > 0 && path.parentPath?.isJSXOpeningElement()) {
@@ -2230,8 +2306,14 @@ function transformSourceCode(source) {
2230
2306
  path.node.name.name = "className";
2231
2307
  if (t.isStringLiteral(resolved)) {
2232
2308
  path.node.value = resolved;
2309
+ for (const c of resolved.value.split(/\s+/)) {
2310
+ if (c) {
2311
+ collectedClasses.add(c);
2312
+ }
2313
+ }
2233
2314
  } else {
2234
2315
  value.expression = resolved;
2316
+ collectFromExpr(resolved, collectedClasses);
2235
2317
  }
2236
2318
  transformed = true;
2237
2319
  return;
@@ -2245,8 +2327,14 @@ function transformSourceCode(source) {
2245
2327
  path.node.name.name = "className";
2246
2328
  if (t.isStringLiteral(resolved)) {
2247
2329
  path.node.value = resolved;
2330
+ for (const c of resolved.value.split(/\s+/)) {
2331
+ if (c) {
2332
+ collectedClasses.add(c);
2333
+ }
2334
+ }
2248
2335
  } else {
2249
2336
  value.expression = resolved;
2337
+ collectFromExpr(resolved, collectedClasses);
2250
2338
  }
2251
2339
  transformed = true;
2252
2340
  return;
@@ -2271,11 +2359,12 @@ function transformSourceCode(source) {
2271
2359
  code: result?.code || source,
2272
2360
  transformed,
2273
2361
  usesRuntime,
2274
- usesColorVar
2362
+ usesColorVar,
2363
+ classes: collectedClasses
2275
2364
  };
2276
2365
  } catch (e) {
2277
2366
  console.warn("[csszyx] AST transform failed, falling back to original code:", e);
2278
- return { code: source, transformed: false, usesRuntime: false, usesColorVar: false };
2367
+ return { code: source, transformed: false, usesRuntime: false, usesColorVar: false, classes: collectedClasses };
2279
2368
  }
2280
2369
  }
2281
2370
  function tryStaticTransformNode(node) {
@@ -2514,6 +2603,18 @@ function generateStyleValueExpression(info) {
2514
2603
  );
2515
2604
  }
2516
2605
  }
2606
+ function collectFromExpr(node, classes) {
2607
+ if (t.isStringLiteral(node)) {
2608
+ for (const c of node.value.split(/\s+/)) {
2609
+ if (c) {
2610
+ classes.add(c);
2611
+ }
2612
+ }
2613
+ } else if (t.isConditionalExpression(node)) {
2614
+ collectFromExpr(node.consequent, classes);
2615
+ collectFromExpr(node.alternate, classes);
2616
+ }
2617
+ }
2517
2618
  function buildCSSVarClassName(info) {
2518
2619
  const { twPrefix, varName, variantChain } = info;
2519
2620
  const variantPrefix = variantChain ? `${getVariantPrefix(variantChain)}:` : "";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@csszyx/compiler",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Core compiler and transformation logic for csszyx",
5
5
  "keywords": [
6
6
  "csszyx",
@@ -38,7 +38,7 @@
38
38
  "@babel/core": "^7.23.7",
39
39
  "@babel/types": "^7.23.6",
40
40
  "@babel/traverse": "^7.23.7",
41
- "@csszyx/core": "0.2.0"
41
+ "@csszyx/core": "0.3.0"
42
42
  },
43
43
  "devDependencies": {
44
44
  "@types/babel__core": "^7.20.5",