@csszyx/compiler 0.9.9 → 0.10.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.
@@ -191,6 +191,22 @@ function getCSSVariableName(property, variantPrefix) {
191
191
  return `--_sz-${prop}`;
192
192
  }
193
193
 
194
+ const MAX_SZ_DEPTH = 32;
195
+ class SzDepthError extends Error {
196
+ /**
197
+ * @param depth - the depth limit that was exceeded (for the message).
198
+ */
199
+ constructor(depth = MAX_SZ_DEPTH) {
200
+ super(
201
+ `[csszyx] sz nesting exceeded the maximum depth of ${depth}. This usually means untrusted/looping data reached an sz prop.`
202
+ );
203
+ this.name = "SzDepthError";
204
+ }
205
+ }
206
+ function isForbiddenSzKey(key) {
207
+ return key === "__proto__" || key === "constructor" || key === "prototype";
208
+ }
209
+
194
210
  const COLOR_STRING_KEYWORDS = /* @__PURE__ */ new Set([
195
211
  "inherit",
196
212
  "current",
@@ -230,11 +246,17 @@ function hasSlashOpacity(value) {
230
246
  }
231
247
  return slashIdx > 0 && /\d$/.test(value.slice(0, slashIdx));
232
248
  }
233
- function stripInvalidColorStrings(sz) {
249
+ function stripInvalidColorStrings(sz, _depth = 0) {
250
+ if (_depth >= MAX_SZ_DEPTH) {
251
+ throw new SzDepthError();
252
+ }
234
253
  const result = {};
235
254
  for (const [key, value] of Object.entries(sz)) {
255
+ if (isForbiddenSzKey(key)) {
256
+ continue;
257
+ }
236
258
  if (typeof value === "object" && value !== null && !Array.isArray(value)) {
237
- result[key] = stripInvalidColorStrings(value);
259
+ result[key] = stripInvalidColorStrings(value, _depth + 1);
238
260
  continue;
239
261
  }
240
262
  if (typeof value === "string" && PROPERTY_CATEGORY_MAP[key] === PropertyCategory.COLOR) {
@@ -412,10 +434,13 @@ const PROPERTY_MAP = {
412
434
  // Typography
413
435
  color: "text",
414
436
  text: "text",
415
- fontWeight: "font",
416
437
  weight: "font",
417
438
  fontFamily: "font",
418
439
  fontStretch: "font-stretch",
440
+ // fontStyle/fontSmoothing are emitted by closed direct-output handlers; the
441
+ // prefix here only marks them as known props (diagnostics, editor tooling).
442
+ fontStyle: "font-style",
443
+ fontSmoothing: "font-smoothing",
419
444
  textAlign: "text",
420
445
  decoration: "decoration",
421
446
  decorationColor: "decoration",
@@ -441,6 +466,9 @@ const PROPERTY_MAP = {
441
466
  listImg: "list-image",
442
467
  // Flex & Grid
443
468
  basis: "basis",
469
+ // `flex` is the flex shorthand (flex: 1 → flex-1, flex: 'auto' → flex-auto).
470
+ // The `flex: true` display sugar was removed (use display: 'flex').
471
+ flex: "flex",
444
472
  flexDir: "flex",
445
473
  flexWrap: "flex",
446
474
  grow: "grow",
@@ -482,6 +510,8 @@ const PROPERTY_MAP = {
482
510
  mixBlend: "mix-blend",
483
511
  bgBlend: "bg-blend",
484
512
  // Filters
513
+ filter: "filter",
514
+ backdropFilter: "backdrop-filter",
485
515
  blur: "blur",
486
516
  brightness: "brightness",
487
517
  contrast: "contrast",
@@ -537,6 +567,8 @@ const PROPERTY_MAP = {
537
567
  maskPos: "mask-position",
538
568
  maskRepeat: "mask-repeat",
539
569
  maskShape: "mask",
570
+ maskClip: "mask-clip",
571
+ maskOrigin: "mask-origin",
540
572
  // Interactivity
541
573
  cursor: "cursor",
542
574
  caret: "caret",
@@ -605,7 +637,7 @@ const PROPERTY_MAP = {
605
637
  };
606
638
  const CSS_VAR_TYPE_HINTS = {
607
639
  fontFamily: "family-name",
608
- fontWeight: "weight",
640
+ weight: "weight",
609
641
  text: "length"
610
642
  };
611
643
  const SUGGESTION_MAP = {
@@ -654,10 +686,10 @@ const SUGGESTION_MAP = {
654
686
  objectPosition: "objectPos",
655
687
  zIndex: "z",
656
688
  // Typography
657
- font: "fontWeight (for weight) or fontFamily (for family)",
658
- fontStyle: "italic/notItalic (boolean)",
659
- weight: "fontWeight",
660
- textDecoration: "decoration or underline/lineThrough/noUnderline (boolean)",
689
+ font: "weight (for font-weight) or fontFamily (for family)",
690
+ fontWeight: "weight",
691
+ fontSize: "text",
692
+ textDecoration: "decoration",
661
693
  textDecorationColor: "decorationColor",
662
694
  textDecorationStyle: "decorationStyle",
663
695
  textDecorationThickness: "decorationThickness",
@@ -668,7 +700,6 @@ const SUGGESTION_MAP = {
668
700
  verticalAlign: "align",
669
701
  wordBreak: "break",
670
702
  overflowWrap: "wrap",
671
- textWrap: "textWrap",
672
703
  listStyleType: "list",
673
704
  listStylePosition: "listPos",
674
705
  listStyleImage: "listImg",
@@ -924,45 +955,8 @@ const ARIA_STATES = /* @__PURE__ */ new Set([
924
955
  "modal"
925
956
  ]);
926
957
  const BOOLEAN_SHORTHANDS = /* @__PURE__ */ new Set([
927
- // Display
928
- "block",
929
- "inline",
930
- "inlineBlock",
931
- "flex",
932
- "inlineFlex",
933
- "grid",
934
- "inlineGrid",
935
- "hidden",
936
- "contents",
937
- "table",
938
- "tableRow",
939
- "tableCell",
940
- "flowRoot",
941
- "listItem",
942
- // Position
943
- "static",
944
- "fixed",
945
- "absolute",
946
- "relative",
947
- "sticky",
948
- // Visibility
949
- "visible",
950
- "invisible",
951
- "collapse",
952
- // Typography
958
+ // Typography (composite — no single-property canonical form)
953
959
  "truncate",
954
- "uppercase",
955
- "lowercase",
956
- "capitalize",
957
- "normalCase",
958
- "underline",
959
- "overline",
960
- "lineThrough",
961
- "noUnderline",
962
- "italic",
963
- "notItalic",
964
- "antialiased",
965
- "subpixelAntialiased",
966
960
  // Flexbox (grow/shrink only — flexWrap uses string values)
967
961
  "grow",
968
962
  "shrink",
@@ -981,10 +975,9 @@ const BOOLEAN_SHORTHANDS = /* @__PURE__ */ new Set([
981
975
  "proseInvert",
982
976
  "srOnly",
983
977
  "notSrOnly",
984
- "isolate",
985
978
  "ordinal",
986
979
  "slashedZero",
987
- // Font variant numeric
980
+ // Font variant numeric (additive — these combine, so they stay boolean flags)
988
981
  "liningNums",
989
982
  "oldstyleNums",
990
983
  "proportionalNums",
@@ -1001,19 +994,52 @@ const BOOLEAN_SHORTHANDS = /* @__PURE__ */ new Set([
1001
994
  // Outline
1002
995
  "outline"
1003
996
  ]);
997
+ const REMOVED_BOOLEAN_SUGAR = {
998
+ // display
999
+ block: { key: "display", value: "block" },
1000
+ inline: { key: "display", value: "inline" },
1001
+ inlineBlock: { key: "display", value: "inline-block" },
1002
+ flex: { key: "display", value: "flex" },
1003
+ inlineFlex: { key: "display", value: "inline-flex" },
1004
+ grid: { key: "display", value: "grid" },
1005
+ inlineGrid: { key: "display", value: "inline-grid" },
1006
+ hidden: { key: "display", value: "none" },
1007
+ contents: { key: "display", value: "contents" },
1008
+ table: { key: "display", value: "table" },
1009
+ tableRow: { key: "display", value: "table-row" },
1010
+ tableCell: { key: "display", value: "table-cell" },
1011
+ flowRoot: { key: "display", value: "flow-root" },
1012
+ listItem: { key: "display", value: "list-item" },
1013
+ // position
1014
+ static: { key: "position", value: "static" },
1015
+ fixed: { key: "position", value: "fixed" },
1016
+ absolute: { key: "position", value: "absolute" },
1017
+ relative: { key: "position", value: "relative" },
1018
+ sticky: { key: "position", value: "sticky" },
1019
+ // visibility
1020
+ visible: { key: "visibility", value: "visible" },
1021
+ invisible: { key: "visibility", value: "hidden" },
1022
+ collapse: { key: "visibility", value: "collapse" },
1023
+ // isolation
1024
+ isolate: { key: "isolation", value: "isolate" },
1025
+ // text-transform
1026
+ uppercase: { key: "textTransform", value: "uppercase" },
1027
+ lowercase: { key: "textTransform", value: "lowercase" },
1028
+ capitalize: { key: "textTransform", value: "capitalize" },
1029
+ normalCase: { key: "textTransform", value: "none" },
1030
+ // font-style
1031
+ italic: { key: "fontStyle", value: "italic" },
1032
+ notItalic: { key: "fontStyle", value: "normal" },
1033
+ // text-decoration-line
1034
+ underline: { key: "decoration", value: "underline" },
1035
+ overline: { key: "decoration", value: "overline" },
1036
+ lineThrough: { key: "decoration", value: "line-through" },
1037
+ noUnderline: { key: "decoration", value: "none" },
1038
+ // font-smoothing
1039
+ antialiased: { key: "fontSmoothing", value: "grayscale" },
1040
+ subpixelAntialiased: { key: "fontSmoothing", value: "subpixel" }
1041
+ };
1004
1042
  const BOOLEAN_TO_CLASS = {
1005
- inlineBlock: "inline-block",
1006
- inlineFlex: "inline-flex",
1007
- inlineGrid: "inline-grid",
1008
- tableRow: "table-row",
1009
- tableCell: "table-cell",
1010
- flowRoot: "flow-root",
1011
- listItem: "list-item",
1012
- normalCase: "normal-case",
1013
- lineThrough: "line-through",
1014
- noUnderline: "no-underline",
1015
- notItalic: "not-italic",
1016
- subpixelAntialiased: "subpixel-antialiased",
1017
1043
  backdropBlur: "backdrop-blur",
1018
1044
  backdropGrayscale: "backdrop-grayscale",
1019
1045
  backdropInvert: "backdrop-invert",
@@ -1433,23 +1459,38 @@ function handleSupports(supportsObj, prefix) {
1433
1459
  }
1434
1460
  return classes;
1435
1461
  }
1462
+ let szTransformDepth = 0;
1436
1463
  function transform(szProp, prefix = "", mangleMap) {
1437
1464
  if (!szProp || typeof szProp !== "object") {
1438
1465
  return { className: "", attributes: {} };
1439
1466
  }
1467
+ if (szTransformDepth >= MAX_SZ_DEPTH) {
1468
+ throw new SzDepthError();
1469
+ }
1470
+ szTransformDepth++;
1471
+ try {
1472
+ return transformImpl(szProp, prefix, mangleMap);
1473
+ } finally {
1474
+ szTransformDepth--;
1475
+ }
1476
+ }
1477
+ function transformImpl(szProp, prefix, mangleMap) {
1440
1478
  const classes = [];
1441
1479
  const attributes = {};
1442
1480
  for (const [rawKey, value] of Object.entries(szProp)) {
1443
- if (value === false) {
1444
- if (rawKey === "italic") {
1445
- classes.push(`${prefix}not-italic`);
1446
- } else if (rawKey === "antialiased") {
1447
- classes.push(`${prefix}subpixel-antialiased`);
1448
- }
1481
+ if (value === false || value === null || value === void 0) {
1449
1482
  continue;
1450
1483
  }
1451
- if (value === null || value === void 0) {
1452
- continue;
1484
+ if (value === true) {
1485
+ const removed = REMOVED_BOOLEAN_SUGAR[rawKey];
1486
+ if (removed) {
1487
+ if (process.env.NODE_ENV !== "production" && typeof window === "undefined") {
1488
+ console.warn(
1489
+ `[csszyx] "${rawKey}" boolean sugar was removed. Use { ${removed.key}: '${removed.value}' } instead, or run \`csszyx migrate\`.`
1490
+ );
1491
+ }
1492
+ continue;
1493
+ }
1453
1494
  }
1454
1495
  if (rawKey === "css") {
1455
1496
  if (value && typeof value === "object" && !Array.isArray(value)) {
@@ -1792,11 +1833,52 @@ function transform(szProp, prefix = "", mangleMap) {
1792
1833
  }
1793
1834
  }
1794
1835
  if (rawKey === "textTransform") {
1795
- if (["uppercase", "lowercase", "capitalize", "normal-case"].includes(value)) {
1836
+ if (["uppercase", "lowercase", "capitalize"].includes(value)) {
1796
1837
  className += value;
1797
1838
  classes.push(className);
1798
1839
  continue;
1799
1840
  }
1841
+ if (value === "normal-case" || value === "none") {
1842
+ className += "normal-case";
1843
+ classes.push(className);
1844
+ continue;
1845
+ }
1846
+ }
1847
+ if (rawKey === "fontStyle") {
1848
+ if (value === "italic") {
1849
+ className += "italic";
1850
+ classes.push(className);
1851
+ continue;
1852
+ }
1853
+ if (value === "normal") {
1854
+ className += "not-italic";
1855
+ classes.push(className);
1856
+ continue;
1857
+ }
1858
+ if (process.env.NODE_ENV !== "production" && typeof window === "undefined") {
1859
+ console.warn(
1860
+ `[csszyx] fontStyle: '${value}' is not supported \u2014 Tailwind only models 'italic' and 'normal'. For oblique, use css: { fontStyle: '${value}' }.`
1861
+ );
1862
+ }
1863
+ continue;
1864
+ }
1865
+ if (rawKey === "fontSmoothing") {
1866
+ if (value === "grayscale") {
1867
+ className += "antialiased";
1868
+ classes.push(className);
1869
+ continue;
1870
+ }
1871
+ if (value === "subpixel") {
1872
+ className += "subpixel-antialiased";
1873
+ classes.push(className);
1874
+ continue;
1875
+ }
1876
+ if (process.env.NODE_ENV !== "production" && typeof window === "undefined") {
1877
+ console.warn(
1878
+ `[csszyx] fontSmoothing: '${value}' is not supported \u2014 use 'grayscale' or 'subpixel'.`
1879
+ );
1880
+ }
1881
+ continue;
1800
1882
  }
1801
1883
  if (rawKey === "fontVariant") {
1802
1884
  const FONT_VARIANT_CLASSES = /* @__PURE__ */ new Set([
@@ -1857,7 +1939,9 @@ function transform(szProp, prefix = "", mangleMap) {
1857
1939
  }
1858
1940
  if (rawKey === "lineClamp") {
1859
1941
  const sValue = String(value);
1860
- if (sValue.startsWith("--")) {
1942
+ if (sValue === "none") {
1943
+ className += "line-clamp-none";
1944
+ } else if (sValue.startsWith("--")) {
1861
1945
  className += `line-clamp-(${sValue})`;
1862
1946
  } else {
1863
1947
  const numVal = Number(sValue);
@@ -2203,7 +2287,7 @@ function transform(szProp, prefix = "", mangleMap) {
2203
2287
  if (STANDARD_ORIGINS.has(value)) {
2204
2288
  className += `perspective-origin-${value}`;
2205
2289
  } else {
2206
- className += `perspective-origin-[${value}]`;
2290
+ className += `perspective-origin-[${normalizeArbitraryValue(value)}]`;
2207
2291
  }
2208
2292
  classes.push(className);
2209
2293
  continue;
@@ -2345,4 +2429,4 @@ function normalizeClassName(className) {
2345
2429
  return className.split(/\s+/).filter(Boolean).join(" ");
2346
2430
  }
2347
2431
 
2348
- export { BOOLEAN_SHORTHANDS as B, COLOR_PROPERTIES as C, KNOWN_VARIANTS as K, PROPERTY_MAP as P, SPECIAL_VARIANTS as S, VARIANT_MAP as V, PropertyCategory as a, getVariantPrefix as b, getPropertyCategory as c, PROPERTY_CATEGORY_MAP as d, SUGGESTION_MAP as e, normalizeArbitraryValue as f, getCSSVariableName as g, normalizeArbitraryVariant as h, isValidSzProp as i, normalizeClassName as n, stripInvalidColorStrings as s, transform as t };
2432
+ export { BOOLEAN_SHORTHANDS as B, COLOR_PROPERTIES as C, KNOWN_VARIANTS as K, MAX_SZ_DEPTH as M, PROPERTY_MAP as P, REMOVED_BOOLEAN_SUGAR as R, SPECIAL_VARIANTS as S, VARIANT_MAP as V, PropertyCategory as a, getVariantPrefix as b, getPropertyCategory as c, PROPERTY_CATEGORY_MAP as d, SUGGESTION_MAP as e, SzDepthError as f, getCSSVariableName as g, isForbiddenSzKey as h, isValidSzProp as i, normalizeArbitraryValue as j, normalizeArbitraryVariant as k, normalizeClassName as n, stripInvalidColorStrings as s, transform as t };