styled-components-to-stylex-codemod 0.0.26 → 0.0.27
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/transform.mjs +594 -243
- package/package.json +1 -1
package/dist/transform.mjs
CHANGED
|
@@ -591,6 +591,51 @@ function literalToString(node) {
|
|
|
591
591
|
return typeof v === "string" ? v : null;
|
|
592
592
|
}
|
|
593
593
|
/**
|
|
594
|
+
* Scans the file AST for TypeScript string/numeric enum declarations and
|
|
595
|
+
* returns a two-level map: enumName -> memberName -> static value.
|
|
596
|
+
* Only handles members with literal initializers.
|
|
597
|
+
*/
|
|
598
|
+
function buildEnumValueMap(root, j) {
|
|
599
|
+
const map = /* @__PURE__ */ new Map();
|
|
600
|
+
root.find(j.TSEnumDeclaration).forEach((path) => {
|
|
601
|
+
const enumNode = path.value;
|
|
602
|
+
const enumName = enumNode.id.name;
|
|
603
|
+
const members = /* @__PURE__ */ new Map();
|
|
604
|
+
let nextNumericValue = 0;
|
|
605
|
+
for (const member of enumNode.members) {
|
|
606
|
+
const memberName = member.id.type === "Identifier" ? member.id.name : member.id.value;
|
|
607
|
+
if (member.initializer) {
|
|
608
|
+
const val = literalToStaticValue(member.initializer);
|
|
609
|
+
if (val !== null) {
|
|
610
|
+
members.set(memberName, val);
|
|
611
|
+
nextNumericValue = typeof val === "number" ? val + 1 : 0;
|
|
612
|
+
}
|
|
613
|
+
} else {
|
|
614
|
+
members.set(memberName, nextNumericValue);
|
|
615
|
+
nextNumericValue++;
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
if (members.size > 0) map.set(enumName, members);
|
|
619
|
+
});
|
|
620
|
+
return map;
|
|
621
|
+
}
|
|
622
|
+
/**
|
|
623
|
+
* Resolves a MemberExpression node (e.g., `ProgressType.success`) to its
|
|
624
|
+
* static enum value using a pre-built enum map. Returns null if the node
|
|
625
|
+
* is not a MemberExpression or doesn't reference a known enum member.
|
|
626
|
+
*/
|
|
627
|
+
function resolveStaticExpressionValue(node, enumValueMap) {
|
|
628
|
+
const v = literalToStaticValue(node);
|
|
629
|
+
if (v !== null) return v;
|
|
630
|
+
if (!enumValueMap || !node || typeof node !== "object") return null;
|
|
631
|
+
const n = node;
|
|
632
|
+
if (n.type !== "MemberExpression" || n.computed) return null;
|
|
633
|
+
const obj = n.object;
|
|
634
|
+
const prop = n.property;
|
|
635
|
+
if (obj?.type !== "Identifier" || !obj.name || prop?.type !== "Identifier" || !prop.name) return null;
|
|
636
|
+
return enumValueMap.get(obj.name)?.get(prop.name) ?? null;
|
|
637
|
+
}
|
|
638
|
+
/**
|
|
594
639
|
* Returns true if an AST node represents an "empty" CSS branch value.
|
|
595
640
|
* Styled-components treats falsy interpolations as "omit this declaration".
|
|
596
641
|
*
|
|
@@ -1360,7 +1405,7 @@ const isValidIdentifier = (name) => /^[$A-Z_][0-9A-Z_$]*$/i.test(name);
|
|
|
1360
1405
|
* - Disjunction: `"a || b"` → `a || b`
|
|
1361
1406
|
* - Grouped negation: `"!(a || b)"` → `!(a || b)`
|
|
1362
1407
|
*/
|
|
1363
|
-
function parseVariantWhenToAst(j, when) {
|
|
1408
|
+
function parseVariantWhenToAst(j, when, booleanProps) {
|
|
1364
1409
|
const buildMemberExpr = (raw) => {
|
|
1365
1410
|
if (!raw.includes(".")) return null;
|
|
1366
1411
|
const parts = raw.split(".").map((part) => part.trim()).filter(Boolean);
|
|
@@ -1414,7 +1459,7 @@ function parseVariantWhenToAst(j, when) {
|
|
|
1414
1459
|
isBoolean: true
|
|
1415
1460
|
};
|
|
1416
1461
|
if (trimmed.startsWith("!(") && trimmed.endsWith(")")) {
|
|
1417
|
-
const innerParsed = parseVariantWhenToAst(j, trimmed.slice(2, -1).trim());
|
|
1462
|
+
const innerParsed = parseVariantWhenToAst(j, trimmed.slice(2, -1).trim(), booleanProps);
|
|
1418
1463
|
return {
|
|
1419
1464
|
cond: j.unaryExpression("!", innerParsed.cond),
|
|
1420
1465
|
props: innerParsed.props,
|
|
@@ -1422,7 +1467,7 @@ function parseVariantWhenToAst(j, when) {
|
|
|
1422
1467
|
};
|
|
1423
1468
|
}
|
|
1424
1469
|
if (trimmed.includes("&&")) {
|
|
1425
|
-
const parsed = trimmed.split("&&").map((s) => s.trim()).filter(Boolean).map((p) => parseVariantWhenToAst(j, p));
|
|
1470
|
+
const parsed = trimmed.split("&&").map((s) => s.trim()).filter(Boolean).map((p) => parseVariantWhenToAst(j, p, booleanProps));
|
|
1426
1471
|
const firstParsed = parsed[0];
|
|
1427
1472
|
if (!firstParsed) return {
|
|
1428
1473
|
cond: j.identifier("true"),
|
|
@@ -1436,7 +1481,7 @@ function parseVariantWhenToAst(j, when) {
|
|
|
1436
1481
|
};
|
|
1437
1482
|
}
|
|
1438
1483
|
if (trimmed.includes(" || ")) {
|
|
1439
|
-
const parsed = trimmed.split(" || ").map((s) => s.trim()).filter(Boolean).map((p) => parseVariantWhenToAst(j, p));
|
|
1484
|
+
const parsed = trimmed.split(" || ").map((s) => s.trim()).filter(Boolean).map((p) => parseVariantWhenToAst(j, p, booleanProps));
|
|
1440
1485
|
const firstParsedOr = parsed[0];
|
|
1441
1486
|
if (!firstParsedOr) return {
|
|
1442
1487
|
cond: j.identifier("true"),
|
|
@@ -1450,7 +1495,7 @@ function parseVariantWhenToAst(j, when) {
|
|
|
1450
1495
|
};
|
|
1451
1496
|
}
|
|
1452
1497
|
if (trimmed.startsWith("!")) {
|
|
1453
|
-
const innerParsed = parseVariantWhenToAst(j, trimmed.slice(1).trim());
|
|
1498
|
+
const innerParsed = parseVariantWhenToAst(j, trimmed.slice(1).trim(), booleanProps);
|
|
1454
1499
|
return {
|
|
1455
1500
|
cond: j.unaryExpression("!", innerParsed.cond),
|
|
1456
1501
|
props: innerParsed.props,
|
|
@@ -1471,10 +1516,11 @@ function parseVariantWhenToAst(j, when) {
|
|
|
1471
1516
|
};
|
|
1472
1517
|
}
|
|
1473
1518
|
const simple = parsePropRef(trimmed);
|
|
1519
|
+
const propIsBoolean = !!(simple.propName && booleanProps?.has(simple.propName));
|
|
1474
1520
|
return {
|
|
1475
1521
|
cond: simple.expr,
|
|
1476
1522
|
props: simple.propName ? [simple.propName] : [],
|
|
1477
|
-
isBoolean:
|
|
1523
|
+
isBoolean: propIsBoolean
|
|
1478
1524
|
};
|
|
1479
1525
|
}
|
|
1480
1526
|
/**
|
|
@@ -1483,8 +1529,8 @@ function parseVariantWhenToAst(j, when) {
|
|
|
1483
1529
|
* function's parameter destructuring.
|
|
1484
1530
|
*/
|
|
1485
1531
|
function collectConditionProps(j, args) {
|
|
1486
|
-
const { when, destructureProps } = args;
|
|
1487
|
-
const parsed = parseVariantWhenToAst(j, when);
|
|
1532
|
+
const { when, destructureProps, booleanProps } = args;
|
|
1533
|
+
const parsed = parseVariantWhenToAst(j, when, booleanProps);
|
|
1488
1534
|
if (destructureProps) {
|
|
1489
1535
|
for (const p of parsed.props) if (p && !destructureProps.includes(p)) destructureProps.push(p);
|
|
1490
1536
|
}
|
|
@@ -1492,8 +1538,9 @@ function collectConditionProps(j, args) {
|
|
|
1492
1538
|
}
|
|
1493
1539
|
/**
|
|
1494
1540
|
* Creates a conditional style expression that's safe for stylex.props().
|
|
1495
|
-
* For boolean conditions, uses && (since false is valid
|
|
1496
|
-
* For non-boolean conditions
|
|
1541
|
+
* For boolean conditions, uses `cond && expr` (since `false` is a valid StyleXArray element).
|
|
1542
|
+
* For non-boolean conditions, uses `cond ? expr : undefined` to avoid producing
|
|
1543
|
+
* values like `""` or `0` which are not valid StyleXArray elements.
|
|
1497
1544
|
*/
|
|
1498
1545
|
function makeConditionalStyleExpr(j, args) {
|
|
1499
1546
|
const { cond, expr, isBoolean } = args;
|
|
@@ -1525,7 +1572,7 @@ function areEquivalentWhen(left, right) {
|
|
|
1525
1572
|
* `prop ? trueExpr : falseExpr` instead of emitting separate conditionals.
|
|
1526
1573
|
*/
|
|
1527
1574
|
function buildExtraStylexPropsExprs(j, args) {
|
|
1528
|
-
const { entries, destructureProps } = args;
|
|
1575
|
+
const { entries, destructureProps, booleanProps } = args;
|
|
1529
1576
|
const result = [];
|
|
1530
1577
|
const consumed = /* @__PURE__ */ new Set();
|
|
1531
1578
|
for (let i = 0; i < entries.length; i++) {
|
|
@@ -1552,7 +1599,8 @@ function buildExtraStylexPropsExprs(j, args) {
|
|
|
1552
1599
|
}
|
|
1553
1600
|
const { cond, isBoolean } = collectConditionProps(j, {
|
|
1554
1601
|
when: entry.when,
|
|
1555
|
-
destructureProps
|
|
1602
|
+
destructureProps,
|
|
1603
|
+
booleanProps
|
|
1556
1604
|
});
|
|
1557
1605
|
result.push(makeConditionalStyleExpr(j, {
|
|
1558
1606
|
cond,
|
|
@@ -1880,10 +1928,11 @@ function analyzeBeforeEmitStep(ctx) {
|
|
|
1880
1928
|
if (decl.isDirectJsxResolution) continue;
|
|
1881
1929
|
if (decl.base.kind !== "intrinsic") continue;
|
|
1882
1930
|
if (relationChildStyleKeys.has(decl.styleKey)) continue;
|
|
1883
|
-
|
|
1931
|
+
const usageCount = getJsxUsageCount(decl.localName);
|
|
1932
|
+
if (decl.promotedStyleProps?.length && decl.promotedStyleProps.length >= usageCount) continue;
|
|
1884
1933
|
const { ref } = getJsxAttributeUsage(decl.localName);
|
|
1885
1934
|
if (ref) continue;
|
|
1886
|
-
if (
|
|
1935
|
+
if (usageCount > INLINE_USAGE_THRESHOLD) decl.needsWrapperComponent = true;
|
|
1887
1936
|
}
|
|
1888
1937
|
const hasSpreadInJsx = (name) => {
|
|
1889
1938
|
let found = false;
|
|
@@ -1970,11 +2019,13 @@ function analyzeBeforeEmitStep(ctx) {
|
|
|
1970
2019
|
existingPropNames.add("className").add("style").add("children").add("ref").add("key").add("as");
|
|
1971
2020
|
if (decl.base.kind === "component") collectBaseComponentPropNames(root, j, decl.base.ident, existingPropNames);
|
|
1972
2021
|
if (decl.base.kind === "intrinsic") for (const attr of BLOCKED_INTRINSIC_ATTR_RENAMES[decl.base.tagName] ?? []) existingPropNames.add(attr);
|
|
1973
|
-
|
|
2022
|
+
const { hasSpread, explicitTransientAtSpreadSites } = collectCallSiteAttrNames(root, j, decl.localName, existingPropNames);
|
|
1974
2023
|
const renames = /* @__PURE__ */ new Map();
|
|
1975
2024
|
for (const prop of transientProps) {
|
|
1976
2025
|
const stripped = prop.slice(1);
|
|
1977
|
-
if (
|
|
2026
|
+
if (existingPropNames.has(stripped)) continue;
|
|
2027
|
+
if (hasSpread && !explicitTransientAtSpreadSites?.has(prop)) continue;
|
|
2028
|
+
renames.set(prop, stripped);
|
|
1978
2029
|
}
|
|
1979
2030
|
if (renames.size > 0) {
|
|
1980
2031
|
if (collectReferencedTypeNames(decl.propsType).some((name) => isTypeNameUsedElsewhere(root, j, name, decl.localName) || !isTypeLocallyDefined(root, j, name))) continue;
|
|
@@ -2148,10 +2199,12 @@ function analyzeBeforeEmitStep(ctx) {
|
|
|
2148
2199
|
decl.variantStyleKeys[whenKey] = styleKey;
|
|
2149
2200
|
}
|
|
2150
2201
|
if (decl.callSiteCombinedStyles?.length) for (const { styleKey, styles } of decl.callSiteCombinedStyles) ctx.resolvedStyleObjects.set(styleKey, styles);
|
|
2151
|
-
if (decl.promotedStyleProps?.length) for (const entry of decl.promotedStyleProps) if (entry.mergeIntoBase)
|
|
2202
|
+
if (decl.promotedStyleProps?.length) for (const entry of decl.promotedStyleProps) if (entry.mergeIntoBase) if (isAstNode(entry.styleValue)) ctx.resolvedStyleObjects.set(decl.styleKey, entry.styleValue);
|
|
2203
|
+
else {
|
|
2152
2204
|
const existing = ctx.resolvedStyleObjects.get(decl.styleKey);
|
|
2153
2205
|
if (existing && typeof existing === "object" && !isAstNode(existing)) Object.assign(existing, entry.styleValue);
|
|
2154
|
-
}
|
|
2206
|
+
}
|
|
2207
|
+
else ctx.resolvedStyleObjects.set(entry.styleKey, entry.styleValue);
|
|
2155
2208
|
}
|
|
2156
2209
|
return CONTINUE;
|
|
2157
2210
|
}
|
|
@@ -2245,19 +2298,26 @@ function collectResolverImportNames(ctx) {
|
|
|
2245
2298
|
}
|
|
2246
2299
|
return names;
|
|
2247
2300
|
}
|
|
2248
|
-
/**
|
|
2249
|
-
* Collects non-`$`-prefixed attribute names from JSX call sites of a component.
|
|
2250
|
-
* Returns true if any call site uses a JSX spread attribute (e.g., `{...props}`),
|
|
2251
|
-
* which means the spread may contain `$`-prefixed keys at runtime — all renames
|
|
2252
|
-
* must be blocked to prevent mismatches.
|
|
2253
|
-
*/
|
|
2254
2301
|
function collectCallSiteAttrNames(root, j, componentName, names) {
|
|
2255
2302
|
let hasSpread = false;
|
|
2303
|
+
const spreadSiteTransientProps = [];
|
|
2256
2304
|
const collectFromElement = (openingElement) => {
|
|
2257
|
-
|
|
2258
|
-
|
|
2305
|
+
let siteHasSpread = false;
|
|
2306
|
+
const siteTransientAfterSpread = /* @__PURE__ */ new Set();
|
|
2307
|
+
const siteTransientBeforeSpread = /* @__PURE__ */ new Set();
|
|
2308
|
+
for (const attr of openingElement.attributes ?? []) if (attr.type === "JSXSpreadAttribute") {
|
|
2309
|
+
hasSpread = true;
|
|
2310
|
+
siteHasSpread = true;
|
|
2311
|
+
for (const name of siteTransientAfterSpread) siteTransientBeforeSpread.add(name);
|
|
2312
|
+
siteTransientAfterSpread.clear();
|
|
2313
|
+
} else if (attr.type === "JSXAttribute" && attr.name?.type === "JSXIdentifier") {
|
|
2259
2314
|
const name = attr.name.name;
|
|
2260
|
-
if (
|
|
2315
|
+
if (name.startsWith("$")) siteTransientAfterSpread.add(name);
|
|
2316
|
+
else names.add(name);
|
|
2317
|
+
}
|
|
2318
|
+
if (siteHasSpread) {
|
|
2319
|
+
for (const name of siteTransientBeforeSpread) siteTransientAfterSpread.delete(name);
|
|
2320
|
+
spreadSiteTransientProps.push(siteTransientAfterSpread);
|
|
2261
2321
|
}
|
|
2262
2322
|
};
|
|
2263
2323
|
root.find(j.JSXElement, { openingElement: { name: {
|
|
@@ -2268,7 +2328,20 @@ function collectCallSiteAttrNames(root, j, componentName, names) {
|
|
|
2268
2328
|
type: "JSXIdentifier",
|
|
2269
2329
|
name: componentName
|
|
2270
2330
|
} }).forEach((p) => collectFromElement(p.node));
|
|
2271
|
-
return
|
|
2331
|
+
if (!hasSpread) return {
|
|
2332
|
+
hasSpread: false,
|
|
2333
|
+
explicitTransientAtSpreadSites: null
|
|
2334
|
+
};
|
|
2335
|
+
if (spreadSiteTransientProps.length === 0) return {
|
|
2336
|
+
hasSpread: true,
|
|
2337
|
+
explicitTransientAtSpreadSites: /* @__PURE__ */ new Set()
|
|
2338
|
+
};
|
|
2339
|
+
const intersection = new Set(spreadSiteTransientProps[0]);
|
|
2340
|
+
for (let i = 1; i < spreadSiteTransientProps.length; i++) for (const prop of intersection) if (!spreadSiteTransientProps[i].has(prop)) intersection.delete(prop);
|
|
2341
|
+
return {
|
|
2342
|
+
hasSpread: true,
|
|
2343
|
+
explicitTransientAtSpreadSites: intersection
|
|
2344
|
+
};
|
|
2272
2345
|
}
|
|
2273
2346
|
/**
|
|
2274
2347
|
* Collects prop names from a locally-defined base component's type that match
|
|
@@ -2382,6 +2455,7 @@ function applyTransientPropRenames(decl, renames) {
|
|
|
2382
2455
|
}
|
|
2383
2456
|
if (decl.styleFnFromProps) for (const sf of decl.styleFnFromProps) {
|
|
2384
2457
|
sf.jsxProp = renames.get(sf.jsxProp) ?? sf.jsxProp;
|
|
2458
|
+
if (sf.propsObjectKey) sf.propsObjectKey = renames.get(sf.propsObjectKey) ?? sf.propsObjectKey;
|
|
2385
2459
|
if (sf.conditionWhen) sf.conditionWhen = renamePropsInWhenString(sf.conditionWhen, renames);
|
|
2386
2460
|
if (sf.callArg) renameIdentifiersInAst(sf.callArg, renames);
|
|
2387
2461
|
}
|
|
@@ -2466,7 +2540,6 @@ function renameIdentifiersInAst(node, renames) {
|
|
|
2466
2540
|
if (n.type === "Identifier" && typeof n.name === "string") {
|
|
2467
2541
|
const renamed = renames.get(n.name);
|
|
2468
2542
|
if (renamed) n.name = renamed;
|
|
2469
|
-
return;
|
|
2470
2543
|
}
|
|
2471
2544
|
for (const [key, value] of Object.entries(n)) {
|
|
2472
2545
|
if (AST_METADATA_KEYS.has(key)) continue;
|
|
@@ -2621,8 +2694,11 @@ const NUMERIC_CSS_PROPS = new Set([
|
|
|
2621
2694
|
"widows",
|
|
2622
2695
|
"columnCount"
|
|
2623
2696
|
]);
|
|
2624
|
-
/**
|
|
2625
|
-
|
|
2697
|
+
/**
|
|
2698
|
+
* CSS properties that accept numeric values in standard CSS / React inline styles
|
|
2699
|
+
* but are typed as `string` in StyleX. Numeric values must be coerced to strings.
|
|
2700
|
+
*/
|
|
2701
|
+
const STYLEX_STRING_ONLY_CSS_PROPS = new Set([
|
|
2626
2702
|
"gridRow",
|
|
2627
2703
|
"gridColumn",
|
|
2628
2704
|
"gridRowStart",
|
|
@@ -2635,16 +2711,22 @@ const IDENTIFIER_NAME_RE = /^[$A-Z_][0-9A-Z_$]*$/i;
|
|
|
2635
2711
|
function isValidIdentifierName$1(name) {
|
|
2636
2712
|
return IDENTIFIER_NAME_RE.test(name);
|
|
2637
2713
|
}
|
|
2714
|
+
function coerceToStringForStyleX(cssProp, value) {
|
|
2715
|
+
if (STYLEX_STRING_ONLY_CSS_PROPS.has(cssProp) && typeof value === "number") return String(value);
|
|
2716
|
+
return value;
|
|
2717
|
+
}
|
|
2638
2718
|
/**
|
|
2639
2719
|
* Infers a TS type keyword for a dynamic expression based on the CSS property it's assigned to.
|
|
2640
2720
|
* Numeric-only properties get `number`; ambiguous length-like values get `number | string`.
|
|
2721
|
+
* Properties in STYLEX_STRING_ONLY_CSS_PROPS always get `string` even when the value is numeric.
|
|
2641
2722
|
*/
|
|
2642
2723
|
function inferTypeForCssProp(cssProp, expr) {
|
|
2724
|
+
if (STYLEX_STRING_ONLY_CSS_PROPS.has(cssProp)) return "string";
|
|
2643
2725
|
const staticVal = literalToStaticValue(expr);
|
|
2644
2726
|
if (typeof staticVal === "number") return "number";
|
|
2645
2727
|
if (typeof staticVal === "string") return "string";
|
|
2646
2728
|
if (NUMERIC_CSS_PROPS.has(cssProp)) return "number";
|
|
2647
|
-
if (
|
|
2729
|
+
if (LENGTH_LIKE_CSS_PROP_RE.test(cssProp)) return "numberOrString";
|
|
2648
2730
|
return "string";
|
|
2649
2731
|
}
|
|
2650
2732
|
/**
|
|
@@ -2773,7 +2855,7 @@ function analyzePromotableStyleProps(root, j, styledDecls, declByLocal, getJsxUs
|
|
|
2773
2855
|
const hasDynamic = site.properties.some((p) => p.dynamicExpr !== null);
|
|
2774
2856
|
if (allStatic && !hasDynamic) {
|
|
2775
2857
|
const staticObj = {};
|
|
2776
|
-
for (const p of site.properties) staticObj[p.key] = p.staticValue;
|
|
2858
|
+
for (const p of site.properties) staticObj[p.key] = coerceToStringForStyleX(p.key, p.staticValue);
|
|
2777
2859
|
if (usageCount <= 1 && !decl.isExported && !hasPropertyOverlap(staticObj, resolvedStyleObjects.get(decl.styleKey))) {
|
|
2778
2860
|
promotedEntries.push({
|
|
2779
2861
|
styleKey: decl.styleKey,
|
|
@@ -2791,15 +2873,31 @@ function analyzePromotableStyleProps(root, j, styledDecls, declByLocal, getJsxUs
|
|
|
2791
2873
|
site.opening.__promotedStyleKey = styleKey;
|
|
2792
2874
|
}
|
|
2793
2875
|
} else if (hasDynamic) {
|
|
2794
|
-
const
|
|
2795
|
-
usedKeyNames.add(styleKey);
|
|
2796
|
-
const staticObj = {};
|
|
2876
|
+
const inlineStaticObj = {};
|
|
2797
2877
|
const dynamicParams = [];
|
|
2798
|
-
for (const p of site.properties) if (p.staticValue !== null)
|
|
2878
|
+
for (const p of site.properties) if (p.staticValue !== null) inlineStaticObj[p.key] = coerceToStringForStyleX(p.key, p.staticValue);
|
|
2799
2879
|
else dynamicParams.push({
|
|
2800
2880
|
cssProp: p.key,
|
|
2801
2881
|
expr: p.dynamicExpr
|
|
2802
2882
|
});
|
|
2883
|
+
const baseObj = resolvedStyleObjects.get(decl.styleKey);
|
|
2884
|
+
const baseIsSimpleObject = baseObj && typeof baseObj === "object" && !isAstNode(baseObj) && Object.values(baseObj).every((v) => typeof v === "string" || typeof v === "number" || typeof v === "boolean" || isAstNode(v));
|
|
2885
|
+
const isExtendedByOther = styledDecls.some((d) => d !== decl && d.base.kind === "component" && d.base.ident === decl.localName);
|
|
2886
|
+
const canMergeDynamic = usageCount <= 1 && !decl.isExported && !isExtendedByOther && baseIsSimpleObject && !hasPropertyOverlap(inlineStaticObj, baseObj);
|
|
2887
|
+
const dynamicPropKeys = new Set(dynamicParams.map((dp) => dp.cssProp));
|
|
2888
|
+
const mergedStaticProps = [];
|
|
2889
|
+
if (canMergeDynamic) {
|
|
2890
|
+
for (const [k, v] of Object.entries(baseObj)) if (!dynamicPropKeys.has(k)) mergedStaticProps.push({
|
|
2891
|
+
key: k,
|
|
2892
|
+
value: v
|
|
2893
|
+
});
|
|
2894
|
+
}
|
|
2895
|
+
for (const [k, v] of Object.entries(inlineStaticObj)) mergedStaticProps.push({
|
|
2896
|
+
key: k,
|
|
2897
|
+
value: v
|
|
2898
|
+
});
|
|
2899
|
+
const styleKey = canMergeDynamic ? decl.styleKey : generatePromotedDynamicStyleKey(decl.styleKey, usedKeyNames, site.children);
|
|
2900
|
+
if (!canMergeDynamic) usedKeyNames.add(styleKey);
|
|
2803
2901
|
const paramEntries = [];
|
|
2804
2902
|
const seenParamNames = /* @__PURE__ */ new Set();
|
|
2805
2903
|
for (const dp of dynamicParams) {
|
|
@@ -2819,24 +2917,34 @@ function analyzePromotableStyleProps(root, j, styledDecls, declByLocal, getJsxUs
|
|
|
2819
2917
|
id.typeAnnotation = j.tsTypeAnnotation(typeNode);
|
|
2820
2918
|
return id;
|
|
2821
2919
|
});
|
|
2822
|
-
const bodyProperties =
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
}
|
|
2920
|
+
const bodyProperties = [];
|
|
2921
|
+
for (const sp of mergedStaticProps) {
|
|
2922
|
+
const val = isAstNode(sp.value) ? sp.value : typeof sp.value === "string" ? j.stringLiteral(sp.value) : typeof sp.value === "number" ? j.numericLiteral(sp.value) : j.booleanLiteral(sp.value);
|
|
2923
|
+
bodyProperties.push(j.property("init", j.identifier(sp.key), val));
|
|
2924
|
+
}
|
|
2925
|
+
for (const p of site.properties) if (p.dynamicExpr !== null) {
|
|
2926
|
+
const prop = j.property("init", j.identifier(p.key), j.identifier(p.key));
|
|
2927
|
+
prop.shorthand = true;
|
|
2928
|
+
bodyProperties.push(prop);
|
|
2929
|
+
}
|
|
2832
2930
|
const fnNode = j.arrowFunctionExpression(params, j.objectExpression(bodyProperties));
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2931
|
+
if (canMergeDynamic) {
|
|
2932
|
+
promotedEntries.push({
|
|
2933
|
+
styleKey: decl.styleKey,
|
|
2934
|
+
styleValue: fnNode,
|
|
2935
|
+
mergeIntoBase: true
|
|
2936
|
+
});
|
|
2937
|
+
site.opening.__promotedMergeIntoBase = true;
|
|
2938
|
+
site.opening.__promotedMergeArgs = dynamicParams.map((dp) => STYLEX_STRING_ONLY_CSS_PROPS.has(dp.cssProp) ? j.callExpression(j.identifier("String"), [dp.expr]) : dp.expr);
|
|
2939
|
+
} else {
|
|
2940
|
+
promotedEntries.push({
|
|
2941
|
+
styleKey,
|
|
2942
|
+
styleValue: fnNode
|
|
2943
|
+
});
|
|
2944
|
+
site.opening.__promotedStyleKey = styleKey;
|
|
2945
|
+
const callArgs = dynamicParams.map((dp) => STYLEX_STRING_ONLY_CSS_PROPS.has(dp.cssProp) ? j.callExpression(j.identifier("String"), [dp.expr]) : dp.expr);
|
|
2946
|
+
site.opening.__promotedStyleArgs = callArgs;
|
|
2947
|
+
}
|
|
2840
2948
|
}
|
|
2841
2949
|
}
|
|
2842
2950
|
if (promotedEntries.length > 0) decl.promotedStyleProps = promotedEntries;
|
|
@@ -7991,8 +8099,8 @@ function buildInlineResolverVariantDimensions(args) {
|
|
|
7991
8099
|
return type === "ArrowFunctionExpression" || type === "FunctionExpression";
|
|
7992
8100
|
});
|
|
7993
8101
|
const hasCompleteCallsiteVisibility = !willHaveExternalInterface(ctx, decl, styledDecls) && !decl.usedAsValue;
|
|
7994
|
-
if (variantKeys.length === 1
|
|
7995
|
-
if (hasCompleteCallsiteVisibility) {
|
|
8102
|
+
if (variantKeys.length === 1) {
|
|
8103
|
+
if (hasCompleteCallsiteVisibility && !hasPropReferencingTemplateExpressions) {
|
|
7996
8104
|
if (usageResult.propsByUsage.filter((siteProps) => propName in siteProps).length === totalCallSites) {
|
|
7997
8105
|
const [, singleVariantStyles] = Object.entries(variants)[0];
|
|
7998
8106
|
for (const [cssKey, cssVal] of Object.entries(singleVariantStyles)) foldedBaseSx[cssKey] = String(cssVal);
|
|
@@ -9625,6 +9733,22 @@ function buildVariantDimPropTypeMap(d) {
|
|
|
9625
9733
|
return [dim.propName, typeText];
|
|
9626
9734
|
}));
|
|
9627
9735
|
}
|
|
9736
|
+
/**
|
|
9737
|
+
* Collects prop names that are known to have `boolean` type from all available sources:
|
|
9738
|
+
* - `staticBooleanVariants` without a variantKey (confirmed boolean from prepass)
|
|
9739
|
+
* - `variantDimensions` with `isBooleanProp` flag
|
|
9740
|
+
* - `propsType` AST type literal with `boolean` type annotations
|
|
9741
|
+
*
|
|
9742
|
+
* Used to emit `cond && styles.key` (valid for StyleXArray since `false` is accepted)
|
|
9743
|
+
* instead of `cond ? styles.key : undefined` for boolean-guarded variant conditions.
|
|
9744
|
+
*/
|
|
9745
|
+
function collectBooleanPropNames(d) {
|
|
9746
|
+
const result = /* @__PURE__ */ new Set();
|
|
9747
|
+
for (const sbv of d.staticBooleanVariants ?? []) if (!sbv.variantKey) result.add(sbv.propName);
|
|
9748
|
+
for (const dim of d.variantDimensions ?? []) if (dim.isBooleanProp) result.add(dim.propName);
|
|
9749
|
+
collectBooleanPropsFromTypeLiteral(d.propsType, result);
|
|
9750
|
+
return result;
|
|
9751
|
+
}
|
|
9628
9752
|
function getAttrsAsString(d) {
|
|
9629
9753
|
const v = d.attrsInfo?.staticAttrs?.as;
|
|
9630
9754
|
return typeof v === "string" ? v : null;
|
|
@@ -9658,6 +9782,41 @@ function injectStylePropsIntoTypeLiteralString(typeText, options) {
|
|
|
9658
9782
|
}
|
|
9659
9783
|
return `${typeText} & { ${propsToAdd.join(", ")} }`;
|
|
9660
9784
|
}
|
|
9785
|
+
function collectBooleanPropsFromTypeLiteral(node, result) {
|
|
9786
|
+
for (const name of extractBooleanProps(node)) {
|
|
9787
|
+
result.add(name);
|
|
9788
|
+
if (name.startsWith("$")) result.add(name.slice(1));
|
|
9789
|
+
}
|
|
9790
|
+
}
|
|
9791
|
+
function extractBooleanProps(node) {
|
|
9792
|
+
const typed = node;
|
|
9793
|
+
if (!typed || typeof typed !== "object") return /* @__PURE__ */ new Set();
|
|
9794
|
+
if (typed.type === "TSTypeLiteral") {
|
|
9795
|
+
const props = /* @__PURE__ */ new Set();
|
|
9796
|
+
for (const member of typed.members ?? []) {
|
|
9797
|
+
if (member?.type !== "TSPropertySignature") continue;
|
|
9798
|
+
const key = member.key;
|
|
9799
|
+
const name = key?.type === "Identifier" ? key.name : null;
|
|
9800
|
+
if (!name) continue;
|
|
9801
|
+
if ((member.typeAnnotation?.typeAnnotation)?.type === "TSBooleanKeyword") props.add(name);
|
|
9802
|
+
}
|
|
9803
|
+
return props;
|
|
9804
|
+
}
|
|
9805
|
+
if (typed.type === "TSIntersectionType") {
|
|
9806
|
+
const combined = /* @__PURE__ */ new Set();
|
|
9807
|
+
for (const t of typed.types ?? []) for (const p of extractBooleanProps(t)) combined.add(p);
|
|
9808
|
+
return combined;
|
|
9809
|
+
}
|
|
9810
|
+
if (typed.type === "TSUnionType") {
|
|
9811
|
+
const arms = (typed.types ?? []).map(extractBooleanProps);
|
|
9812
|
+
if (arms.length === 0) return /* @__PURE__ */ new Set();
|
|
9813
|
+
const first = arms[0];
|
|
9814
|
+
const intersection = /* @__PURE__ */ new Set();
|
|
9815
|
+
for (const name of first) if (arms.every((arm) => arm.has(name))) intersection.add(name);
|
|
9816
|
+
return intersection;
|
|
9817
|
+
}
|
|
9818
|
+
return /* @__PURE__ */ new Set();
|
|
9819
|
+
}
|
|
9661
9820
|
|
|
9662
9821
|
//#endregion
|
|
9663
9822
|
//#region src/internal/emit-wrappers/jsx-builders.ts
|
|
@@ -9816,6 +9975,15 @@ function styleRef(j, stylesIdentifier, key) {
|
|
|
9816
9975
|
return j.memberExpression(j.identifier(stylesIdentifier), j.identifier(key));
|
|
9817
9976
|
}
|
|
9818
9977
|
/**
|
|
9978
|
+
* When a style function uses a `props` object parameter, wraps the raw call
|
|
9979
|
+
* argument in `{ [propsObjectKey]: rawArg }`. Returns `rawArg` unchanged when
|
|
9980
|
+
* `propsObjectKey` is not set.
|
|
9981
|
+
*/
|
|
9982
|
+
function wrapCallArgForPropsObject(j, rawArg, propsObjectKey) {
|
|
9983
|
+
if (!propsObjectKey) return rawArg;
|
|
9984
|
+
return j.objectExpression([j.property("init", j.identifier(propsObjectKey), rawArg)]);
|
|
9985
|
+
}
|
|
9986
|
+
/**
|
|
9819
9987
|
* Splits a declaration's extra style keys into those that appear before and
|
|
9820
9988
|
* after the base style in stylex.props() argument order.
|
|
9821
9989
|
*/
|
|
@@ -10093,9 +10261,10 @@ function buildStyleFnExpressions(emitter, args) {
|
|
|
10093
10261
|
}
|
|
10094
10262
|
return null;
|
|
10095
10263
|
};
|
|
10264
|
+
const booleanProps = collectBooleanPropNames(d);
|
|
10096
10265
|
for (const p of styleFnPairs) {
|
|
10097
10266
|
const propExpr = p.jsxProp === "__props" ? propsId : propExprBuilder(p.jsxProp);
|
|
10098
|
-
const callArg = p.callArg ?? propExpr;
|
|
10267
|
+
const callArg = wrapCallArgForPropsObject(j, p.callArg ?? propExpr, p.propsObjectKey);
|
|
10099
10268
|
const call = j.callExpression(styleRef(j, stylesIdentifier, p.fnKey), [callArg]);
|
|
10100
10269
|
if (p.callArg?.type === "Identifier") {
|
|
10101
10270
|
const name = p.callArg.name;
|
|
@@ -10122,7 +10291,8 @@ function buildStyleFnExpressions(emitter, args) {
|
|
|
10122
10291
|
if (p.conditionWhen) {
|
|
10123
10292
|
const { cond, isBoolean } = collectConditionProps(j, {
|
|
10124
10293
|
when: p.conditionWhen,
|
|
10125
|
-
destructureProps
|
|
10294
|
+
destructureProps,
|
|
10295
|
+
booleanProps
|
|
10126
10296
|
});
|
|
10127
10297
|
pushExpr(makeConditionalStyleExpr(j, {
|
|
10128
10298
|
cond,
|
|
@@ -11769,6 +11939,7 @@ function emitSimpleExportedIntrinsicWrappers(ctx) {
|
|
|
11769
11939
|
const needsUseTheme = appendThemeBooleanStyleArgs(d.needsUseThemeHook, styleArgs, j, stylesIdentifier, () => ctx.markNeedsUseThemeImport());
|
|
11770
11940
|
for (const gp of appendAllPseudoStyleArgs(d, styleArgs, j, stylesIdentifier)) if (!destructureProps.includes(gp)) destructureProps.push(gp);
|
|
11771
11941
|
const compoundVariantKeys = collectCompoundVariantKeys(d.compoundVariants);
|
|
11942
|
+
const booleanProps = collectBooleanPropNames(d);
|
|
11772
11943
|
const hasSourceOrder = !!(d.variantSourceOrder && Object.keys(d.variantSourceOrder).length > 0);
|
|
11773
11944
|
const orderedEntries = [];
|
|
11774
11945
|
if (d.variantStyleKeys) {
|
|
@@ -11787,7 +11958,8 @@ function emitSimpleExportedIntrinsicWrappers(ctx) {
|
|
|
11787
11958
|
const positiveWhen = getPositiveWhen(when, otherWhen) ?? when;
|
|
11788
11959
|
const { cond } = emitter.collectConditionProps({
|
|
11789
11960
|
when: positiveWhen,
|
|
11790
|
-
destructureProps
|
|
11961
|
+
destructureProps,
|
|
11962
|
+
booleanProps
|
|
11791
11963
|
});
|
|
11792
11964
|
const isCurrentPositive = areEquivalentWhen(when, positiveWhen);
|
|
11793
11965
|
const trueKey = isCurrentPositive ? variantKey : otherKey;
|
|
@@ -11805,7 +11977,8 @@ function emitSimpleExportedIntrinsicWrappers(ctx) {
|
|
|
11805
11977
|
}
|
|
11806
11978
|
const { cond, isBoolean } = emitter.collectConditionProps({
|
|
11807
11979
|
when,
|
|
11808
|
-
destructureProps
|
|
11980
|
+
destructureProps,
|
|
11981
|
+
booleanProps
|
|
11809
11982
|
});
|
|
11810
11983
|
const styleExpr = j.memberExpression(j.identifier(stylesIdentifier), j.identifier(variantKey));
|
|
11811
11984
|
const expr = emitter.makeConditionalStyleExpr({
|
|
@@ -12167,12 +12340,12 @@ function appendAllPseudoStyleArgs(d, styleArgs, j, stylesIdentifier) {
|
|
|
12167
12340
|
* Each entry is mapped to an expression via `buildExpr`, then optionally
|
|
12168
12341
|
* wrapped in a conditional if the entry has a `guard`.
|
|
12169
12342
|
*/
|
|
12170
|
-
function appendGuardedStyleArgs(entries, styleArgs, j, buildExpr) {
|
|
12343
|
+
function appendGuardedStyleArgs(entries, styleArgs, j, buildExpr, booleanProps) {
|
|
12171
12344
|
const guardProps = [];
|
|
12172
12345
|
for (const entry of entries) {
|
|
12173
12346
|
const expr = buildExpr(entry);
|
|
12174
12347
|
if (entry.guard) {
|
|
12175
|
-
const parsed = parseVariantWhenToAst(j, entry.guard.when);
|
|
12348
|
+
const parsed = parseVariantWhenToAst(j, entry.guard.when, booleanProps);
|
|
12176
12349
|
for (const p of parsed.props) if (p && !guardProps.includes(p)) guardProps.push(p);
|
|
12177
12350
|
styleArgs.push(makeConditionalStyleExpr(j, {
|
|
12178
12351
|
cond: parsed.cond,
|
|
@@ -12364,6 +12537,7 @@ function emitComponentWrappers(emitter) {
|
|
|
12364
12537
|
];
|
|
12365
12538
|
const hasSourceOrder = !!(d.variantSourceOrder && Object.keys(d.variantSourceOrder).length > 0);
|
|
12366
12539
|
const orderedEntries = [];
|
|
12540
|
+
const booleanProps = collectBooleanPropNames(d);
|
|
12367
12541
|
if (d.variantStyleKeys) {
|
|
12368
12542
|
const sortedEntries = sortVariantEntriesBySpecificity(Object.entries(d.variantStyleKeys));
|
|
12369
12543
|
const consumedVariantIndices = /* @__PURE__ */ new Set();
|
|
@@ -12378,7 +12552,8 @@ function emitComponentWrappers(emitter) {
|
|
|
12378
12552
|
const positiveWhen = getPositiveWhen(when, otherWhen) ?? when;
|
|
12379
12553
|
const { cond } = emitter.collectConditionProps({
|
|
12380
12554
|
when: positiveWhen,
|
|
12381
|
-
destructureProps
|
|
12555
|
+
destructureProps,
|
|
12556
|
+
booleanProps
|
|
12382
12557
|
});
|
|
12383
12558
|
for (let i = prevLength; i < destructureProps.length; i++) styleOnlyConditionProps.add(destructureProps[i]);
|
|
12384
12559
|
const isCurrentPositive = areEquivalentWhen(when, positiveWhen);
|
|
@@ -12397,7 +12572,8 @@ function emitComponentWrappers(emitter) {
|
|
|
12397
12572
|
}
|
|
12398
12573
|
const { cond, isBoolean } = emitter.collectConditionProps({
|
|
12399
12574
|
when,
|
|
12400
|
-
destructureProps
|
|
12575
|
+
destructureProps,
|
|
12576
|
+
booleanProps
|
|
12401
12577
|
});
|
|
12402
12578
|
for (let i = prevLength; i < destructureProps.length; i++) styleOnlyConditionProps.add(destructureProps[i]);
|
|
12403
12579
|
const styleExpr = j.memberExpression(j.identifier(stylesIdentifier), j.identifier(variantKey));
|
|
@@ -13344,6 +13520,7 @@ function emitIntrinsicPolymorphicWrappers(ctx) {
|
|
|
13344
13520
|
...extraStyleArgsAfterBase
|
|
13345
13521
|
];
|
|
13346
13522
|
const compoundVariantKeys = collectCompoundVariantKeys(d.compoundVariants);
|
|
13523
|
+
const booleanProps = collectBooleanPropNames(d);
|
|
13347
13524
|
const hasSourceOrder = !!(d.variantSourceOrder && Object.keys(d.variantSourceOrder).length > 0);
|
|
13348
13525
|
const orderedEntries = [];
|
|
13349
13526
|
if (d.variantStyleKeys) {
|
|
@@ -13352,7 +13529,8 @@ function emitIntrinsicPolymorphicWrappers(ctx) {
|
|
|
13352
13529
|
if (compoundVariantKeys.has(when)) continue;
|
|
13353
13530
|
const { cond, isBoolean } = emitter.collectConditionProps({
|
|
13354
13531
|
when,
|
|
13355
|
-
destructureProps
|
|
13532
|
+
destructureProps,
|
|
13533
|
+
booleanProps
|
|
13356
13534
|
});
|
|
13357
13535
|
const styleExpr = j.memberExpression(j.identifier(stylesIdentifier), j.identifier(variantKey));
|
|
13358
13536
|
const expr = emitter.makeConditionalStyleExpr({
|
|
@@ -13653,13 +13831,17 @@ function emitShouldForwardPropWrappers(ctx) {
|
|
|
13653
13831
|
const needsUseTheme = appendThemeBooleanStyleArgs(d.needsUseThemeHook, styleArgs, j, stylesIdentifier, () => ctx.markNeedsUseThemeImport());
|
|
13654
13832
|
const pseudoGuardProps = appendAllPseudoStyleArgs(d, styleArgs, j, stylesIdentifier);
|
|
13655
13833
|
const compoundVariantKeys = collectCompoundVariantKeys(d.compoundVariants);
|
|
13834
|
+
const booleanProps = collectBooleanPropNames(d);
|
|
13656
13835
|
const hasSourceOrder = !!(d.variantSourceOrder && Object.keys(d.variantSourceOrder).length > 0);
|
|
13657
13836
|
const orderedEntries = [];
|
|
13658
13837
|
if (d.variantStyleKeys) {
|
|
13659
13838
|
const sortedEntries = sortVariantEntriesBySpecificity(Object.entries(d.variantStyleKeys));
|
|
13660
13839
|
for (const [when, variantKey] of sortedEntries) {
|
|
13661
13840
|
if (compoundVariantKeys.has(when)) continue;
|
|
13662
|
-
const { cond, isBoolean } = emitter.collectConditionProps({
|
|
13841
|
+
const { cond, isBoolean } = emitter.collectConditionProps({
|
|
13842
|
+
when,
|
|
13843
|
+
booleanProps
|
|
13844
|
+
});
|
|
13663
13845
|
const styleExpr = j.memberExpression(j.identifier(stylesIdentifier), j.identifier(variantKey));
|
|
13664
13846
|
const expr = emitter.makeConditionalStyleExpr({
|
|
13665
13847
|
cond,
|
|
@@ -13703,13 +13885,14 @@ function emitShouldForwardPropWrappers(ctx) {
|
|
|
13703
13885
|
const prefix = dropPrefix;
|
|
13704
13886
|
const isPrefixProp = !!prefix && typeof p.jsxProp === "string" && p.jsxProp !== "__props" && p.jsxProp.startsWith(prefix);
|
|
13705
13887
|
const propExpr = isPrefixProp ? knownPrefixPropsSet.has(p.jsxProp) ? j.identifier(p.jsxProp) : j.memberExpression(j.identifier("props"), j.literal(p.jsxProp), true) : p.jsxProp === "__props" ? j.identifier("props") : j.identifier(p.jsxProp);
|
|
13706
|
-
const callArg = p.callArg ?? propExpr;
|
|
13888
|
+
const callArg = wrapCallArgForPropsObject(j, p.callArg ?? propExpr, p.propsObjectKey);
|
|
13707
13889
|
const call = j.callExpression(styleRef(j, stylesIdentifier, p.fnKey), [callArg]);
|
|
13708
13890
|
let expr;
|
|
13709
13891
|
if (p.conditionWhen) {
|
|
13710
13892
|
const { cond, isBoolean } = emitter.collectConditionProps({
|
|
13711
13893
|
when: p.conditionWhen,
|
|
13712
|
-
destructureProps: destructureParts
|
|
13894
|
+
destructureProps: destructureParts,
|
|
13895
|
+
booleanProps
|
|
13713
13896
|
});
|
|
13714
13897
|
expr = emitter.makeConditionalStyleExpr({
|
|
13715
13898
|
cond,
|
|
@@ -16088,6 +16271,7 @@ function createLowerRulesState(ctx) {
|
|
|
16088
16271
|
j,
|
|
16089
16272
|
importMap
|
|
16090
16273
|
});
|
|
16274
|
+
const enumValueMap = buildEnumValueMap(root, j);
|
|
16091
16275
|
const crossFileSelectorsByLocal = /* @__PURE__ */ new Map();
|
|
16092
16276
|
if (ctx.crossFileSelectorUsages) for (const usage of ctx.crossFileSelectorUsages) crossFileSelectorsByLocal.set(usage.localName, usage);
|
|
16093
16277
|
const state = {
|
|
@@ -16132,6 +16316,7 @@ function createLowerRulesState(ctx) {
|
|
|
16132
16316
|
resolveCssHelperTemplate,
|
|
16133
16317
|
resolveImportInScope,
|
|
16134
16318
|
resolveImportForExpr,
|
|
16319
|
+
enumValueMap,
|
|
16135
16320
|
crossFileSelectorsByLocal,
|
|
16136
16321
|
inlineKeyframeNameMap: void 0,
|
|
16137
16322
|
bail: false,
|
|
@@ -17024,7 +17209,15 @@ function tryResolveConditionalValue(node, ctx) {
|
|
|
17024
17209
|
if (!isArrowFunctionExpression(expr)) return null;
|
|
17025
17210
|
const info = getArrowFnThemeParamInfo(expr);
|
|
17026
17211
|
const paramName = info?.kind === "propsParam" ? info.propsName : null;
|
|
17212
|
+
const propsParamName = paramName ?? void 0;
|
|
17213
|
+
const themeBindingName = info?.kind === "themeBinding" ? info.themeName : void 0;
|
|
17027
17214
|
const paramBindings = !paramName && !info ? getArrowFnParamBindings(expr) : null;
|
|
17215
|
+
const runtimeCallState = { info: null };
|
|
17216
|
+
const buildRuntimeCallResult = () => runtimeCallState.info ? {
|
|
17217
|
+
type: "runtimeCallOnly",
|
|
17218
|
+
resolveCallContext: runtimeCallState.info.resolveCallContext,
|
|
17219
|
+
resolveCallResult: runtimeCallState.info.resolveCallResult
|
|
17220
|
+
} : null;
|
|
17028
17221
|
const body = getFunctionBodyExpr(expr);
|
|
17029
17222
|
if (!body || body.type !== "ConditionalExpression") return null;
|
|
17030
17223
|
const checkThemeBooleanTest = (test) => {
|
|
@@ -17148,17 +17341,66 @@ function tryResolveConditionalValue(node, ctx) {
|
|
|
17148
17341
|
};
|
|
17149
17342
|
}
|
|
17150
17343
|
if (!b || typeof b !== "object") return null;
|
|
17344
|
+
const callHasThemeArg = (call) => (call.arguments ?? []).some((arg) => {
|
|
17345
|
+
if (!arg || typeof arg !== "object" || arg.type !== "MemberExpression") return false;
|
|
17346
|
+
if (propsParamName) {
|
|
17347
|
+
const parts = getMemberPathFromIdentifier(arg, propsParamName);
|
|
17348
|
+
return parts !== null && parts[0] === "theme" && parts.length > 1;
|
|
17349
|
+
}
|
|
17350
|
+
if (themeBindingName) {
|
|
17351
|
+
const parts = getMemberPathFromIdentifier(arg, themeBindingName);
|
|
17352
|
+
return parts !== null && parts.length > 0;
|
|
17353
|
+
}
|
|
17354
|
+
return false;
|
|
17355
|
+
});
|
|
17356
|
+
const markAsRuntimeCall = (call) => {
|
|
17357
|
+
runtimeCallState.info = {
|
|
17358
|
+
resolveCallContext: {
|
|
17359
|
+
callSiteFilePath: ctx.filePath,
|
|
17360
|
+
calleeImportedName: "<local>",
|
|
17361
|
+
calleeSource: {
|
|
17362
|
+
kind: "specifier",
|
|
17363
|
+
value: ctx.filePath
|
|
17364
|
+
},
|
|
17365
|
+
args: [],
|
|
17366
|
+
...call.loc?.start ? { loc: {
|
|
17367
|
+
line: call.loc.start.line,
|
|
17368
|
+
column: call.loc.start.column
|
|
17369
|
+
} } : {}
|
|
17370
|
+
},
|
|
17371
|
+
resolveCallResult: { preserveRuntimeCall: true }
|
|
17372
|
+
};
|
|
17373
|
+
};
|
|
17151
17374
|
const resolveCallExpr = (call, cssProperty) => {
|
|
17152
|
-
const res = resolveImportedHelperCall(call, ctx,
|
|
17153
|
-
if (res.kind === "resolved"
|
|
17375
|
+
const res = resolveImportedHelperCall(call, ctx, propsParamName, cssProperty, themeBindingName);
|
|
17376
|
+
if (res.kind === "resolved") {
|
|
17377
|
+
if ("expr" in res.result) return res.result;
|
|
17378
|
+
if (res.result.preserveRuntimeCall) {
|
|
17379
|
+
runtimeCallState.info = {
|
|
17380
|
+
resolveCallContext: res.resolveCallContext,
|
|
17381
|
+
resolveCallResult: res.resolveCallResult
|
|
17382
|
+
};
|
|
17383
|
+
return null;
|
|
17384
|
+
}
|
|
17385
|
+
}
|
|
17154
17386
|
if (isCallExpressionNode(call.callee)) {
|
|
17155
17387
|
const inner = call.callee;
|
|
17156
17388
|
const outerArgs = call.arguments ?? [];
|
|
17157
17389
|
if (outerArgs.length === 1 && outerArgs[0] && typeof outerArgs[0] === "object") {
|
|
17158
|
-
const innerRes = resolveImportedHelperCall(inner, ctx,
|
|
17159
|
-
if (innerRes.kind === "resolved"
|
|
17390
|
+
const innerRes = resolveImportedHelperCall(inner, ctx, propsParamName, cssProperty, themeBindingName);
|
|
17391
|
+
if (innerRes.kind === "resolved") {
|
|
17392
|
+
if ("expr" in innerRes.result) return innerRes.result;
|
|
17393
|
+
if (innerRes.result.preserveRuntimeCall) {
|
|
17394
|
+
runtimeCallState.info = {
|
|
17395
|
+
resolveCallContext: innerRes.resolveCallContext,
|
|
17396
|
+
resolveCallResult: innerRes.resolveCallResult
|
|
17397
|
+
};
|
|
17398
|
+
return null;
|
|
17399
|
+
}
|
|
17400
|
+
}
|
|
17160
17401
|
}
|
|
17161
17402
|
}
|
|
17403
|
+
if (callHasThemeArg(call)) markAsRuntimeCall(call);
|
|
17162
17404
|
return null;
|
|
17163
17405
|
};
|
|
17164
17406
|
const templateResult = resolveTemplateLiteralExpressions(b, (expr) => {
|
|
@@ -17239,7 +17481,7 @@ function tryResolveConditionalValue(node, ctx) {
|
|
|
17239
17481
|
};
|
|
17240
17482
|
const extractConditionInfo = (test) => {
|
|
17241
17483
|
if (test.type !== "BinaryExpression" || test.operator !== "===" && test.operator !== "!==") return null;
|
|
17242
|
-
const rhsRaw =
|
|
17484
|
+
const rhsRaw = resolveStaticExpressionValue(test.right, ctx.enumValueMap);
|
|
17243
17485
|
if (rhsRaw === null) return null;
|
|
17244
17486
|
if (paramName && test.left.type === "MemberExpression") {
|
|
17245
17487
|
const leftPath = getMemberPathFromIdentifier(test.left, paramName);
|
|
@@ -17389,7 +17631,7 @@ function tryResolveConditionalValue(node, ctx) {
|
|
|
17389
17631
|
}
|
|
17390
17632
|
}
|
|
17391
17633
|
}
|
|
17392
|
-
if (!cons || !alt) return
|
|
17634
|
+
if (!cons || !alt) return buildRuntimeCallResult();
|
|
17393
17635
|
if (new Set([cons.usage, alt.usage]).size !== 1) return null;
|
|
17394
17636
|
const usage = cons.usage;
|
|
17395
17637
|
const variants = [{
|
|
@@ -17438,6 +17680,7 @@ function tryResolveConditionalValue(node, ctx) {
|
|
|
17438
17680
|
};
|
|
17439
17681
|
}
|
|
17440
17682
|
}
|
|
17683
|
+
if (!cons || !alt) return buildRuntimeCallResult();
|
|
17441
17684
|
}
|
|
17442
17685
|
if (paramBindings?.kind === "destructured" && test.type === "Identifier" && typeof test.name === "string") {
|
|
17443
17686
|
const resolvedProp = resolveIdentifierToPropName(test, paramBindings);
|
|
@@ -17475,6 +17718,7 @@ function tryResolveConditionalValue(node, ctx) {
|
|
|
17475
17718
|
if (result) return result;
|
|
17476
17719
|
}
|
|
17477
17720
|
}
|
|
17721
|
+
if (!cons || !alt) return buildRuntimeCallResult();
|
|
17478
17722
|
}
|
|
17479
17723
|
}
|
|
17480
17724
|
const condInfo = extractConditionInfo(test);
|
|
@@ -17520,7 +17764,7 @@ function tryResolveConditionalValue(node, ctx) {
|
|
|
17520
17764
|
};
|
|
17521
17765
|
}
|
|
17522
17766
|
}
|
|
17523
|
-
return
|
|
17767
|
+
return buildRuntimeCallResult();
|
|
17524
17768
|
}
|
|
17525
17769
|
function tryResolveConditionalCssBlock(node, ctx) {
|
|
17526
17770
|
const expr = node.expr;
|
|
@@ -17600,7 +17844,7 @@ function tryResolveConditionalCssBlockTernary(node, ctx) {
|
|
|
17600
17844
|
return null;
|
|
17601
17845
|
}
|
|
17602
17846
|
if (t.type === "BinaryExpression" && (t.operator === "===" || t.operator === "!==")) {
|
|
17603
|
-
const rhsRaw =
|
|
17847
|
+
const rhsRaw = resolveStaticExpressionValue(t.right, ctx.enumValueMap);
|
|
17604
17848
|
if (rhsRaw === null) return null;
|
|
17605
17849
|
const left = t.left;
|
|
17606
17850
|
if (paramName && left?.type === "MemberExpression") {
|
|
@@ -17982,7 +18226,7 @@ function replaceThemeRefsWithHookVar(expr, paramName, info) {
|
|
|
17982
18226
|
* Order matters: more-specific transforms first, then fall back to prop-access emission.
|
|
17983
18227
|
*/
|
|
17984
18228
|
function resolveDynamicNode(node, ctx) {
|
|
17985
|
-
return tryResolveThemeAccess(node, ctx) ?? tryResolveCallExpression(node, ctx) ?? tryResolveArrowFnHelperCallWithThemeArg(node, ctx) ?? tryResolveArrowFnCallWithConditionalArgs(node, ctx) ?? tryResolveConditionalValue(node, ctx) ?? tryResolveIndexedThemeWithPropFallback(node, ctx) ?? tryResolveConditionalCssBlockTernary(node, ctx) ?? tryResolveConditionalCssBlock(node, ctx) ?? tryResolveArrowFnCallWithSinglePropArg(node, ctx) ?? tryResolveThemeDependentTemplateLiteral(node, ctx) ?? tryResolveStyleFunctionFromTemplateLiteral(node) ?? tryResolveInlineStyleValueForNestedPropAccess(node) ?? tryResolvePropAccess(node) ?? tryResolveConditionalPropStyleFunction(node) ?? tryResolveInlineStyleValueForConditionalExpression(node) ?? tryResolveInlineStyleValueForLogicalExpression(node) ?? tryResolveInlineStyleValueFromArrowFn(node);
|
|
18229
|
+
return tryResolveThemeAccess(node, ctx) ?? tryResolveCallExpression(node, ctx) ?? tryResolveArrowFnHelperCallWithThemeArg(node, ctx) ?? tryResolveArrowFnCallWithConditionalArgs(node, ctx) ?? tryResolveConditionalValue(node, ctx) ?? tryResolveIndexedThemeWithPropFallback(node, ctx) ?? tryResolveConditionalCssBlockTernary(node, ctx) ?? tryResolveConditionalCssBlock(node, ctx) ?? tryResolveArrowFnCallWithSinglePropArg(node, ctx) ?? tryResolveThemeDependentTemplateLiteral(node, ctx) ?? tryResolveStyleFunctionFromTemplateLiteral(node) ?? tryResolveInlineStyleValueForNestedPropAccess(node) ?? tryResolvePropAccess(node) ?? tryResolveConditionalPropStyleFunction(node) ?? tryResolveArrowFnPropExpression(node) ?? tryResolveInlineStyleValueForConditionalExpression(node) ?? tryResolveInlineStyleValueForLogicalExpression(node) ?? tryResolveInlineStyleValueFromArrowFn(node);
|
|
17986
18230
|
}
|
|
17987
18231
|
function tryResolveThemeAccess(node, ctx) {
|
|
17988
18232
|
const expr = node.expr;
|
|
@@ -18375,6 +18619,29 @@ function collectPropsFromExprTree(nodes, paramName) {
|
|
|
18375
18619
|
props
|
|
18376
18620
|
};
|
|
18377
18621
|
}
|
|
18622
|
+
/**
|
|
18623
|
+
* Checks whether the param name is used as a bare identifier anywhere in the
|
|
18624
|
+
* expression tree (i.e., not as the `object` of a non-computed MemberExpression
|
|
18625
|
+
* like `props.X`). This detects patterns like `helper(props)` or computed access
|
|
18626
|
+
* `props[expr]` where the full props object is needed, which would break
|
|
18627
|
+
* `emitStyleFunctionFromPropsObject` since that handler only forwards a subset
|
|
18628
|
+
* of collected prop names.
|
|
18629
|
+
*/
|
|
18630
|
+
function hasBareParamUsage(root, paramName) {
|
|
18631
|
+
const visit = (node, skipIdent) => {
|
|
18632
|
+
if (!node || typeof node !== "object") return false;
|
|
18633
|
+
if (Array.isArray(node)) return node.some((child) => visit(child, false));
|
|
18634
|
+
const n = node;
|
|
18635
|
+
if (n.type === "Identifier" && n.name === paramName && !skipIdent) return true;
|
|
18636
|
+
for (const key of Object.keys(n)) {
|
|
18637
|
+
if (key === "loc" || key === "comments") continue;
|
|
18638
|
+
const child = n[key];
|
|
18639
|
+
if (visit(child, (n.type === "MemberExpression" || n.type === "OptionalMemberExpression") && !n.computed && (key === "object" || key === "property"))) return true;
|
|
18640
|
+
}
|
|
18641
|
+
return false;
|
|
18642
|
+
};
|
|
18643
|
+
return visit(root, false);
|
|
18644
|
+
}
|
|
18378
18645
|
function tryResolveStyleFunctionFromTemplateLiteral(node) {
|
|
18379
18646
|
if (!node.css.property) return null;
|
|
18380
18647
|
const expr = node.expr;
|
|
@@ -18460,6 +18727,35 @@ function tryDecomposeConditionalBranches(condBody, paramName) {
|
|
|
18460
18727
|
isStaticWhenFalse
|
|
18461
18728
|
};
|
|
18462
18729
|
}
|
|
18730
|
+
/**
|
|
18731
|
+
* Handles arrow functions whose body is a computational expression referencing props.
|
|
18732
|
+
*
|
|
18733
|
+
* Catches expression types not covered by specific handlers (e.g. BinaryExpression,
|
|
18734
|
+
* UnaryExpression) and emits a StyleX style function that takes the props object.
|
|
18735
|
+
*
|
|
18736
|
+
* Pattern: `(props) => props.$depth * 16 + 4`
|
|
18737
|
+
* Output: `(props) => ({ paddingLeft: \`${props.$depth * 16 + 4}px\` })`
|
|
18738
|
+
*/
|
|
18739
|
+
function tryResolveArrowFnPropExpression(node) {
|
|
18740
|
+
if (!node.css.property) return null;
|
|
18741
|
+
const expr = node.expr;
|
|
18742
|
+
if (!isArrowFunctionExpression(expr)) return null;
|
|
18743
|
+
const paramName = getArrowFnSingleParamName(expr);
|
|
18744
|
+
if (!paramName) return null;
|
|
18745
|
+
const body = getFunctionBodyExpr(expr);
|
|
18746
|
+
if (!body) return null;
|
|
18747
|
+
const bodyType = body.type;
|
|
18748
|
+
if (bodyType !== "BinaryExpression" && bodyType !== "UnaryExpression") return null;
|
|
18749
|
+
if (hasThemeAccessInArrowFn(expr)) return null;
|
|
18750
|
+
if (hasBareParamUsage(body, paramName)) return null;
|
|
18751
|
+
const { hasUsableProps, hasNonTransientProps, props } = collectPropsFromExprTree([body], paramName);
|
|
18752
|
+
if (!hasUsableProps) return null;
|
|
18753
|
+
if (hasNonTransientProps && node.component.withConfig?.shouldForwardProp) return null;
|
|
18754
|
+
return {
|
|
18755
|
+
type: "emitStyleFunctionFromPropsObject",
|
|
18756
|
+
props
|
|
18757
|
+
};
|
|
18758
|
+
}
|
|
18463
18759
|
function tryResolveInlineStyleValueForNestedPropAccess(node) {
|
|
18464
18760
|
if (!node.css.property) return null;
|
|
18465
18761
|
const expr = node.expr;
|
|
@@ -20729,7 +21025,7 @@ const createValuePatternHandlers = (ctx) => {
|
|
|
20729
21025
|
const p = leftPath[0];
|
|
20730
21026
|
propName = propName ?? p;
|
|
20731
21027
|
if (propName !== p) return false;
|
|
20732
|
-
const rhs =
|
|
21028
|
+
const rhs = resolveStaticExpressionValue(test.right, ctx.enumValueMap);
|
|
20733
21029
|
if (rhs === null) return false;
|
|
20734
21030
|
const retValue = readIfReturnValue(stmt);
|
|
20735
21031
|
if (retValue === null) return false;
|
|
@@ -20892,7 +21188,7 @@ const createValuePatternHandlers = (ctx) => {
|
|
|
20892
21188
|
* Core concepts: per-component style buckets, helper factories, and resolver wiring.
|
|
20893
21189
|
*/
|
|
20894
21190
|
function createDeclProcessingState(state, decl) {
|
|
20895
|
-
const { api, j, root, filePath, warnings, resolverImports, parseExpr, resolveValue, resolveValueDirectional, resolveCall, resolveCallOptional, resolveSelector, importMap, cssHelperFunctions, stringMappingFns, hasLocalThemeBinding, isCssHelperTaggedTemplate, resolveCssHelperTemplate, resolveImportInScope, usedCssHelperFunctions, markBail } = state;
|
|
21191
|
+
const { api, j, root, filePath, warnings, resolverImports, parseExpr, resolveValue, resolveValueDirectional, resolveCall, resolveCallOptional, resolveSelector, importMap, cssHelperFunctions, stringMappingFns, hasLocalThemeBinding, isCssHelperTaggedTemplate, resolveCssHelperTemplate, resolveImportInScope, usedCssHelperFunctions, enumValueMap, markBail } = state;
|
|
20896
21192
|
const styleObj = {};
|
|
20897
21193
|
const perPropPseudo = {};
|
|
20898
21194
|
const perPropMedia = {};
|
|
@@ -20990,6 +21286,7 @@ function createDeclProcessingState(state, decl) {
|
|
|
20990
21286
|
...sharedFromState,
|
|
20991
21287
|
api,
|
|
20992
21288
|
importMap,
|
|
21289
|
+
enumValueMap,
|
|
20993
21290
|
decl,
|
|
20994
21291
|
styleObj,
|
|
20995
21292
|
variantBuckets,
|
|
@@ -21009,7 +21306,8 @@ function createDeclProcessingState(state, decl) {
|
|
|
21009
21306
|
resolveCall,
|
|
21010
21307
|
resolveCallOptional,
|
|
21011
21308
|
resolveImport: resolveImportInScope,
|
|
21012
|
-
hasImportIgnoringShadowing: (localName) => importMap.has(localName)
|
|
21309
|
+
hasImportIgnoringShadowing: (localName) => importMap.has(localName),
|
|
21310
|
+
enumValueMap
|
|
21013
21311
|
};
|
|
21014
21312
|
const withConfig = decl.shouldForwardProp ? { shouldForwardProp: true } : void 0;
|
|
21015
21313
|
const componentInfo = decl.base.kind === "intrinsic" ? {
|
|
@@ -21859,13 +22157,13 @@ function handleSplitVariantsResolvedValue(ctx) {
|
|
|
21859
22157
|
}
|
|
21860
22158
|
if (isHeterogeneousBackground) {
|
|
21861
22159
|
const isNestedTernary = allPosParsed.length > 1;
|
|
22160
|
+
const defaultStylexProp = neg ? resolveBackgroundStylexProp(neg.expr) : null;
|
|
21862
22161
|
if (neg && negParsed) {
|
|
21863
|
-
|
|
21864
|
-
|
|
21865
|
-
|
|
21866
|
-
|
|
21867
|
-
|
|
21868
|
-
variantStyleKeys[neg.when] ??= `${decl.styleKey}${suffix}`;
|
|
22162
|
+
if (!applyParsed(styleObj, negParsed, defaultStylexProp)) {
|
|
22163
|
+
bailUnsupported(decl, "Resolved conditional border variant could not be expanded to longhand properties");
|
|
22164
|
+
setBail();
|
|
22165
|
+
return true;
|
|
22166
|
+
}
|
|
21869
22167
|
}
|
|
21870
22168
|
for (let i = 0; i < allPosParsed.length; i++) {
|
|
21871
22169
|
const { when, nameHint, parsed } = allPosParsed[i];
|
|
@@ -21874,6 +22172,7 @@ function handleSplitVariantsResolvedValue(ctx) {
|
|
|
21874
22172
|
const whenClean = when.replace(/^!/, "");
|
|
21875
22173
|
const bucket = { ...variantBuckets.get(whenClean) };
|
|
21876
22174
|
applyParsed(bucket, parsed, posStylexProp);
|
|
22175
|
+
if (defaultStylexProp && posStylexProp !== defaultStylexProp) bucket[defaultStylexProp] = j.literal("transparent");
|
|
21877
22176
|
variantBuckets.set(whenClean, bucket);
|
|
21878
22177
|
const suffix = isNestedTernary && nameHint && !new Set([
|
|
21879
22178
|
"truthy",
|
|
@@ -23477,6 +23776,12 @@ function handleInterpolatedDeclaration(args) {
|
|
|
23477
23776
|
const { prefix, suffix } = extractStaticPartsForDecl(d);
|
|
23478
23777
|
const valueExpr = prefix || suffix ? buildTemplateWithStaticParts(j, valueExprRaw, prefix, suffix) : valueExprRaw;
|
|
23479
23778
|
const param = j.identifier(paramName);
|
|
23779
|
+
if (/\.(ts|tsx)$/.test(filePath)) {
|
|
23780
|
+
if (!(decl.propsType?.type === "TSTypeReference")) {
|
|
23781
|
+
const typeName = `${decl.localName}Props`;
|
|
23782
|
+
param.typeAnnotation = j.tsTypeAnnotation(j.tsTypeReference(j.identifier(typeName)));
|
|
23783
|
+
}
|
|
23784
|
+
}
|
|
23480
23785
|
const body = j.objectExpression([j.property("init", makeCssPropKey(j, out.prop), buildPseudoMediaPropValue({
|
|
23481
23786
|
j,
|
|
23482
23787
|
valueExpr,
|
|
@@ -23485,18 +23790,10 @@ function handleInterpolatedDeclaration(args) {
|
|
|
23485
23790
|
}))]);
|
|
23486
23791
|
styleFnDecls.set(fnKey, j.arrowFunctionExpression([param], body));
|
|
23487
23792
|
}
|
|
23488
|
-
if (!styleFnFromProps.some((p) => p.fnKey === fnKey)) {
|
|
23489
|
-
|
|
23490
|
-
|
|
23491
|
-
|
|
23492
|
-
return prop;
|
|
23493
|
-
}));
|
|
23494
|
-
styleFnFromProps.push({
|
|
23495
|
-
fnKey,
|
|
23496
|
-
jsxProp: "__props",
|
|
23497
|
-
callArg
|
|
23498
|
-
});
|
|
23499
|
-
}
|
|
23793
|
+
if (!styleFnFromProps.some((p) => p.fnKey === fnKey)) styleFnFromProps.push({
|
|
23794
|
+
fnKey,
|
|
23795
|
+
jsxProp: "__props"
|
|
23796
|
+
});
|
|
23500
23797
|
}
|
|
23501
23798
|
continue;
|
|
23502
23799
|
}
|
|
@@ -25560,11 +25857,195 @@ function finalizeDeclProcessing(ctx) {
|
|
|
25560
25857
|
});
|
|
25561
25858
|
decl.styleFnFromProps = styleFnFromProps;
|
|
25562
25859
|
}
|
|
25563
|
-
|
|
25860
|
+
mergeBaseIntoSingleStyleFn({
|
|
25861
|
+
j: state.j,
|
|
25862
|
+
decl,
|
|
25863
|
+
styleObj,
|
|
25864
|
+
styleFnFromProps,
|
|
25865
|
+
styleFnDecls,
|
|
25866
|
+
remainingStyleKeys,
|
|
25867
|
+
extraStyleObjects,
|
|
25868
|
+
styledDecls: state.styledDecls
|
|
25869
|
+
});
|
|
25870
|
+
convertStyleFnsToPropsPattern(state.j, styleFnDecls, styleFnFromProps, decl.styleKey);
|
|
25871
|
+
insertStyleFnDeclsAfterComponent(resolvedStyleObjects, styleFnDecls, {
|
|
25872
|
+
styleKey: decl.styleKey,
|
|
25873
|
+
extraStyleObjects,
|
|
25874
|
+
remainingStyleKeys,
|
|
25875
|
+
attrBuckets,
|
|
25876
|
+
enumVariant: decl.enumVariant
|
|
25877
|
+
});
|
|
25564
25878
|
if (styleFnDecls.has(decl.styleKey) && Object.keys(styleObj).length === 0) decl.skipBaseStyleRef = true;
|
|
25565
25879
|
if (inlineStyleProps.length) decl.inlineStyleProps = inlineStyleProps;
|
|
25566
25880
|
}
|
|
25567
25881
|
/**
|
|
25882
|
+
* Inserts styleFnDecls entries into resolvedStyleObjects right after the last
|
|
25883
|
+
* entry belonging to the current component. This ensures dynamic style functions
|
|
25884
|
+
* appear adjacent to their static counterparts in stylex.create() output.
|
|
25885
|
+
*/
|
|
25886
|
+
function insertStyleFnDeclsAfterComponent(resolvedStyleObjects, styleFnDecls, component) {
|
|
25887
|
+
if (styleFnDecls.size === 0) return;
|
|
25888
|
+
const componentKeys = /* @__PURE__ */ new Set();
|
|
25889
|
+
componentKeys.add(component.styleKey);
|
|
25890
|
+
for (const k of component.extraStyleObjects.keys()) componentKeys.add(k);
|
|
25891
|
+
for (const k of Object.values(component.remainingStyleKeys)) componentKeys.add(k);
|
|
25892
|
+
for (const k of component.attrBuckets.keys()) componentKeys.add(k);
|
|
25893
|
+
if (component.enumVariant) {
|
|
25894
|
+
componentKeys.add(component.enumVariant.baseKey);
|
|
25895
|
+
for (const c of component.enumVariant.cases) componentKeys.add(c.styleKey);
|
|
25896
|
+
}
|
|
25897
|
+
for (const k of styleFnDecls.keys()) if (resolvedStyleObjects.has(k)) componentKeys.add(k);
|
|
25898
|
+
let lastComponentKey = null;
|
|
25899
|
+
for (const k of resolvedStyleObjects.keys()) if (componentKeys.has(k)) lastComponentKey = k;
|
|
25900
|
+
if (lastComponentKey === null) {
|
|
25901
|
+
for (const [k, v] of styleFnDecls.entries()) resolvedStyleObjects.set(k, v);
|
|
25902
|
+
return;
|
|
25903
|
+
}
|
|
25904
|
+
const emittedFnKeys = /* @__PURE__ */ new Set();
|
|
25905
|
+
const entries = [...resolvedStyleObjects.entries()];
|
|
25906
|
+
resolvedStyleObjects.clear();
|
|
25907
|
+
for (const [k, v] of entries) {
|
|
25908
|
+
if (styleFnDecls.has(k)) {
|
|
25909
|
+
resolvedStyleObjects.set(k, styleFnDecls.get(k));
|
|
25910
|
+
emittedFnKeys.add(k);
|
|
25911
|
+
} else resolvedStyleObjects.set(k, v);
|
|
25912
|
+
if (k === lastComponentKey) {
|
|
25913
|
+
for (const [fk, fv] of styleFnDecls.entries()) if (!emittedFnKeys.has(fk)) {
|
|
25914
|
+
resolvedStyleObjects.set(fk, fv);
|
|
25915
|
+
emittedFnKeys.add(fk);
|
|
25916
|
+
}
|
|
25917
|
+
}
|
|
25918
|
+
}
|
|
25919
|
+
}
|
|
25920
|
+
/**
|
|
25921
|
+
* Merges static base properties into a single unconditional style function.
|
|
25922
|
+
*
|
|
25923
|
+
* When a styled component has both static CSS properties and a single
|
|
25924
|
+
* unconditional dynamic style function, the static properties are folded
|
|
25925
|
+
* into the function's return object so that the emitted code uses a single
|
|
25926
|
+
* `styles.key(arg)` call instead of separate `styles.key, styles.keyDynamic(arg)`.
|
|
25927
|
+
*
|
|
25928
|
+
* Preconditions:
|
|
25929
|
+
* - Exactly one unconditional styleFn entry (no conditionWhen)
|
|
25930
|
+
* - Base styleObj has at least one property
|
|
25931
|
+
* - No variant style keys, extra style objects, or enum variants
|
|
25932
|
+
* - The component is not extended by other styled components
|
|
25933
|
+
*/
|
|
25934
|
+
function mergeBaseIntoSingleStyleFn(args) {
|
|
25935
|
+
const { j, decl, styleObj, styleFnFromProps, styleFnDecls, remainingStyleKeys, extraStyleObjects, styledDecls } = args;
|
|
25936
|
+
if (Object.keys(styleObj).length === 0) return;
|
|
25937
|
+
if (styleFnFromProps.length === 0) return;
|
|
25938
|
+
if (Object.keys(remainingStyleKeys).length > 0) return;
|
|
25939
|
+
if (extraStyleObjects.size > 0) return;
|
|
25940
|
+
if (decl.enumVariant) return;
|
|
25941
|
+
for (const other of styledDecls) if (other !== decl && other.extendsStyleKey === decl.styleKey) return;
|
|
25942
|
+
const unconditionalEntries = styleFnFromProps.filter((p) => !p.conditionWhen && p.condition === "always");
|
|
25943
|
+
if (unconditionalEntries.length !== 1) return;
|
|
25944
|
+
const entry = unconditionalEntries[0];
|
|
25945
|
+
const fnKey = entry.fnKey;
|
|
25946
|
+
const fnAst = styleFnDecls.get(fnKey);
|
|
25947
|
+
if (!fnAst || typeof fnAst !== "object") return;
|
|
25948
|
+
const body = getFunctionBodyExpr(fnAst);
|
|
25949
|
+
if (!body || body.type !== "ObjectExpression") return;
|
|
25950
|
+
const bodyObj = body;
|
|
25951
|
+
if (!Array.isArray(bodyObj.properties)) return;
|
|
25952
|
+
const existingKeys = /* @__PURE__ */ new Set();
|
|
25953
|
+
for (const prop of bodyObj.properties) {
|
|
25954
|
+
const key = prop.key;
|
|
25955
|
+
if (key) existingKeys.add(key.name ?? key.value ?? "");
|
|
25956
|
+
}
|
|
25957
|
+
if (Object.keys(styleObj).filter((k) => !k.startsWith("__")).some((k) => existingKeys.has(k))) return;
|
|
25958
|
+
const prependProps = [];
|
|
25959
|
+
for (const [cssProp, cssValue] of Object.entries(styleObj)) {
|
|
25960
|
+
if (cssProp.startsWith("__")) continue;
|
|
25961
|
+
const valueAst = literalToAst(j, cssValue);
|
|
25962
|
+
const key = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(cssProp) ? j.identifier(cssProp) : j.literal(cssProp);
|
|
25963
|
+
prependProps.push(j.property("init", key, valueAst));
|
|
25964
|
+
}
|
|
25965
|
+
bodyObj.properties.unshift(...prependProps);
|
|
25966
|
+
if (fnKey !== decl.styleKey) {
|
|
25967
|
+
styleFnDecls.delete(fnKey);
|
|
25968
|
+
styleFnDecls.set(decl.styleKey, fnAst);
|
|
25969
|
+
entry.fnKey = decl.styleKey;
|
|
25970
|
+
}
|
|
25971
|
+
for (const key of Object.keys(styleObj)) delete styleObj[key];
|
|
25972
|
+
}
|
|
25973
|
+
/**
|
|
25974
|
+
* Converts single-positional-param style functions to use a named `props`
|
|
25975
|
+
* object parameter. Skips functions that already use a `props` parameter
|
|
25976
|
+
* (e.g. consolidated multi-param functions).
|
|
25977
|
+
*
|
|
25978
|
+
* Before: `(color: string) => ({ color })`
|
|
25979
|
+
* After: `(props: { color: string }) => ({ color: props.color })`
|
|
25980
|
+
*/
|
|
25981
|
+
function convertStyleFnsToPropsPattern(j, styleFnDecls, styleFnFromProps, baseStyleKey) {
|
|
25982
|
+
const managedFnKeys = new Set(styleFnFromProps.map((p) => p.fnKey));
|
|
25983
|
+
for (const [fnKey, fnAst] of styleFnDecls.entries()) {
|
|
25984
|
+
if (fnKey !== baseStyleKey) continue;
|
|
25985
|
+
if (!managedFnKeys.has(fnKey)) continue;
|
|
25986
|
+
if (!fnAst || typeof fnAst !== "object") continue;
|
|
25987
|
+
const fn = fnAst;
|
|
25988
|
+
if (!Array.isArray(fn.params) || fn.params.length !== 1) continue;
|
|
25989
|
+
const param = fn.params[0];
|
|
25990
|
+
if (param.type !== "Identifier" || !param.name || param.name === "props") continue;
|
|
25991
|
+
const paramName = param.name;
|
|
25992
|
+
const paramTypeAnnotation = param.typeAnnotation;
|
|
25993
|
+
const body = getFunctionBodyExpr(fn);
|
|
25994
|
+
if (!body || body.type !== "ObjectExpression") continue;
|
|
25995
|
+
replaceIdentifierInAst(j, body, paramName);
|
|
25996
|
+
const propsParam = j.identifier("props");
|
|
25997
|
+
if (paramTypeAnnotation) {
|
|
25998
|
+
const innerType = paramTypeAnnotation.typeAnnotation;
|
|
25999
|
+
if (innerType) {
|
|
26000
|
+
const propSignature = j.tsPropertySignature(j.identifier(paramName), j.tsTypeAnnotation(innerType));
|
|
26001
|
+
propsParam.typeAnnotation = j.tsTypeAnnotation(j.tsTypeLiteral([propSignature]));
|
|
26002
|
+
}
|
|
26003
|
+
}
|
|
26004
|
+
fn.params[0] = propsParam;
|
|
26005
|
+
for (const entry of styleFnFromProps) if (entry.fnKey === fnKey && !entry.propsObjectKey) entry.propsObjectKey = paramName;
|
|
26006
|
+
}
|
|
26007
|
+
}
|
|
26008
|
+
/**
|
|
26009
|
+
* Recursively replaces all `Identifier` references matching `oldName` with
|
|
26010
|
+
* `props.oldName` (a MemberExpression). Handles shorthand properties by
|
|
26011
|
+
* un-shorthanding them.
|
|
26012
|
+
*/
|
|
26013
|
+
function replaceIdentifierInAst(j, node, oldName) {
|
|
26014
|
+
if (!node || typeof node !== "object") return;
|
|
26015
|
+
const n = node;
|
|
26016
|
+
if (n.type === "ObjectExpression") {
|
|
26017
|
+
const properties = n.properties;
|
|
26018
|
+
if (!Array.isArray(properties)) return;
|
|
26019
|
+
for (const prop of properties) {
|
|
26020
|
+
if (prop.type === "SpreadElement" || prop.type === "SpreadProperty") {
|
|
26021
|
+
if (prop.argument?.type === "Identifier" && prop.argument.name === oldName) prop.argument = j.memberExpression(j.identifier("props"), j.identifier(oldName));
|
|
26022
|
+
else replaceIdentifierInAst(j, prop.argument, oldName);
|
|
26023
|
+
continue;
|
|
26024
|
+
}
|
|
26025
|
+
if (prop.type !== "Property") continue;
|
|
26026
|
+
if (prop.shorthand && prop.value?.type === "Identifier" && prop.value.name === oldName) {
|
|
26027
|
+
prop.shorthand = false;
|
|
26028
|
+
prop.value = j.memberExpression(j.identifier("props"), j.identifier(oldName));
|
|
26029
|
+
continue;
|
|
26030
|
+
}
|
|
26031
|
+
if (prop.computed) if (prop.key?.type === "Identifier" && prop.key.name === oldName) prop.key = j.memberExpression(j.identifier("props"), j.identifier(oldName));
|
|
26032
|
+
else replaceIdentifierInAst(j, prop.key, oldName);
|
|
26033
|
+
if (prop.value?.type === "Identifier" && prop.value.name === oldName) prop.value = j.memberExpression(j.identifier("props"), j.identifier(oldName));
|
|
26034
|
+
else replaceIdentifierInAst(j, prop.value, oldName);
|
|
26035
|
+
}
|
|
26036
|
+
return;
|
|
26037
|
+
}
|
|
26038
|
+
for (const key of Object.keys(n)) {
|
|
26039
|
+
if (key === "type" || key === "loc" || key === "start" || key === "end" || key === "comments") continue;
|
|
26040
|
+
if (key === "property" && n.type === "MemberExpression" && !n.computed) continue;
|
|
26041
|
+
const child = n[key];
|
|
26042
|
+
if (Array.isArray(child)) for (let i = 0; i < child.length; i++) if (child[i]?.type === "Identifier" && child[i].name === oldName) child[i] = j.memberExpression(j.identifier("props"), j.identifier(oldName));
|
|
26043
|
+
else replaceIdentifierInAst(j, child[i], oldName);
|
|
26044
|
+
else if (child?.type === "Identifier" && child.name === oldName) n[key] = j.memberExpression(j.identifier("props"), j.identifier(oldName));
|
|
26045
|
+
else if (child && typeof child === "object" && child.type) replaceIdentifierInAst(j, child, oldName);
|
|
26046
|
+
}
|
|
26047
|
+
}
|
|
26048
|
+
/**
|
|
25568
26049
|
* Merges a per-property condition bucket (pseudo or media) into the style object.
|
|
25569
26050
|
* When a property already exists as an object in styleObj, merges entries to
|
|
25570
26051
|
* preserve both pseudo-class and media query entries on the same property.
|
|
@@ -26623,123 +27104,11 @@ function appendToMapList(map, key, value) {
|
|
|
26623
27104
|
else map.set(key, [value]);
|
|
26624
27105
|
}
|
|
26625
27106
|
|
|
26626
|
-
//#endregion
|
|
26627
|
-
//#region src/internal/post-process/event-handler-annotations.ts
|
|
26628
|
-
/** Maps event handler prop names to their React event type. */
|
|
26629
|
-
const EVENT_TYPE_MAP = {
|
|
26630
|
-
onClick: "React.MouseEvent",
|
|
26631
|
-
onContextMenu: "React.MouseEvent",
|
|
26632
|
-
onMouseDown: "React.MouseEvent",
|
|
26633
|
-
onMouseUp: "React.MouseEvent",
|
|
26634
|
-
onMouseEnter: "React.MouseEvent",
|
|
26635
|
-
onMouseLeave: "React.MouseEvent",
|
|
26636
|
-
onMouseMove: "React.MouseEvent",
|
|
26637
|
-
onMouseOver: "React.MouseEvent",
|
|
26638
|
-
onDoubleClick: "React.MouseEvent",
|
|
26639
|
-
onKeyDown: "React.KeyboardEvent",
|
|
26640
|
-
onKeyUp: "React.KeyboardEvent",
|
|
26641
|
-
onKeyPress: "React.KeyboardEvent",
|
|
26642
|
-
onChange: "React.ChangeEvent",
|
|
26643
|
-
onInput: "React.FormEvent",
|
|
26644
|
-
onFocus: "React.FocusEvent",
|
|
26645
|
-
onBlur: "React.FocusEvent",
|
|
26646
|
-
onSubmit: "React.FormEvent",
|
|
26647
|
-
onScroll: "React.UIEvent",
|
|
26648
|
-
onWheel: "React.WheelEvent",
|
|
26649
|
-
onDragStart: "React.DragEvent",
|
|
26650
|
-
onDragEnd: "React.DragEvent",
|
|
26651
|
-
onDrop: "React.DragEvent",
|
|
26652
|
-
onDragOver: "React.DragEvent",
|
|
26653
|
-
onTouchStart: "React.TouchEvent",
|
|
26654
|
-
onTouchEnd: "React.TouchEvent",
|
|
26655
|
-
onTouchMove: "React.TouchEvent",
|
|
26656
|
-
onPointerDown: "React.PointerEvent",
|
|
26657
|
-
onPointerUp: "React.PointerEvent",
|
|
26658
|
-
onPointerMove: "React.PointerEvent",
|
|
26659
|
-
onCopy: "React.ClipboardEvent",
|
|
26660
|
-
onCut: "React.ClipboardEvent",
|
|
26661
|
-
onPaste: "React.ClipboardEvent",
|
|
26662
|
-
onAnimationEnd: "React.AnimationEvent",
|
|
26663
|
-
onAnimationStart: "React.AnimationEvent",
|
|
26664
|
-
onTransitionEnd: "React.TransitionEvent"
|
|
26665
|
-
};
|
|
26666
|
-
/** Maps intrinsic JSX tag names to their DOM element interface names. */
|
|
26667
|
-
const INTRINSIC_TAG_TO_ELEMENT_TYPE = {
|
|
26668
|
-
a: "HTMLAnchorElement",
|
|
26669
|
-
button: "HTMLButtonElement",
|
|
26670
|
-
div: "HTMLDivElement",
|
|
26671
|
-
form: "HTMLFormElement",
|
|
26672
|
-
img: "HTMLImageElement",
|
|
26673
|
-
input: "HTMLInputElement",
|
|
26674
|
-
label: "HTMLLabelElement",
|
|
26675
|
-
li: "HTMLLIElement",
|
|
26676
|
-
ol: "HTMLOListElement",
|
|
26677
|
-
option: "HTMLOptionElement",
|
|
26678
|
-
select: "HTMLSelectElement",
|
|
26679
|
-
span: "HTMLSpanElement",
|
|
26680
|
-
svg: "SVGSVGElement",
|
|
26681
|
-
table: "HTMLTableElement",
|
|
26682
|
-
tbody: "HTMLTableSectionElement",
|
|
26683
|
-
td: "HTMLTableCellElement",
|
|
26684
|
-
textarea: "HTMLTextAreaElement",
|
|
26685
|
-
th: "HTMLTableCellElement",
|
|
26686
|
-
thead: "HTMLTableSectionElement",
|
|
26687
|
-
tr: "HTMLTableRowElement",
|
|
26688
|
-
ul: "HTMLUListElement"
|
|
26689
|
-
};
|
|
26690
|
-
/**
|
|
26691
|
-
* Annotates event handler arrow function parameters at JSX usage sites of converted components.
|
|
26692
|
-
*
|
|
26693
|
-
* `componentTagMap` is best-effort and only populated for intrinsic-base conversions.
|
|
26694
|
-
* For wrappers around non-intrinsic components, event annotations stay non-generic.
|
|
26695
|
-
*
|
|
26696
|
-
* @returns true if any annotations were added
|
|
26697
|
-
*/
|
|
26698
|
-
function annotateEventHandlerParams(args) {
|
|
26699
|
-
const { root, j, convertedNames, componentTagMap } = args;
|
|
26700
|
-
if (convertedNames.size === 0) return false;
|
|
26701
|
-
let changed = false;
|
|
26702
|
-
root.find(j.JSXOpeningElement).filter((path) => {
|
|
26703
|
-
const name = path.node.name;
|
|
26704
|
-
if (name.type === "JSXIdentifier") return convertedNames.has(name.name);
|
|
26705
|
-
return false;
|
|
26706
|
-
}).forEach((jsxPath) => {
|
|
26707
|
-
const openingName = jsxPath.node.name;
|
|
26708
|
-
const componentName = openingName.type === "JSXIdentifier" ? openingName.name : null;
|
|
26709
|
-
const intrinsicTag = componentName ? componentTagMap.get(componentName) : void 0;
|
|
26710
|
-
const elementType = intrinsicTag ? INTRINSIC_TAG_TO_ELEMENT_TYPE[intrinsicTag] : void 0;
|
|
26711
|
-
for (const attr of jsxPath.node.attributes ?? []) {
|
|
26712
|
-
if (attr.type !== "JSXAttribute" || !attr.name || attr.name.type !== "JSXIdentifier") continue;
|
|
26713
|
-
const eventType = EVENT_TYPE_MAP[attr.name.name];
|
|
26714
|
-
if (!eventType) continue;
|
|
26715
|
-
const value = attr.value;
|
|
26716
|
-
if (!value || value.type !== "JSXExpressionContainer") continue;
|
|
26717
|
-
const expr = value.expression;
|
|
26718
|
-
if (!expr || expr.type !== "ArrowFunctionExpression") continue;
|
|
26719
|
-
const firstParam = expr.params[0];
|
|
26720
|
-
if (!firstParam) continue;
|
|
26721
|
-
if (firstParam.typeAnnotation) continue;
|
|
26722
|
-
if (firstParam.type !== "Identifier") continue;
|
|
26723
|
-
const parts = eventType.split(".");
|
|
26724
|
-
const typeRef = j.tsTypeReference(j.tsQualifiedName(j.identifier(parts[0]), j.identifier(parts[1])));
|
|
26725
|
-
if (elementType) typeRef.typeParameters = j.tsTypeParameterInstantiation([j.tsTypeReference(j.identifier(elementType))]);
|
|
26726
|
-
const annotatedParam = j.identifier(firstParam.name);
|
|
26727
|
-
annotatedParam.typeAnnotation = j.tsTypeAnnotation(typeRef);
|
|
26728
|
-
const newArrow = j.arrowFunctionExpression([annotatedParam, ...expr.params.slice(1)], expr.body, expr.expression);
|
|
26729
|
-
newArrow.async = expr.async ?? false;
|
|
26730
|
-
newArrow.returnType = expr.returnType ?? null;
|
|
26731
|
-
value.expression = newArrow;
|
|
26732
|
-
changed = true;
|
|
26733
|
-
}
|
|
26734
|
-
});
|
|
26735
|
-
return changed;
|
|
26736
|
-
}
|
|
26737
|
-
|
|
26738
27107
|
//#endregion
|
|
26739
27108
|
//#region src/internal/transform-steps/post-process.ts
|
|
26740
27109
|
/**
|
|
26741
27110
|
* Step: post-process transformed AST and cleanup imports.
|
|
26742
|
-
* Core concepts: relation overrides
|
|
27111
|
+
* Core concepts: relation overrides and import reconciliation.
|
|
26743
27112
|
*/
|
|
26744
27113
|
/**
|
|
26745
27114
|
* Performs post-processing rewrites, import cleanup, and descendant/ancestor selector adjustments.
|
|
@@ -26799,34 +27168,7 @@ function postProcessStep(ctx) {
|
|
|
26799
27168
|
return true;
|
|
26800
27169
|
}).size() === 0) fnPaths.forEach((p) => p.prune());
|
|
26801
27170
|
}
|
|
26802
|
-
if (/\.(ts|tsx)$/.test(file.path)) {
|
|
26803
|
-
const hasLocalAsUsage = (componentName) => {
|
|
26804
|
-
const hasAsAttr = (attrs) => (attrs ?? []).some((attr) => attr?.type === "JSXAttribute" && attr.name?.type === "JSXIdentifier" && (attr.name.name === "as" || attr.name.name === "forwardedAs"));
|
|
26805
|
-
if (root.find(j.JSXElement, { openingElement: { name: {
|
|
26806
|
-
type: "JSXIdentifier",
|
|
26807
|
-
name: componentName
|
|
26808
|
-
} } }).some((p) => hasAsAttr(p.node?.openingElement?.attributes))) return true;
|
|
26809
|
-
return root.find(j.JSXSelfClosingElement, { name: {
|
|
26810
|
-
type: "JSXIdentifier",
|
|
26811
|
-
name: componentName
|
|
26812
|
-
} }).some((p) => hasAsAttr(p.node?.attributes));
|
|
26813
|
-
};
|
|
26814
|
-
const convertedNames = /* @__PURE__ */ new Set();
|
|
26815
|
-
const componentTagMap = /* @__PURE__ */ new Map();
|
|
26816
|
-
for (const decl of styledDecls) {
|
|
26817
|
-
const isPolymorphic = !!decl.supportsAsProp || hasLocalAsUsage(decl.localName);
|
|
26818
|
-
if (decl.base.kind === "intrinsic" && !isPolymorphic) {
|
|
26819
|
-
convertedNames.add(decl.localName);
|
|
26820
|
-
componentTagMap.set(decl.localName, decl.base.tagName);
|
|
26821
|
-
}
|
|
26822
|
-
}
|
|
26823
|
-
if (annotateEventHandlerParams({
|
|
26824
|
-
root,
|
|
26825
|
-
j,
|
|
26826
|
-
convertedNames,
|
|
26827
|
-
componentTagMap
|
|
26828
|
-
})) ctx.markChanged();
|
|
26829
|
-
}
|
|
27171
|
+
if (/\.(ts|tsx)$/.test(file.path)) {}
|
|
26830
27172
|
return CONTINUE;
|
|
26831
27173
|
}
|
|
26832
27174
|
|
|
@@ -26921,13 +27263,16 @@ function rewriteJsxStep(ctx) {
|
|
|
26921
27263
|
if (renamed) attr.name.name = renamed;
|
|
26922
27264
|
}
|
|
26923
27265
|
});
|
|
26924
|
-
continue;
|
|
27266
|
+
if (!decl.promotedStyleProps?.length) continue;
|
|
26925
27267
|
}
|
|
26926
27268
|
root.find(j.JSXElement, { openingElement: { name: {
|
|
26927
27269
|
type: "JSXIdentifier",
|
|
26928
27270
|
name: decl.localName
|
|
26929
27271
|
} } }).forEach((p) => {
|
|
26930
27272
|
const opening = p.node.openingElement;
|
|
27273
|
+
if (decl.needsWrapperComponent) {
|
|
27274
|
+
if (!(opening.__promotedStyleKey && !opening.__promotedMergeIntoBase || opening.__promotedMergeArgs)) return;
|
|
27275
|
+
}
|
|
26931
27276
|
const closing = p.node.closingElement;
|
|
26932
27277
|
let finalTag = decl.base.kind === "intrinsic" ? decl.base.tagName : decl.base.ident;
|
|
26933
27278
|
const inlineVariantDimensions = decl.inlinedBaseComponent?.hasInlineJsxVariants ? decl.variantDimensions ?? [] : [];
|
|
@@ -27049,10 +27394,13 @@ function rewriteJsxStep(ctx) {
|
|
|
27049
27394
|
}
|
|
27050
27395
|
}
|
|
27051
27396
|
const baseStyleKey = matchedCombinedStyleKey ?? decl.styleKey;
|
|
27397
|
+
const mergeArgs = matchedCombinedStyleKey ? void 0 : opening.__promotedMergeArgs;
|
|
27398
|
+
const baseMember = j.memberExpression(j.identifier(ctx.stylesIdentifier ?? "styles"), j.identifier(baseStyleKey));
|
|
27399
|
+
const baseExpr = mergeArgs ? j.callExpression(baseMember, mergeArgs) : baseMember;
|
|
27052
27400
|
const styleArgs = [
|
|
27053
27401
|
...decl.extendsStyleKey ? [j.memberExpression(j.identifier(ctx.stylesIdentifier ?? "styles"), j.identifier(decl.extendsStyleKey))] : [],
|
|
27054
27402
|
...extraMixinArgs,
|
|
27055
|
-
|
|
27403
|
+
baseExpr,
|
|
27056
27404
|
...extraAfterBaseArgs
|
|
27057
27405
|
];
|
|
27058
27406
|
const variantKeys = decl.variantStyleKeys ?? {};
|
|
@@ -27095,7 +27443,10 @@ function rewriteJsxStep(ctx) {
|
|
|
27095
27443
|
if (styleFnProps.has(n)) {
|
|
27096
27444
|
const pairs = styleFnPairs.filter((p) => p.jsxProp === n);
|
|
27097
27445
|
const valueExpr = !attr.value ? j.literal(true) : attr.value.type === "StringLiteral" ? j.literal(attr.value.value) : attr.value.type === "Literal" ? j.literal(attr.value.value) : attr.value.type === "JSXExpressionContainer" ? attr.value.expression : null;
|
|
27098
|
-
if (valueExpr) for (const p of pairs)
|
|
27446
|
+
if (valueExpr) for (const p of pairs) {
|
|
27447
|
+
const callArg = wrapCallArgForPropsObject(j, valueExpr, p.propsObjectKey);
|
|
27448
|
+
styleArgs.push(j.callExpression(j.memberExpression(j.identifier(ctx.stylesIdentifier ?? "styles"), j.identifier(p.fnKey)), [callArg]));
|
|
27449
|
+
}
|
|
27099
27450
|
return;
|
|
27100
27451
|
}
|
|
27101
27452
|
if (combinedStylePropNames.has(n) && matchedCombinedStyleKey) return;
|