@homebound/truss 2.8.4 → 2.9.1

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.
@@ -724,7 +724,7 @@ function collectAtomicRules(chains, mapping) {
724
724
  const rules = /* @__PURE__ */ new Map();
725
725
  let needsMaybeInc = false;
726
726
  function collectSegment(seg) {
727
- if (seg.error || seg.styleArrayArg) return;
727
+ if (seg.error || seg.styleArrayArg || seg.classNameArg) return;
728
728
  if (seg.typographyLookup) {
729
729
  for (const segments of Object.values(seg.typographyLookup.segmentsByName)) {
730
730
  for (const nestedSeg of segments) {
@@ -942,7 +942,7 @@ function buildStyleHashProperties(segments, mapping, maybeIncHelperName) {
942
942
  entries.push(entry);
943
943
  }
944
944
  for (const seg of segments) {
945
- if (seg.error || seg.styleArrayArg || seg.typographyLookup) continue;
945
+ if (seg.error || seg.styleArrayArg || seg.typographyLookup || seg.classNameArg) continue;
946
946
  const { prefix } = segmentContext(seg, mapping);
947
947
  const isConditional = prefix !== "";
948
948
  if (seg.variableProps) {
@@ -1252,6 +1252,17 @@ function resolveChain(chain, mapping) {
1252
1252
  segments.push(seg);
1253
1253
  continue;
1254
1254
  }
1255
+ if (abbr === "className") {
1256
+ const seg = resolveClassNameCall(
1257
+ node,
1258
+ currentMediaQuery,
1259
+ currentPseudoClass,
1260
+ currentPseudoElement,
1261
+ currentWhenPseudo
1262
+ );
1263
+ segments.push(seg);
1264
+ continue;
1265
+ }
1255
1266
  if (abbr === "typography") {
1256
1267
  const resolved = resolveTypographyCall(
1257
1268
  node,
@@ -1499,6 +1510,26 @@ function buildParameterizedSegment(params) {
1499
1510
  }
1500
1511
  return base;
1501
1512
  }
1513
+ function resolveClassNameCall(node, mediaQuery, pseudoClass, pseudoElement, whenPseudo) {
1514
+ if (node.args.length !== 1) {
1515
+ throw new UnsupportedPatternError(`className() expects exactly 1 argument, got ${node.args.length}`);
1516
+ }
1517
+ const arg = node.args[0];
1518
+ if (arg.type === "SpreadElement") {
1519
+ throw new UnsupportedPatternError(`className() does not support spread arguments`);
1520
+ }
1521
+ if (mediaQuery || pseudoClass || pseudoElement || whenPseudo) {
1522
+ throw new UnsupportedPatternError(
1523
+ `className() cannot be used inside media query, pseudo-class, pseudo-element, or when() contexts`
1524
+ );
1525
+ }
1526
+ return {
1527
+ // I.e. this is metadata for the rewriter/runtime, not an atomic CSS rule.
1528
+ abbr: "className",
1529
+ defs: {},
1530
+ classNameArg: arg
1531
+ };
1532
+ }
1502
1533
  function resolveAddCall(node, mapping, mediaQuery, pseudoClass, pseudoElement, whenPseudo) {
1503
1534
  const isAddCss = node.name === "addCss";
1504
1535
  if (isAddCss) {
@@ -2072,6 +2103,7 @@ function buildStyleHashFromChain(chain, options) {
2072
2103
  function buildStyleHashMembers(segments, options) {
2073
2104
  const members = [];
2074
2105
  const normalSegs = [];
2106
+ const classNameArgs = [];
2075
2107
  function flushNormal() {
2076
2108
  if (normalSegs.length > 0) {
2077
2109
  members.push(...buildStyleHashProperties(normalSegs, options.mapping, options.maybeIncHelperName));
@@ -2080,6 +2112,10 @@ function buildStyleHashMembers(segments, options) {
2080
2112
  }
2081
2113
  for (const seg of segments) {
2082
2114
  if (seg.error) continue;
2115
+ if (seg.classNameArg) {
2116
+ classNameArgs.push(t3.cloneNode(seg.classNameArg, true));
2117
+ continue;
2118
+ }
2083
2119
  if (seg.styleArrayArg) {
2084
2120
  flushNormal();
2085
2121
  if (seg.isAddCss && t3.isObjectExpression(seg.styleArrayArg)) {
@@ -2105,8 +2141,26 @@ function buildStyleHashMembers(segments, options) {
2105
2141
  normalSegs.push(seg);
2106
2142
  }
2107
2143
  flushNormal();
2144
+ if (classNameArgs.length > 0) {
2145
+ members.push(...buildCustomClassNameMembers(classNameArgs));
2146
+ }
2108
2147
  return members;
2109
2148
  }
2149
+ function buildCustomClassNameMembers(classNameArgs) {
2150
+ const counts = /* @__PURE__ */ new Map();
2151
+ return classNameArgs.map((arg) => {
2152
+ const baseKey = `className_${sanitizeClassNameKey(arg)}`;
2153
+ const count = (counts.get(baseKey) ?? 0) + 1;
2154
+ counts.set(baseKey, count);
2155
+ const key = count === 1 ? baseKey : `${baseKey}_${count}`;
2156
+ return t3.objectProperty(t3.identifier(key), t3.cloneNode(arg, true));
2157
+ });
2158
+ }
2159
+ function sanitizeClassNameKey(arg) {
2160
+ const raw = t3.isStringLiteral(arg) ? arg.value : t3.isTemplateLiteral(arg) && arg.expressions.length === 0 && arg.quasis.length === 1 ? arg.quasis[0].value.cooked ?? "" : generate(arg).code;
2161
+ const sanitized = raw.replace(/[^a-zA-Z0-9_$]/g, "_").replace(/_+/g, "_").replace(/^_+|_+$/g, "");
2162
+ return sanitized || "value";
2163
+ }
2110
2164
  function buildAddCssObjectMembers(styleObject) {
2111
2165
  const members = [];
2112
2166
  for (const property of styleObject.properties) {
@@ -2138,7 +2192,7 @@ function buildAddCssObjectMembers(styleObject) {
2138
2192
  function collectConditionalOnlyProps(segments) {
2139
2193
  const allProps = /* @__PURE__ */ new Map();
2140
2194
  for (const seg of segments) {
2141
- if (seg.error || seg.styleArrayArg || seg.typographyLookup) continue;
2195
+ if (seg.error || seg.styleArrayArg || seg.typographyLookup || seg.classNameArg) continue;
2142
2196
  const hasCondition = !!(seg.pseudoClass || seg.mediaQuery || seg.pseudoElement || seg.whenPseudo);
2143
2197
  const props = seg.variableProps ?? Object.keys(seg.defs);
2144
2198
  for (const prop of props) {
@@ -2232,7 +2286,7 @@ function clonePropertyKey(key) {
2232
2286
  function injectDebugInfo(expr, line, options) {
2233
2287
  if (!options.debug) return;
2234
2288
  const firstProp = expr.properties.find((p) => {
2235
- return t3.isObjectProperty(p) && !(t3.isIdentifier(p.key) && p.key.name === "__marker" || t3.isStringLiteral(p.key) && p.key.value === "__marker");
2289
+ return t3.isObjectProperty(p) && !(t3.isIdentifier(p.key) && p.key.name.startsWith("className_") || t3.isStringLiteral(p.key) && p.key.value.startsWith("className_") || t3.isIdentifier(p.key) && p.key.name === "__marker" || t3.isStringLiteral(p.key) && p.key.value === "__marker");
2236
2290
  });
2237
2291
  if (!firstProp) return;
2238
2292
  options.needsTrussDebugInfo.current = true;