@homebound/truss 2.10.0 → 2.11.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.
@@ -2443,7 +2443,12 @@ function rewriteExpressionSites(options) {
2443
2443
  const cssAttrPath = getCssAttributePath(site.path);
2444
2444
  const line = site.path.node.loc?.start.line ?? null;
2445
2445
  if (cssAttrPath) {
2446
- cssAttrPath.replaceWith(t3.jsxSpreadAttribute(buildCssSpreadExpression(cssAttrPath, styleHash, line, options)));
2446
+ if (!options.debug && isFullyStaticStyleHash(styleHash) && !hasExistingAttribute(cssAttrPath, "className") && !hasExistingAttribute(cssAttrPath, "style")) {
2447
+ const classNames = extractStaticClassNames(styleHash);
2448
+ cssAttrPath.replaceWith(t3.jsxAttribute(t3.jsxIdentifier("className"), t3.stringLiteral(classNames)));
2449
+ } else {
2450
+ cssAttrPath.replaceWith(t3.jsxSpreadAttribute(buildCssSpreadExpression(cssAttrPath, styleHash, line, options)));
2451
+ }
2447
2452
  } else {
2448
2453
  if (options.debug && line !== null) {
2449
2454
  injectDebugInfo(styleHash, line, options);
@@ -2815,6 +2820,29 @@ function extractSiblingClassName(callPath) {
2815
2820
  function isMatchingPropertyName(key, name) {
2816
2821
  return t3.isIdentifier(key) && key.name === name || t3.isStringLiteral(key) && key.value === name;
2817
2822
  }
2823
+ function isFullyStaticStyleHash(hash) {
2824
+ for (const prop of hash.properties) {
2825
+ if (!t3.isObjectProperty(prop)) return false;
2826
+ if (!t3.isStringLiteral(prop.value)) return false;
2827
+ }
2828
+ return true;
2829
+ }
2830
+ function extractStaticClassNames(hash) {
2831
+ const classNames = [];
2832
+ for (const prop of hash.properties) {
2833
+ if (t3.isObjectProperty(prop) && t3.isStringLiteral(prop.value)) {
2834
+ classNames.push(prop.value.value);
2835
+ }
2836
+ }
2837
+ return classNames.join(" ");
2838
+ }
2839
+ function hasExistingAttribute(path, attrName) {
2840
+ const openingElement = path.parentPath;
2841
+ if (!openingElement || !openingElement.isJSXOpeningElement()) return false;
2842
+ return openingElement.node.attributes.some((attr) => {
2843
+ return t3.isJSXAttribute(attr) && t3.isJSXIdentifier(attr.name, { name: attrName });
2844
+ });
2845
+ }
2818
2846
 
2819
2847
  // src/plugin/transform.ts
2820
2848
  var traverse2 = _traverse2.default ?? _traverse2;
@@ -2833,6 +2861,7 @@ function transformTruss(code, filename, mapping, options = {}) {
2833
2861
  const sites = [];
2834
2862
  const errorMessages = [];
2835
2863
  let hasCssPropsCall = false;
2864
+ let hasJsxCssAttribute = false;
2836
2865
  traverse2(ast, {
2837
2866
  // -- Css.*.$ chain collection --
2838
2867
  MemberExpression(path) {
@@ -2858,9 +2887,16 @@ function transformTruss(code, filename, mapping, options = {}) {
2858
2887
  if (t4.isMemberExpression(callee) && !callee.computed && t4.isIdentifier(callee.object, { name: cssBindingName }) && t4.isIdentifier(callee.property, { name: "props" })) {
2859
2888
  hasCssPropsCall = true;
2860
2889
  }
2890
+ },
2891
+ // -- JSX css={...} attribute detection (so we don't bail when there are only css props) --
2892
+ JSXAttribute(path) {
2893
+ if (hasJsxCssAttribute) return;
2894
+ if (t4.isJSXIdentifier(path.node.name, { name: "css" })) {
2895
+ hasJsxCssAttribute = true;
2896
+ }
2861
2897
  }
2862
2898
  });
2863
- if (sites.length === 0 && !hasCssPropsCall) return null;
2899
+ if (sites.length === 0 && !hasCssPropsCall && !hasJsxCssAttribute) return null;
2864
2900
  const chains = sites.map((s) => s.resolvedChain);
2865
2901
  const { rules, needsMaybeInc } = collectAtomicRules(chains, mapping);
2866
2902
  const cssText = generateCssText(rules);