styled-components-to-stylex-codemod 0.0.51 → 0.0.53

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.
@@ -2,7 +2,7 @@ import { t as createModuleResolver } from "./resolve-imports-DgSAddIF.mjs";
2
2
  import { a as isDirectionalResult, n as mergeMarkerDeclarations, o as assertValidAdapter, r as DEFAULT_THEME_HOOK, t as transformedComponentAcceptsSx } from "./sx-surface-CEPFSTO1.mjs";
3
3
  import { a as findImportSource, c as resolveBarrelReExportBinding, d as UNSUPPORTED_SHOULD_FORWARD_PROP_WARNING, l as CASCADE_CONFLICT_WARNING, n as createPrepassParser, o as getReExportedSourceName, r as fileExports, t as walkAst, u as Logger } from "./ast-walk-BOXS-DT7.mjs";
4
4
  import { n as resolveExistingFilePath, r as toRealPath, t as isRelativeSpecifier } from "./path-utils-BC4U8X_q.mjs";
5
- import { a as isBackgroundImageValue, c as isSingleBackgroundComponent, d as kebabToCamelCase, f as looksLikeLength, h as sanitizeIdentifier, i as getCommentBody, l as isStyleSectionMarkerComment, m as normalizeWhitespace, n as capitalize$1, o as isJSDocBlockComment, p as lowerFirst, r as escapeRegex, s as isPrettierIgnoreComment, t as camelToKebabCase, u as isValidIdentifierName } from "./string-utils-BYTEHwNg.mjs";
5
+ import { a as hasTopLevelMatch, c as isPrettierIgnoreComment, d as isValidIdentifierName, f as kebabToCamelCase, g as sanitizeIdentifier, h as normalizeWhitespace, i as getCommentBody, l as isSingleBackgroundComponent, m as lowerFirst, n as capitalize$1, o as isBackgroundImageValue, p as looksLikeLength, r as escapeRegex, s as isJSDocBlockComment, t as camelToKebabCase, u as isStyleSectionMarkerComment } from "./string-utils-Bo3cWgss.mjs";
6
6
  import { a as terminateStandaloneInterpolationStatements, i as parseStyledTemplateLiteral, n as isTemplatePlaceholderInSelectorContext, r as PLACEHOLDER_RE } from "./selector-context-heuristic-LVizWWOR.mjs";
7
7
  import { _ as walkForImportsAndTemplates, a as mergeComponentPropUsage, i as getExhaustiveObservedStaticValues, n as createComponentPropUsageInfo, o as readStaticJsxLiteral, r as formatObservedVariantCondition, s as collectStylexExportNames, t as KNOWN_NON_ELEMENT_PROPS, u as buildImportMapFromNodes } from "./prop-usage-SADzZJdX.mjs";
8
8
  import { createRequire } from "node:module";
@@ -12,6 +12,89 @@ import { existsSync, readFileSync, realpathSync } from "node:fs";
12
12
  import valueParser from "postcss-value-parser";
13
13
  import { compile } from "stylis";
14
14
  import selectorParser from "postcss-selector-parser";
15
+ //#region src/internal/css-value-split.ts
16
+ function splitCssValueWhitespace(raw) {
17
+ return valueParser(raw).nodes.filter((node) => node.type !== "space").map((node) => valueParser.stringify(node)).filter((value) => value !== "");
18
+ }
19
+ //#endregion
20
+ //#region src/internal/css-border-radius.ts
21
+ function expandBorderRadiusInStyleObject(styleObj, expanded, options) {
22
+ const entries = Object.entries(styleObj);
23
+ const shorthandIndex = entries.findIndex(([key]) => key === "borderRadius");
24
+ if (shorthandIndex < 0) return styleObj;
25
+ const replacements = borderRadiusReplacementEntries(entries, shorthandIndex, expanded).filter(([prop]) => !options?.omitCorners?.has(prop));
26
+ const next = {};
27
+ for (const [key, value] of entries) {
28
+ if (key === "borderRadius") {
29
+ for (const [prop, replacement] of replacements) next[prop] = replacement;
30
+ continue;
31
+ }
32
+ if (isBorderRadiusLonghandProp(key)) continue;
33
+ next[key] = value;
34
+ }
35
+ return next;
36
+ }
37
+ function expandBorderRadiusShorthandValue(value, options) {
38
+ if (value.includes("/")) return null;
39
+ const parts = splitCssValueWhitespace(value.trim());
40
+ const minParts = options?.includeSingleValue === true ? 1 : 2;
41
+ if (parts.length < minParts || parts.length > 4) return null;
42
+ const topLeft = parts[0];
43
+ if (topLeft === void 0) return null;
44
+ const topRight = parts[1] ?? topLeft;
45
+ return {
46
+ topLeft,
47
+ topRight,
48
+ bottomRight: parts[2] ?? topLeft,
49
+ bottomLeft: parts[3] ?? topRight
50
+ };
51
+ }
52
+ const BORDER_RADIUS_LONGHAND_ENTRIES = [
53
+ ["borderTopLeftRadius", "topLeft"],
54
+ ["borderTopRightRadius", "topRight"],
55
+ ["borderBottomRightRadius", "bottomRight"],
56
+ ["borderBottomLeftRadius", "bottomLeft"]
57
+ ];
58
+ function borderRadiusReplacementEntries(entries, shorthandIndex, expanded) {
59
+ return BORDER_RADIUS_LONGHAND_ENTRIES.map(([prop, corner]) => [prop, latestBorderRadiusCornerValue(entries, shorthandIndex, prop, expanded[corner])]);
60
+ }
61
+ function latestBorderRadiusCornerValue(entries, shorthandIndex, prop, shorthandValue) {
62
+ let latest = {
63
+ index: shorthandIndex,
64
+ value: shorthandValue
65
+ };
66
+ for (let index = shorthandIndex + 1; index < entries.length; index++) {
67
+ const entry = entries[index];
68
+ if (!entry) continue;
69
+ const [key, value] = entry;
70
+ if (key === prop) latest = {
71
+ index,
72
+ value: mergeConditionMapDefault(value, latest.value)
73
+ };
74
+ }
75
+ return latest.value;
76
+ }
77
+ function isBorderRadiusLonghandProp(prop) {
78
+ return BORDER_RADIUS_LONGHAND_ENTRIES.some(([longhand]) => prop === longhand);
79
+ }
80
+ function mergeConditionMapDefault(value, defaultValue) {
81
+ if (!isConditionMap(value)) return value;
82
+ const merged = isConditionMap(defaultValue) ? {
83
+ ...defaultValue,
84
+ ...value
85
+ } : { ...value };
86
+ if (merged.default === null || merged.default === void 0) merged.default = conditionMapDefault(defaultValue);
87
+ return merged;
88
+ }
89
+ function conditionMapDefault(value) {
90
+ return isConditionMap(value) ? value.default : value;
91
+ }
92
+ function isConditionMap(value) {
93
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
94
+ const keys = Object.keys(value);
95
+ return keys.includes("default") || keys.some((key) => key.startsWith(":") || key.startsWith("@"));
96
+ }
97
+ //#endregion
15
98
  //#region src/internal/stylex-shorthands.ts
16
99
  /**
17
100
  * Utilities for expanding CSS shorthands to StyleX longhands.
@@ -268,24 +351,33 @@ const UNSUPPORTED_STYLEX_CSS_PROPS = new Set([
268
351
  "all",
269
352
  "scroll-margin-block",
270
353
  "scroll-margin-block-start",
271
- "scroll-margin-block-end",
272
- "scroll-margin-inline",
273
- "scroll-margin-inline-start",
274
- "scroll-margin-inline-end",
275
- "scroll-padding-block",
276
- "scroll-padding-block-start",
277
- "scroll-padding-block-end",
278
- "scroll-padding-inline",
279
- "scroll-padding-inline-start",
280
- "scroll-padding-inline-end"
354
+ "scroll-margin-block-end"
281
355
  ]);
282
356
  /**
357
+ * Logical scroll shorthands that expand to Start/End longhands. StyleX's
358
+ * valid-styles rule accepts only the longhand forms.
359
+ */
360
+ const LOGICAL_SCROLL_AXIS_SHORTHANDS = {
361
+ "scroll-margin-inline": "scrollMarginInline",
362
+ "scroll-padding-block": "scrollPaddingBlock",
363
+ "scroll-padding-inline": "scrollPaddingInline"
364
+ };
365
+ /**
283
366
  * Returns true if the CSS property is a shorthand that StyleX cannot express directly
284
367
  * and requires expansion (e.g., `padding`, `margin`, `border`, `background`).
285
368
  */
286
369
  function isCssShorthandProperty(cssProp) {
287
370
  return cssProp in DIRECTIONAL_SHORTHAND_MAP || cssProp === "border" || /^border-(top|right|bottom|left)$/.test(cssProp) || cssProp === "background";
288
371
  }
372
+ /**
373
+ * True for the logical scroll axis shorthands (`scroll-margin-inline`,
374
+ * `scroll-padding-block`, `scroll-padding-inline`). StyleX accepts only their
375
+ * Start/End longhands, so a static value is expanded; a dynamic value cannot be
376
+ * split losslessly and must bail.
377
+ */
378
+ function isLogicalScrollAxisShorthand(cssProp) {
379
+ return cssProp.trim() in LOGICAL_SCROLL_AXIS_SHORTHANDS;
380
+ }
289
381
  function isUnsupportedStylexProperty(cssProp) {
290
382
  return UNSUPPORTED_STYLEX_CSS_PROPS.has(cssProp.trim());
291
383
  }
@@ -311,6 +403,111 @@ function resolveBackgroundStylexPropForVariants(values) {
311
403
  if (hasGradient && hasColor) return null;
312
404
  return hasGradient ? "backgroundImage" : "backgroundColor";
313
405
  }
406
+ /**
407
+ * Expands a static multi-component `background` shorthand (single layer) into
408
+ * the full set of StyleX background longhands, e.g.
409
+ * `#fff url(a.svg) no-repeat center / cover`. Components omitted from the
410
+ * shorthand are emitted at their CSS initial value (e.g. `backgroundColor:
411
+ * transparent`), reproducing the shorthand's reset semantics so the expansion
412
+ * fully overrides any background longhand inherited from a merged/extended base.
413
+ *
414
+ * Returns null when the value cannot be expanded losslessly: multiple layers
415
+ * (top-level commas), unrecognized tokens, duplicate components, or fewer than
416
+ * two explicit components (single components keep the single-longhand path).
417
+ */
418
+ function expandBackgroundShorthandComponents(rawValue) {
419
+ const value = rawValue.trim();
420
+ if (!value || hasTopLevelMatch(value, /,/)) return null;
421
+ const tokens = tokenizeBackgroundValue(value);
422
+ if (!tokens) return null;
423
+ let color;
424
+ let image;
425
+ let attachment;
426
+ const repeatTokens = [];
427
+ const positionTokens = [];
428
+ const sizeTokens = [];
429
+ const boxTokens = [];
430
+ let inSizeMode = false;
431
+ for (const token of tokens) {
432
+ if (token === "/") {
433
+ if (inSizeMode || positionTokens.length === 0) return null;
434
+ inSizeMode = true;
435
+ continue;
436
+ }
437
+ if (inSizeMode) {
438
+ if (sizeTokens.length >= 2 || !isBackgroundSizeToken(token)) return null;
439
+ sizeTokens.push(token);
440
+ continue;
441
+ }
442
+ if (token === "none" || isBackgroundImageValue(token)) {
443
+ if (image !== void 0) return null;
444
+ image = token;
445
+ continue;
446
+ }
447
+ if (isCssColorToken(token)) {
448
+ if (color !== void 0) return null;
449
+ color = token;
450
+ continue;
451
+ }
452
+ if (BACKGROUND_REPEAT_KEYWORDS.has(token)) {
453
+ if (repeatTokens.length >= 2) return null;
454
+ repeatTokens.push(token);
455
+ continue;
456
+ }
457
+ if (BACKGROUND_ATTACHMENT_KEYWORDS.has(token)) {
458
+ if (attachment !== void 0) return null;
459
+ attachment = token;
460
+ continue;
461
+ }
462
+ if (BACKGROUND_BOX_KEYWORDS.has(token)) {
463
+ if (boxTokens.length >= 2) return null;
464
+ boxTokens.push(token);
465
+ continue;
466
+ }
467
+ if (isBackgroundPositionToken(token)) {
468
+ if (positionTokens.length >= 2) return null;
469
+ positionTokens.push(token);
470
+ continue;
471
+ }
472
+ return null;
473
+ }
474
+ if (inSizeMode && sizeTokens.length === 0) return null;
475
+ if ((color !== void 0 ? 1 : 0) + (image !== void 0 ? 1 : 0) + (attachment !== void 0 ? 1 : 0) + (repeatTokens.length ? 1 : 0) + (positionTokens.length ? 1 : 0) + (sizeTokens.length ? 1 : 0) + (boxTokens.length ? 1 : 0) < 2) return null;
476
+ return [
477
+ {
478
+ prop: "backgroundColor",
479
+ value: color ?? "transparent"
480
+ },
481
+ {
482
+ prop: "backgroundImage",
483
+ value: image ?? "none"
484
+ },
485
+ {
486
+ prop: "backgroundRepeat",
487
+ value: repeatTokens.length ? repeatTokens.join(" ") : "repeat"
488
+ },
489
+ {
490
+ prop: "backgroundAttachment",
491
+ value: attachment ?? "scroll"
492
+ },
493
+ {
494
+ prop: "backgroundPosition",
495
+ value: positionTokens.length ? positionTokens.join(" ") : "0% 0%"
496
+ },
497
+ {
498
+ prop: "backgroundSize",
499
+ value: sizeTokens.length ? sizeTokens.join(" ") : "auto"
500
+ },
501
+ {
502
+ prop: "backgroundOrigin",
503
+ value: boxTokens[0] ?? "padding-box"
504
+ },
505
+ {
506
+ prop: "backgroundClip",
507
+ value: boxTokens[1] ?? boxTokens[0] ?? "border-box"
508
+ }
509
+ ];
510
+ }
314
511
  function parseInterpolatedBorderStaticParts(args) {
315
512
  const { prop, prefix, suffix } = args;
316
513
  const borderMatch = prop.match(/^border(-top|-right|-bottom|-left)?$/);
@@ -381,6 +578,28 @@ function cssDeclarationToStylexDeclarations(decl) {
381
578
  }
382
579
  }));
383
580
  }
581
+ const logicalScrollAxis = LOGICAL_SCROLL_AXIS_SHORTHANDS[prop];
582
+ if (logicalScrollAxis && decl.value.kind === "static") {
583
+ const values = splitCssValueWhitespace(decl.valueRaw.trim());
584
+ if (values.length >= 1 && values.length <= 2) {
585
+ const start = values[0];
586
+ const end = values[1] ?? start;
587
+ const withImportant = (value) => decl.important ? `${value} !important` : value;
588
+ return [{
589
+ prop: `${logicalScrollAxis}Start`,
590
+ value: {
591
+ kind: "static",
592
+ value: withImportant(start)
593
+ }
594
+ }, {
595
+ prop: `${logicalScrollAxis}End`,
596
+ value: {
597
+ kind: "static",
598
+ value: withImportant(end)
599
+ }
600
+ }];
601
+ }
602
+ }
384
603
  if (prop === "background") {
385
604
  const rawVal = (decl.valueRaw ?? "").trim();
386
605
  if (rawVal === "none") return [{
@@ -399,6 +618,22 @@ function cssDeclarationToStylexDeclarations(decl) {
399
618
  }];
400
619
  }
401
620
  if (prop === "display" && decl.value.kind === "static" && decl.valueRaw.trim() === "wrap") return [];
621
+ if (prop === "overflow" && decl.value.kind === "static") {
622
+ const tokens = decl.valueRaw.trim().split(/\s+/);
623
+ if (tokens.length === 2) return [{
624
+ prop: "overflowX",
625
+ value: {
626
+ kind: "static",
627
+ value: tokens[0]
628
+ }
629
+ }, {
630
+ prop: "overflowY",
631
+ value: {
632
+ kind: "static",
633
+ value: tokens[1]
634
+ }
635
+ }];
636
+ }
402
637
  if (prop === "animation" && decl.value.kind === "static" && decl.valueRaw.trim() === "none") return [{
403
638
  prop: "animationName",
404
639
  value: decl.value
@@ -408,6 +643,16 @@ function cssDeclarationToStylexDeclarations(decl) {
408
643
  if (decl.value.kind === "interpolated") return expandInterpolatedBorder(prop, "", decl.value);
409
644
  return borderShorthandToStylex(raw, "");
410
645
  }
646
+ if (prop === "border-radius" && decl.value.kind === "static") {
647
+ const expanded = borderRadiusShorthandToStylex(decl.valueRaw.trim());
648
+ if (expanded.length > 0) return expanded.map(({ prop, value }) => ({
649
+ prop,
650
+ value: {
651
+ kind: "static",
652
+ value
653
+ }
654
+ }));
655
+ }
411
656
  const borderDirectionMatch = prop.match(/^border-(top|right|bottom|left)$/);
412
657
  if (borderDirectionMatch) {
413
658
  const direction = borderDirectionMatch[1];
@@ -444,6 +689,28 @@ function normalizeGridLineSlashSpacing(stylexProp, value) {
444
689
  value: normalizeUnescapedSlashSpacing(value.value)
445
690
  };
446
691
  }
692
+ function borderRadiusShorthandToStylex(raw) {
693
+ const expanded = expandBorderRadiusShorthandValue(raw);
694
+ if (!expanded) return [];
695
+ return [
696
+ {
697
+ prop: "borderTopLeftRadius",
698
+ value: expanded.topLeft
699
+ },
700
+ {
701
+ prop: "borderTopRightRadius",
702
+ value: expanded.topRight
703
+ },
704
+ {
705
+ prop: "borderBottomRightRadius",
706
+ value: expanded.bottomRight
707
+ },
708
+ {
709
+ prop: "borderBottomLeftRadius",
710
+ value: expanded.bottomLeft
711
+ }
712
+ ];
713
+ }
447
714
  function normalizeUnescapedSlashSpacing(value) {
448
715
  let output = "";
449
716
  for (let index = 0; index < value.length; index++) {
@@ -614,6 +881,87 @@ function classifyBorderTokens(tokens) {
614
881
  color
615
882
  };
616
883
  }
884
+ const BACKGROUND_REPEAT_KEYWORDS = new Set([
885
+ "repeat",
886
+ "repeat-x",
887
+ "repeat-y",
888
+ "no-repeat",
889
+ "space",
890
+ "round"
891
+ ]);
892
+ const BACKGROUND_ATTACHMENT_KEYWORDS = new Set([
893
+ "scroll",
894
+ "fixed",
895
+ "local"
896
+ ]);
897
+ const BACKGROUND_BOX_KEYWORDS = new Set([
898
+ "border-box",
899
+ "padding-box",
900
+ "content-box"
901
+ ]);
902
+ const BACKGROUND_POSITION_KEYWORDS = new Set([
903
+ "left",
904
+ "right",
905
+ "top",
906
+ "bottom",
907
+ "center"
908
+ ]);
909
+ const CSS_COLOR_FUNCTION_RE = /^(?:rgb|rgba|hsl|hsla|hwb|lab|lch|oklab|oklch|color)\(/i;
910
+ const CSS_NAMED_COLORS = new Set("aliceblue antiquewhite aqua aquamarine azure beige bisque black blanchedalmond blue blueviolet brown burlywood cadetblue chartreuse chocolate coral cornflowerblue cornsilk crimson cyan darkblue darkcyan darkgoldenrod darkgray darkgreen darkgrey darkkhaki darkmagenta darkolivegreen darkorange darkorchid darkred darksalmon darkseagreen darkslateblue darkslategray darkslategrey darkturquoise darkviolet deeppink deepskyblue dimgray dimgrey dodgerblue firebrick floralwhite forestgreen fuchsia gainsboro ghostwhite gold goldenrod gray green greenyellow grey honeydew hotpink indianred indigo ivory khaki lavender lavenderblush lawngreen lemonchiffon lightblue lightcoral lightcyan lightgoldenrodyellow lightgray lightgreen lightgrey lightpink lightsalmon lightseagreen lightskyblue lightslategray lightslategrey lightsteelblue lightyellow lime limegreen linen magenta maroon mediumaquamarine mediumblue mediumorchid mediumpurple mediumseagreen mediumslateblue mediumspringgreen mediumturquoise mediumvioletred midnightblue mintcream mistyrose moccasin navajowhite navy oldlace olive olivedrab orange orangered orchid palegoldenrod palegreen paleturquoise palevioletred papayawhip peachpuff peru pink plum powderblue purple rebeccapurple red rosybrown royalblue saddlebrown salmon sandybrown seagreen seashell sienna silver skyblue slateblue slategray slategrey snow springgreen steelblue tan teal thistle tomato turquoise violet wheat white whitesmoke yellow yellowgreen transparent currentcolor".split(" "));
911
+ function isCssColorToken(token) {
912
+ if (token.startsWith("#")) return /^#(?:[0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(token);
913
+ if (CSS_COLOR_FUNCTION_RE.test(token)) return true;
914
+ return CSS_NAMED_COLORS.has(token.toLowerCase());
915
+ }
916
+ function isBackgroundPositionToken(token) {
917
+ return BACKGROUND_POSITION_KEYWORDS.has(token.toLowerCase()) || /^-?\d*\.?\d+(?:[a-z%]*)$/i.test(token) || /^calc\(/i.test(token);
918
+ }
919
+ function isBackgroundSizeToken(token) {
920
+ const lower = token.toLowerCase();
921
+ return lower === "cover" || lower === "contain" || lower === "auto" || /^-?\d*\.?\d+(?:[a-z%]*)$/i.test(token) || /^calc\(/i.test(token);
922
+ }
923
+ /**
924
+ * Splits a background shorthand value into top-level tokens, keeping function
925
+ * calls intact and emitting `/` (position/size separator) as its own token.
926
+ * Returns null for values containing placeholders or unbalanced parens.
927
+ */
928
+ function tokenizeBackgroundValue(value) {
929
+ if (value.includes("__SC_EXPR_")) return null;
930
+ const tokens = [];
931
+ let current = "";
932
+ let depth = 0;
933
+ const flush = () => {
934
+ if (current) {
935
+ tokens.push(current);
936
+ current = "";
937
+ }
938
+ };
939
+ for (const c of value) {
940
+ if (c === "(") {
941
+ depth++;
942
+ current += c;
943
+ continue;
944
+ }
945
+ if (c === ")") {
946
+ depth = Math.max(0, depth - 1);
947
+ current += c;
948
+ continue;
949
+ }
950
+ if (depth === 0 && /\s/.test(c)) {
951
+ flush();
952
+ continue;
953
+ }
954
+ if (depth === 0 && c === "/") {
955
+ flush();
956
+ tokens.push("/");
957
+ continue;
958
+ }
959
+ current += c;
960
+ }
961
+ if (depth !== 0) return null;
962
+ flush();
963
+ return tokens.length ? tokens : null;
964
+ }
617
965
  //#endregion
618
966
  //#region src/internal/transform-parse-expr.ts
619
967
  function parseExpr(api, exprSource) {
@@ -1626,6 +1974,11 @@ function toSuffixFromProp(propName) {
1626
1974
  return suffixes.join("");
1627
1975
  }
1628
1976
  }
1977
+ const defaultTruthyMatch = trimmed.match(/^(.+?) === undefined \|\| (.+)$/);
1978
+ if (defaultTruthyMatch) {
1979
+ const lhs = defaultTruthyMatch[1].replace(/^\$/, "");
1980
+ if (lhs === defaultTruthyMatch[2].replace(/^\$/, "")) return toSuffixFromProp(lhs);
1981
+ }
1629
1982
  if (trimmed.includes(" || ")) {
1630
1983
  const parts = trimmed.split(" || ").map((s) => s.trim()).filter(Boolean);
1631
1984
  if (parts.length) {
@@ -3383,7 +3736,7 @@ function specifierExportedName(spec) {
3383
3736
  * - Disjunction: `"a || b"` → `a || b`
3384
3737
  * - Grouped negation: `"!(a || b)"` → `!(a || b)`
3385
3738
  */
3386
- function parseVariantWhenToAst(j, when, booleanProps, knownProps) {
3739
+ function parseVariantWhenToAst(j, when, booleanProps, knownProps, nonPropRoots) {
3387
3740
  const buildMemberExpr = (raw) => {
3388
3741
  if (!raw.includes(".")) return null;
3389
3742
  const parts = raw.split(".").map((part) => part.trim()).filter(Boolean);
@@ -3418,7 +3771,7 @@ function parseVariantWhenToAst(j, when, booleanProps, knownProps) {
3418
3771
  }
3419
3772
  const memberExpr = buildMemberExpr(trimmedRaw);
3420
3773
  if (memberExpr) return {
3421
- propName: root && root !== "theme" && isConditionPropIdentifier(root) ? root : null,
3774
+ propName: root && root !== "theme" && !nonPropRoots?.has(root) && isConditionPropIdentifier(root) ? root : null,
3422
3775
  expr: memberExpr
3423
3776
  };
3424
3777
  return {
@@ -3427,7 +3780,7 @@ function parseVariantWhenToAst(j, when, booleanProps, knownProps) {
3427
3780
  };
3428
3781
  }
3429
3782
  return {
3430
- propName: trimmedRaw === "theme" || !isConditionPropIdentifier(trimmedRaw) ? null : trimmedRaw,
3783
+ propName: trimmedRaw === "theme" || nonPropRoots?.has(trimmedRaw) || !isConditionPropIdentifier(trimmedRaw) ? null : trimmedRaw,
3431
3784
  expr: j.identifier(trimmedRaw)
3432
3785
  };
3433
3786
  };
@@ -3438,7 +3791,7 @@ function parseVariantWhenToAst(j, when, booleanProps, knownProps) {
3438
3791
  isBoolean: true
3439
3792
  };
3440
3793
  if (trimmed.startsWith("!(") && trimmed.endsWith(")")) {
3441
- const innerParsed = parseVariantWhenToAst(j, trimmed.slice(2, -1).trim(), booleanProps, knownProps);
3794
+ const innerParsed = parseVariantWhenToAst(j, trimmed.slice(2, -1).trim(), booleanProps, knownProps, nonPropRoots);
3442
3795
  return {
3443
3796
  cond: j.unaryExpression("!", innerParsed.cond),
3444
3797
  props: innerParsed.props,
@@ -3446,7 +3799,7 @@ function parseVariantWhenToAst(j, when, booleanProps, knownProps) {
3446
3799
  };
3447
3800
  }
3448
3801
  if (trimmed.includes("&&")) {
3449
- const parsed = trimmed.split("&&").map((s) => s.trim()).filter(Boolean).map((p) => parseVariantWhenToAst(j, p, booleanProps, knownProps));
3802
+ const parsed = trimmed.split("&&").map((s) => s.trim()).filter(Boolean).map((p) => parseVariantWhenToAst(j, p, booleanProps, knownProps, nonPropRoots));
3450
3803
  const firstParsed = parsed[0];
3451
3804
  if (!firstParsed) return {
3452
3805
  cond: j.identifier("true"),
@@ -3460,7 +3813,7 @@ function parseVariantWhenToAst(j, when, booleanProps, knownProps) {
3460
3813
  };
3461
3814
  }
3462
3815
  if (trimmed.includes(" || ")) {
3463
- const parsed = trimmed.split(" || ").map((s) => s.trim()).filter(Boolean).map((p) => parseVariantWhenToAst(j, p, booleanProps, knownProps));
3816
+ const parsed = trimmed.split(" || ").map((s) => s.trim()).filter(Boolean).map((p) => parseVariantWhenToAst(j, p, booleanProps, knownProps, nonPropRoots));
3464
3817
  const firstParsedOr = parsed[0];
3465
3818
  if (!firstParsedOr) return {
3466
3819
  cond: j.identifier("true"),
@@ -3474,7 +3827,7 @@ function parseVariantWhenToAst(j, when, booleanProps, knownProps) {
3474
3827
  };
3475
3828
  }
3476
3829
  if (trimmed.startsWith("!")) {
3477
- const innerParsed = parseVariantWhenToAst(j, trimmed.slice(1).trim(), booleanProps, knownProps);
3830
+ const innerParsed = parseVariantWhenToAst(j, trimmed.slice(1).trim(), booleanProps, knownProps, nonPropRoots);
3478
3831
  return {
3479
3832
  cond: j.unaryExpression("!", innerParsed.cond),
3480
3833
  props: innerParsed.props,
@@ -3603,8 +3956,8 @@ function isConditionPropIdentifier(name, knownProps) {
3603
3956
  * function's parameter destructuring.
3604
3957
  */
3605
3958
  function collectConditionProps(j, args) {
3606
- const { when, destructureProps, booleanProps, knownProps } = args;
3607
- const parsed = parseVariantWhenToAst(j, when, booleanProps, knownProps);
3959
+ const { when, destructureProps, booleanProps, knownProps, nonPropRoots } = args;
3960
+ const parsed = parseVariantWhenToAst(j, when, booleanProps, knownProps, nonPropRoots);
3608
3961
  if (destructureProps) {
3609
3962
  for (const p of parsed.props) if (p && !destructureProps.includes(p)) destructureProps.push(p);
3610
3963
  }
@@ -4512,6 +4865,19 @@ function getPropertyNameFromKey(key) {
4512
4865
  * Core concepts: deep merge semantics, AST node detection, and media query resolution.
4513
4866
  */
4514
4867
  /**
4868
+ * Marks an emitted AST value node as proven to be a single CSS token (e.g. a
4869
+ * numeric stylex const that had a unit suffix). Shorthand properties holding
4870
+ * such values cannot expand to multiple tokens, so the opaque-shorthand
4871
+ * warning does not apply to them.
4872
+ */
4873
+ function markProvenSingleTokenValue(node) {
4874
+ if (node && typeof node === "object") provenSingleTokenValues.add(node);
4875
+ }
4876
+ function isProvenSingleTokenValue(node) {
4877
+ return !!node && typeof node === "object" && provenSingleTokenValues.has(node);
4878
+ }
4879
+ const provenSingleTokenValues = /* @__PURE__ */ new WeakSet();
4880
+ /**
4515
4881
  * Tries to resolve a CallExpression via the adapter's `resolveCall`.
4516
4882
  * Shared by both css-helper and process-rules slot resolution.
4517
4883
  *
@@ -5137,6 +5503,335 @@ function buildChildStyleObjectList(childKeys, resolvedStyleObjects) {
5137
5503
  return childStyleObjects;
5138
5504
  }
5139
5505
  //#endregion
5506
+ //#region src/internal/lower-rules/style-object-normalization.ts
5507
+ function expandStyleObjectShorthands(styleObj) {
5508
+ const borderRadius = staticStringValue(styleObj.borderRadius);
5509
+ if (borderRadius === null) return styleObj;
5510
+ const expanded = expandBorderRadiusShorthandValue(borderRadius);
5511
+ if (!expanded) return styleObj;
5512
+ return expandBorderRadiusInStyleObject(styleObj, expanded);
5513
+ }
5514
+ /**
5515
+ * Resolves a style value to a static string when possible: plain strings,
5516
+ * string-literal AST nodes, and expression-free template literals.
5517
+ */
5518
+ function staticStringValue(value) {
5519
+ if (typeof value === "string") return value;
5520
+ if (!value || typeof value !== "object") return null;
5521
+ const node = value;
5522
+ if ((node.type === "Literal" || node.type === "StringLiteral") && typeof node.value === "string") return node.value;
5523
+ if (node.type === "TemplateLiteral" && node.expressions?.length === 0) {
5524
+ const quasi = node.quasis?.[0];
5525
+ return quasi?.value?.cooked ?? quasi?.value?.raw ?? null;
5526
+ }
5527
+ return null;
5528
+ }
5529
+ //#endregion
5530
+ //#region src/internal/lower-rules/variant-utils.ts
5531
+ /**
5532
+ * Inverts a "when" condition string for the opposite variant branch.
5533
+ * E.g., "!$active" -> "$active", "$x === true" -> "$x !== true"
5534
+ */
5535
+ function invertWhen(when) {
5536
+ if (when.startsWith("!(") && when.endsWith(")")) return when.slice(2, -1);
5537
+ if (when.startsWith("!")) return when.slice(1);
5538
+ if (when.includes(" || ") || when.includes(" && ")) {
5539
+ if (when.includes(" || ") && when.includes(" && ")) return null;
5540
+ return `!(${when})`;
5541
+ }
5542
+ const match = when.match(/^(.+)\s+(===|!==)\s+(.+)$/);
5543
+ if (match) {
5544
+ const [, propName, op, rhs] = match;
5545
+ return `${propName} ${op === "===" ? "!==" : "==="} ${rhs}`;
5546
+ }
5547
+ if (!when.includes(" ")) return `!${when}`;
5548
+ return null;
5549
+ }
5550
+ function buildPseudoMediaPropValue(args) {
5551
+ const { j, valueExpr, pseudos, media } = args;
5552
+ const pseudoList = pseudos ?? [];
5553
+ const hasPseudos = pseudoList.length > 0;
5554
+ if (!media && !hasPseudos) return valueExpr;
5555
+ if (media && hasPseudos) {
5556
+ const pseudoProps = pseudoList.map((ps) => j.property("init", j.literal(ps), j.objectExpression([j.property("init", j.identifier("default"), j.literal(null)), j.property("init", j.literal(media), valueExpr)])));
5557
+ return j.objectExpression([j.property("init", j.identifier("default"), j.literal(null)), ...pseudoProps]);
5558
+ }
5559
+ if (media) return j.objectExpression([j.property("init", j.identifier("default"), j.literal(null)), j.property("init", j.literal(media), valueExpr)]);
5560
+ const pseudoProps = pseudoList.map((ps) => j.property("init", j.literal(ps), valueExpr));
5561
+ return j.objectExpression([j.property("init", j.identifier("default"), j.literal(null)), ...pseudoProps]);
5562
+ }
5563
+ const createPropTestHelpers = (bindings) => {
5564
+ const paramName = bindings.kind === "simple" ? bindings.paramName : null;
5565
+ const getMemberExpressionSource = (node) => {
5566
+ const info = extractRootAndPath(node);
5567
+ if (!info) return null;
5568
+ if (info.path.length === 0) return info.rootName;
5569
+ return `${info.rootName}.${info.path.join(".")}`;
5570
+ };
5571
+ const readPropAccess = (node) => {
5572
+ const info = extractRootAndPath(node);
5573
+ if (!info) return null;
5574
+ if (paramName && info.rootName === paramName) {
5575
+ if (info.path.length === 0) return null;
5576
+ const [propRoot, ...rest] = info.path;
5577
+ if (!propRoot) return null;
5578
+ if (propRoot === "theme") return null;
5579
+ return {
5580
+ propName: propRoot,
5581
+ whenName: [propRoot, ...rest].join(".")
5582
+ };
5583
+ }
5584
+ if (bindings.kind === "destructured") {
5585
+ const propName = resolveIdentifierToPropName(info.rootNode, bindings);
5586
+ if (!propName) return null;
5587
+ return {
5588
+ propName,
5589
+ whenName: info.path.length > 0 ? `${propName}.${info.path.join(".")}` : propName
5590
+ };
5591
+ }
5592
+ return null;
5593
+ };
5594
+ const applyDefaultToTruthyWhen = (whenName, propName) => {
5595
+ if (bindings.kind !== "destructured" || !bindings.defaults?.has(propName)) return whenName;
5596
+ if (whenName !== propName) return null;
5597
+ const defaultValue = literalToStaticValue(bindings.defaults.get(propName));
5598
+ if (defaultValue === null) return null;
5599
+ return defaultValue ? `${whenName} === undefined || ${whenName}` : whenName;
5600
+ };
5601
+ const parseTestInfo = (test) => {
5602
+ if (!test || typeof test !== "object") return null;
5603
+ if (test.type === "Identifier" && bindings.kind === "destructured") {
5604
+ const propAccess = readPropAccess(test);
5605
+ if (!propAccess) return null;
5606
+ const when = applyDefaultToTruthyWhen(propAccess.whenName, propAccess.propName);
5607
+ return when === null ? null : {
5608
+ when,
5609
+ propName: propAccess.propName
5610
+ };
5611
+ }
5612
+ if (isMemberExpression(test)) {
5613
+ const propAccess = readPropAccess(test);
5614
+ if (!propAccess) return null;
5615
+ const when = applyDefaultToTruthyWhen(propAccess.whenName, propAccess.propName);
5616
+ return when === null ? null : {
5617
+ when,
5618
+ propName: propAccess.propName
5619
+ };
5620
+ }
5621
+ if (test.type === "UnaryExpression" && test.operator === "!" && test.argument) {
5622
+ const propAccess = readPropAccess(test.argument);
5623
+ if (!propAccess) return null;
5624
+ const truthyWhen = applyDefaultToTruthyWhen(propAccess.whenName, propAccess.propName);
5625
+ if (truthyWhen === null) return null;
5626
+ return {
5627
+ when: truthyWhen === propAccess.whenName ? `!${truthyWhen}` : `!(${truthyWhen})`,
5628
+ propName: propAccess.propName
5629
+ };
5630
+ }
5631
+ if (test.type === "BinaryExpression" && (test.operator === "===" || test.operator === "!==")) {
5632
+ const left = test.left;
5633
+ const operator = test.operator;
5634
+ const getRhsValue = () => {
5635
+ const rhsTyped = test.right;
5636
+ if (rhsTyped.type === "Identifier" && rhsTyped.name === "undefined") return "undefined";
5637
+ const rhs = literalToStaticValue(test.right);
5638
+ if (rhs === null) return getMemberExpressionSource(test.right);
5639
+ return JSON.stringify(rhs);
5640
+ };
5641
+ const buildBinaryWhen = (propAccess, rhsValue) => {
5642
+ const base = `${propAccess.whenName} ${operator} ${rhsValue}`;
5643
+ if (bindings.kind !== "destructured" || !bindings.defaults?.has(propAccess.propName)) return base;
5644
+ if (propAccess.whenName !== propAccess.propName || rhsValue === "undefined") return null;
5645
+ const defaultValue = literalToStaticValue(bindings.defaults.get(propAccess.propName));
5646
+ if (defaultValue === null) return null;
5647
+ let rhsStatic;
5648
+ try {
5649
+ rhsStatic = JSON.parse(rhsValue);
5650
+ } catch {
5651
+ return null;
5652
+ }
5653
+ if (defaultValue !== rhsStatic) return base;
5654
+ return operator === "===" ? `${propAccess.whenName} === undefined || ${base}` : `${propAccess.whenName} !== undefined && ${base}`;
5655
+ };
5656
+ if (bindings.kind === "destructured" && left.type === "Identifier") {
5657
+ const propAccess = readPropAccess(left);
5658
+ const rhsValue = getRhsValue();
5659
+ if (!propAccess || rhsValue === null) return null;
5660
+ const when = buildBinaryWhen(propAccess, rhsValue);
5661
+ return when === null ? null : {
5662
+ when,
5663
+ propName: propAccess.propName
5664
+ };
5665
+ }
5666
+ if (isMemberExpression(left)) {
5667
+ const propAccess = readPropAccess(left);
5668
+ const rhsValue = getRhsValue();
5669
+ if (!propAccess || rhsValue === null) return null;
5670
+ const when = buildBinaryWhen(propAccess, rhsValue);
5671
+ return when === null ? null : {
5672
+ when,
5673
+ propName: propAccess.propName
5674
+ };
5675
+ }
5676
+ }
5677
+ return null;
5678
+ };
5679
+ /**
5680
+ * Parse chained && / || conditions, returning a combined TestInfo.
5681
+ *
5682
+ * Supported patterns:
5683
+ * props.a && props.b → { when: 'a && b' }
5684
+ * props.$a || props.$b → { when: '$a || $b' }
5685
+ * props.$a && (props.$b || $c) → { when: '$a && $b || $c' }
5686
+ * !(props.$a || props.$b) → { when: '!($a || $b)' }
5687
+ *
5688
+ * Bails (returns null) on || wrapping && children to avoid ambiguous
5689
+ * serialization: "a && b || c" would be reparsed as "a && (b || c)"
5690
+ * by parseVariantWhenToAst, which splits on && first.
5691
+ */
5692
+ const parseChainedTestInfo = (test) => {
5693
+ const simple = parseTestInfo(test);
5694
+ if (simple) return simple;
5695
+ if (!test || typeof test !== "object") return null;
5696
+ if (test.type === "UnaryExpression" && test.operator === "!" && test.argument) {
5697
+ const innerInfo = parseChainedTestInfo(test.argument);
5698
+ if (innerInfo) {
5699
+ const allProps = innerInfo.allPropNames ?? (innerInfo.propName ? [innerInfo.propName] : []);
5700
+ return {
5701
+ when: `!(${innerInfo.when})`,
5702
+ propName: innerInfo.propName,
5703
+ allPropNames: allProps
5704
+ };
5705
+ }
5706
+ }
5707
+ if (test.type === "LogicalExpression" && (test.operator === "&&" || test.operator === "||")) {
5708
+ const leftInfo = parseChainedTestInfo(test.left);
5709
+ const rightInfo = parseChainedTestInfo(test.right);
5710
+ if (leftInfo && rightInfo) {
5711
+ if (test.operator === "||" && (leftInfo.when.includes(" && ") || rightInfo.when.includes(" && "))) return null;
5712
+ if (hasOperatorInsideParens(leftInfo.when, test.operator) || hasOperatorInsideParens(rightInfo.when, test.operator)) return null;
5713
+ const combinedWhen = `${leftInfo.when} ${test.operator} ${rightInfo.when}`;
5714
+ const leftProps = leftInfo.allPropNames ?? (leftInfo.propName ? [leftInfo.propName] : []);
5715
+ const rightProps = rightInfo.allPropNames ?? (rightInfo.propName ? [rightInfo.propName] : []);
5716
+ const allPropNames = [...new Set([...leftProps, ...rightProps])];
5717
+ return {
5718
+ when: combinedWhen,
5719
+ propName: rightInfo.propName,
5720
+ allPropNames
5721
+ };
5722
+ }
5723
+ }
5724
+ return null;
5725
+ };
5726
+ return {
5727
+ parseTestInfo,
5728
+ parseChainedTestInfo
5729
+ };
5730
+ };
5731
+ /**
5732
+ * Per-decl snapshot of the base style object's entries at the moment each
5733
+ * variant (`when`) first received styles. Captures the source position of
5734
+ * conditional blocks relative to base declarations: keys missing from a
5735
+ * variant's snapshot — or whose value changed since — were (re)declared after
5736
+ * that variant in the original CSS.
5737
+ */
5738
+ const variantBaseKeySnapshots = /* @__PURE__ */ new WeakMap();
5739
+ const variantSourceOrders = /* @__PURE__ */ new WeakMap();
5740
+ function getVariantBaseKeySnapshot(decl, when) {
5741
+ return variantBaseKeySnapshots.get(decl)?.get(when);
5742
+ }
5743
+ function getVariantSourceOrder(decl, when) {
5744
+ return variantSourceOrders.get(decl)?.get(when);
5745
+ }
5746
+ function renameVariantSourceOrderConditions(decl, renameWhen) {
5747
+ const sourceOrders = variantSourceOrders.get(decl);
5748
+ if (!sourceOrders) return;
5749
+ const renamed = /* @__PURE__ */ new Map();
5750
+ for (const [when, sourceOrder] of sourceOrders) {
5751
+ const renamedWhen = renameWhen(when);
5752
+ if (!renamed.has(renamedWhen)) renamed.set(renamedWhen, sourceOrder);
5753
+ }
5754
+ variantSourceOrders.set(decl, renamed);
5755
+ }
5756
+ const createVariantApplier = (args) => {
5757
+ const { decl, variantBuckets, variantStyleKeys, baseStyleObj, conditionStyleObjs, getCurrentSourceOrder } = args;
5758
+ const dropAllTestInfoProps = (testInfo) => {
5759
+ const propsToCheck = testInfo.allPropNames ?? (testInfo.propName ? [testInfo.propName] : []);
5760
+ for (const prop of propsToCheck) if (prop && !prop.startsWith("$")) ensureShouldForwardPropDrop(decl, prop);
5761
+ };
5762
+ return (testInfo, consStyle) => {
5763
+ const when = testInfo.when;
5764
+ if (baseStyleObj) {
5765
+ const snapshots = variantBaseKeySnapshots.get(decl) ?? /* @__PURE__ */ new Map();
5766
+ if (!snapshots.has(when)) {
5767
+ snapshots.set(when, createBaseKeySnapshot(baseStyleObj, conditionStyleObjs));
5768
+ variantBaseKeySnapshots.set(decl, snapshots);
5769
+ const sourceOrder = getCurrentSourceOrder?.();
5770
+ if (sourceOrder !== void 0) {
5771
+ const sourceOrders = variantSourceOrders.get(decl) ?? /* @__PURE__ */ new Map();
5772
+ sourceOrders.set(when, sourceOrder);
5773
+ variantSourceOrders.set(decl, sourceOrders);
5774
+ }
5775
+ }
5776
+ }
5777
+ const existingBucket = variantBuckets.get(when);
5778
+ const nextBucket = existingBucket ? { ...existingBucket } : {};
5779
+ mergeStyleObjects(nextBucket, expandStyleObjectShorthands(consStyle));
5780
+ variantBuckets.set(when, nextBucket);
5781
+ variantStyleKeys[when] ??= styleKeyWithSuffix(decl.styleKey, when);
5782
+ dropAllTestInfoProps(testInfo);
5783
+ };
5784
+ };
5785
+ function createBaseKeySnapshot(baseStyleObj, conditionStyleObjs) {
5786
+ const snapshot = new Map(Object.entries(baseStyleObj).map(([key, value]) => [key, cloneSnapshotValue(value)]));
5787
+ for (const conditionStyleObj of conditionStyleObjs ?? []) for (const [key, value] of Object.entries(conditionStyleObj)) mergeSnapshotConditionMap(snapshot, key, value);
5788
+ return snapshot;
5789
+ }
5790
+ function mergeSnapshotConditionMap(snapshot, key, value) {
5791
+ const existing = snapshot.get(key);
5792
+ const next = cloneSnapshotValue(value);
5793
+ if (!isSnapshotPlainMap(next)) {
5794
+ snapshot.set(key, next);
5795
+ return;
5796
+ }
5797
+ if (isSnapshotPlainMap(existing)) {
5798
+ mergeStyleObjects(existing, next);
5799
+ return;
5800
+ }
5801
+ if (existing !== void 0 && (next.default === null || next.default === void 0)) next.default = cloneSnapshotValue(existing);
5802
+ snapshot.set(key, next);
5803
+ }
5804
+ /**
5805
+ * Clones plain condition-map values for snapshots so later in-place merges
5806
+ * into the base style object cannot retroactively alter what the snapshot
5807
+ * recorded. AST nodes are kept by reference — redeclarations replace them.
5808
+ */
5809
+ function cloneSnapshotValue(value) {
5810
+ if (!isSnapshotPlainMap(value)) return value;
5811
+ const cloned = {};
5812
+ for (const [key, entryValue] of Object.entries(value)) cloned[key] = cloneSnapshotValue(entryValue);
5813
+ return cloned;
5814
+ }
5815
+ function isSnapshotPlainMap(value) {
5816
+ return !!value && typeof value === "object" && !Array.isArray(value) && typeof value.type !== "string";
5817
+ }
5818
+ /**
5819
+ * Returns true if the string contains the given operator (`&&` or `||`)
5820
+ * inside parenthesized groups. Used to detect when strings like
5821
+ * `"!($b && $c)"` or `"!($b || $c)"` that would be broken by the naive
5822
+ * split in `parseVariantWhenToAst`.
5823
+ */
5824
+ function hasOperatorInsideParens(when, operator) {
5825
+ let depth = 0;
5826
+ for (let i = 0; i < when.length; i++) {
5827
+ const ch = when[i];
5828
+ if (ch === "(") depth++;
5829
+ else if (ch === ")") depth--;
5830
+ else if (depth > 0 && when[i] === operator[0] && when.startsWith(operator, i)) return true;
5831
+ }
5832
+ return false;
5833
+ }
5834
+ //#endregion
5140
5835
  //#region src/internal/utilities/style-composition-plan.ts
5141
5836
  function buildStyleKeySequence(ctx, decl, options) {
5142
5837
  const entries = [];
@@ -5280,7 +5975,8 @@ function buildVariantAndStyleFnEntries(decl) {
5280
5975
  styleKey,
5281
5976
  patchable: true,
5282
5977
  contributes: false,
5283
- source: "variant"
5978
+ source: "variant",
5979
+ sourceOrder: getVariantSourceOrder(decl, when)
5284
5980
  }
5285
5981
  }));
5286
5982
  const styleFnEntries = (decl.styleFnFromProps ?? []).map((styleFn) => ({
@@ -5332,12 +6028,14 @@ function buildVariantDimensionEntries(decl) {
5332
6028
  styleObj,
5333
6029
  patchable: true,
5334
6030
  contributes: false,
5335
- source: "variant"
6031
+ source: "variant",
6032
+ sourceOrder: dimension.sourceOrder
5336
6033
  }));
5337
6034
  if (dimension.fallbackFnKey) entries.push({
5338
6035
  styleKey: dimension.fallbackFnKey,
5339
6036
  patchable: true,
5340
- source: "styleFn"
6037
+ source: "styleFn",
6038
+ sourceOrder: dimension.sourceOrder
5341
6039
  });
5342
6040
  if (dimension.sourceOrder === void 0) {
5343
6041
  immediate.push(...entries);
@@ -5462,6 +6160,29 @@ function buildEnumVariantEntries(decl) {
5462
6160
  }))];
5463
6161
  }
5464
6162
  //#endregion
6163
+ //#region src/internal/lower-rules/condition-source-order.ts
6164
+ /**
6165
+ * Source-order metadata for pseudo/media condition maps.
6166
+ * Core concepts: non-emitted metadata and CSS cascade comparisons.
6167
+ */
6168
+ const conditionSourceOrders = /* @__PURE__ */ new WeakMap();
6169
+ function setConditionSourceOrder(map, condition, sourceOrder) {
6170
+ if (sourceOrder === void 0) return;
6171
+ const orders = conditionSourceOrders.get(map) ?? /* @__PURE__ */ new Map();
6172
+ orders.set(condition, sourceOrder);
6173
+ conditionSourceOrders.set(map, orders);
6174
+ }
6175
+ function getConditionSourceOrder(map, condition) {
6176
+ return conditionSourceOrders.get(map)?.get(condition);
6177
+ }
6178
+ function copyConditionSourceOrders(target, source) {
6179
+ const sourceOrders = conditionSourceOrders.get(source);
6180
+ if (!sourceOrders) return;
6181
+ const targetOrders = conditionSourceOrders.get(target) ?? /* @__PURE__ */ new Map();
6182
+ for (const [condition, sourceOrder] of sourceOrders) targetOrders.set(condition, sourceOrder);
6183
+ conditionSourceOrders.set(target, targetOrders);
6184
+ }
6185
+ //#endregion
5465
6186
  //#region src/internal/utilities/conditional-style-defaults.ts
5466
6187
  const FLAT_ERASES_CONDITIONAL_WARNING = "Flat StyleX value would erase earlier conditional property states";
5467
6188
  function flatStylexValueErasureExample(prop) {
@@ -5486,11 +6207,11 @@ function defaultInferenceFromPropertyShape(shape) {
5486
6207
  if (shape.kind === "conditionalMap") return shape.defaultValue;
5487
6208
  return shape;
5488
6209
  }
5489
- function patchFlatValueAgainstPriorPropertyShape(styleObj, prop, earlier, laterSource = "mixin") {
6210
+ function patchFlatValueAgainstPriorPropertyShape(styleObj, prop, earlier, laterSource = "mixin", laterSourceOrder) {
5490
6211
  if (earlier.kind !== "conditionalMap") return "safe";
5491
6212
  const current = inferPropertyShapeFromValue(styleObj[prop]);
5492
6213
  if (current.kind !== "flat") return "safe";
5493
- const preservedConditions = staticConditionsPreservedByLaterFlat(earlier, laterSource);
6214
+ const preservedConditions = staticConditionsPreservedByLaterFlat(earlier, laterSource, laterSourceOrder);
5494
6215
  if (!preservedConditions) return "bail";
5495
6216
  if (Object.keys(preservedConditions).length === 0) return "safe";
5496
6217
  styleObj[prop] = {
@@ -5558,7 +6279,7 @@ function patchConditionalDefaultsForSequence(args) {
5558
6279
  const earlier = shapes.get(prop) ?? { kind: "absent" };
5559
6280
  const patchTarget = clonedPatchSources.get(entry.styleKey)?.source ?? (needsSharedFlatEntryClone(entry, source, prop, earlier) && ctx.resolvedStyleObjects ? cloneSharedStyleEntryForPatch(ctx.resolvedStyleObjects, decl, entry.styleKey, source, clonedPatchSources, styleKeyUseCounts) : source);
5560
6281
  contributionSource = patchTarget;
5561
- if (patchFlatValueAgainstPriorPropertyShape(patchTarget, prop, earlier, entry.source) !== "bail") continue;
6282
+ if (patchFlatValueAgainstPriorPropertyShape(patchTarget, prop, earlier, entry.source, entry.sourceOrder) !== "bail") continue;
5562
6283
  ctx.warnings.push({
5563
6284
  severity: "warning",
5564
6285
  type: FLAT_ERASES_CONDITIONAL_WARNING,
@@ -5784,6 +6505,7 @@ function inferPropertyShapeFromValue(value) {
5784
6505
  const defaultValue = value.default;
5785
6506
  const conditionKeys = Object.keys(value).filter(isStyleConditionKey$1);
5786
6507
  const staticConditions = readStaticConditionValues(value, conditionKeys);
6508
+ const conditionSourceOrders = readConditionSourceOrders(value, conditionKeys);
5787
6509
  return {
5788
6510
  kind: "conditionalMap",
5789
6511
  defaultValue: isStaticStyleValue(defaultValue) ? defaultValue === null ? { kind: "absent" } : {
@@ -5791,7 +6513,8 @@ function inferPropertyShapeFromValue(value) {
5791
6513
  value: defaultValue
5792
6514
  } : { kind: "dynamic" },
5793
6515
  conditionKeys,
5794
- ...staticConditions ? { staticConditions } : {}
6516
+ ...staticConditions ? { staticConditions } : {},
6517
+ ...conditionSourceOrders ? { conditionSourceOrders } : {}
5795
6518
  };
5796
6519
  }
5797
6520
  return { kind: "dynamic" };
@@ -5806,9 +6529,21 @@ function readStaticConditionValues(value, conditionKeys) {
5806
6529
  }
5807
6530
  return conditions;
5808
6531
  }
5809
- function staticConditionsPreservedByLaterFlat(earlier, laterSource) {
6532
+ function readConditionSourceOrders(value, conditionKeys) {
6533
+ const orders = {};
6534
+ for (const key of conditionKeys) {
6535
+ const sourceOrder = getConditionSourceOrder(value, key);
6536
+ if (sourceOrder !== void 0) orders[key] = sourceOrder;
6537
+ }
6538
+ return Object.keys(orders).length ? orders : void 0;
6539
+ }
6540
+ function staticConditionsPreservedByLaterFlat(earlier, laterSource, laterSourceOrder) {
5810
6541
  const minSpecificity = conditionSpecificityNeededToOutrankFlatSource(laterSource);
5811
- const preservedKeys = earlier.conditionKeys.filter((key) => conditionSpecificity(key) > minSpecificity);
6542
+ const preservedKeys = earlier.conditionKeys.filter((key) => {
6543
+ const conditionSourceOrder = earlier.conditionSourceOrders?.[key];
6544
+ if (laterSourceOrder !== void 0 && conditionSourceOrder !== void 0 && conditionSourceOrder <= laterSourceOrder) return false;
6545
+ return conditionSpecificity(key) > minSpecificity;
6546
+ });
5812
6547
  if (preservedKeys.length === 0) return {};
5813
6548
  if (!earlier.staticConditions) return;
5814
6549
  const preserved = {};
@@ -8065,10 +8800,10 @@ function collectDeclPropNames(root, j, decl, filter) {
8065
8800
  const addIfMatch = (name) => {
8066
8801
  if (filter(name)) result.add(name);
8067
8802
  };
8068
- for (const when of Object.keys(decl.variantStyleKeys ?? {})) for (const p of parseVariantWhenToAst(j, when).props) addIfMatch(p);
8803
+ for (const when of Object.keys(decl.variantStyleKeys ?? {})) for (const p of parseVariantWhenToAst(j, when, void 0, void 0, decl.nonPropConditionRoots).props) addIfMatch(p);
8069
8804
  for (const sf of decl.styleFnFromProps ?? []) {
8070
8805
  addIfMatch(sf.jsxProp);
8071
- if (sf.conditionWhen) for (const p of parseVariantWhenToAst(j, sf.conditionWhen).props) addIfMatch(p);
8806
+ if (sf.conditionWhen) for (const p of parseVariantWhenToAst(j, sf.conditionWhen, void 0, void 0, decl.nonPropConditionRoots).props) addIfMatch(p);
8072
8807
  }
8073
8808
  for (const isp of decl.inlineStyleProps ?? []) addIfMatch(isp.jsxProp ?? isp.prop);
8074
8809
  for (const cv of decl.compoundVariants ?? []) if (cv.kind === "3branch" || cv.kind === "4branch") {
@@ -8191,6 +8926,7 @@ function applyTransientPropRenames(decl, renames) {
8191
8926
  for (const [when, order] of Object.entries(decl.variantSourceOrder)) updated[renamePropsInWhenString(when, renames)] = order;
8192
8927
  decl.variantSourceOrder = updated;
8193
8928
  }
8929
+ renameVariantSourceOrderConditions(decl, (when) => renamePropsInWhenString(when, renames));
8194
8930
  if (decl.styleFnFromProps) for (const sf of decl.styleFnFromProps) {
8195
8931
  sf.jsxProp = renames.get(sf.jsxProp) ?? sf.jsxProp;
8196
8932
  if (sf.propsObjectKey) sf.propsObjectKey = renames.get(sf.propsObjectKey) ?? sf.propsObjectKey;
@@ -9553,6 +10289,12 @@ function validateSxRestrictedWrappedComponentStyles(ctx, styledDecls) {
9553
10289
  if (!rejectedProperty) {
9554
10290
  const disallowedProperty = allowed ? findSxDisallowedStyleProperty(style, allowed) : null;
9555
10291
  if (!disallowedProperty) continue;
10292
+ /**
10293
+ * Keep this as a warning instead of bailing. Some component wrappers expose
10294
+ * narrow style APIs (for example icon `color` props instead of raw `fill`
10295
+ * styles), but the generated output is still localized and manually fixable
10296
+ * by the migration author.
10297
+ */
9556
10298
  ctx.warnings.push({
9557
10299
  severity: "warning",
9558
10300
  type: "Wrapped component sx prop does not accept generated StyleX property",
@@ -9974,6 +10716,26 @@ function normalizeStylisAstToIR(stylisAst, slots, options = {}) {
9974
10716
  rules.push(created);
9975
10717
  return created;
9976
10718
  };
10719
+ const recoveredSelectorAliases = (selector) => {
10720
+ const normalized = normalizeRecoveredSelector(selector);
10721
+ const aliases = [normalized];
10722
+ const withoutLeadingAmpersands = splitTopLevelSelectorList(normalized).map((part) => part.startsWith("&") && part.length > 1 ? part.slice(1) : part).join(",");
10723
+ if (withoutLeadingAmpersands && withoutLeadingAmpersands !== normalized) aliases.push(withoutLeadingAmpersands);
10724
+ return aliases;
10725
+ };
10726
+ const findRecoveredRule = (selector, stack) => {
10727
+ const aliases = recoveredSelectorAliases(selector);
10728
+ for (const alias of aliases) {
10729
+ const rule = findRule(alias, stack);
10730
+ if (rule) return rule;
10731
+ }
10732
+ for (const rule of rules) {
10733
+ if (!sameArray(rule.atRuleStack, stack)) continue;
10734
+ const normalizedRuleSelector = rule.selector.replace(/^(?:__SC_EXPR_\d+__\s*)+/, "").trim();
10735
+ if (aliases.includes(normalizedRuleSelector)) return rule;
10736
+ }
10737
+ };
10738
+ const ensureRecoveredRule = (selector, stack) => findRecoveredRule(selector, stack) ?? ensureRule(normalizeRecoveredSelector(selector), stack);
9977
10739
  const visit = (node) => {
9978
10740
  if (!node) return;
9979
10741
  if (Array.isArray(node)) {
@@ -10069,12 +10831,19 @@ function normalizeStylisAstToIR(stylisAst, slots, options = {}) {
10069
10831
  const selectorStack = [];
10070
10832
  const recoveryAtRuleStack = [];
10071
10833
  const rawDeclarationCountByRule = /* @__PURE__ */ new WeakMap();
10834
+ let rawSourceOrder = 0;
10072
10835
  const recordRawDeclarations = (trimmed, selector, recoveryAtRules) => {
10073
10836
  const decls = parseDeclarations(trimmed, slotByPlaceholder);
10074
10837
  if (!decls.length) return;
10075
- const targetRule = findRule(normalizeRecoveredSelector(selector), recoveryAtRules);
10838
+ const targetRule = findRecoveredRule(selector, recoveryAtRules);
10076
10839
  if (!targetRule) return;
10077
- rawDeclarationCountByRule.set(targetRule, (rawDeclarationCountByRule.get(targetRule) ?? 0) + decls.length);
10840
+ const rawDeclarationCount = rawDeclarationCountByRule.get(targetRule) ?? 0;
10841
+ for (let i = 0; i < decls.length; i++) {
10842
+ const targetDecl = targetRule.declarations[rawDeclarationCount + i];
10843
+ if (targetDecl) targetDecl.sourceOrder ??= rawSourceOrder;
10844
+ rawSourceOrder++;
10845
+ }
10846
+ rawDeclarationCountByRule.set(targetRule, rawDeclarationCount + decls.length);
10078
10847
  };
10079
10848
  const recoverPlaceholder = (trimmed, selector, recoveryAtRules) => {
10080
10849
  const m = trimmed.match(placeholderLineRe);
@@ -10084,11 +10853,18 @@ function normalizeStylisAstToIR(stylisAst, slots, options = {}) {
10084
10853
  const mapped = slotByPlaceholder.get(placeholder);
10085
10854
  if (mapped === void 0) return false;
10086
10855
  const shouldPreserveRawDeclarationPosition = isIdentifierSlot(slotExpressionById.get(slotId));
10087
- if (rules.some((r) => r.declarations.some((decl) => {
10088
- if (decl.value.kind !== "interpolated") return false;
10089
- return decl.value.parts.some((p) => p.kind === "slot" && p.slotId === mapped);
10090
- }))) return false;
10091
- const targetRule = ensureRule(normalizeRecoveredSelector(selector), recoveryAtRules);
10856
+ const existingSlotDecl = (() => {
10857
+ for (const r of rules) for (const decl of r.declarations) {
10858
+ if (decl.value.kind !== "interpolated") continue;
10859
+ if (decl.value.parts.some((p) => p.kind === "slot" && p.slotId === mapped)) return decl;
10860
+ }
10861
+ return null;
10862
+ })();
10863
+ if (existingSlotDecl) {
10864
+ existingSlotDecl.sourceOrder ??= rawSourceOrder++;
10865
+ return false;
10866
+ }
10867
+ const targetRule = ensureRecoveredRule(selector, recoveryAtRules);
10092
10868
  const decl = {
10093
10869
  property: "",
10094
10870
  value: {
@@ -10099,7 +10875,8 @@ function normalizeStylisAstToIR(stylisAst, slots, options = {}) {
10099
10875
  }]
10100
10876
  },
10101
10877
  important: false,
10102
- valueRaw: placeholder
10878
+ valueRaw: placeholder,
10879
+ sourceOrder: rawSourceOrder++
10103
10880
  };
10104
10881
  if (shouldPreserveRawDeclarationPosition) {
10105
10882
  const rawDeclarationCount = rawDeclarationCountByRule.get(targetRule) ?? 0;
@@ -13266,6 +14043,10 @@ function isNumericStylexExpression(value, options = {}) {
13266
14043
  if (!value) return false;
13267
14044
  if (value.type === "NumericLiteral" || value.type === "Literal" && typeof value.value === "number") return true;
13268
14045
  if (value.type === "Identifier") return options.numericIdentifiers?.has(value.name) ?? false;
14046
+ if (value.type === "MemberExpression") {
14047
+ const rootName = memberExpressionRootIdentifier(value);
14048
+ return rootName ? options.numericIdentifiers?.has(rootName) ?? false : false;
14049
+ }
13269
14050
  if (value.type === "UnaryExpression") return (value.operator === "-" || value.operator === "+") && isNumericStylexExpression(value.argument, options);
13270
14051
  if (value.type === "BinaryExpression") return [
13271
14052
  "+",
@@ -13283,17 +14064,170 @@ function isNumericStylexExpression(value, options = {}) {
13283
14064
  function isExpressionNode(value) {
13284
14065
  return Boolean(value && typeof value === "object" && typeof value.type === "string");
13285
14066
  }
14067
+ function memberExpressionRootIdentifier(value) {
14068
+ if (value.type === "Identifier") return value.name;
14069
+ if (value.type !== "MemberExpression") return null;
14070
+ return memberExpressionRootIdentifier(value.object);
14071
+ }
14072
+ //#endregion
14073
+ //#region src/internal/utilities/stylex-import-source.ts
14074
+ /**
14075
+ * Matches StyleX sidecar/token module sources like "./tokens.stylex" or
14076
+ * "../vars.stylex.ts". By StyleX convention these modules only export
14077
+ * `defineVars`/`defineConsts` values and plain constants — never components —
14078
+ * so they can be ignored when tracing styled-component dependencies.
14079
+ */
14080
+ function isStylexImportSource(source) {
14081
+ return /\.stylex(?:\.[cm]?[jt]sx?)?$/u.test(source);
14082
+ }
14083
+ //#endregion
14084
+ //#region src/internal/utilities/stylex-numeric-imports.ts
14085
+ /**
14086
+ * Resolves local `.stylex` imports whose exported values are proven numeric.
14087
+ */
14088
+ function collectNumericStylexImportBindings(args) {
14089
+ const identifiers = /* @__PURE__ */ new Set();
14090
+ const exportCache = /* @__PURE__ */ new Map();
14091
+ for (const binding of args.bindings) {
14092
+ if (!isStylexImportSource(binding.source.value)) continue;
14093
+ const cacheKey = `${binding.source.kind}\0${binding.source.value}`;
14094
+ let numericExports = exportCache.get(cacheKey);
14095
+ if (!numericExports) {
14096
+ numericExports = collectNumericStylexExportNames(args.j, args.filePath, binding.source);
14097
+ exportCache.set(cacheKey, numericExports);
14098
+ }
14099
+ if (numericExports.has(binding.importedName)) identifiers.add(binding.localName);
14100
+ }
14101
+ return identifiers;
14102
+ }
14103
+ function resolveStylexImportFile(filePath, source) {
14104
+ const sourceValue = source.value;
14105
+ if (!isStylexImportSource(sourceValue)) return null;
14106
+ if (source.kind === "specifier" && !sourceValue.startsWith(".")) return null;
14107
+ const basePath = source.kind === "absolutePath" || isAbsolute(sourceValue) ? sourceValue : join(dirname(filePath), sourceValue);
14108
+ return (/\.[cm]?[jt]sx?$/.test(basePath) ? [basePath] : [
14109
+ `${basePath}.ts`,
14110
+ `${basePath}.tsx`,
14111
+ `${basePath}.js`,
14112
+ `${basePath}.jsx`
14113
+ ]).find((candidate) => existsSync(candidate)) ?? null;
14114
+ }
14115
+ function collectNumericStylexExportNames(j, filePath, source) {
14116
+ const resolvedPath = resolveStylexImportFile(filePath, source);
14117
+ if (!resolvedPath) return /* @__PURE__ */ new Set();
14118
+ let root;
14119
+ try {
14120
+ root = j(readFileSync(resolvedPath, "utf8"));
14121
+ } catch {
14122
+ return /* @__PURE__ */ new Set();
14123
+ }
14124
+ const localNumericBindings = /* @__PURE__ */ new Map();
14125
+ const exportedNumericNames = /* @__PURE__ */ new Set();
14126
+ root.find(j.VariableDeclarator).forEach((path) => {
14127
+ if (!isImmutableTopLevelVariableDeclaratorPath$1(path)) return;
14128
+ const id = path.node.id;
14129
+ if (id?.type !== "Identifier" || !id.name) return;
14130
+ localNumericBindings.set(id.name, isNumericStylexExportValue(path.node.init));
14131
+ });
14132
+ root.find(j.ExportNamedDeclaration).forEach((path) => {
14133
+ const declaration = path.node.declaration;
14134
+ if (declaration?.type === "VariableDeclaration") {
14135
+ const variableDeclaration = declaration;
14136
+ for (const decl of variableDeclaration.declarations ?? []) {
14137
+ const id = decl.id;
14138
+ if (id?.type === "Identifier" && id.name && isNumericStylexExportValue(decl.init)) exportedNumericNames.add(id.name);
14139
+ }
14140
+ }
14141
+ for (const specifier of path.node.specifiers ?? []) {
14142
+ const localName = exportSpecifierLocalName(specifier);
14143
+ const exportedName = exportSpecifierExportedName(specifier);
14144
+ if (localName && exportedName && localNumericBindings.get(localName) === true) exportedNumericNames.add(exportedName);
14145
+ }
14146
+ });
14147
+ root.find(j.ExportDefaultDeclaration).forEach((path) => {
14148
+ if (isNumericStylexExportValue(path.node.declaration)) exportedNumericNames.add("default");
14149
+ });
14150
+ return exportedNumericNames;
14151
+ }
14152
+ function exportSpecifierLocalName(specifier) {
14153
+ return specifier.local?.name ?? specifier.local?.value ?? null;
14154
+ }
14155
+ function exportSpecifierExportedName(specifier) {
14156
+ return specifier.exported?.name ?? specifier.exported?.value ?? null;
14157
+ }
14158
+ function isNumericStylexExportValue(value) {
14159
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
14160
+ const node = value;
14161
+ if (node.type === "NumericLiteral" || node.type === "Literal" && typeof node.value === "number") return true;
14162
+ if (node.type === "UnaryExpression") return (node.operator === "-" || node.operator === "+") && isNumericStylexExportValue(node.argument);
14163
+ if (node.type === "TSAsExpression" || node.type === "TSSatisfiesExpression" || node.type === "TSNonNullExpression" || node.type === "ParenthesizedExpression") return isNumericStylexExportValue(node.expression);
14164
+ if (node.type === "CallExpression" && isStylexDefineConstsCall(node.callee)) return isNumericStylexExportValue(node.arguments?.[0]);
14165
+ if (node.type !== "ObjectExpression" || !Array.isArray(node.properties)) return false;
14166
+ return node.properties.every((property) => {
14167
+ if (!property || typeof property !== "object" || Array.isArray(property)) return false;
14168
+ const prop = property;
14169
+ return (prop.type === "Property" || prop.type === "ObjectProperty") && isNumericStylexExportValue(prop.value);
14170
+ });
14171
+ }
14172
+ function isStylexDefineConstsCall(callee) {
14173
+ if (!callee || typeof callee !== "object" || Array.isArray(callee)) return false;
14174
+ const node = callee;
14175
+ if (node.type === "Identifier") return node.name === "defineConsts";
14176
+ return node.type === "MemberExpression" && node.computed !== true && node.property?.type === "Identifier" && node.property.name === "defineConsts";
14177
+ }
14178
+ function isImmutableTopLevelVariableDeclaratorPath$1(path) {
14179
+ const declaration = path.parentPath?.node;
14180
+ if (declaration?.type !== "VariableDeclaration" || declaration.kind !== "const") return false;
14181
+ let current = path.parentPath;
14182
+ while (current && typeof current === "object") {
14183
+ const node = current.node;
14184
+ if (node?.type === "Program") return true;
14185
+ if (node?.type === "FunctionDeclaration" || node?.type === "FunctionExpression" || node?.type === "ArrowFunctionExpression" || node?.type === "ClassDeclaration" || node?.type === "ClassExpression") return false;
14186
+ current = current.parentPath;
14187
+ }
14188
+ return false;
14189
+ }
13286
14190
  //#endregion
13287
14191
  //#region src/internal/lower-rules/inline-styles.ts
13288
14192
  function getImportedStylexIdentifiers(importMap, resolverImports) {
13289
14193
  const identifiers = /* @__PURE__ */ new Set();
13290
- for (const [localName, importEntry] of importMap) if (importEntry?.source?.value?.includes(".stylex")) identifiers.add(localName);
14194
+ for (const [localName, importEntry] of importMap) {
14195
+ const sourceValue = importEntry?.source?.value;
14196
+ if (typeof sourceValue === "string" && isStylexImportSource(sourceValue)) identifiers.add(localName);
14197
+ }
13291
14198
  for (const importSpec of resolverImports.values()) {
13292
- if (!importSpec.from.value.includes(".stylex")) continue;
14199
+ if (!isStylexImportSource(importSpec.from.value)) continue;
13293
14200
  for (const name of importSpec.names) identifiers.add(name.local ?? name.imported);
13294
14201
  }
13295
14202
  return identifiers;
13296
14203
  }
14204
+ function getNumericImportedStylexIdentifiers(j, filePath, importMap, resolverImports) {
14205
+ const bindings = [];
14206
+ for (const [localName, importEntry] of importMap) {
14207
+ const source = importEntry?.source;
14208
+ const sourceValue = source?.value;
14209
+ const importedName = importEntry?.importedName;
14210
+ if (!source || typeof sourceValue !== "string" || !importedName) continue;
14211
+ bindings.push({
14212
+ localName,
14213
+ importedName,
14214
+ source: "kind" in source ? source : {
14215
+ kind: "specifier",
14216
+ value: sourceValue
14217
+ }
14218
+ });
14219
+ }
14220
+ for (const importSpec of resolverImports.values()) for (const name of importSpec.names) bindings.push({
14221
+ localName: name.local ?? name.imported,
14222
+ importedName: name.imported,
14223
+ source: importSpec.from
14224
+ });
14225
+ return collectNumericStylexImportBindings({
14226
+ j,
14227
+ filePath,
14228
+ bindings
14229
+ });
14230
+ }
13297
14231
  function buildTemplateWithStaticParts(j, expr, prefix, suffix, multilineContext) {
13298
14232
  if (!prefix && !suffix) return expr;
13299
14233
  const staticValue = literalToStaticValue(expr);
@@ -13874,10 +14808,13 @@ function tryHandleAnimation(args) {
13874
14808
  for (let segmentIndex = 0; segmentIndex < segments.length; segmentIndex++) {
13875
14809
  const tokens = segments[segmentIndex];
13876
14810
  if (!tokens.length) return false;
13877
- const m = tokens.shift().match(/^__SC_EXPR_(\d+)__$/);
13878
- if (!m) return false;
14811
+ const nameIdx = tokens.findIndex((t) => {
14812
+ const slotMatch = t.match(/^__SC_EXPR_(\d+)__$/);
14813
+ return slotMatch ? getKeyframeFromSlot(Number(slotMatch[1])) !== null : false;
14814
+ });
14815
+ if (nameIdx === -1) return false;
14816
+ const m = tokens.splice(nameIdx, 1)[0].match(/^__SC_EXPR_(\d+)__$/);
13879
14817
  const kf = getKeyframeFromSlot(Number(m[1]));
13880
- if (!kf) return false;
13881
14818
  animNames.push({
13882
14819
  kind: "ident",
13883
14820
  name: kf
@@ -15045,6 +15982,7 @@ function exportedBindingDependsOnLocalNames(args) {
15045
15982
  const targets = collectExportTargets(parsed, args.exportedName, args.includeDefault);
15046
15983
  if (targets.localNames.size === 0 && targets.nodes.length === 0) return true;
15047
15984
  const dependencyNames = expandLocalDependencyNames(parsed, args.localNames);
15985
+ if (args.memberPath !== void 0 && args.memberPath.length > 0) return staticMemberDependsOnLocalNames(parsed, targets, args.memberPath, dependencyNames);
15048
15986
  for (const localName of targets.localNames) {
15049
15987
  if (dependencyNames.has(localName)) return true;
15050
15988
  const node = findLocalBindingNode(parsed, localName);
@@ -15053,6 +15991,94 @@ function exportedBindingDependsOnLocalNames(args) {
15053
15991
  for (const node of targets.nodes) if (nodeReferencesLocalNames(exportedNodeBody(node), dependencyNames)) return true;
15054
15992
  return false;
15055
15993
  }
15994
+ /**
15995
+ * Dependency check for `Exported.Member` consumers: locate static member
15996
+ * assignments (`Root.Member = Value`, or `Member:` properties in the root's
15997
+ * object-literal / `Object.assign` initializer) and test the assigned values.
15998
+ * Returns true (dependent) when the member cannot be proven independent.
15999
+ */
16000
+ function staticMemberDependsOnLocalNames(program, targets, memberPath, dependencyNames) {
16001
+ const memberName = memberPath[0];
16002
+ if (memberPath.length !== 1 || memberName === void 0 || targets.nodes.length > 0) return true;
16003
+ const memberValues = collectStaticMemberValues(program, expandAliasNamesBothWays(program, targets.localNames), memberName);
16004
+ if (memberValues.hasUnknownSource || memberValues.values.length === 0) return true;
16005
+ return memberValues.values.some((value) => nodeReferencesLocalNames(value, dependencyNames));
16006
+ }
16007
+ /**
16008
+ * Expand a name set across identity aliases in both directions, so member
16009
+ * assignments written on any alias of the export (e.g. `CustomSelect.Option = X`
16010
+ * behind `export const Public = CustomSelect`) are found.
16011
+ */
16012
+ function expandAliasNamesBothWays(program, initialNames) {
16013
+ const aliases = collectIdentityAliases(program);
16014
+ const expanded = new Set(initialNames);
16015
+ let changed = true;
16016
+ while (changed) {
16017
+ changed = false;
16018
+ for (const [aliasName, targetName] of aliases) if (expanded.has(aliasName) !== expanded.has(targetName)) {
16019
+ expanded.add(aliasName);
16020
+ expanded.add(targetName);
16021
+ changed = true;
16022
+ }
16023
+ }
16024
+ return expanded;
16025
+ }
16026
+ function collectStaticMemberValues(program, rootNames, memberName) {
16027
+ const result = {
16028
+ values: [],
16029
+ hasUnknownSource: false
16030
+ };
16031
+ for (const stmt of programBody(program)) {
16032
+ if (stmt.type !== "ExpressionStatement") continue;
16033
+ const assignedValue = staticMemberAssignmentValue(stmt.expression, rootNames, memberName);
16034
+ if (assignedValue) result.values.push(assignedValue);
16035
+ }
16036
+ for (const binding of localBindings(program)) if (rootNames.has(binding.name)) {
16037
+ const bindingValues = objectLiteralMemberValues(unwrapTransparentExpression(binding.node), memberName);
16038
+ result.values.push(...bindingValues.values);
16039
+ result.hasUnknownSource ||= bindingValues.hasUnknownSource;
16040
+ }
16041
+ return result;
16042
+ }
16043
+ /** Value assigned by a `Root.Member = Value` statement, if `expression` is one. */
16044
+ function staticMemberAssignmentValue(expression, rootNames, memberName) {
16045
+ if (expression?.type !== "AssignmentExpression" || expression.operator !== "=") return;
16046
+ const left = expression.left;
16047
+ if (left?.type !== "MemberExpression" || left.computed === true) return;
16048
+ const objectName = nodeName(left.object);
16049
+ const propertyName = nodeName(left.property);
16050
+ if (!objectName || !rootNames.has(objectName) || propertyName !== memberName) return;
16051
+ return expression.right;
16052
+ }
16053
+ /** `Member:` property values in an object-literal or `Object.assign(...)` initializer. */
16054
+ function objectLiteralMemberValues(init, memberName) {
16055
+ const result = {
16056
+ values: [],
16057
+ hasUnknownSource: false
16058
+ };
16059
+ if (init.type === "ObjectExpression") collectObjectExpressionMemberValues(init, memberName, result);
16060
+ else if (init.type === "CallExpression" && isObjectAssignCallee(init.callee)) for (const arg of astArray(init.arguments)) if (arg.type === "ObjectExpression") collectObjectExpressionMemberValues(arg, memberName, result);
16061
+ else {
16062
+ result.hasUnknownSource = true;
16063
+ result.values = [];
16064
+ }
16065
+ return result;
16066
+ }
16067
+ function collectObjectExpressionMemberValues(objectNode, memberName, result) {
16068
+ for (const property of astArray(objectNode.properties)) if ((property.type === "ObjectProperty" || property.type === "Property") && property.computed !== true && nodeName(property.key) === memberName) {
16069
+ const value = property.value;
16070
+ if (value) {
16071
+ result.values = [value];
16072
+ result.hasUnknownSource = false;
16073
+ }
16074
+ } else if (property.type === "SpreadElement" || property.type === "SpreadProperty") {
16075
+ result.hasUnknownSource = true;
16076
+ result.values = [];
16077
+ }
16078
+ }
16079
+ function isObjectAssignCallee(callee) {
16080
+ return callee?.type === "MemberExpression" && callee.computed !== true && nodeName(callee.object) === "Object" && nodeName(callee.property) === "assign";
16081
+ }
15056
16082
  function parseProgram$1(source) {
15057
16083
  for (const parserName of ["tsx", "babel"]) try {
15058
16084
  const ast = createPrepassParser(parserName).parse(source);
@@ -15300,8 +16326,10 @@ function detectCascadeConflictStep(ctx) {
15300
16326
  if (decl.skipTransform) continue;
15301
16327
  if (decl.base.kind !== "component") continue;
15302
16328
  const baseIdent = decl.base.ident;
15303
- if (localStyledNames.has(baseIdent)) continue;
15304
- const importEntry = importMap.get(baseIdent);
16329
+ const baseImportLocalName = rootLocalName(baseIdent);
16330
+ const baseMemberPath = baseIdent.split(".").slice(1);
16331
+ if (localStyledNames.has(baseIdent) || localStyledNames.has(baseImportLocalName)) continue;
16332
+ const importEntry = importMap.get(baseImportLocalName);
15305
16333
  if (!importEntry || importEntry.source.kind !== "absolutePath") continue;
15306
16334
  if (skipImportedRoots) continue;
15307
16335
  const importedPath = importEntry.source.value;
@@ -15309,17 +16337,36 @@ function detectCascadeConflictStep(ctx) {
15309
16337
  path: importedPath,
15310
16338
  importedName: importEntry.importedName
15311
16339
  };
15312
- if (transformedComponents && transformedComponentExists(transformedComponents, definition.path, definition.importedName, definition.importedName === "default")) continue;
15313
- if (ctx.options.transformMode === "leavesOnly" && ctx.options.globalLeafKeys?.size) {
16340
+ if (baseMemberPath.length === 0 && ctx.options.transformMode === "leavesOnly" && ctx.options.globalLeafKeys?.size) {
15314
16341
  if (globalLeafKeyExists(ctx.options.globalLeafKeys, definition.path, definition.importedName, definition.importedName === "default")) continue;
15315
16342
  }
15316
16343
  const styledDefinitions = styledDefFiles && resolveStyledDefFile(definition.path, styledDefFiles) || scanFileForStyledDefs(definition.path, definition.importedName, ctx.options.resolveModule);
15317
- if (!styledDefinitions) continue;
15318
- if (transformedComponents && transformedComponentsHasPath(transformedComponents, styledDefinitions.path) && !bindingDependsOnStyledDefinitions({
15319
- ...styledDefinitions,
15320
- names: unconvertedStyledDefinitionNames(styledDefinitions, transformedComponents)
15321
- }, definition.importedName)) continue;
15322
- if (canSkipCascadeForStylexExport(ctx, styledDefinitions, definition.importedName)) continue;
16344
+ if (transformedComponents && transformedComponentExists(transformedComponents, definition.path, definition.importedName, definition.importedName === "default") && bindingIsIndependentOfRemainingStyledDefinitions(ctx, {
16345
+ sourcePath: definition.path,
16346
+ bindingName: definition.importedName,
16347
+ memberPath: baseMemberPath,
16348
+ styledDefinitions: styledDefinitions ? {
16349
+ ...styledDefinitions,
16350
+ names: unconvertedStyledDefinitionNames(styledDefinitions, transformedComponents)
16351
+ } : void 0
16352
+ })) continue;
16353
+ if (!styledDefinitions) {
16354
+ if (bindingIsIndependentOfRemainingStyledDefinitions(ctx, {
16355
+ sourcePath: definition.path,
16356
+ bindingName: definition.importedName,
16357
+ memberPath: baseMemberPath,
16358
+ styledDefinitions: void 0
16359
+ })) continue;
16360
+ } else if (transformedComponents && transformedComponentsHasPath(transformedComponents, styledDefinitions.path) && bindingIsIndependentOfRemainingStyledDefinitions(ctx, {
16361
+ sourcePath: styledDefinitions.path,
16362
+ bindingName: definition.importedName,
16363
+ memberPath: baseMemberPath,
16364
+ styledDefinitions: {
16365
+ ...styledDefinitions,
16366
+ names: unconvertedStyledDefinitionNames(styledDefinitions, transformedComponents)
16367
+ }
16368
+ })) continue;
16369
+ if (styledDefinitions && canSkipCascadeForStylexExport(ctx, styledDefinitions, definition.importedName, baseMemberPath)) continue;
15323
16370
  ctx.warnings.push({
15324
16371
  severity: "warning",
15325
16372
  type: CASCADE_CONFLICT_WARNING,
@@ -15328,7 +16375,7 @@ function detectCascadeConflictStep(ctx) {
15328
16375
  component: decl.localName,
15329
16376
  base: baseIdent,
15330
16377
  importedPath,
15331
- definitionPath: styledDefinitions.path
16378
+ definitionPath: styledDefinitions?.path ?? definition.path
15332
16379
  }
15333
16380
  });
15334
16381
  foundCascadeConflict = true;
@@ -15348,6 +16395,19 @@ function resolveImportedDefinition(ctx, importedPath, importedName) {
15348
16395
  importedName: resolved.exportedName
15349
16396
  } : null;
15350
16397
  }
16398
+ /**
16399
+ * Import sources the codemod itself emits into transformed files (the adapter's
16400
+ * style-merger helper). These never carry styled-component exports.
16401
+ */
16402
+ function generatedImportSources(ctx) {
16403
+ const sources = /* @__PURE__ */ new Set();
16404
+ const mergerSource = ctx.adapter.styleMerger?.importSource?.value;
16405
+ if (typeof mergerSource === "string" && mergerSource.length > 0) sources.add(mergerSource);
16406
+ return sources;
16407
+ }
16408
+ function rootLocalName(componentName) {
16409
+ return componentName.split(".")[0] ?? componentName;
16410
+ }
15351
16411
  /** Common TypeScript/JavaScript file extensions to try when matching import paths to styledDefFiles keys. */
15352
16412
  const EXTENSIONS = [
15353
16413
  ".tsx",
@@ -15432,17 +16492,19 @@ function componentExportExistsByDirectScan(importedPath, bindingName) {
15432
16492
  }
15433
16493
  return false;
15434
16494
  }
15435
- function canSkipCascadeForStylexExport(ctx, styledDefinitions, bindingName) {
15436
- return componentExportExists(ctx.options.crossFileInfo?.stylexComponentFiles, styledDefinitions.path, bindingName) && bindingIsIndependentOfStyledDefinitions(ctx, styledDefinitions, bindingName);
16495
+ function canSkipCascadeForStylexExport(ctx, styledDefinitions, bindingName, memberPath) {
16496
+ return componentExportExists(ctx.options.crossFileInfo?.stylexComponentFiles, styledDefinitions.path, bindingName) && bindingIsIndependentOfStyledDefinitions(ctx, styledDefinitions, bindingName, memberPath);
15437
16497
  }
15438
- function bindingIsIndependentOfStyledDefinitions(ctx, styledDefinitions, bindingName) {
15439
- if (bindingDependsOnStyledDefinitions(styledDefinitions, bindingName)) return false;
16498
+ function bindingIsIndependentOfStyledDefinitions(ctx, styledDefinitions, bindingName, memberPath) {
16499
+ if (bindingDependsOnStyledDefinitions(styledDefinitions, bindingName, memberPath)) return false;
15440
16500
  return !bindingDependsOnImportedStyledDefinitions({
15441
16501
  bindingName,
16502
+ memberPath,
15442
16503
  sourcePath: styledDefinitions.path,
15443
16504
  styledDefFiles: ctx.options.crossFileInfo?.styledDefFiles,
15444
16505
  stylexComponentFiles: ctx.options.crossFileInfo?.stylexComponentFiles,
15445
- resolveModule: ctx.options.resolveModule
16506
+ resolveModule: ctx.options.resolveModule,
16507
+ ignoredImportSources: generatedImportSources(ctx)
15446
16508
  });
15447
16509
  }
15448
16510
  function transformedComponentExists(transformedComponents, importedPath, bindingName, allowDefaultFallback) {
@@ -15466,15 +16528,31 @@ function transformedNamesForPath(transformedComponents, filePath) {
15466
16528
  if (transformedNames) return transformedNames;
15467
16529
  }
15468
16530
  }
15469
- function bindingDependsOnStyledDefinitions(styledDefinitions, bindingName) {
16531
+ function bindingDependsOnStyledDefinitions(styledDefinitions, bindingName, memberPath = []) {
16532
+ if (styledDefinitions.names.size === 0) return false;
15470
16533
  const source = tryReadFile(styledDefinitions.path);
15471
16534
  return source ? exportedBindingDependsOnLocalNames({
15472
16535
  source,
15473
16536
  exportedName: bindingName,
15474
16537
  includeDefault: bindingName === "default",
15475
- localNames: styledDefinitions.names
16538
+ localNames: styledDefinitions.names,
16539
+ memberPath
15476
16540
  }) : true;
15477
16541
  }
16542
+ function bindingIsIndependentOfRemainingStyledDefinitions(ctx, args) {
16543
+ if (args.styledDefinitions && bindingDependsOnStyledDefinitions(args.styledDefinitions, args.bindingName, args.memberPath)) return false;
16544
+ if (!args.styledDefinitions && args.memberPath.length === 0) return true;
16545
+ if (!args.styledDefinitions && !tryReadFile(args.sourcePath)) return true;
16546
+ return !bindingDependsOnImportedStyledDefinitions({
16547
+ bindingName: args.bindingName,
16548
+ memberPath: args.memberPath,
16549
+ sourcePath: args.sourcePath,
16550
+ styledDefFiles: ctx.options.crossFileInfo?.styledDefFiles,
16551
+ stylexComponentFiles: ctx.options.crossFileInfo?.stylexComponentFiles,
16552
+ resolveModule: ctx.options.resolveModule,
16553
+ ignoredImportSources: generatedImportSources(ctx)
16554
+ });
16555
+ }
15478
16556
  function bindingDependsOnImportedStyledDefinitions(args) {
15479
16557
  const visitKey = `${args.sourcePath}:${args.bindingName}`;
15480
16558
  if (args.visited?.has(visitKey)) return true;
@@ -15491,18 +16569,20 @@ function bindingDependsOnImportedStyledDefinitions(args) {
15491
16569
  source,
15492
16570
  exportedName: args.bindingName,
15493
16571
  includeDefault: args.bindingName === "default",
15494
- localNames: importedStyledNames
16572
+ localNames: importedStyledNames,
16573
+ memberPath: args.memberPath ?? []
15495
16574
  });
15496
16575
  }
15497
16576
  function collectImportedStyledLocalNames(args) {
15498
16577
  const source = tryReadFile(args.sourcePath);
15499
16578
  const program = source ? parseProgram(source) : null;
15500
- if (!program) return null;
16579
+ if (!source || !program) return null;
15501
16580
  const importNodes = [];
15502
16581
  walkForImportsAndTemplates(program, importNodes, []);
15503
16582
  const importMap = buildImportMapFromNodes(importNodes);
15504
16583
  const importedStyledNames = /* @__PURE__ */ new Set();
15505
16584
  for (const [localName, importEntry] of importMap) {
16585
+ if (args.ignoredImportSources?.has(importEntry.source) || isStylexImportSource(importEntry.source)) continue;
15506
16586
  if (!args.resolveModule) {
15507
16587
  if (isRelativeSpecifier(importEntry.source)) importedStyledNames.add(localName);
15508
16588
  continue;
@@ -15513,37 +16593,59 @@ function collectImportedStyledLocalNames(args) {
15513
16593
  continue;
15514
16594
  }
15515
16595
  const styledDefinitions = args.styledDefFiles && resolveStyledDefFile(resolvedPath, args.styledDefFiles) || scanFileForStyledDefs(resolvedPath, importEntry.importedName, args.resolveModule);
16596
+ const memberPath = exportedMemberReferencesImportedRoot({
16597
+ source,
16598
+ bindingName: args.bindingName,
16599
+ memberPath: args.memberPath ?? [],
16600
+ localName
16601
+ }) ? args.memberPath : void 0;
15516
16602
  recordImportedStyledNameIfNeeded(importedStyledNames, localName, {
15517
16603
  bindingName: importEntry.importedName,
16604
+ memberPath,
15518
16605
  styledDefinitions,
15519
16606
  styledDefFiles: args.styledDefFiles,
15520
16607
  stylexComponentFiles: args.stylexComponentFiles,
15521
16608
  resolveModule: args.resolveModule,
16609
+ ignoredImportSources: args.ignoredImportSources,
15522
16610
  visited: args.visited
15523
16611
  });
15524
16612
  }
15525
16613
  return importedStyledNames;
15526
16614
  }
16615
+ function exportedMemberReferencesImportedRoot(args) {
16616
+ if (args.memberPath.length === 0) return false;
16617
+ return exportedBindingDependsOnLocalNames({
16618
+ source: args.source,
16619
+ exportedName: args.bindingName,
16620
+ includeDefault: args.bindingName === "default",
16621
+ localNames: new Set([args.localName]),
16622
+ memberPath: args.memberPath
16623
+ });
16624
+ }
15527
16625
  function recordImportedStyledNameIfNeeded(importedStyledNames, localName, args) {
15528
16626
  if (importedBindingShouldCountAsStyled(args)) importedStyledNames.add(localName);
15529
16627
  }
15530
16628
  function importedBindingShouldCountAsStyled(args) {
15531
16629
  return !!args.styledDefinitions && !importedBindingIsIndependentStylex({
15532
16630
  bindingName: args.bindingName,
16631
+ memberPath: args.memberPath,
15533
16632
  styledDefinitions: args.styledDefinitions,
15534
16633
  styledDefFiles: args.styledDefFiles,
15535
16634
  stylexComponentFiles: args.stylexComponentFiles,
15536
16635
  resolveModule: args.resolveModule,
16636
+ ignoredImportSources: args.ignoredImportSources,
15537
16637
  visited: args.visited
15538
16638
  });
15539
16639
  }
15540
16640
  function importedBindingIsIndependentStylex(args) {
15541
- return componentExportExists(args.stylexComponentFiles, args.styledDefinitions.path, args.bindingName) && !bindingDependsOnStyledDefinitions(args.styledDefinitions, args.bindingName) && !bindingDependsOnImportedStyledDefinitions({
16641
+ return componentExportExists(args.stylexComponentFiles, args.styledDefinitions.path, args.bindingName) && !bindingDependsOnStyledDefinitions(args.styledDefinitions, args.bindingName, args.memberPath ?? []) && !bindingDependsOnImportedStyledDefinitions({
15542
16642
  bindingName: args.bindingName,
16643
+ memberPath: args.memberPath,
15543
16644
  sourcePath: args.styledDefinitions.path,
15544
16645
  styledDefFiles: args.styledDefFiles,
15545
16646
  stylexComponentFiles: args.stylexComponentFiles,
15546
16647
  resolveModule: args.resolveModule,
16648
+ ignoredImportSources: args.ignoredImportSources,
15547
16649
  visited: args.visited
15548
16650
  });
15549
16651
  }
@@ -17297,7 +18399,7 @@ function emitStylesAndImports(ctx) {
17297
18399
  }
17298
18400
  const nonEmptyStyleEntries = [...resolvedStyleObjects.entries()].filter(([k]) => !emptyStyleKeys.has(k) && !preservedCssHelperStyleKeys.has(k));
17299
18401
  const buildStyleEntryProperty = ([k, v]) => {
17300
- const prop = j.property("init", j.identifier(k), v && typeof v === "object" && !isAstNode$1(v) ? objectToAst(j, v) : literalToAst(j, v));
18402
+ const prop = j.property("init", j.identifier(k), v && typeof v === "object" && !isAstNode$1(v) ? objectToAst(j, normalizeStyleObjectForEmission(v)) : literalToAst(j, v));
17301
18403
  const comments = styleKeyToComments.get(k);
17302
18404
  if (comments && comments.length > 0) prop.comments = comments.map((c) => ({
17303
18405
  ...c,
@@ -17396,10 +18498,13 @@ function emitStylesAndImports(ctx) {
17396
18498
  function emitVariantDimensionDecl(j, dimension) {
17397
18499
  const properties = Object.entries(dimension.variants).map(([variantValue, styles]) => {
17398
18500
  const key = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(variantValue) ? j.identifier(variantValue) : isFiniteNumericString(variantValue) ? j.literal(Number(variantValue)) : j.literal(variantValue);
17399
- return j.property("init", key, styles && typeof styles === "object" && !isAstNode$1(styles) ? objectToAst(j, styles) : literalToAst(j, styles));
18501
+ return j.property("init", key, styles && typeof styles === "object" && !isAstNode$1(styles) ? objectToAst(j, normalizeStyleObjectForEmission(styles)) : literalToAst(j, styles));
17400
18502
  });
17401
18503
  return j.variableDeclaration("const", [j.variableDeclarator(j.identifier(dimension.variantObjectName), j.callExpression(j.memberExpression(j.identifier("stylex"), j.identifier("create")), [j.objectExpression(properties)]))]);
17402
18504
  }
18505
+ function normalizeStyleObjectForEmission(styleObj) {
18506
+ return expandStyleObjectShorthands(styleObj);
18507
+ }
17403
18508
  /**
17404
18509
  * Returns true when `s` is a canonical numeric string (round-trips through Number).
17405
18510
  * Rejects non-canonical forms like "08", "0x10", "1e2" where `String(Number(s)) !== s`,
@@ -17954,7 +19059,28 @@ function normalizeResolvedNumericPxValues(ctx) {
17954
19059
  for (const [key, value] of ctx.resolvedStyleObjects) ctx.resolvedStyleObjects.set(key, normalizeStylexNumericPxValue(ctx, value, void 0, rootNumericIdentifiers));
17955
19060
  }
17956
19061
  function collectRootNumericConstantNames(ctx) {
17957
- const names = /* @__PURE__ */ new Set();
19062
+ const importBindings = [];
19063
+ ctx.root.find(ctx.j.ImportDeclaration).forEach((path) => {
19064
+ const sourceValue = path.node.source.value;
19065
+ if (typeof sourceValue !== "string" || !isStylexImportSource(sourceValue)) return;
19066
+ for (const specifier of path.node.specifiers ?? []) {
19067
+ const localName = specifier.local?.name;
19068
+ const importedName = importSpecifierExportName(specifier);
19069
+ if (localName && importedName) importBindings.push({
19070
+ localName,
19071
+ importedName,
19072
+ source: {
19073
+ kind: "specifier",
19074
+ value: sourceValue
19075
+ }
19076
+ });
19077
+ }
19078
+ });
19079
+ const names = collectNumericStylexImportBindings({
19080
+ j: ctx.j,
19081
+ filePath: ctx.file.path,
19082
+ bindings: importBindings
19083
+ });
17958
19084
  ctx.root.find(ctx.j.VariableDeclarator).forEach((path) => {
17959
19085
  if (!isImmutableTopLevelVariableDeclaratorPath(path)) return;
17960
19086
  const node = path.node;
@@ -17964,6 +19090,12 @@ function collectRootNumericConstantNames(ctx) {
17964
19090
  });
17965
19091
  return names;
17966
19092
  }
19093
+ function importSpecifierExportName(specifier) {
19094
+ const node = specifier;
19095
+ if (node.type === "ImportDefaultSpecifier") return "default";
19096
+ if (node.type !== "ImportSpecifier") return null;
19097
+ return node.imported?.name ?? node.imported?.value ?? null;
19098
+ }
17967
19099
  function isImmutableTopLevelVariableDeclaratorPath(path) {
17968
19100
  const declaration = path.parentPath?.node;
17969
19101
  if (declaration?.type !== "VariableDeclaration" || declaration.kind !== "const") return false;
@@ -17998,6 +19130,10 @@ function isNumericExpressionNode(value, numericIdentifiers) {
17998
19130
  const node = value;
17999
19131
  if (node.type === "NumericLiteral" || node.type === "Literal" && typeof node.value === "number") return true;
18000
19132
  if (node.type === "Identifier") return Boolean(node.name && numericIdentifiers.has(node.name));
19133
+ if (node.type === "MemberExpression") {
19134
+ const rootName = memberExpressionRootName(node);
19135
+ return Boolean(rootName && numericIdentifiers.has(rootName));
19136
+ }
18001
19137
  if (node.type === "UnaryExpression") return (node.operator === "-" || node.operator === "+") && isNumericExpressionNode(node.argument, numericIdentifiers);
18002
19138
  if (node.type === "BinaryExpression") return [
18003
19139
  "+",
@@ -18010,6 +19146,11 @@ function isNumericExpressionNode(value, numericIdentifiers) {
18010
19146
  if (node.type === "ParenthesizedExpression" || node.type === "TSAsExpression") return isNumericExpressionNode(node.expression, numericIdentifiers);
18011
19147
  return false;
18012
19148
  }
19149
+ function memberExpressionRootName(node) {
19150
+ if (node.type === "Identifier") return node.name ?? null;
19151
+ if (node.type !== "MemberExpression" || !node.object || typeof node.object !== "object") return null;
19152
+ return memberExpressionRootName(node.object);
19153
+ }
18013
19154
  function normalizeStylexNumericPxValue(ctx, value, currentProp, numericIdentifiers) {
18014
19155
  if (!value || typeof value !== "object") return value;
18015
19156
  if (Array.isArray(value)) return value.map((entry) => normalizeStylexNumericPxValue(ctx, entry, currentProp, numericIdentifiers));
@@ -18763,7 +19904,7 @@ function groupVariantBucketsIntoDimensions(variantBuckets, variantStyleKeys, bas
18763
19904
  }
18764
19905
  const { conditionWhen } = conditionGroup;
18765
19906
  for (const v of variants) {
18766
- variantMap[v.value] = v.styles;
19907
+ variantMap[v.value] = expandStyleObjectShorthands(v.styles);
18767
19908
  for (const cssProp of Object.keys(v.styles)) allOverriddenProps.add(cssProp);
18768
19909
  }
18769
19910
  const defaultStyles = {};
@@ -18775,10 +19916,10 @@ function groupVariantBucketsIntoDimensions(variantBuckets, variantStyleKeys, bas
18775
19916
  const remainingValues = unionValues.map(String).filter((v) => !explicitValues.has(v));
18776
19917
  if (remainingValues.length === 1 && remainingValues[0]) {
18777
19918
  defaultValue = remainingValues[0];
18778
- variantMap[defaultValue] = defaultStyles;
19919
+ variantMap[defaultValue] = expandStyleObjectShorthands(defaultStyles);
18779
19920
  } else {
18780
19921
  defaultValue = "default";
18781
- variantMap["default"] = defaultStyles;
19922
+ variantMap["default"] = expandStyleObjectShorthands(defaultStyles);
18782
19923
  }
18783
19924
  }
18784
19925
  const firstVariantForProps = variants[0];
@@ -18816,7 +19957,7 @@ function groupVariantBucketsIntoDimensions(variantBuckets, variantStyleKeys, bas
18816
19957
  else merged[cssProp] = boolValue;
18817
19958
  }
18818
19959
  for (const [cssProp, boolValue] of Object.entries(overlappingBoolStyles)) if (!(cssProp in merged)) merged[cssProp] = boolValue;
18819
- disabledVariantMap[variantValue] = merged;
19960
+ disabledVariantMap[variantValue] = expandStyleObjectShorthands(merged);
18820
19961
  }
18821
19962
  dimensions.push({
18822
19963
  propName,
@@ -19802,7 +20943,8 @@ function buildVariantStyleExprs(opts) {
19802
20943
  when: positiveWhen,
19803
20944
  destructureProps,
19804
20945
  booleanProps,
19805
- ...knownProps ? { knownProps } : {}
20946
+ ...knownProps ? { knownProps } : {},
20947
+ nonPropRoots: d.nonPropConditionRoots
19806
20948
  });
19807
20949
  if (onNewDestructureProp && prevLengthRef && destructureProps) for (let i = prevLengthRef.value; i < destructureProps.length; i++) onNewDestructureProp(destructureProps[i]);
19808
20950
  const isCurrentPositive = areEquivalentWhen(when, positiveWhen);
@@ -19817,7 +20959,8 @@ function buildVariantStyleExprs(opts) {
19817
20959
  when,
19818
20960
  destructureProps,
19819
20961
  booleanProps,
19820
- ...knownProps ? { knownProps } : {}
20962
+ ...knownProps ? { knownProps } : {},
20963
+ nonPropRoots: d.nonPropConditionRoots
19821
20964
  });
19822
20965
  if (onNewDestructureProp && prevLengthRef && destructureProps) for (let i = prevLengthRef.value; i < destructureProps.length; i++) onNewDestructureProp(destructureProps[i]);
19823
20966
  const styleExpr = styleRef(j, stylesIdentifier, variantKey);
@@ -19833,7 +20976,8 @@ function buildVariantStyleExprs(opts) {
19833
20976
  when,
19834
20977
  destructureProps,
19835
20978
  booleanProps,
19836
- ...knownProps ? { knownProps } : {}
20979
+ ...knownProps ? { knownProps } : {},
20980
+ nonPropRoots: d.nonPropConditionRoots
19837
20981
  });
19838
20982
  const styleExpr = styleRef(j, stylesIdentifier, variantKey);
19839
20983
  pushExpr(emitter.makeConditionalStyleExpr({
@@ -23718,7 +24862,8 @@ function emitShouldForwardPropWrappers(ctx) {
23718
24862
  for (const when of Object.keys(d.variantStyleKeys ?? {})) {
23719
24863
  const { props } = emitter.collectConditionProps({
23720
24864
  when,
23721
- ...knownConditionProps ? { knownProps: knownConditionProps } : {}
24865
+ ...knownConditionProps ? { knownProps: knownConditionProps } : {},
24866
+ nonPropRoots: d.nonPropConditionRoots
23722
24867
  });
23723
24868
  for (const p of props) if (p) extraProps.add(p);
23724
24869
  }
@@ -23864,7 +25009,8 @@ function emitShouldForwardPropWrappers(ctx) {
23864
25009
  if (compoundVariantKeys.has(when)) continue;
23865
25010
  const { props } = emitter.collectConditionProps({
23866
25011
  when,
23867
- ...knownProps ? { knownProps } : {}
25012
+ ...knownProps ? { knownProps } : {},
25013
+ nonPropRoots: d.nonPropConditionRoots
23868
25014
  });
23869
25015
  for (const p of props) if (p && !dropProps.includes(p)) dropProps.push(p);
23870
25016
  }
@@ -23875,7 +25021,8 @@ function emitShouldForwardPropWrappers(ctx) {
23875
25021
  for (const extra of d.extraStylexPropsArgs) if (extra.when) {
23876
25022
  const { props } = emitter.collectConditionProps({
23877
25023
  when: extra.when,
23878
- ...knownProps ? { knownProps } : {}
25024
+ ...knownProps ? { knownProps } : {},
25025
+ nonPropRoots: d.nonPropConditionRoots
23879
25026
  });
23880
25027
  for (const p of props) if (p && !destructureParts.includes(p)) destructureParts.push(p);
23881
25028
  }
@@ -23909,7 +25056,8 @@ function emitShouldForwardPropWrappers(ctx) {
23909
25056
  when: p.conditionWhen,
23910
25057
  destructureProps: destructureParts,
23911
25058
  booleanProps,
23912
- ...knownProps ? { knownProps } : {}
25059
+ ...knownProps ? { knownProps } : {},
25060
+ nonPropRoots: d.nonPropConditionRoots
23913
25061
  });
23914
25062
  expr = emitter.makeConditionalStyleExpr({
23915
25063
  cond,
@@ -24208,7 +25356,8 @@ function emitSimpleWithConfigWrappers(ctx) {
24208
25356
  if (d.variantStyleKeys) for (const [when] of Object.entries(d.variantStyleKeys)) {
24209
25357
  const { props } = emitter.collectConditionProps({
24210
25358
  when,
24211
- ...knownProps ? { knownProps } : {}
25359
+ ...knownProps ? { knownProps } : {},
25360
+ nonPropRoots: d.nonPropConditionRoots
24212
25361
  });
24213
25362
  for (const p of props) if (p) variantProps.add(p);
24214
25363
  }
@@ -24222,7 +25371,8 @@ function emitSimpleWithConfigWrappers(ctx) {
24222
25371
  if (!extra.when) continue;
24223
25372
  const { props } = emitter.collectConditionProps({
24224
25373
  when: extra.when,
24225
- ...knownProps ? { knownProps } : {}
25374
+ ...knownProps ? { knownProps } : {},
25375
+ nonPropRoots: d.nonPropConditionRoots
24226
25376
  });
24227
25377
  for (const p of props) if (p) extraProps.add(p);
24228
25378
  }
@@ -24817,7 +25967,7 @@ function collectPropsUsedOutsideExtraStyleConditionals(j, d, knownProps) {
24817
25967
  if (name) used.add(name);
24818
25968
  };
24819
25969
  for (const [when] of Object.entries(d.variantStyleKeys ?? {})) {
24820
- const parsed = parseVariantWhenToAst(j, when, void 0, knownProps);
25970
+ const parsed = parseVariantWhenToAst(j, when, void 0, knownProps, d.nonPropConditionRoots);
24821
25971
  for (const prop of parsed.props) add(prop);
24822
25972
  }
24823
25973
  for (const dim of d.variantDimensions ?? []) {
@@ -25497,204 +26647,6 @@ function getTransformedComponentNames(ctx) {
25497
26647
  return names && names.length > 0 ? names : void 0;
25498
26648
  }
25499
26649
  //#endregion
25500
- //#region src/internal/lower-rules/variant-utils.ts
25501
- /**
25502
- * Inverts a "when" condition string for the opposite variant branch.
25503
- * E.g., "!$active" -> "$active", "$x === true" -> "$x !== true"
25504
- */
25505
- function invertWhen(when) {
25506
- if (when.startsWith("!(") && when.endsWith(")")) return when.slice(2, -1);
25507
- if (when.startsWith("!")) return when.slice(1);
25508
- const match = when.match(/^(.+)\s+(===|!==)\s+(.+)$/);
25509
- if (match) {
25510
- const [, propName, op, rhs] = match;
25511
- return `${propName} ${op === "===" ? "!==" : "==="} ${rhs}`;
25512
- }
25513
- if (!when.includes(" ")) return `!${when}`;
25514
- return null;
25515
- }
25516
- function buildPseudoMediaPropValue(args) {
25517
- const { j, valueExpr, pseudos, media } = args;
25518
- const pseudoList = pseudos ?? [];
25519
- const hasPseudos = pseudoList.length > 0;
25520
- if (!media && !hasPseudos) return valueExpr;
25521
- if (media && hasPseudos) {
25522
- const pseudoProps = pseudoList.map((ps) => j.property("init", j.literal(ps), j.objectExpression([j.property("init", j.identifier("default"), j.literal(null)), j.property("init", j.literal(media), valueExpr)])));
25523
- return j.objectExpression([j.property("init", j.identifier("default"), j.literal(null)), ...pseudoProps]);
25524
- }
25525
- if (media) return j.objectExpression([j.property("init", j.identifier("default"), j.literal(null)), j.property("init", j.literal(media), valueExpr)]);
25526
- const pseudoProps = pseudoList.map((ps) => j.property("init", j.literal(ps), valueExpr));
25527
- return j.objectExpression([j.property("init", j.identifier("default"), j.literal(null)), ...pseudoProps]);
25528
- }
25529
- const createPropTestHelpers = (bindings) => {
25530
- const paramName = bindings.kind === "simple" ? bindings.paramName : null;
25531
- const getMemberExpressionSource = (node) => {
25532
- const info = extractRootAndPath(node);
25533
- if (!info) return null;
25534
- if (info.path.length === 0) return info.rootName;
25535
- return `${info.rootName}.${info.path.join(".")}`;
25536
- };
25537
- const readPropAccess = (node) => {
25538
- const info = extractRootAndPath(node);
25539
- if (!info) return null;
25540
- if (paramName && info.rootName === paramName) {
25541
- if (info.path.length === 0) return null;
25542
- const [propRoot, ...rest] = info.path;
25543
- if (!propRoot) return null;
25544
- if (propRoot === "theme") return null;
25545
- return {
25546
- propName: propRoot,
25547
- whenName: [propRoot, ...rest].join(".")
25548
- };
25549
- }
25550
- if (bindings.kind === "destructured") {
25551
- const propName = resolveIdentifierToPropName(info.rootNode, bindings);
25552
- if (!propName) return null;
25553
- return {
25554
- propName,
25555
- whenName: info.path.length > 0 ? `${propName}.${info.path.join(".")}` : propName
25556
- };
25557
- }
25558
- return null;
25559
- };
25560
- const parseTestInfo = (test) => {
25561
- if (!test || typeof test !== "object") return null;
25562
- if (test.type === "Identifier" && bindings.kind === "destructured") {
25563
- const propAccess = readPropAccess(test);
25564
- return propAccess ? {
25565
- when: propAccess.whenName,
25566
- propName: propAccess.propName
25567
- } : null;
25568
- }
25569
- if (isMemberExpression(test)) {
25570
- const propAccess = readPropAccess(test);
25571
- return propAccess ? {
25572
- when: propAccess.whenName,
25573
- propName: propAccess.propName
25574
- } : null;
25575
- }
25576
- if (test.type === "UnaryExpression" && test.operator === "!" && test.argument) {
25577
- const propAccess = readPropAccess(test.argument);
25578
- return propAccess ? {
25579
- when: `!${propAccess.whenName}`,
25580
- propName: propAccess.propName
25581
- } : null;
25582
- }
25583
- if (test.type === "BinaryExpression" && (test.operator === "===" || test.operator === "!==")) {
25584
- const left = test.left;
25585
- const getRhsValue = () => {
25586
- const rhsTyped = test.right;
25587
- if (rhsTyped.type === "Identifier" && rhsTyped.name === "undefined") return "undefined";
25588
- const rhs = literalToStaticValue(test.right);
25589
- if (rhs === null) return getMemberExpressionSource(test.right);
25590
- return JSON.stringify(rhs);
25591
- };
25592
- if (bindings.kind === "destructured" && left.type === "Identifier") {
25593
- const propAccess = readPropAccess(left);
25594
- const rhsValue = getRhsValue();
25595
- if (!propAccess || rhsValue === null) return null;
25596
- return {
25597
- when: `${propAccess.whenName} ${test.operator} ${rhsValue}`,
25598
- propName: propAccess.propName
25599
- };
25600
- }
25601
- if (isMemberExpression(left)) {
25602
- const propAccess = readPropAccess(left);
25603
- const rhsValue = getRhsValue();
25604
- if (!propAccess || rhsValue === null) return null;
25605
- return {
25606
- when: `${propAccess.whenName} ${test.operator} ${rhsValue}`,
25607
- propName: propAccess.propName
25608
- };
25609
- }
25610
- }
25611
- return null;
25612
- };
25613
- /**
25614
- * Parse chained && / || conditions, returning a combined TestInfo.
25615
- *
25616
- * Supported patterns:
25617
- * props.a && props.b → { when: 'a && b' }
25618
- * props.$a || props.$b → { when: '$a || $b' }
25619
- * props.$a && (props.$b || $c) → { when: '$a && $b || $c' }
25620
- * !(props.$a || props.$b) → { when: '!($a || $b)' }
25621
- *
25622
- * Bails (returns null) on || wrapping && children to avoid ambiguous
25623
- * serialization: "a && b || c" would be reparsed as "a && (b || c)"
25624
- * by parseVariantWhenToAst, which splits on && first.
25625
- */
25626
- const parseChainedTestInfo = (test) => {
25627
- const simple = parseTestInfo(test);
25628
- if (simple) return simple;
25629
- if (!test || typeof test !== "object") return null;
25630
- if (test.type === "UnaryExpression" && test.operator === "!" && test.argument) {
25631
- const innerInfo = parseChainedTestInfo(test.argument);
25632
- if (innerInfo) {
25633
- const allProps = innerInfo.allPropNames ?? (innerInfo.propName ? [innerInfo.propName] : []);
25634
- return {
25635
- when: `!(${innerInfo.when})`,
25636
- propName: innerInfo.propName,
25637
- allPropNames: allProps
25638
- };
25639
- }
25640
- }
25641
- if (test.type === "LogicalExpression" && (test.operator === "&&" || test.operator === "||")) {
25642
- const leftInfo = parseChainedTestInfo(test.left);
25643
- const rightInfo = parseChainedTestInfo(test.right);
25644
- if (leftInfo && rightInfo) {
25645
- if (test.operator === "||" && (leftInfo.when.includes(" && ") || rightInfo.when.includes(" && "))) return null;
25646
- if (hasOperatorInsideParens(leftInfo.when, test.operator) || hasOperatorInsideParens(rightInfo.when, test.operator)) return null;
25647
- const combinedWhen = `${leftInfo.when} ${test.operator} ${rightInfo.when}`;
25648
- const leftProps = leftInfo.allPropNames ?? (leftInfo.propName ? [leftInfo.propName] : []);
25649
- const rightProps = rightInfo.allPropNames ?? (rightInfo.propName ? [rightInfo.propName] : []);
25650
- const allPropNames = [...new Set([...leftProps, ...rightProps])];
25651
- return {
25652
- when: combinedWhen,
25653
- propName: rightInfo.propName,
25654
- allPropNames
25655
- };
25656
- }
25657
- }
25658
- return null;
25659
- };
25660
- return {
25661
- parseTestInfo,
25662
- parseChainedTestInfo
25663
- };
25664
- };
25665
- const createVariantApplier = (args) => {
25666
- const { decl, variantBuckets, variantStyleKeys } = args;
25667
- const dropAllTestInfoProps = (testInfo) => {
25668
- const propsToCheck = testInfo.allPropNames ?? (testInfo.propName ? [testInfo.propName] : []);
25669
- for (const prop of propsToCheck) if (prop && !prop.startsWith("$")) ensureShouldForwardPropDrop(decl, prop);
25670
- };
25671
- return (testInfo, consStyle) => {
25672
- const when = testInfo.when;
25673
- const existingBucket = variantBuckets.get(when);
25674
- const nextBucket = existingBucket ? { ...existingBucket } : {};
25675
- mergeStyleObjects(nextBucket, consStyle);
25676
- variantBuckets.set(when, nextBucket);
25677
- variantStyleKeys[when] ??= styleKeyWithSuffix(decl.styleKey, when);
25678
- dropAllTestInfoProps(testInfo);
25679
- };
25680
- };
25681
- /**
25682
- * Returns true if the string contains the given operator (`&&` or `||`)
25683
- * inside parenthesized groups. Used to detect when strings like
25684
- * `"!($b && $c)"` or `"!($b || $c)"` that would be broken by the naive
25685
- * split in `parseVariantWhenToAst`.
25686
- */
25687
- function hasOperatorInsideParens(when, operator) {
25688
- let depth = 0;
25689
- for (let i = 0; i < when.length; i++) {
25690
- const ch = when[i];
25691
- if (ch === "(") depth++;
25692
- else if (ch === ")") depth--;
25693
- else if (depth > 0 && when[i] === operator[0] && when.startsWith(operator, i)) return true;
25694
- }
25695
- return false;
25696
- }
25697
- //#endregion
25698
26650
  //#region src/internal/lower-rules/slot-utils.ts
25699
26651
  /**
25700
26652
  * Locate the slot interpolation in a `${...}` value and return its
@@ -26615,43 +27567,47 @@ function tryResolveConditionalValue(node, ctx) {
26615
27567
  }
26616
27568
  if (info?.kind === "themeBinding" && test.type === "Identifier" && typeof test.name === "string" && isDestructuredFromParam(expr, test.name)) {
26617
27569
  const destructuredProp = test.name;
26618
- const cons = getBranch(consequent);
26619
- const alt = getBranch(alternate);
26620
- if (cons && alt) {
26621
- if (new Set([cons.usage, alt.usage]).size === 1) {
26622
- const usage = cons.usage;
26623
- const variants = [{
26624
- nameHint: "truthy",
26625
- when: destructuredProp,
26626
- expr: cons.expr,
26627
- imports: cons.imports
26628
- }, {
26629
- nameHint: "falsy",
26630
- when: `!${destructuredProp}`,
26631
- expr: alt.expr,
26632
- imports: alt.imports
26633
- }];
26634
- return usage === "props" ? {
26635
- type: "splitVariantsResolvedStyles",
26636
- variants
26637
- } : {
26638
- type: "splitVariantsResolvedValue",
26639
- variants
26640
- };
27570
+ const whens = destructuredBooleanWhens(destructuredProp, getArrowFnParamBindings(expr));
27571
+ if (whens) {
27572
+ const cons = getBranch(consequent);
27573
+ const alt = getBranch(alternate);
27574
+ if (cons && alt) {
27575
+ if (new Set([cons.usage, alt.usage]).size === 1) {
27576
+ const usage = cons.usage;
27577
+ const variants = [{
27578
+ nameHint: "truthy",
27579
+ when: whens.truthy,
27580
+ expr: cons.expr,
27581
+ imports: cons.imports
27582
+ }, {
27583
+ nameHint: "falsy",
27584
+ when: whens.falsy,
27585
+ expr: alt.expr,
27586
+ imports: alt.imports
27587
+ }];
27588
+ return usage === "props" ? {
27589
+ type: "splitVariantsResolvedStyles",
27590
+ variants
27591
+ } : {
27592
+ type: "splitVariantsResolvedValue",
27593
+ variants
27594
+ };
27595
+ }
26641
27596
  }
27597
+ const oneSided = buildOneSidedVariantResult({
27598
+ cons,
27599
+ alt,
27600
+ alternate,
27601
+ truthyWhen: whens.truthy
27602
+ });
27603
+ if (oneSided) return oneSided;
27604
+ if (!cons || !alt) return buildRuntimeCallResult();
26642
27605
  }
26643
- const oneSided = buildOneSidedVariantResult({
26644
- cons,
26645
- alt,
26646
- alternate,
26647
- truthyWhen: destructuredProp
26648
- });
26649
- if (oneSided) return oneSided;
26650
- if (!cons || !alt) return buildRuntimeCallResult();
26651
27606
  }
26652
27607
  if (paramBindings?.kind === "destructured" && test.type === "Identifier" && typeof test.name === "string") {
26653
27608
  const resolvedProp = resolveIdentifierToPropName(test, paramBindings);
26654
- if (resolvedProp) {
27609
+ const resolvedWhens = resolvedProp ? destructuredBooleanWhens(resolvedProp, paramBindings) : null;
27610
+ if (resolvedProp && resolvedWhens) {
26655
27611
  const cons = getBranch(consequent);
26656
27612
  const alt = getBranch(alternate);
26657
27613
  if (cons && alt) {
@@ -26659,12 +27615,12 @@ function tryResolveConditionalValue(node, ctx) {
26659
27615
  const usage = cons.usage;
26660
27616
  const variants = [{
26661
27617
  nameHint: "truthy",
26662
- when: resolvedProp,
27618
+ when: resolvedWhens.truthy,
26663
27619
  expr: cons.expr,
26664
27620
  imports: cons.imports
26665
27621
  }, {
26666
27622
  nameHint: "falsy",
26667
- when: `!${resolvedProp}`,
27623
+ when: resolvedWhens.falsy,
26668
27624
  expr: alt.expr,
26669
27625
  imports: alt.imports
26670
27626
  }];
@@ -26689,7 +27645,7 @@ function tryResolveConditionalValue(node, ctx) {
26689
27645
  cons,
26690
27646
  alt,
26691
27647
  alternate,
26692
- truthyWhen: resolvedProp
27648
+ truthyWhen: resolvedWhens.truthy
26693
27649
  });
26694
27650
  if (oneSided) return oneSided;
26695
27651
  if (!cons || !alt) return buildRuntimeCallResult();
@@ -26766,6 +27722,8 @@ function tryResolveConditionalCssBlock(node, ctx) {
26766
27722
  const { left, right } = body;
26767
27723
  const testProp = paramName ? getSinglePropFromMemberExpr(left, paramName) : bindings?.kind === "destructured" ? resolveIdentifierToPropName(left, bindings) : null;
26768
27724
  if (!testProp) return null;
27725
+ const whens = destructuredBooleanWhens(testProp, bindings);
27726
+ if (!whens) return null;
26769
27727
  const cssText = literalToString(right);
26770
27728
  if (cssText !== null && cssText !== void 0) {
26771
27729
  const style = parseCssDeclarationBlock(cssText);
@@ -26774,7 +27732,7 @@ function tryResolveConditionalCssBlock(node, ctx) {
26774
27732
  type: "splitVariants",
26775
27733
  variants: [{
26776
27734
  nameHint: "truthy",
26777
- when: testProp,
27735
+ when: whens.truthy,
26778
27736
  style
26779
27737
  }]
26780
27738
  };
@@ -26782,7 +27740,7 @@ function tryResolveConditionalCssBlock(node, ctx) {
26782
27740
  if (!paramName) return null;
26783
27741
  return resolveThemeTemplateToCssVariant(right, paramName, ctx, {
26784
27742
  nameHint: "truthy",
26785
- when: testProp
27743
+ when: whens.truthy
26786
27744
  });
26787
27745
  }
26788
27746
  function tryResolveConditionalCssBlockTernary(node, ctx) {
@@ -27234,6 +28192,35 @@ function replaceThemeRefsWithHookVar(expr, paramName, info) {
27234
28192
  };
27235
28193
  return replace(cloned);
27236
28194
  }
28195
+ /**
28196
+ * Builds truthy/falsy `when` condition strings for a destructured boolean-ish prop,
28197
+ * accounting for destructuring defaults. A default applies only when the prop is
28198
+ * `undefined`, so a statically-truthy default means the truthy branch must also
28199
+ * apply when the prop is unset (`prop === undefined || prop`).
28200
+ *
28201
+ * Returns null when the prop has a default whose truthiness cannot be determined
28202
+ * statically — callers should fall back to other handlers instead of emitting a
28203
+ * condition that ignores the default.
28204
+ */
28205
+ function destructuredBooleanWhens(propName, bindings) {
28206
+ if (bindings?.kind !== "destructured" || !bindings.defaults?.has(propName)) return {
28207
+ truthy: propName,
28208
+ falsy: `!${propName}`
28209
+ };
28210
+ const defaultValue = literalToStaticValue(bindings.defaults.get(propName));
28211
+ if (defaultValue === null) return null;
28212
+ if (defaultValue) {
28213
+ const truthy = `${propName} === undefined || ${propName}`;
28214
+ return {
28215
+ truthy,
28216
+ falsy: `!(${truthy})`
28217
+ };
28218
+ }
28219
+ return {
28220
+ truthy: propName,
28221
+ falsy: `!${propName}`
28222
+ };
28223
+ }
27237
28224
  //#endregion
27238
28225
  //#region src/internal/builtin-handlers.ts
27239
28226
  /**
@@ -28666,7 +29653,7 @@ function tryHandleInterpolatedStringValue(args) {
28666
29653
  if (!entries.length) return false;
28667
29654
  for (const entry of entries) {
28668
29655
  const usesExpr = entry.value.includes(`__SC_EXPR_${slotId}__`);
28669
- setValue(entry.prop, usesExpr ? maybeOmitPxUnitFromStylexValue(j, tl, entry.prop, d.important) : 0);
29656
+ setValue(entry.prop, usesExpr ? maybeOmitPxUnitFromStylexValue(j, tl, entry.prop, d.important, { numericIdentifiers: args.numericIdentifiers }) : 0);
28670
29657
  }
28671
29658
  return true;
28672
29659
  }
@@ -28733,7 +29720,9 @@ function tryHandleInterpolatedStringValue(args) {
28733
29720
  const outputs = cssDeclarationToStylexDeclarations(d);
28734
29721
  for (let i = 0; i < outputs.length; i++) {
28735
29722
  const out = outputs[i];
28736
- setValue(out.prop, maybeOmitPxUnitFromStylexValue(j, tl, out.prop, d.important));
29723
+ const emitted = maybeOmitPxUnitFromStylexValue(j, tl, out.prop, d.important, { numericIdentifiers: args.numericIdentifiers });
29724
+ if (emitted !== tl && hasSingleSlotUnitSuffix(d.value)) markProvenSingleTokenValue(emitted);
29725
+ setValue(out.prop, emitted);
28737
29726
  if (i === 0 && (d.leadingComment || d.leadingLineComment)) addPropComments(styleObj, out.prop, {
28738
29727
  leading: d.leadingComment,
28739
29728
  leadingLine: d.leadingLineComment
@@ -32841,7 +33830,12 @@ const createValuePatternHandlers = (ctx) => {
32841
33830
  callArg,
32842
33831
  condition: "always"
32843
33832
  });
32844
- } else styleFnFromProps.push({
33833
+ } else if (expr.body.operator === "||") styleFnFromProps.push({
33834
+ fnKey,
33835
+ jsxProp,
33836
+ condition: "truthy"
33837
+ });
33838
+ else styleFnFromProps.push({
32845
33839
  fnKey,
32846
33840
  jsxProp
32847
33841
  });
@@ -33270,6 +34264,7 @@ function createDeclProcessingState(state, decl) {
33270
34264
  const styleFnDecls = /* @__PURE__ */ new Map();
33271
34265
  const attrBuckets = /* @__PURE__ */ new Map();
33272
34266
  const observedVariantFallbackFns = /* @__PURE__ */ new Map();
34267
+ let currentDeclarationSourceOrder;
33273
34268
  const inlineStyleProps = [];
33274
34269
  const localVarValues = /* @__PURE__ */ new Map();
33275
34270
  const cssHelperPropValues = /* @__PURE__ */ new Map();
@@ -33333,7 +34328,10 @@ function createDeclProcessingState(state, decl) {
33333
34328
  const applyVariant = createVariantApplier({
33334
34329
  decl,
33335
34330
  variantBuckets,
33336
- variantStyleKeys
34331
+ variantStyleKeys,
34332
+ baseStyleObj: styleObj,
34333
+ conditionStyleObjs: [perPropPseudo, perPropMedia],
34334
+ getCurrentSourceOrder: () => currentDeclarationSourceOrder
33337
34335
  });
33338
34336
  const dropAllTestInfoProps = (testInfo) => {
33339
34337
  const propsToCheck = testInfo.allPropNames ?? (testInfo.propName ? [testInfo.propName] : []);
@@ -33484,6 +34482,10 @@ function createDeclProcessingState(state, decl) {
33484
34482
  styleFnDecls,
33485
34483
  attrBuckets,
33486
34484
  observedVariantFallbackFns,
34485
+ getCurrentDeclarationSourceOrder: () => currentDeclarationSourceOrder,
34486
+ setCurrentDeclarationSourceOrder: (sourceOrder) => {
34487
+ currentDeclarationSourceOrder = sourceOrder;
34488
+ },
33487
34489
  inlineStyleProps,
33488
34490
  localVarValues,
33489
34491
  cssHelperPropValues,
@@ -33540,6 +34542,89 @@ function createDeclProcessingState(state, decl) {
33540
34542
  };
33541
34543
  }
33542
34544
  //#endregion
34545
+ //#region src/internal/lower-rules/validate-decl-conflicts.ts
34546
+ /**
34547
+ * Returns the name of an imported runtime-condition root (recorded in
34548
+ * `nonPropConditionRoots`) that also appears as a genuine component prop. Such a
34549
+ * collision is unrepresentable: the decl-wide non-prop marking suppresses
34550
+ * destructuring of the prop, so a prop-based variant would silently read the
34551
+ * imported binding instead. Covers both typed props and props inferred from
34552
+ * `props.<name>` usage in styling.
34553
+ *
34554
+ * `variantWhens` must be sourced from the in-progress finalize state, since
34555
+ * `decl.variantStyleKeys` is not assigned until later in finalize.
34556
+ */
34557
+ function findImportedRootPropCollision(decl, variantWhens) {
34558
+ const roots = decl.nonPropConditionRoots;
34559
+ if (!roots || roots.size === 0) return null;
34560
+ const directProps = collectDirectPropReferences(decl);
34561
+ for (const root of roots) {
34562
+ if (directProps.has(root)) return root;
34563
+ const bareRef = new RegExp(`(?:^|[^\\w.])${escapeRegex(root)}(?:$|[^\\w.])`);
34564
+ if (variantWhens.some((when) => bareRef.test(when))) return root;
34565
+ }
34566
+ return null;
34567
+ }
34568
+ /**
34569
+ * Returns true when the component declares both a logical scroll longhand
34570
+ * (e.g. `scroll-padding-inline-start`) and a physical scroll side
34571
+ * (e.g. `scroll-padding-left`) in the same scroll family. StyleX's
34572
+ * logical/physical conflict normalization resolves these to physical sides
34573
+ * assuming horizontal-tb LTR, but the logical-to-physical mapping depends on
34574
+ * `writing-mode`/`direction` (e.g. `inline-start` is the right side in RTL),
34575
+ * so any such mix may silently preserve or override the wrong side — bail.
34576
+ */
34577
+ function hasConflictingLogicalPhysicalScrollProps(decl) {
34578
+ for (const family of SCROLL_FAMILIES) {
34579
+ let hasLogical = false;
34580
+ let hasPhysical = false;
34581
+ for (const rule of decl.rules) for (const declaration of rule.declarations) {
34582
+ const prop = declaration.property?.trim();
34583
+ if (!prop) continue;
34584
+ const camel = kebabToCamel(prop);
34585
+ if (!camel.startsWith(family)) continue;
34586
+ const side = camel.slice(family.length);
34587
+ if (/^(?:Inline|Block)/.test(side)) hasLogical = true;
34588
+ else if (side === "" || /^(?:Top|Right|Bottom|Left)$/.test(side)) hasPhysical = true;
34589
+ }
34590
+ if (hasLogical && hasPhysical) return true;
34591
+ }
34592
+ return false;
34593
+ }
34594
+ const SCROLL_FAMILIES = ["scrollMargin", "scrollPadding"];
34595
+ function collectDirectPropReferences(decl) {
34596
+ const props = /* @__PURE__ */ new Set();
34597
+ const add = (name) => {
34598
+ if (name && !name.startsWith("__")) props.add(name);
34599
+ };
34600
+ for (const name of decl.typeScriptExplicitPropNames ?? []) add(name);
34601
+ for (const entry of decl.styleFnFromProps ?? []) {
34602
+ add(entry.jsxProp);
34603
+ for (const extra of entry.extraCallArgs ?? []) add(extra.jsxProp);
34604
+ }
34605
+ for (const entry of decl.inlineStyleProps ?? []) add(entry.jsxProp);
34606
+ for (const dim of decl.variantDimensions ?? []) {
34607
+ add(dim.propName);
34608
+ add(dim.namespaceBooleanProp);
34609
+ }
34610
+ for (const cv of decl.compoundVariants ?? []) {
34611
+ add(cv.outerProp);
34612
+ add(cv.innerProp);
34613
+ }
34614
+ const attrs = decl.attrsInfo;
34615
+ if (attrs) {
34616
+ for (const entry of attrs.defaultAttrs ?? []) add(entry.jsxProp);
34617
+ for (const entry of attrs.dynamicAttrs ?? []) add(entry.jsxProp);
34618
+ for (const entry of attrs.conditionalAttrs ?? []) add(entry.jsxProp);
34619
+ for (const entry of attrs.invertedBoolAttrs ?? []) add(entry.jsxProp);
34620
+ for (const entry of attrs.attrsDynamicStyles ?? []) add(entry.jsxProp);
34621
+ }
34622
+ return props;
34623
+ }
34624
+ function kebabToCamel(prop) {
34625
+ return prop.replace(/-([a-z])/g, (_, ch) => ch.toUpperCase());
34626
+ }
34627
+ //#endregion
33543
34628
  //#region src/internal/lower-rules/finalize-decl.ts
33544
34629
  /**
33545
34630
  * Finalizes per-declaration style objects after rule processing.
@@ -33548,6 +34633,14 @@ function createDeclProcessingState(state, decl) {
33548
34633
  function finalizeDeclProcessing(ctx) {
33549
34634
  const { state, decl, styleObj, perPropPseudo, perPropMedia, perPropComputedMedia, nestedSelectors, variantBuckets, variantStyleKeys, variantSourceOrder, extraStyleObjects, styleFnFromProps, styleFnDecls, attrBuckets, observedVariantFallbackFns, inlineStyleProps, localVarValues, cssHelperPropValues } = ctx;
33550
34635
  const { rewriteCssVarsInStyleObject, rewriteCssVarsInAstNode, relationOverridePseudoBuckets, relationOverrides, ancestorSelectorParents, resolvedStyleObjects, warnings } = state;
34636
+ if (findImportedRootPropCollision(decl, Object.keys(variantStyleKeys ?? {}))) {
34637
+ state.bailUnsupported(decl, "Imported runtime condition root collides with a component prop of the same name");
34638
+ return;
34639
+ }
34640
+ if (hasConflictingLogicalPhysicalScrollProps(decl)) {
34641
+ state.bailUnsupported(decl, "Mixed logical and physical scroll properties cannot be normalized without a known writing-mode");
34642
+ return;
34643
+ }
33551
34644
  mergeConditionBucket(styleObj, perPropPseudo);
33552
34645
  mergeConditionBucket(styleObj, perPropMedia);
33553
34646
  for (const [prop, entry] of perPropComputedMedia) {
@@ -33572,8 +34665,29 @@ function finalizeDeclProcessing(ctx) {
33572
34665
  }
33573
34666
  }
33574
34667
  for (const [sel, obj] of Object.entries(nestedSelectors)) styleObj[sel] = obj;
34668
+ const baseRawEntries = Object.entries(styleObj);
34669
+ resolveBoxShorthandConflicts(styleObj);
33575
34670
  resolveDirectionalConflicts(styleObj);
34671
+ expandMultiValueBorderRadius(styleObj);
33576
34672
  warnOpaqueShorthands(styleObj, decl, warnings);
34673
+ for (const bucket of variantBuckets.values()) {
34674
+ resolveBoxShorthandConflicts(bucket);
34675
+ resolveDirectionalConflicts(bucket, { skipNullishShorthandDefault: true });
34676
+ expandMultiValueBorderRadius(bucket);
34677
+ warnOpaqueShorthands(bucket, decl, warnings);
34678
+ }
34679
+ const variantBucketObjects = [...variantBuckets.values()];
34680
+ harmonizeShorthandExpansion([
34681
+ styleObj,
34682
+ ...variantBucketObjects,
34683
+ ...extraStyleObjects.values()
34684
+ ], {
34685
+ baseStyleObj: styleObj,
34686
+ inheritBaseLateSides: new Set(variantBucketObjects),
34687
+ baseRawEntries,
34688
+ bucketBaseKeySnapshot: bucketSnapshotLookup(decl, variantBuckets),
34689
+ bucketSourceOrder: bucketSourceOrderLookup(decl, variantBuckets)
34690
+ });
33577
34691
  registerLocalStylexVarFallbacks(state, decl, styleObj);
33578
34692
  const varsToDrop = /* @__PURE__ */ new Set();
33579
34693
  const staticInlineStyleProps = decl.staticInlineStyleProps ?? [];
@@ -33755,13 +34869,21 @@ function finalizeDeclProcessing(ctx) {
33755
34869
  const oldKey = decl.styleKey;
33756
34870
  decl.styleKey = baseKey;
33757
34871
  resolvedStyleObjects.delete(oldKey);
34872
+ expandMultiValueBorderRadius(styleObj);
33758
34873
  resolvedStyleObjects.set(baseKey, styleObj);
33759
- for (const [k, v] of extraStyleObjects.entries()) resolvedStyleObjects.set(k, v);
34874
+ for (const [k, v] of extraStyleObjects.entries()) {
34875
+ expandMultiValueBorderRadius(v);
34876
+ resolvedStyleObjects.set(k, v);
34877
+ }
33760
34878
  for (const c of cases) resolvedStyleObjects.set(c.styleKey, { backgroundColor: c.value });
33761
34879
  decl.needsWrapperComponent = true;
33762
34880
  } else {
34881
+ expandMultiValueBorderRadius(styleObj);
33763
34882
  resolvedStyleObjects.set(decl.styleKey, styleObj);
33764
- for (const [k, v] of extraStyleObjects.entries()) resolvedStyleObjects.set(k, v);
34883
+ for (const [k, v] of extraStyleObjects.entries()) {
34884
+ expandMultiValueBorderRadius(v);
34885
+ resolvedStyleObjects.set(k, v);
34886
+ }
33765
34887
  }
33766
34888
  {
33767
34889
  const isPseudoOrMediaMap = (v) => {
@@ -33847,8 +34969,22 @@ function finalizeDeclProcessing(ctx) {
33847
34969
  extraStyleObjects,
33848
34970
  attrBuckets
33849
34971
  });
34972
+ const remainingBucketObjects = [...remainingBuckets.values()];
34973
+ harmonizeShorthandExpansion([
34974
+ styleObj,
34975
+ ...remainingBucketObjects,
34976
+ ...extraStyleObjects.values(),
34977
+ ...attrBuckets.values()
34978
+ ], {
34979
+ baseStyleObj: styleObj,
34980
+ inheritBaseLateSides: new Set(remainingBucketObjects),
34981
+ baseRawEntries,
34982
+ bucketBaseKeySnapshot: bucketSnapshotLookup(decl, remainingBuckets),
34983
+ bucketSourceOrder: bucketSourceOrderLookup(decl, remainingBuckets)
34984
+ });
33850
34985
  for (const [when, obj] of remainingBuckets.entries()) {
33851
34986
  const key = remainingStyleKeys[when];
34987
+ expandMultiValueBorderRadius(obj);
33852
34988
  resolvedStyleObjects.set(key, obj);
33853
34989
  }
33854
34990
  for (const [k, v] of attrBuckets.entries()) resolvedStyleObjects.set(k, v);
@@ -34768,8 +35904,10 @@ function replaceIdentifierInAst(j, node, oldName) {
34768
35904
  function mergeConditionBucket(styleObj, bucket) {
34769
35905
  for (const [prop, map] of Object.entries(bucket)) {
34770
35906
  const existing = styleObj[prop];
34771
- if (existing && typeof existing === "object" && !isAstNode$1(existing) && !Array.isArray(existing)) mergeStyleObjects(existing, map);
34772
- else {
35907
+ if (existing && typeof existing === "object" && !isAstNode$1(existing) && !Array.isArray(existing)) {
35908
+ mergeStyleObjects(existing, map);
35909
+ copyConditionSourceOrders(existing, map);
35910
+ } else {
34773
35911
  if (existing !== void 0 && (map.default === null || map.default === void 0)) map.default = existing;
34774
35912
  styleObj[prop] = map;
34775
35913
  }
@@ -34855,6 +35993,23 @@ const AXIS_PAIRS = [
34855
35993
  end: "marginRight"
34856
35994
  }
34857
35995
  ];
35996
+ const BOX_SHORTHAND_CONFLICTS = [{
35997
+ shorthand: "padding",
35998
+ top: "paddingTop",
35999
+ right: "paddingRight",
36000
+ bottom: "paddingBottom",
36001
+ left: "paddingLeft",
36002
+ block: "paddingBlock",
36003
+ inline: "paddingInline"
36004
+ }, {
36005
+ shorthand: "margin",
36006
+ top: "marginTop",
36007
+ right: "marginRight",
36008
+ bottom: "marginBottom",
36009
+ left: "marginLeft",
36010
+ block: "marginBlock",
36011
+ inline: "marginInline"
36012
+ }];
34858
36013
  const LOGICAL_SIDE_PAIRS = [
34859
36014
  {
34860
36015
  logical: "paddingBlockStart",
@@ -34897,6 +36052,94 @@ function isMediaOrPseudoMap(v) {
34897
36052
  const keys = Object.keys(v);
34898
36053
  return keys.includes("default") || keys.some((k) => k.startsWith(":") || k.startsWith("@"));
34899
36054
  }
36055
+ function resolveBoxShorthandConflicts(styleObj) {
36056
+ for (const config of BOX_SHORTHAND_CONFLICTS) {
36057
+ const shorthandVal = styleObj[config.shorthand];
36058
+ if (shorthandVal === void 0) continue;
36059
+ const sideProps = [
36060
+ config.top,
36061
+ config.right,
36062
+ config.bottom,
36063
+ config.left,
36064
+ config.block,
36065
+ config.inline
36066
+ ];
36067
+ if (!sideProps.some((prop) => prop in styleObj)) continue;
36068
+ const entries = Object.entries(styleObj);
36069
+ const shorthandIndex = entries.findIndex(([key]) => key === config.shorthand);
36070
+ recordLateSideOverrides(styleObj, config, entries, shorthandIndex);
36071
+ const replacements = {
36072
+ [config.top]: resolveBoxSideConflictValue({
36073
+ shorthandVal,
36074
+ shorthandIndex,
36075
+ longhandVal: styleObj[config.top],
36076
+ longhandIndex: entries.findIndex(([key]) => key === config.top),
36077
+ axisVal: styleObj[config.block],
36078
+ axisIndex: entries.findIndex(([key]) => key === config.block)
36079
+ }),
36080
+ [config.right]: resolveBoxSideConflictValue({
36081
+ shorthandVal,
36082
+ shorthandIndex,
36083
+ longhandVal: styleObj[config.right],
36084
+ longhandIndex: entries.findIndex(([key]) => key === config.right),
36085
+ axisVal: styleObj[config.inline],
36086
+ axisIndex: entries.findIndex(([key]) => key === config.inline)
36087
+ }),
36088
+ [config.bottom]: resolveBoxSideConflictValue({
36089
+ shorthandVal,
36090
+ shorthandIndex,
36091
+ longhandVal: styleObj[config.bottom],
36092
+ longhandIndex: entries.findIndex(([key]) => key === config.bottom),
36093
+ axisVal: styleObj[config.block],
36094
+ axisIndex: entries.findIndex(([key]) => key === config.block)
36095
+ }),
36096
+ [config.left]: resolveBoxSideConflictValue({
36097
+ shorthandVal,
36098
+ shorthandIndex,
36099
+ longhandVal: styleObj[config.left],
36100
+ longhandIndex: entries.findIndex(([key]) => key === config.left),
36101
+ axisVal: styleObj[config.inline],
36102
+ axisIndex: entries.findIndex(([key]) => key === config.inline)
36103
+ })
36104
+ };
36105
+ for (const key of Object.keys(styleObj)) delete styleObj[key];
36106
+ for (const [key, val] of entries) if (key === config.shorthand) {
36107
+ styleObj[config.top] = replacements[config.top];
36108
+ styleObj[config.right] = replacements[config.right];
36109
+ styleObj[config.bottom] = replacements[config.bottom];
36110
+ styleObj[config.left] = replacements[config.left];
36111
+ } else if (sideProps.includes(key)) continue;
36112
+ else styleObj[key] = val;
36113
+ }
36114
+ }
36115
+ function resolveBoxSideConflictValue(args) {
36116
+ const { shorthandVal, shorthandIndex, longhandVal, longhandIndex, axisVal, axisIndex } = args;
36117
+ const base = latestIndexedValue([{
36118
+ value: axisVal,
36119
+ index: axisIndex
36120
+ }, {
36121
+ value: longhandVal,
36122
+ index: longhandIndex
36123
+ }]);
36124
+ if (!isMediaOrPseudoMap(shorthandVal)) {
36125
+ if (!base || shorthandIndex > base.index) return shorthandVal;
36126
+ if (isMediaOrPseudoMap(base.value)) return mergeScalarDefaultIntoLonghand(base.value, shorthandVal);
36127
+ return base.value;
36128
+ }
36129
+ const defaultValue = shorthandVal.default != null && (!base || shorthandIndex > base.index) ? shorthandVal.default : base?.value ?? shorthandVal.default ?? null;
36130
+ if (base && base.index > shorthandIndex && isMediaOrPseudoMap(base.value)) return computeMergedLonghand(base.value, shorthandVal);
36131
+ const result = { default: defaultValue };
36132
+ for (const [condition, conditionValue] of Object.entries(shorthandVal)) if (condition !== "default" && conditionValue != null) result[condition] = conditionValue;
36133
+ return result;
36134
+ }
36135
+ function latestIndexedValue(candidates) {
36136
+ let latest = null;
36137
+ for (const candidate of candidates) {
36138
+ if (candidate.index < 0 || candidate.value === void 0) continue;
36139
+ if (!latest || candidate.index > latest.index) latest = candidate;
36140
+ }
36141
+ return latest;
36142
+ }
34900
36143
  /**
34901
36144
  * Resolves conflicts between directional shorthand properties (e.g., `paddingBlock`)
34902
36145
  * and their individual longhand overrides (e.g., `paddingBottom`).
@@ -34913,10 +36156,11 @@ function isMediaOrPseudoMap(v) {
34913
36156
  * Property ordering is preserved: the split longhands replace the shorthand's
34914
36157
  * position in the object to maintain a natural CSS property order.
34915
36158
  */
34916
- function resolveDirectionalConflicts(styleObj) {
36159
+ function resolveDirectionalConflicts(styleObj, options) {
34917
36160
  for (const { shorthand, start, end } of AXIS_PAIRS) {
34918
36161
  const shorthandVal = styleObj[shorthand];
34919
36162
  if (shorthandVal === void 0) continue;
36163
+ if (options?.skipNullishShorthandDefault === true && hasNullishDefault(shorthandVal)) continue;
34920
36164
  const hasStart = start in styleObj;
34921
36165
  const hasEnd = end in styleObj;
34922
36166
  if (!hasStart && !hasEnd) continue;
@@ -34966,6 +36210,464 @@ function resolveLogicalSideConflicts(styleObj) {
34966
36210
  else styleObj[key] = val;
34967
36211
  }
34968
36212
  }
36213
+ const BORDER_RADIUS_CORNER_PROPS = [
36214
+ "borderTopLeftRadius",
36215
+ "borderTopRightRadius",
36216
+ "borderBottomRightRadius",
36217
+ "borderBottomLeftRadius"
36218
+ ];
36219
+ function harmonizeShorthandExpansion(styleObjs, options) {
36220
+ harmonizeBoxShorthandExpansion(styleObjs, options);
36221
+ harmonizeBorderRadiusExpansion(styleObjs, options);
36222
+ }
36223
+ /** Resolve a bucket object back to its `when` snapshot recorded during decl processing. */
36224
+ function bucketSnapshotLookup(decl, buckets) {
36225
+ const whenByObject = /* @__PURE__ */ new Map();
36226
+ for (const [when, obj] of buckets.entries()) whenByObject.set(obj, when);
36227
+ return (styleObj) => {
36228
+ const when = whenByObject.get(styleObj);
36229
+ return when === void 0 ? void 0 : getVariantBaseKeySnapshot(decl, when);
36230
+ };
36231
+ }
36232
+ function bucketSourceOrderLookup(decl, buckets) {
36233
+ const whenByObject = /* @__PURE__ */ new Map();
36234
+ for (const [when, obj] of buckets.entries()) whenByObject.set(obj, when);
36235
+ return (styleObj) => {
36236
+ const when = whenByObject.get(styleObj);
36237
+ return when === void 0 ? void 0 : getVariantSourceOrder(decl, when);
36238
+ };
36239
+ }
36240
+ /**
36241
+ * StyleX priorities put side longhands (`paddingTop`) above axis shorthands
36242
+ * (`paddingBlock`) above box shorthands (`padding`) regardless of application
36243
+ * order. When the declaration family mixes these levels across style objects
36244
+ * (e.g. the base expanded `padding: 4px; padding-top: 2px` into side longhands
36245
+ * while a variant kept `padding: 8px`), a later-applied lower-level value can
36246
+ * never override an earlier higher-level one. Expand statically expandable
36247
+ * shorthand/axis values to side longhands in every object so overrides resolve
36248
+ * through plain per-property merging.
36249
+ */
36250
+ /**
36251
+ * Side props whose longhand was declared after the box shorthand (per style
36252
+ * object). A variant carrying the same shorthand must not override these sides
36253
+ * when it gets expanded to longhands — the later longhand wins over the
36254
+ * variant's shorthand in the original CSS cascade too.
36255
+ */
36256
+ const lateSideOverrides = /* @__PURE__ */ new WeakMap();
36257
+ function recordLateSideOverrides(styleObj, config, entries, shorthandIndex) {
36258
+ const lateSides = /* @__PURE__ */ new Set();
36259
+ const markIfLate = (prop, ...sides) => {
36260
+ const index = entries.findIndex(([key]) => key === prop);
36261
+ if (index <= shorthandIndex) return;
36262
+ const value = entries[index]?.[1];
36263
+ if (isMediaOrPseudoMap(value) && hasNullishDefault(value)) return;
36264
+ for (const side of sides) lateSides.add(side);
36265
+ };
36266
+ markIfLate(config.top, config.top);
36267
+ markIfLate(config.right, config.right);
36268
+ markIfLate(config.bottom, config.bottom);
36269
+ markIfLate(config.left, config.left);
36270
+ markIfLate(config.block, config.top, config.bottom);
36271
+ markIfLate(config.inline, config.left, config.right);
36272
+ if (lateSides.size === 0) return;
36273
+ const byShorthand = lateSideOverrides.get(styleObj) ?? /* @__PURE__ */ new Map();
36274
+ byShorthand.set(config.shorthand, lateSides);
36275
+ lateSideOverrides.set(styleObj, byShorthand);
36276
+ }
36277
+ /**
36278
+ * Sides of `config` whose base longhand/axis declaration is absent from the
36279
+ * variant's base-key snapshot — i.e. it was declared after the variant block
36280
+ * in source order and must keep winning over the variant's shorthand.
36281
+ * Conditional-only values (nullish default) never suppress: their default
36282
+ * still falls back to the variant's shorthand.
36283
+ */
36284
+ function baseSidesDeclaredAfterSnapshot(baseRawEntries, snapshot, config) {
36285
+ const lateSides = /* @__PURE__ */ new Set();
36286
+ const sidesByKey = boxSidesByKey(config);
36287
+ for (const [key, value] of baseRawEntries) {
36288
+ const sides = sidesByKey.get(key);
36289
+ if (!sides || !declaredAfterSnapshot(snapshot, key, value)) continue;
36290
+ if (isMediaOrPseudoMap(value) && hasNullishDefault(value)) continue;
36291
+ for (const side of sides) lateSides.add(side);
36292
+ }
36293
+ return lateSides;
36294
+ }
36295
+ function boxSidesByKey(config) {
36296
+ return new Map([
36297
+ [config.top, [config.top]],
36298
+ [config.right, [config.right]],
36299
+ [config.bottom, [config.bottom]],
36300
+ [config.left, [config.left]],
36301
+ [config.block, [config.top, config.bottom]],
36302
+ [config.inline, [config.left, config.right]]
36303
+ ]);
36304
+ }
36305
+ /**
36306
+ * Base side/axis condition entries that were added after the variant snapshot.
36307
+ * Later pseudo/media condition classes target the same property, and a flat
36308
+ * variant value would replace the base map entirely in `stylex.props()`.
36309
+ */
36310
+ function conditionalBaseSidesAfterSnapshot(baseRawEntries, snapshot, variantSourceOrder, config) {
36311
+ const conditionMaps = /* @__PURE__ */ new Map();
36312
+ const sidesByKey = boxSidesByKey(config);
36313
+ for (const [key, value] of baseRawEntries) {
36314
+ const sides = sidesByKey.get(key);
36315
+ const changedConditions = changedConditionEntriesAfterSnapshot(snapshot, variantSourceOrder, key, value);
36316
+ if (!sides || !changedConditions) continue;
36317
+ for (const side of sides) mergeConditionMapForSide(conditionMaps, side, changedConditions);
36318
+ }
36319
+ return conditionMaps;
36320
+ }
36321
+ function mergeConditionMapForSide(conditionMaps, side, changedConditions) {
36322
+ const existing = conditionMaps.get(side);
36323
+ if (existing) {
36324
+ mergeStyleObjects(existing, changedConditions);
36325
+ return;
36326
+ }
36327
+ conditionMaps.set(side, { ...changedConditions });
36328
+ }
36329
+ function changedConditionEntriesAfterSnapshot(snapshot, variantSourceOrder, key, value) {
36330
+ if (!isMediaOrPseudoMap(value) || !hasNullishDefault(value)) return null;
36331
+ const snapshotHasKey = snapshot?.has(key) ?? false;
36332
+ const snapshotValue = snapshotHasKey ? snapshot?.get(key) : void 0;
36333
+ const snapshotMap = isMediaOrPseudoMap(snapshotValue) ? snapshotValue : null;
36334
+ const changed = {};
36335
+ for (const [condition, conditionValue] of Object.entries(value)) {
36336
+ if (condition === "default" || conditionValue == null) continue;
36337
+ const conditionSourceOrder = getConditionSourceOrder(value, condition);
36338
+ if (variantSourceOrder !== void 0 && conditionSourceOrder !== void 0) {
36339
+ if (conditionSourceOrder <= variantSourceOrder) continue;
36340
+ changed[condition] = conditionValue;
36341
+ continue;
36342
+ }
36343
+ if (snapshotHasKey && snapshotMap && condition in snapshotMap && styleValuesEquivalent(snapshotMap[condition], conditionValue)) continue;
36344
+ changed[condition] = conditionValue;
36345
+ }
36346
+ return Object.keys(changed).length ? changed : null;
36347
+ }
36348
+ /**
36349
+ * Merges base condition entries into a variant's expanded side value, keeping
36350
+ * the variant in control of the default. Follows the same convention as
36351
+ * computeMergedLonghand: condition entries win over the flat value.
36352
+ */
36353
+ function mergeBaseConditionsIntoSideValue(variantValue, baseConditionMap) {
36354
+ if (!baseConditionMap) return variantValue;
36355
+ const merged = isMediaOrPseudoMap(variantValue) ? { ...variantValue } : { default: variantValue };
36356
+ for (const [condition, conditionValue] of Object.entries(baseConditionMap)) {
36357
+ if (condition === "default" || conditionValue == null || condition in merged) continue;
36358
+ merged[condition] = conditionValue;
36359
+ }
36360
+ return merged;
36361
+ }
36362
+ /**
36363
+ * A base entry was (re)declared after the variant's snapshot when its key was
36364
+ * absent at snapshot time, or its value changed since — a redeclaration after
36365
+ * the variant block replaces the value in the base style object.
36366
+ */
36367
+ function declaredAfterSnapshot(snapshot, key, value) {
36368
+ return !snapshot.has(key) || !styleValuesEquivalent(snapshot.get(key), value);
36369
+ }
36370
+ /**
36371
+ * Structural equality for snapshot comparison: condition maps are compared by
36372
+ * entries (snapshots clone them, and base merges may replace or mutate the map
36373
+ * object), everything else by identity.
36374
+ */
36375
+ function styleValuesEquivalent(a, b) {
36376
+ if (Object.is(a, b)) return true;
36377
+ if (!isPlainStyleValueMap(a) || !isPlainStyleValueMap(b)) return false;
36378
+ const aEntries = Object.entries(a);
36379
+ if (aEntries.length !== Object.keys(b).length) return false;
36380
+ return aEntries.every(([key, value]) => key in b && styleValuesEquivalent(value, b[key]));
36381
+ }
36382
+ function isPlainStyleValueMap(value) {
36383
+ return !!value && typeof value === "object" && !Array.isArray(value) && typeof value.type !== "string";
36384
+ }
36385
+ function harmonizeBoxShorthandExpansion(styleObjs, options) {
36386
+ for (const config of BOX_SHORTHAND_CONFLICTS) {
36387
+ const levels = /* @__PURE__ */ new Set();
36388
+ for (const obj of styleObjs) {
36389
+ if (config.shorthand in obj) levels.add("shorthand");
36390
+ if (config.block in obj || config.inline in obj) levels.add("axis");
36391
+ if (boxSideProps(config).some((prop) => prop in obj)) levels.add("side");
36392
+ }
36393
+ if (levels.size < 2) continue;
36394
+ const baseLateSides = options?.baseStyleObj ? lateSideOverrides.get(options.baseStyleObj)?.get(config.shorthand) : void 0;
36395
+ const conditionalSidesFor = (styleObj) => {
36396
+ if (!options?.inheritBaseLateSides?.has(styleObj) || !options.baseRawEntries) return;
36397
+ return conditionalBaseSidesAfterSnapshot(options.baseRawEntries, options.bucketBaseKeySnapshot?.(styleObj), options.bucketSourceOrder?.(styleObj), config);
36398
+ };
36399
+ const lateSidesFor = (styleObj) => {
36400
+ const localLateSides = lateSideOverrides.get(styleObj)?.get(config.shorthand);
36401
+ if (!options?.inheritBaseLateSides?.has(styleObj)) return localLateSides ?? /* @__PURE__ */ new Set();
36402
+ const snapshot = options.bucketBaseKeySnapshot?.(styleObj);
36403
+ const inheritedLateSides = snapshot && options.baseRawEntries ? baseSidesDeclaredAfterSnapshot(options.baseRawEntries, snapshot, config) : baseLateSides ?? /* @__PURE__ */ new Set();
36404
+ if (!inheritedLateSides.size) return localLateSides ?? /* @__PURE__ */ new Set();
36405
+ if (!localLateSides?.size) return inheritedLateSides;
36406
+ return new Set([...inheritedLateSides, ...localLateSides]);
36407
+ };
36408
+ const targetLevel = levels.has("side") ? "side" : "axis";
36409
+ for (const obj of styleObjs) if (targetLevel === "side") expandBoxLevelsToSides(obj, config, lateSidesFor(obj), conditionalSidesFor(obj));
36410
+ else expandBoxShorthandToAxis(obj, config, lateSidesFor(obj));
36411
+ }
36412
+ }
36413
+ function boxSideProps(config) {
36414
+ return [
36415
+ config.top,
36416
+ config.right,
36417
+ config.bottom,
36418
+ config.left
36419
+ ];
36420
+ }
36421
+ /**
36422
+ * Expands a pure shorthand-level or axis-level style object to side longhands
36423
+ * in place. Mixed-level objects were already reconciled per-object by
36424
+ * resolveBoxShorthandConflicts / resolveDirectionalConflicts and are left
36425
+ * untouched, as are values that cannot be expanded statically.
36426
+ */
36427
+ function expandBoxLevelsToSides(styleObj, config, lateSides, conditionalSides) {
36428
+ const hasSide = boxSideProps(config).some((prop) => prop in styleObj);
36429
+ const shorthandVal = styleObj[config.shorthand];
36430
+ const withoutLateSides = (replacements) => replacements.filter(([sideProp]) => !lateSides.has(sideProp)).map(([sideProp, value]) => [sideProp, mergeBaseConditionsIntoSideValue(value, conditionalSides?.get(sideProp))]);
36431
+ if (shorthandVal !== void 0) {
36432
+ if (hasSide || config.block in styleObj || config.inline in styleObj) return;
36433
+ const expanded = expandBoxShorthandValueToSides(shorthandVal);
36434
+ if (!expanded) return;
36435
+ replaceStyleKeyInPlace(styleObj, config.shorthand, withoutLateSides([
36436
+ [config.top, expanded.top],
36437
+ [config.right, expanded.right],
36438
+ [config.bottom, expanded.bottom],
36439
+ [config.left, expanded.left]
36440
+ ]));
36441
+ return;
36442
+ }
36443
+ if (hasSide) return;
36444
+ if (getUseLogicalProperties()) return;
36445
+ if (config.block in styleObj) {
36446
+ const blockVal = styleObj[config.block];
36447
+ replaceStyleKeyInPlace(styleObj, config.block, withoutLateSides([[config.top, blockVal], [config.bottom, cloneBoxValue(blockVal)]]));
36448
+ }
36449
+ if (config.inline in styleObj) {
36450
+ const inlineVal = styleObj[config.inline];
36451
+ replaceStyleKeyInPlace(styleObj, config.inline, withoutLateSides([[config.left, inlineVal], [config.right, cloneBoxValue(inlineVal)]]));
36452
+ }
36453
+ }
36454
+ /**
36455
+ * Expands a box shorthand to the axis pair (`paddingBlock`/`paddingInline`)
36456
+ * when the family's highest conflicting level is the axis level. Values with
36457
+ * 3-4 parts cannot be represented per-axis and are left untouched.
36458
+ */
36459
+ function expandBoxShorthandToAxis(styleObj, config, lateSides) {
36460
+ const shorthandVal = styleObj[config.shorthand];
36461
+ if (shorthandVal === void 0 || config.block in styleObj || config.inline in styleObj || boxSideProps(config).some((prop) => prop in styleObj)) return;
36462
+ const expanded = expandBoxShorthandValueToAxis(shorthandVal);
36463
+ if (!expanded) return;
36464
+ const replacements = [];
36465
+ if (!lateSides.has(config.top) && !lateSides.has(config.bottom)) replacements.push([config.block, expanded.block]);
36466
+ if (!lateSides.has(config.left) && !lateSides.has(config.right)) replacements.push([config.inline, expanded.inline]);
36467
+ replaceStyleKeyInPlace(styleObj, config.shorthand, replacements);
36468
+ }
36469
+ function expandBoxShorthandValueToAxis(value) {
36470
+ if (typeof value === "number") return {
36471
+ block: value,
36472
+ inline: value
36473
+ };
36474
+ const staticString = typeof value === "string" ? value : staticStringValue(value);
36475
+ if (staticString !== null) {
36476
+ const parts = splitCssValueWhitespace(staticString.trim());
36477
+ const block = parts[0];
36478
+ if (block === void 0 || parts.length > 2) return null;
36479
+ return {
36480
+ block,
36481
+ inline: parts[1] ?? block
36482
+ };
36483
+ }
36484
+ if (!isMediaOrPseudoMap(value)) return null;
36485
+ const block = {};
36486
+ const inline = {};
36487
+ for (const [condition, conditionValue] of Object.entries(value)) {
36488
+ if (conditionValue == null) {
36489
+ block[condition] = conditionValue;
36490
+ inline[condition] = conditionValue;
36491
+ continue;
36492
+ }
36493
+ if (isMediaOrPseudoMap(conditionValue)) return null;
36494
+ const expanded = expandBoxShorthandValueToAxis(conditionValue);
36495
+ if (!expanded) return null;
36496
+ block[condition] = expanded.block;
36497
+ inline[condition] = expanded.inline;
36498
+ }
36499
+ return {
36500
+ block,
36501
+ inline
36502
+ };
36503
+ }
36504
+ function expandBoxShorthandValueToSides(value) {
36505
+ if (typeof value === "number") return {
36506
+ top: value,
36507
+ right: value,
36508
+ bottom: value,
36509
+ left: value
36510
+ };
36511
+ const staticString = typeof value === "string" ? value : staticStringValue(value);
36512
+ if (staticString !== null) return expandBoxShorthandStringToSides(staticString);
36513
+ if (!isMediaOrPseudoMap(value)) return null;
36514
+ const top = {};
36515
+ const right = {};
36516
+ const bottom = {};
36517
+ const left = {};
36518
+ for (const [condition, conditionValue] of Object.entries(value)) {
36519
+ if (conditionValue == null) {
36520
+ top[condition] = conditionValue;
36521
+ right[condition] = conditionValue;
36522
+ bottom[condition] = conditionValue;
36523
+ left[condition] = conditionValue;
36524
+ continue;
36525
+ }
36526
+ if (isMediaOrPseudoMap(conditionValue)) return null;
36527
+ const expanded = expandBoxShorthandValueToSides(conditionValue);
36528
+ if (!expanded) return null;
36529
+ top[condition] = expanded.top;
36530
+ right[condition] = expanded.right;
36531
+ bottom[condition] = expanded.bottom;
36532
+ left[condition] = expanded.left;
36533
+ }
36534
+ return {
36535
+ top,
36536
+ right,
36537
+ bottom,
36538
+ left
36539
+ };
36540
+ }
36541
+ /** CSS box expansion: 1-4 whitespace-separated values to top/right/bottom/left. */
36542
+ function expandBoxShorthandStringToSides(raw) {
36543
+ const parts = splitCssValueWhitespace(raw.trim());
36544
+ const top = parts[0];
36545
+ if (top === void 0 || parts.length > 4) return null;
36546
+ const right = parts[1] ?? top;
36547
+ return {
36548
+ top,
36549
+ right,
36550
+ bottom: parts[2] ?? top,
36551
+ left: parts[3] ?? right
36552
+ };
36553
+ }
36554
+ function replaceStyleKeyInPlace(styleObj, key, replacements) {
36555
+ const entries = Object.entries(styleObj);
36556
+ for (const existingKey of Object.keys(styleObj)) delete styleObj[existingKey];
36557
+ for (const [entryKey, entryValue] of entries) if (entryKey === key) for (const [replacementKey, replacementValue] of replacements) styleObj[replacementKey] = replacementValue;
36558
+ else styleObj[entryKey] = entryValue;
36559
+ }
36560
+ function cloneBoxValue(value) {
36561
+ if (isAstNode$1(value)) return cloneAstNode(value);
36562
+ if (isMediaOrPseudoMap(value)) {
36563
+ const cloned = {};
36564
+ for (const [condition, conditionValue] of Object.entries(value)) cloned[condition] = cloneBoxValue(conditionValue);
36565
+ return cloned;
36566
+ }
36567
+ return value;
36568
+ }
36569
+ /**
36570
+ * StyleX gives longhand properties priority over shorthands regardless of
36571
+ * application order, so a `borderRadius` shorthand in one style object can
36572
+ * never override corner longhands applied from another (e.g. a variant's
36573
+ * `borderRadius: 4px` losing to base corner longhands expanded from
36574
+ * `border-radius: 16px 0`). When any style object in the declaration family
36575
+ * carries corner longhands, expand sibling single-value `borderRadius`
36576
+ * shorthands too so cascade overrides keep working.
36577
+ */
36578
+ function harmonizeBorderRadiusExpansion(styleObjs, options) {
36579
+ if (!styleObjs.some((obj) => BORDER_RADIUS_CORNER_PROPS.some((prop) => prop in obj))) return;
36580
+ for (const obj of styleObjs) expandMultiValueBorderRadius(obj, {
36581
+ includeSingleValue: true,
36582
+ omitCorners: lateBaseCornersFor(obj, options),
36583
+ mergeBaseConditionCorners: conditionalBaseCornersFor(obj, options)
36584
+ });
36585
+ }
36586
+ /**
36587
+ * Corners whose base longhand was (re)declared after the variant block in
36588
+ * source order — those keep winning over the variant's expanded borderRadius,
36589
+ * so the variant must not emit them.
36590
+ */
36591
+ function lateBaseCornersFor(styleObj, options) {
36592
+ if (!options?.inheritBaseLateSides?.has(styleObj) || !options.baseRawEntries) return;
36593
+ const snapshot = options.bucketBaseKeySnapshot?.(styleObj);
36594
+ if (!snapshot) return;
36595
+ const lateCorners = /* @__PURE__ */ new Set();
36596
+ for (const [key, value] of options.baseRawEntries) {
36597
+ if (!BORDER_RADIUS_CORNER_PROPS.includes(key)) continue;
36598
+ if (!declaredAfterSnapshot(snapshot, key, value)) continue;
36599
+ if (isMediaOrPseudoMap(value) && hasNullishDefault(value)) continue;
36600
+ lateCorners.add(key);
36601
+ }
36602
+ return lateCorners;
36603
+ }
36604
+ /** Conditional-only base corner entries a variant's expanded borderRadius must preserve. */
36605
+ function conditionalBaseCornersFor(styleObj, options) {
36606
+ if (!options?.inheritBaseLateSides?.has(styleObj) || !options.baseRawEntries) return;
36607
+ const snapshot = options.bucketBaseKeySnapshot?.(styleObj);
36608
+ const variantSourceOrder = options.bucketSourceOrder?.(styleObj);
36609
+ const conditionMaps = /* @__PURE__ */ new Map();
36610
+ for (const [key, value] of options.baseRawEntries) {
36611
+ if (!BORDER_RADIUS_CORNER_PROPS.includes(key)) continue;
36612
+ const changedConditions = changedConditionEntriesAfterSnapshot(snapshot, variantSourceOrder, key, value);
36613
+ if (!changedConditions) continue;
36614
+ conditionMaps.set(key, changedConditions);
36615
+ }
36616
+ return conditionMaps;
36617
+ }
36618
+ function expandMultiValueBorderRadius(styleObj, options) {
36619
+ const value = styleObj.borderRadius;
36620
+ if (value === void 0) return;
36621
+ const expanded = expandBorderRadiusValue(value, options);
36622
+ if (!expanded) return;
36623
+ const next = expandBorderRadiusInStyleObject(styleObj, expanded, { omitCorners: options?.omitCorners });
36624
+ for (const [corner, conditionMap] of options?.mergeBaseConditionCorners ?? []) if (corner in next) next[corner] = mergeBaseConditionsIntoSideValue(next[corner], conditionMap);
36625
+ for (const key of Object.keys(styleObj)) delete styleObj[key];
36626
+ Object.assign(styleObj, next);
36627
+ }
36628
+ function expandBorderRadiusValue(value, options) {
36629
+ const staticExpanded = expandStaticBorderRadiusValue(value, options);
36630
+ if (staticExpanded) return staticExpanded;
36631
+ if (!isMediaOrPseudoMap(value)) return null;
36632
+ const topLeft = {};
36633
+ const topRight = {};
36634
+ const bottomRight = {};
36635
+ const bottomLeft = {};
36636
+ let changed = false;
36637
+ for (const [condition, conditionValue] of Object.entries(value)) {
36638
+ if (conditionValue == null) {
36639
+ topLeft[condition] = conditionValue;
36640
+ topRight[condition] = conditionValue;
36641
+ bottomRight[condition] = conditionValue;
36642
+ bottomLeft[condition] = conditionValue;
36643
+ continue;
36644
+ }
36645
+ const expanded = expandStaticBorderRadiusValue(conditionValue, options);
36646
+ if (!expanded) return null;
36647
+ changed = true;
36648
+ topLeft[condition] = expanded.topLeft;
36649
+ topRight[condition] = expanded.topRight;
36650
+ bottomRight[condition] = expanded.bottomRight;
36651
+ bottomLeft[condition] = expanded.bottomLeft;
36652
+ }
36653
+ return changed || options?.includeSingleValue === true ? {
36654
+ topLeft,
36655
+ topRight,
36656
+ bottomRight,
36657
+ bottomLeft
36658
+ } : null;
36659
+ }
36660
+ function expandStaticBorderRadiusValue(value, options) {
36661
+ if (typeof value === "number") return options?.includeSingleValue === true ? {
36662
+ topLeft: value,
36663
+ topRight: value,
36664
+ bottomRight: value,
36665
+ bottomLeft: value
36666
+ } : null;
36667
+ const staticString = typeof value === "string" ? value : staticStringValue(value);
36668
+ if (staticString === null) return null;
36669
+ return expandBorderRadiusShorthandValue(staticString, options);
36670
+ }
34969
36671
  function resolveDirectionalConflictValue(args) {
34970
36672
  const { shorthandVal, longhandVal, hasLonghand, shorthandIndex, longhandIndex } = args;
34971
36673
  if (!hasLonghand || longhandIndex < 0) return cloneDirectionalValue(shorthandVal);
@@ -35006,7 +36708,10 @@ function computeMergedLonghand(longhandVal, shorthandMap, options) {
35006
36708
  }
35007
36709
  function shouldUseShorthandMapEntry(args) {
35008
36710
  const { key, longhandMap, shorthandMap, shorthandOverrides } = args;
35009
- if (!shorthandOverrides) return !(key in longhandMap);
36711
+ if (!shorthandOverrides) {
36712
+ if (key === "default" && hasNullishDefault(longhandMap)) return true;
36713
+ return !(key in longhandMap);
36714
+ }
35010
36715
  if (key !== "default") return true;
35011
36716
  return !hasNullishDefault(shorthandMap) || hasNullishDefault(longhandMap);
35012
36717
  }
@@ -35036,7 +36741,7 @@ const OPAQUE_SHORTHAND_PROPS = new Set([
35036
36741
  function warnOpaqueShorthands(styleObj, decl, warnings) {
35037
36742
  for (const prop of OPAQUE_SHORTHAND_PROPS) {
35038
36743
  const val = styleObj[prop];
35039
- if (val !== void 0 && isAstNode$1(val)) warnings.push({
36744
+ if (val !== void 0 && isAstNode$1(val) && !isProvenSingleTokenValue(val)) warnings.push({
35040
36745
  severity: "warning",
35041
36746
  type: "Shorthand property has an opaque value that StyleX will expand to longhands — use `directional` in resolveValue to return separate longhand tokens",
35042
36747
  loc: decl.loc,
@@ -35712,6 +37417,11 @@ function tryHandleInterpolatedBorder(ctx, args) {
35712
37417
  if (width) applyResolvedPropValue(widthProp, width);
35713
37418
  if (style) applyResolvedPropValue(styleProp, style);
35714
37419
  if (color) applyResolvedPropValue(colorProp, color);
37420
+ const stripConsumedStaticParts = () => {
37421
+ const value = d.value;
37422
+ if (!staticRaw || value?.kind !== "interpolated" || !Array.isArray(value.parts)) return;
37423
+ for (const part of value.parts) if (part?.kind === "static") part.value = "";
37424
+ };
35715
37425
  const hasStaticWidthOrStyle = Boolean(width || style);
35716
37426
  const targetProp = interpolationTarget === "color" ? colorProp : interpolationTarget === "width" ? widthProp : styleProp;
35717
37427
  const targetCssProperty = interpolationTarget === "width" ? directionLower ? `border-${directionLower}-width` : "border-width" : interpolationTarget === "style" ? directionLower ? `border-${directionLower}-style` : "border-style" : directionLower ? `border-${directionLower}-color` : "border-color";
@@ -35773,6 +37483,7 @@ function tryHandleInterpolatedBorder(ctx, args) {
35773
37483
  const alt = expr.body.alternate;
35774
37484
  if (isMemberExpression(cons) || isMemberExpression(alt)) {
35775
37485
  d.property = targetCssProperty;
37486
+ stripConsumedStaticParts();
35776
37487
  return false;
35777
37488
  }
35778
37489
  }
@@ -35969,6 +37680,7 @@ function tryHandleInterpolatedBorder(ctx, args) {
35969
37680
  if (expr?.type === "ArrowFunctionExpression") {
35970
37681
  if (expr.body?.type === "MemberExpression") {
35971
37682
  d.property = targetCssProperty;
37683
+ stripConsumedStaticParts();
35972
37684
  return false;
35973
37685
  }
35974
37686
  }
@@ -36162,7 +37874,39 @@ function handleSplitVariantsResolvedValue(ctx) {
36162
37874
  target[prop] = map;
36163
37875
  return map;
36164
37876
  };
36165
- const applyWithContext = (prop, valueAst) => {
37877
+ const withImportant = (valueAst) => {
37878
+ if (!d.important || !valueAst || typeof valueAst !== "object") return valueAst;
37879
+ const node = valueAst;
37880
+ if (node.type === "StringLiteral" || node.type === "Literal" || node.type === "NumericLiteral") {
37881
+ if (typeof node.value === "string") return node.value.includes("!important") ? valueAst : j.literal(`${node.value} !important`);
37882
+ if (typeof node.value === "number") return j.literal(`${node.value} !important`);
37883
+ return valueAst;
37884
+ }
37885
+ if (node.type === "TemplateLiteral" && Array.isArray(node.quasis)) {
37886
+ const quasis = node.quasis;
37887
+ const lastIndex = quasis.length - 1;
37888
+ const last = quasis[lastIndex];
37889
+ const lastText = last?.value?.cooked ?? last?.value?.raw ?? "";
37890
+ if (lastText.includes("!important")) return valueAst;
37891
+ const newQuasis = quasis.map((q, i) => i === lastIndex ? j.templateElement({
37892
+ raw: `${lastText} !important`,
37893
+ cooked: `${lastText} !important`
37894
+ }, true) : j.templateElement({
37895
+ raw: q?.value?.raw ?? q?.value?.cooked ?? "",
37896
+ cooked: q?.value?.cooked ?? q?.value?.raw ?? ""
37897
+ }, false));
37898
+ return j.templateLiteral(newQuasis, node.expressions ?? []);
37899
+ }
37900
+ return j.templateLiteral([j.templateElement({
37901
+ raw: "",
37902
+ cooked: ""
37903
+ }, false), j.templateElement({
37904
+ raw: " !important",
37905
+ cooked: " !important"
37906
+ }, true)], [valueAst]);
37907
+ };
37908
+ const applyWithContext = (prop, valueAstRaw) => {
37909
+ const valueAst = withImportant(valueAstRaw);
36166
37910
  if (media) {
36167
37911
  const map = getOrCreateConditionMap(prop);
36168
37912
  map[media] = valueAst;
@@ -36929,7 +38673,7 @@ function handleInterpolatedDeclaration(args) {
36929
38673
  applyVariant({
36930
38674
  when: formatObservedVariantCondition(jsxProp, value),
36931
38675
  propName: jsxProp
36932
- }, { [stylexProp]: emitStaticObservedValue(value, stylexProp, observedValues !== null, staticParts) });
38676
+ }, staticVariantStyleObject(stylexProp, emitStaticObservedValue(value, stylexProp, observedValues !== null, staticParts)));
36933
38677
  }
36934
38678
  if (observedValues) {
36935
38679
  const numericIdentifiers = numericIdentifierSetForJsxProp(jsxProp, ctx.findJsxPropTsType);
@@ -37513,9 +39257,25 @@ function handleInterpolatedDeclaration(args) {
37513
39257
  };
37514
39258
  const resolveValueResult = resolveValue(resolveValueContext);
37515
39259
  if (!resolveValueResult) {
39260
+ const isPlainOwnedConstant = info.path.length === 0 && imp.source.kind === "absolutePath" && !isStylexImportSource(imp.source.value);
37516
39261
  warnings.push({
37517
39262
  severity: "error",
37518
- type: "Adapter resolveValue returned undefined for imported value",
39263
+ type: isPlainOwnedConstant ? "Imported constant cannot be referenced inside stylex.create() — move it into a `.stylex` defineConsts/defineVars group (or map it via adapter.resolveValue)" : "Adapter resolveValue returned undefined for imported value",
39264
+ loc: getNodeLocStart(expr) ?? decl.loc,
39265
+ context: {
39266
+ localName: decl.localName,
39267
+ importedName: imp.importedName,
39268
+ source: imp.source.value,
39269
+ path: info.path.length ? info.path.join(".") : void 0
39270
+ }
39271
+ });
39272
+ bail = true;
39273
+ return { bail: true };
39274
+ }
39275
+ if (!isStylexImportSource(imp.source.value) && hasRuntimeImport(resolveValueResult.imports)) {
39276
+ warnings.push({
39277
+ severity: "warning",
39278
+ type: "Unsupported interpolation: call expression",
37519
39279
  loc: getNodeLocStart(expr) ?? decl.loc,
37520
39280
  context: {
37521
39281
  localName: decl.localName,
@@ -37600,7 +39360,8 @@ function handleInterpolatedDeclaration(args) {
37600
39360
  attrTarget,
37601
39361
  resolvedSelectorMedia
37602
39362
  })) continue;
37603
- if (isImportedShorthandUnitValue(d, decl, importMap)) {
39363
+ const numericIdentifiers = getNumericImportedStylexIdentifiers(j, filePath, importMap, resolverImports);
39364
+ if (isImportedShorthandUnitValue(d, decl, importMap, numericIdentifiers)) {
37604
39365
  bailUnsupportedLocal(decl, "Unsupported interpolation: call expression");
37605
39366
  continue;
37606
39367
  }
@@ -37613,6 +39374,7 @@ function handleInterpolatedDeclaration(args) {
37613
39374
  addImport,
37614
39375
  resolveImportedValueExpr,
37615
39376
  resolveThemeValue,
39377
+ numericIdentifiers,
37616
39378
  setStyleValue: (prop, value) => applyResolvedPropValue(prop, value, null)
37617
39379
  })) continue;
37618
39380
  if (bail) break;
@@ -37621,9 +39383,31 @@ function handleInterpolatedDeclaration(args) {
37621
39383
  if (slot) {
37622
39384
  const expr = decl.templateExpressions[slot.slotId];
37623
39385
  if (tryEmitObservedCssBlockVariantBuckets(expr)) continue;
39386
+ const bailOnPropDependentCssHelper = (helperDecl) => {
39387
+ for (const helperExpr of helperDecl.templateExpressions ?? []) {
39388
+ if (!helperExpr || helperExpr.type !== "ArrowFunctionExpression" && helperExpr.type !== "FunctionExpression") continue;
39389
+ const propsUsed = new Set([...collectPropsFromArrowFn(helperExpr), ...collectPropsFromArrowFnDestructured(helperExpr)]);
39390
+ propsUsed.delete("theme");
39391
+ if (propsUsed.size > 0) {
39392
+ warnings.push({
39393
+ severity: "warning",
39394
+ type: "css helper with prop-based interpolation cannot be reused as a mixin",
39395
+ loc: decl.loc,
39396
+ context: {
39397
+ localName: decl.localName,
39398
+ mixin: helperDecl.localName
39399
+ }
39400
+ });
39401
+ bail = true;
39402
+ return true;
39403
+ }
39404
+ }
39405
+ return false;
39406
+ };
37624
39407
  if (expr?.type === "Identifier" && cssHelperNames.has(expr.name)) {
37625
39408
  const helperDecl = declByLocalName.get(expr.name);
37626
39409
  if (helperDecl) {
39410
+ if (bailOnPropDependentCssHelper(helperDecl)) break;
37627
39411
  applyCssHelperMixin(decl, helperDecl, cssHelperPropValues, inlineStyleProps);
37628
39412
  continue;
37629
39413
  }
@@ -37632,6 +39416,7 @@ function handleInterpolatedDeclaration(args) {
37632
39416
  const calleeName = expr.callee.name;
37633
39417
  const helperDecl = declByLocalName.get(calleeName);
37634
39418
  if (helperDecl?.isCssHelper) {
39419
+ if (bailOnPropDependentCssHelper(helperDecl)) break;
37635
39420
  applyCssHelperMixin(decl, helperDecl, cssHelperPropValues, inlineStyleProps);
37636
39421
  continue;
37637
39422
  }
@@ -37777,7 +39562,24 @@ function handleInterpolatedDeclaration(args) {
37777
39562
  })) continue;
37778
39563
  if (d.property && d.value.kind === "interpolated" && tryHandleMultiSlotTernary(ctx, d)) continue;
37779
39564
  if (tryHandleMultiSlotRuntimeValue(resolveImportedValueExpr)) continue;
37780
- const slotPart = d.value.parts.find((p) => p.kind === "slot");
39565
+ const remainingSlotParts = d.value.parts.filter((p) => p.kind === "slot");
39566
+ if (remainingSlotParts.filter((p) => {
39567
+ const slotExpr = decl.templateExpressions[p.slotId];
39568
+ return slotExpr?.type === "ArrowFunctionExpression" || slotExpr?.type === "FunctionExpression";
39569
+ }).length > 1) {
39570
+ warnings.push({
39571
+ severity: "error",
39572
+ type: "Unsupported interpolation: multiple dynamic slots in one declaration",
39573
+ loc: decl.loc,
39574
+ context: {
39575
+ localName: decl.localName,
39576
+ property: d.property
39577
+ }
39578
+ });
39579
+ bail = true;
39580
+ break;
39581
+ }
39582
+ const slotPart = remainingSlotParts[0];
37781
39583
  const slotId = slotPart && slotPart.kind === "slot" ? slotPart.slotId : 0;
37782
39584
  const expr = decl.templateExpressions[slotId];
37783
39585
  const loc = getNodeLocStart(expr);
@@ -38303,11 +40105,11 @@ function handleInterpolatedDeclaration(args) {
38303
40105
  const scalarDynamic = shouldUseScalarDynamicArgs(d.property, d.valueRaw) && dynamicProps.length > 0 ? scalarizePropsObjectDynamicValue({
38304
40106
  j,
38305
40107
  valueExpr: dynamicValueExpr,
38306
- paramName: "props",
40108
+ paramName,
38307
40109
  propNames: dynamicProps
38308
40110
  }) : null;
38309
40111
  const dynamicStyleValueExpr = scalarDynamic?.valueExpr ?? dynamicValueExpr;
38310
- const dynamicStyleParams = scalarDynamic ? scalarDynamic.paramNames.map((propName) => j.identifier(propName)) : [j.identifier("props")];
40112
+ const dynamicStyleParams = scalarDynamic ? scalarDynamic.paramNames.map((propName) => j.identifier(propName)) : [j.identifier(paramName)];
38311
40113
  if (scalarDynamic) annotateScalarParams(dynamicStyleParams, scalarDynamic.paramNames);
38312
40114
  const callArg = j.objectExpression(dynamicProps.map((name) => {
38313
40115
  const prop = j.property("init", j.identifier(name), j.identifier(name));
@@ -38595,17 +40397,22 @@ function handleInterpolatedDeclaration(args) {
38595
40397
  const callArg = resolvedCallArg ?? scalarCallArg;
38596
40398
  const hasExplicitType = !!decl.propsType;
38597
40399
  const isOptional = ctx.isJsxPropOptional(jsxProp);
40400
+ const foldsStaticBaseIntoPseudoDefault = !media && !!pseudos?.length && staticBaseValueWouldFold(styleObj[out.prop]);
38598
40401
  styleFnFromProps.push({
38599
40402
  fnKey,
38600
40403
  jsxProp,
38601
40404
  ...callArg ? { callArg } : {},
38602
- ...hasExplicitType && !isOptional ? { condition: "always" } : {}
40405
+ ...hasExplicitType && !isOptional || foldsStaticBaseIntoPseudoDefault ? { condition: "always" } : {}
38603
40406
  });
38604
40407
  if (!styleFnDecls.has(fnKey)) {
38605
40408
  const param = j.identifier(outParamName);
38606
40409
  const valueId = j.identifier(outParamName);
38607
40410
  if (jsxProp !== "__props") annotateParamFromJsxProp(param, jsxProp);
38608
40411
  if (resolvedCallArg && /\.(ts|tsx)$/.test(filePath)) param.typeAnnotation = j.tsTypeAnnotation(j.tsStringKeyword());
40412
+ if (foldsStaticBaseIntoPseudoDefault && isOptional && jsxProp !== "__props" && /\.(ts|tsx)$/.test(filePath)) {
40413
+ const baseTypeNode = param.typeAnnotation?.typeAnnotation ?? j.tsStringKeyword();
40414
+ param.typeAnnotation = j.tsTypeAnnotation(j.tsUnionType([baseTypeNode, j.tsUndefinedKeyword()]));
40415
+ }
38609
40416
  if (jsxProp?.startsWith?.("$")) ensureShouldForwardPropDrop(decl, jsxProp);
38610
40417
  const buildValueExpr = () => {
38611
40418
  const transformed = (() => {
@@ -38670,7 +40477,28 @@ function handleInterpolatedDeclaration(args) {
38670
40477
  };
38671
40478
  const valueExpr = buildValueExpr();
38672
40479
  const getPropValue = () => {
40480
+ if (!media && !pseudos?.length) return valueExpr;
40481
+ if (!media && pseudos?.length) {
40482
+ const existingStatic = styleObj[out.prop];
40483
+ let defaultValue = j.literal(null);
40484
+ if (existingStatic !== void 0 && existingStatic !== null) if (typeof existingStatic === "object") {
40485
+ if ("type" in existingStatic) {
40486
+ defaultValue = cloneAstNode(existingStatic);
40487
+ delete styleObj[out.prop];
40488
+ }
40489
+ } else {
40490
+ defaultValue = staticValueToLiteral(j, existingStatic);
40491
+ delete styleObj[out.prop];
40492
+ }
40493
+ return j.objectExpression([j.property("init", j.identifier("default"), defaultValue), ...pseudos.map((ps) => j.property("init", j.literal(ps), valueExpr))]);
40494
+ }
38673
40495
  if (!media) return valueExpr;
40496
+ if (pseudos?.length) return buildPseudoMediaPropValue({
40497
+ j,
40498
+ valueExpr,
40499
+ pseudos,
40500
+ media
40501
+ });
38674
40502
  const existingFn = styleFnDecls.get(fnKey);
38675
40503
  let existingValue = null;
38676
40504
  if (existingFn?.type === "ArrowFunctionExpression") {
@@ -38926,6 +40754,17 @@ function resolveDerivedLocalVariable(j, fnBody, fnParamName, localName, jsxProp)
38926
40754
  function isPseudoElementSelector(pseudoElement) {
38927
40755
  return pseudoElement === "::before" || pseudoElement === "::after" || pseudoElement === "::placeholder";
38928
40756
  }
40757
+ /**
40758
+ * Whether a base style value for a property would be folded into a pseudo-gated
40759
+ * dynamic style function's `default` (mirrors the fold logic in getPropValue):
40760
+ * plain primitives and AST-node values fold; existing pseudo/media condition
40761
+ * buckets (plain objects without a `type` discriminator) do not.
40762
+ */
40763
+ function staticBaseValueWouldFold(existingStatic) {
40764
+ if (existingStatic === void 0 || existingStatic === null) return false;
40765
+ if (typeof existingStatic === "object") return "type" in existingStatic;
40766
+ return true;
40767
+ }
38929
40768
  function tryHandleLocalCustomPropertyDefinition(args) {
38930
40769
  const { j, d, decl, expr, getOrCreateLocalStylexVar, inlineStyleProps } = args;
38931
40770
  if (!expr || typeof expr !== "object") return false;
@@ -38980,16 +40819,45 @@ function tryHandleRuntimeConditionalStaticBranches(ctx, args) {
38980
40819
  state.bailUnsupported(decl, "Unsupported interpolation: call expression");
38981
40820
  return true;
38982
40821
  }
38983
- if (hasLaterDeclarationOverlap(rule, allRules, d, new Set(Object.keys(consequentStyle)))) {
40822
+ if (!subtractLaterStaticOverrides({
40823
+ rule,
40824
+ allRules,
40825
+ currentDecl: d,
40826
+ branchStyles: [consequentStyle, alternateStyle]
40827
+ })) {
38984
40828
  state.bailUnsupported(decl, "Unsupported interpolation: call expression");
38985
40829
  return true;
38986
40830
  }
40831
+ if (!Object.keys(consequentStyle).length && !Object.keys(alternateStyle).length) return true;
38987
40832
  const target = getBaseStyleTarget();
38988
40833
  for (const [prop, value] of Object.entries(alternateStyle)) target[prop] = value;
38989
40834
  applyVariant({ when }, consequentStyle);
38990
40835
  decl.needsWrapperComponent = true;
40836
+ recordNonPropConditionRoots(decl, expr.test);
38991
40837
  return true;
38992
40838
  }
40839
+ /**
40840
+ * Records the root identifiers of an imported runtime condition on the decl so
40841
+ * wrapper emission treats them as module-scope bindings rather than component
40842
+ * props (which matters for lowercase roots like `browser.isTouchDevice`).
40843
+ */
40844
+ function recordNonPropConditionRoots(decl, test) {
40845
+ const roots = decl.nonPropConditionRoots ??= /* @__PURE__ */ new Set();
40846
+ const visit = (expr) => {
40847
+ if (expr.type === "LogicalExpression") {
40848
+ visit(expr.left);
40849
+ visit(expr.right);
40850
+ return;
40851
+ }
40852
+ if (expr.type === "UnaryExpression") {
40853
+ visit(expr.argument);
40854
+ return;
40855
+ }
40856
+ const info = extractRootAndPath(expr);
40857
+ if (info && info.path.length > 0) roots.add(info.rootName);
40858
+ };
40859
+ visit(test);
40860
+ }
38993
40861
  function buildStaticBranchStyle(d, rawValue) {
38994
40862
  if (d.property === "background" && isUnsupportedBackgroundShorthandValue(rawValue)) return null;
38995
40863
  const staticDecl = {
@@ -39014,24 +40882,120 @@ function sameStyleProps(left, right) {
39014
40882
  const rightKeys = new Set(Object.keys(right));
39015
40883
  return leftKeys.length === rightKeys.size && leftKeys.every((key) => rightKeys.has(key));
39016
40884
  }
39017
- function hasLaterDeclarationOverlap(rule, allRules, currentDecl, stylexProps) {
40885
+ /**
40886
+ * Removes branch properties that are unconditionally overridden by later static
40887
+ * declarations in the same selector context, so the runtime variant cannot
40888
+ * invert the original CSS cascade. Partially overridden directional props are
40889
+ * narrowed to the longhands that survive the override (e.g. `marginBlock`
40890
+ * overridden by a later `margin-top` becomes `marginBlockEnd`).
40891
+ *
40892
+ * Returns false when a later overlapping declaration cannot be subtracted
40893
+ * safely (conditional at-rule context, dynamic value, property-less helper, or
40894
+ * a multi-token branch value that cannot be split per longhand) — the caller
40895
+ * must bail in that case.
40896
+ */
40897
+ function subtractLaterStaticOverrides(args) {
40898
+ const { rule, allRules, currentDecl, branchStyles } = args;
39018
40899
  const currentIndex = rule.declarations.indexOf(currentDecl);
39019
- if (currentIndex === -1) return false;
39020
- if (declarationsOverlap(rule.declarations.slice(currentIndex + 1), stylexProps)) return true;
40900
+ if (currentIndex === -1) return true;
40901
+ const laterContexts = [{
40902
+ declarations: rule.declarations.slice(currentIndex + 1),
40903
+ unconditional: true
40904
+ }];
39021
40905
  const currentRuleIndex = allRules.indexOf(rule);
39022
- if (currentRuleIndex === -1) return false;
39023
- for (const laterRule of allRules.slice(currentRuleIndex + 1)) {
39024
- if (rule.selector !== laterRule.selector) continue;
39025
- if (declarationsOverlap(laterRule.declarations, stylexProps)) return true;
40906
+ if (currentRuleIndex !== -1) for (const laterRule of allRules.slice(currentRuleIndex + 1)) {
40907
+ if (laterRule.selector !== rule.selector) continue;
40908
+ laterContexts.push({
40909
+ declarations: laterRule.declarations,
40910
+ unconditional: sameAtRuleStack(laterRule.atRuleStack, rule.atRuleStack)
40911
+ });
39026
40912
  }
39027
- return false;
40913
+ const branchProps = () => [...new Set(branchStyles.flatMap((style) => Object.keys(style)))];
40914
+ for (const context of laterContexts) for (const laterDecl of context.declarations) {
40915
+ if (!laterDecl.property) {
40916
+ if (branchProps().length) return false;
40917
+ continue;
40918
+ }
40919
+ if (isBorderShorthandProperty(laterDecl.property)) {
40920
+ const borderProps = new Set(cssDeclarationToStylexDeclarations(laterDecl).map((out) => out.prop));
40921
+ if (branchProps().some((prop) => [...borderProps].some((borderProp) => stylexPropsOverlap(prop, borderProp)))) return false;
40922
+ continue;
40923
+ }
40924
+ for (const out of cssDeclarationToStylexDeclarations(laterDecl)) {
40925
+ const overrideProp = out.prop;
40926
+ const overlapped = branchProps().filter((prop) => stylexPropsOverlap(prop, overrideProp));
40927
+ if (!overlapped.length) continue;
40928
+ if (currentDecl.important && !laterDecl.important) return false;
40929
+ if (!context.unconditional || laterDecl.value.kind !== "static") return false;
40930
+ for (const branch of branchStyles) if (!subtractOverrideFromBranch(branch, overlapped, overrideProp)) return false;
40931
+ }
40932
+ }
40933
+ return true;
39028
40934
  }
39029
- function declarationsOverlap(declarations, stylexProps) {
39030
- for (const laterDecl of declarations) {
39031
- if (!laterDecl.property) return true;
39032
- for (const out of cssDeclarationToStylexDeclarations(laterDecl)) if ([...stylexProps].some((prop) => stylexPropsOverlap(prop, out.prop))) return true;
40935
+ function sameAtRuleStack(left, right) {
40936
+ return left.length === right.length && left.every((entry, i) => entry === right[i]);
40937
+ }
40938
+ /** True for the `border` / `border-<side>` shorthands (not the longhands). */
40939
+ function isBorderShorthandProperty(property) {
40940
+ return /^border(?:-(?:top|right|bottom|left))?$/.test(property.trim());
40941
+ }
40942
+ function subtractOverrideFromBranch(branch, overlappedProps, overrideProp) {
40943
+ const overridePhysical = new Set(physicalLonghandExpansion(overrideProp));
40944
+ const overrideIsLogical = isLogicalDirectionalProp(overrideProp);
40945
+ for (const branchProp of overlappedProps) {
40946
+ if (!(branchProp in branch)) continue;
40947
+ const branchPhysical = physicalLonghandExpansion(branchProp);
40948
+ const remainder = branchPhysical.filter((prop) => !overridePhysical.has(prop));
40949
+ if (remainder.length === branchPhysical.length) continue;
40950
+ if (isLogicalDirectionalProp(branchProp) !== overrideIsLogical) return false;
40951
+ const value = branch[branchProp];
40952
+ delete branch[branchProp];
40953
+ if (!remainder.length) continue;
40954
+ if (!isSingleCssToken(value)) return false;
40955
+ for (const physical of remainder) {
40956
+ const name = overrideIsLogical && LOGICAL_TO_PHYSICAL[branchProp] ? logicalFormForPhysical(branchProp, physical) : physical;
40957
+ if (!name) return false;
40958
+ branch[name] = value;
40959
+ }
39033
40960
  }
39034
- return false;
40961
+ return true;
40962
+ }
40963
+ /**
40964
+ * True for a logical directional longhand whose physical side(s) depend on the
40965
+ * writing mode — `marginInline`, `paddingBlockEnd`, `scrollMarginInlineStart`,
40966
+ * etc. The physical-neutral full shorthands (`margin`, `padding`) and physical
40967
+ * sides (`marginTop`) are not logical.
40968
+ */
40969
+ function isLogicalDirectionalProp(prop) {
40970
+ return LOGICAL_TO_PHYSICAL[prop] !== void 0;
40971
+ }
40972
+ /** Physical longhands covered by a StyleX directional/border property. */
40973
+ function physicalLonghandExpansion(prop) {
40974
+ const group = SHORTHAND_LONGHANDS[prop];
40975
+ if (group) return [...group.physical];
40976
+ const logical = LOGICAL_TO_PHYSICAL[prop];
40977
+ if (logical) return [...logical];
40978
+ const borderMatch = prop.match(/^border(Top|Right|Bottom|Left)?(Width|Style|Color)$/);
40979
+ if (borderMatch) {
40980
+ const side = borderMatch[1];
40981
+ const kind = borderMatch[2];
40982
+ return side ? [prop] : [
40983
+ "Top",
40984
+ "Right",
40985
+ "Bottom",
40986
+ "Left"
40987
+ ].map((s) => `border${s}${kind}`);
40988
+ }
40989
+ return [prop];
40990
+ }
40991
+ /** Maps a physical longhand back to the Start/End form of a logical branch prop. */
40992
+ function logicalFormForPhysical(logicalProp, physical) {
40993
+ for (const [name, physicalProps] of Object.entries(LOGICAL_TO_PHYSICAL)) if (physicalProps.length === 1 && physicalProps[0] === physical && name.startsWith(logicalProp)) return name;
40994
+ return null;
40995
+ }
40996
+ function isSingleCssToken(value) {
40997
+ if (typeof value === "number") return true;
40998
+ return typeof value === "string" && value.trim() !== "" && !/\s/.test(value.trim());
39035
40999
  }
39036
41000
  function stylexPropsOverlap(left, right) {
39037
41001
  const leftRelated = relatedDirectionalProps(left);
@@ -39067,21 +41031,20 @@ function addRelatedBorderLonghands(prop, related) {
39067
41031
  }
39068
41032
  function isImportedRuntimeCondition(expr, importMap) {
39069
41033
  const info = extractRootAndPath(expr);
39070
- if (info && info.path.length > 0 && importMap.has(info.rootName) && isRuntimeConditionImportRoot(info.rootName)) return true;
41034
+ if (info && info.path.length > 0 && importMap.has(info.rootName)) return true;
39071
41035
  if (expr.type === "LogicalExpression" && expr.operator === "&&") return isImportedRuntimeCondition(expr.left, importMap) && isImportedRuntimeCondition(expr.right, importMap);
39072
41036
  if (expr.type === "UnaryExpression" && expr.operator === "!") return isImportedRuntimeCondition(expr.argument, importMap);
39073
41037
  return false;
39074
41038
  }
39075
- function isRuntimeConditionImportRoot(rootName) {
39076
- return /^[A-Z]/.test(rootName);
39077
- }
39078
- function isImportedShorthandUnitValue(d, decl, importMap) {
41039
+ function isImportedShorthandUnitValue(d, decl, importMap, numericIdentifiers) {
39079
41040
  if (!d.property || !isCssShorthandProperty(d.property)) return false;
39080
41041
  const staticParts = getSingleSlotStaticParts(d, decl);
39081
41042
  if (!staticParts || !/^[a-zA-Z%]/.test(staticParts.suffix)) return false;
39082
41043
  const slotPart = d.value.kind === "interpolated" ? d.value.parts.find((part) => part.kind === "slot") : null;
39083
41044
  const info = extractRootAndPath(slotPart && slotPart.kind === "slot" ? decl.templateExpressions[slotPart.slotId] : void 0);
39084
- return !!info && importMap.has(info.rootName);
41045
+ if (!info || !importMap.has(info.rootName)) return false;
41046
+ if ((d.property === "margin" || d.property === "padding") && staticParts.prefix.trim() === "" && /^[a-zA-Z%]+$/.test(staticParts.suffix.trim()) && numericIdentifiers.has(info.rootName)) return false;
41047
+ return true;
39085
41048
  }
39086
41049
  function expressionToSource(j, expr) {
39087
41050
  try {
@@ -39244,6 +41207,17 @@ function emitStaticObservedValue(value, stylexProp, isObservedNumeric, staticPar
39244
41207
  if (staticParts.prefix || staticParts.suffix) return `${staticParts.prefix}${value}${staticParts.suffix}`;
39245
41208
  return getNumericCssEmissionMode(stylexProp) === "stylexNumber" ? value : String(value);
39246
41209
  }
41210
+ function staticVariantStyleObject(stylexProp, value) {
41211
+ if (stylexProp !== "borderRadius" || typeof value !== "string") return { [stylexProp]: value };
41212
+ const expanded = expandBorderRadiusShorthandValue(value);
41213
+ if (!expanded) return { [stylexProp]: value };
41214
+ return {
41215
+ borderTopLeftRadius: expanded.topLeft,
41216
+ borderTopRightRadius: expanded.topRight,
41217
+ borderBottomRightRadius: expanded.bottomRight,
41218
+ borderBottomLeftRadius: expanded.bottomLeft
41219
+ };
41220
+ }
39247
41221
  function buildRuntimeObservedValueExpr(j, stylexProp, valueExpr, staticParts, numericIdentifiers = /* @__PURE__ */ new Set()) {
39248
41222
  if (canOmitPxUnitForStylexNumber(stylexProp, staticParts.prefix, staticParts.suffix) && isNumericStylexExpression(valueExpr, { numericIdentifiers })) return staticParts.prefix === "-" ? j.unaryExpression("-", valueExpr, true) : valueExpr;
39249
41223
  if (!staticParts.prefix && !staticParts.suffix) {
@@ -40235,6 +42209,9 @@ function tryHandleMultiSlotTernary(ctx, d) {
40235
42209
  decl.needsWrapperComponent = true;
40236
42210
  return true;
40237
42211
  }
42212
+ function hasRuntimeImport(imports) {
42213
+ return (imports ?? []).some((imp) => !isStylexImportSource(imp.from.value));
42214
+ }
40238
42215
  /**
40239
42216
  * If any variant `when` condition references the styled-components theme object,
40240
42217
  * mark the declaration as needing the `useTheme()` hook so the emitted wrapper
@@ -40809,6 +42786,7 @@ function processRuleDeclarations(args) {
40809
42786
  const { ctx, rule, allRules, media, pseudos, pseudoElement, attrTarget, resolvedSelectorMedia, applyResolvedPropValue } = args;
40810
42787
  const { state } = ctx;
40811
42788
  for (const d of rule.declarations) {
42789
+ ctx.setCurrentDeclarationSourceOrder(d.sourceOrder);
40812
42790
  if (d.property && d.property.includes("__SC_EXPR_")) {
40813
42791
  const resolvedProperty = resolveInterpolatedPropertyName(d.property, ctx);
40814
42792
  if (resolvedProperty === null) {
@@ -40818,6 +42796,12 @@ function processRuleDeclarations(args) {
40818
42796
  d.property = resolvedProperty;
40819
42797
  }
40820
42798
  if (d.value.kind === "interpolated") {
42799
+ if (d.property && isLogicalScrollAxisShorthand(d.property)) {
42800
+ state.bailUnsupported(ctx.decl, "Dynamic logical scroll shorthand cannot be expanded — bind a specific longhand (e.g. scroll-padding-inline-start) instead");
42801
+ if (state.currentDecl === ctx.decl) continue;
42802
+ state.bail = true;
42803
+ break;
42804
+ }
40821
42805
  handleInterpolatedDeclaration({
40822
42806
  ctx,
40823
42807
  rule,
@@ -40863,6 +42847,20 @@ function processRuleDeclarations(args) {
40863
42847
  }
40864
42848
  }
40865
42849
  if (d.property === "background" && isUnsupportedBackgroundShorthandValue(d.valueRaw)) {
42850
+ const expanded = d.value.kind === "static" && !d.important && !hasOtherBackgroundDeclaration(allRules, d) ? expandBackgroundShorthandComponents(d.valueRaw) : null;
42851
+ if (expanded) {
42852
+ const commentSource = {
42853
+ leading: d.leadingComment,
42854
+ leadingLine: d.leadingLineComment,
42855
+ trailingLine: d.trailingLineComment
42856
+ };
42857
+ let isFirst = true;
42858
+ for (const { prop, value } of expanded) {
42859
+ applyResolvedPropValue(prop, value, isFirst ? commentSource : null, d.property);
42860
+ isFirst = false;
42861
+ }
42862
+ continue;
42863
+ }
40866
42864
  state.bailUnsupported(ctx.decl, "Unsupported background shorthand: multiple components cannot be mapped to a single StyleX longhand");
40867
42865
  if (state.currentDecl === ctx.decl) break;
40868
42866
  state.bail = true;
@@ -40917,6 +42915,19 @@ function resolveInterpolatedPropertyName(property, ctx) {
40917
42915
  if (!resolved.startsWith("--")) return null;
40918
42916
  return resolved;
40919
42917
  }
42918
+ /**
42919
+ * True when any declaration other than `current` (across all of the component's
42920
+ * rules) targets a `background`/`background-*` property. A multi-component
42921
+ * background expansion only reproduces reset semantics in isolation, so the
42922
+ * presence of a sibling background declaration makes the expansion unsafe.
42923
+ */
42924
+ function hasOtherBackgroundDeclaration(allRules, current) {
42925
+ for (const rule of allRules) for (const declaration of rule.declarations) {
42926
+ if (declaration === current) continue;
42927
+ if (declaration.property && /^background(-|$)/.test(declaration.property)) return true;
42928
+ }
42929
+ return false;
42930
+ }
40920
42931
  //#endregion
40921
42932
  //#region src/internal/lower-rules/process-rules.ts
40922
42933
  function processDeclRules(ctx) {
@@ -41560,6 +43571,40 @@ function processDeclRules(ctx) {
41560
43571
  for (const bucket of variantBuckets.values()) if (Object.hasOwn(bucket, prop)) wrapStyleConditionValue(bucket, prop, conditionKey, conditionValue);
41561
43572
  patchStyleFnConditionValue(prop, conditionKey, conditionValue);
41562
43573
  };
43574
+ /**
43575
+ * A base-scope declaration later in the CSS overrides any earlier conditional
43576
+ * assignment of the same property — within one styled template the generated
43577
+ * class contains both declarations, and the last one wins regardless of the
43578
+ * runtime condition. Drop the dead base-scope value from earlier variant
43579
+ * buckets so the emitted variant (applied after the base style in
43580
+ * stylex.props) cannot incorrectly win. Condition-scoped values (pseudo/media
43581
+ * maps) only lose their `default` layer.
43582
+ *
43583
+ * Exception: an earlier `!important` conditional value still wins over a later
43584
+ * non-important base declaration in the CSS cascade, so it must be preserved.
43585
+ * (When the later base is itself `!important`, source order decides and the
43586
+ * later one wins, so clearing is correct.)
43587
+ */
43588
+ const clearEarlierVariantBaseValues = (prop, laterBaseValue) => {
43589
+ const laterBaseIsImportant = cssValueIsImportant(laterBaseValue);
43590
+ for (const [when, bucket] of variantBuckets) {
43591
+ if (!Object.hasOwn(bucket, prop)) continue;
43592
+ const bucketValue = bucket[prop];
43593
+ if (bucketValue !== null && typeof bucketValue === "object" && !isAstNode$1(bucketValue) && "default" in bucketValue) {
43594
+ const conditionDefault = bucketValue.default;
43595
+ if (!laterBaseIsImportant && cssValueIsImportant(conditionDefault)) continue;
43596
+ bucketValue.default = null;
43597
+ continue;
43598
+ }
43599
+ if (!laterBaseIsImportant && cssValueIsImportant(bucketValue)) continue;
43600
+ delete bucket[prop];
43601
+ if (Object.keys(bucket).length === 0) {
43602
+ variantBuckets.delete(when);
43603
+ delete ctx.variantStyleKeys[when];
43604
+ delete ctx.variantSourceOrder[when];
43605
+ }
43606
+ }
43607
+ };
41563
43608
  const applyResolvedPropValue = (prop, value, commentSource, sourceCssProperty) => {
41564
43609
  const noteSourceCssProperty = (target) => {
41565
43610
  if (sourceCssProperty) {
@@ -41573,6 +43618,9 @@ function processDeclRules(ctx) {
41573
43618
  sourceProperties[prop] = sourceCssProperty;
41574
43619
  }
41575
43620
  };
43621
+ const noteConditionSourceOrder = (target, condition) => {
43622
+ setConditionSourceOrder(target, condition, ctx.getCurrentDeclarationSourceOrder());
43623
+ };
41576
43624
  if (attrTarget) {
41577
43625
  if (attrPseudoElement) {
41578
43626
  const nested = attrTarget[attrPseudoElement] ?? {};
@@ -41607,7 +43655,10 @@ function processDeclRules(ctx) {
41607
43655
  }
41608
43656
  const current = existing[media];
41609
43657
  const mediaMap = current && typeof current === "object" && !Array.isArray(current) && !isAstNode$1(current) ? current : { default: current ?? getConditionDefaultValue(prop) };
41610
- for (const ps of pseudos) mediaMap[ps] = value;
43658
+ for (const ps of pseudos) {
43659
+ mediaMap[ps] = value;
43660
+ noteConditionSourceOrder(mediaMap, ps);
43661
+ }
41611
43662
  existing[media] = mediaMap;
41612
43663
  } else {
41613
43664
  perPropPseudo[prop] ??= {};
@@ -41624,6 +43675,7 @@ function processDeclRules(ctx) {
41624
43675
  existing[ps] = { default: current !== void 0 ? current : fallbackDefault };
41625
43676
  } else if (!("default" in current)) current.default = getConditionDefaultValue(prop);
41626
43677
  existing[ps][media] = value;
43678
+ noteConditionSourceOrder(existing[ps], media);
41627
43679
  }
41628
43680
  }
41629
43681
  return;
@@ -41704,6 +43756,7 @@ function processDeclRules(ctx) {
41704
43756
  const currentMediaValue = existing[media];
41705
43757
  if (currentMediaValue && typeof currentMediaValue === "object" && !Array.isArray(currentMediaValue) && !isAstNode$1(currentMediaValue)) currentMediaValue.default = value;
41706
43758
  else existing[media] = value;
43759
+ noteConditionSourceOrder(existing, media);
41707
43760
  patchEarlierDynamicConditionValues(prop, media, value);
41708
43761
  return;
41709
43762
  }
@@ -41719,10 +43772,16 @@ function processDeclRules(ctx) {
41719
43772
  const peTarget = nestedSelectors[pseudoElement];
41720
43773
  noteSourceCssProperty(peTarget);
41721
43774
  const existingVal = peTarget[prop];
41722
- if (typeof existingVal === "object" && existingVal !== null && "default" in existingVal) for (const ps of pseudos) existingVal[ps] = value;
43775
+ if (typeof existingVal === "object" && existingVal !== null && "default" in existingVal) for (const ps of pseudos) {
43776
+ existingVal[ps] = value;
43777
+ noteConditionSourceOrder(existingVal, ps);
43778
+ }
41723
43779
  else {
41724
43780
  const pseudoMap = { default: existingVal ?? getConditionDefaultValue(prop) };
41725
- for (const ps of pseudos) pseudoMap[ps] = value;
43781
+ for (const ps of pseudos) {
43782
+ pseudoMap[ps] = value;
43783
+ noteConditionSourceOrder(pseudoMap, ps);
43784
+ }
41726
43785
  peTarget[prop] = pseudoMap;
41727
43786
  }
41728
43787
  return;
@@ -41735,7 +43794,10 @@ function processDeclRules(ctx) {
41735
43794
  const existingVal = styleObj[prop];
41736
43795
  existing.default = existingVal !== void 0 ? existingVal : getConditionDefaultValue(prop);
41737
43796
  }
41738
- for (const ps of pseudos) existing[ps] = value;
43797
+ for (const ps of pseudos) {
43798
+ existing[ps] = value;
43799
+ noteConditionSourceOrder(existing, ps);
43800
+ }
41739
43801
  return;
41740
43802
  }
41741
43803
  const pseudoElementsToApply = pseudoElement ? [pseudoElement] : pseudoElementsList;
@@ -41757,6 +43819,7 @@ function processDeclRules(ctx) {
41757
43819
  }
41758
43820
  return;
41759
43821
  }
43822
+ clearEarlierVariantBaseValues(prop, value);
41760
43823
  const target = ctx.getBaseStyleTarget();
41761
43824
  setStyleObjectValue(target, prop, value);
41762
43825
  noteSourceCssProperty(target);
@@ -42285,9 +44348,23 @@ function recoverStandaloneInterpolationsInPseudoBlock(rule, decl) {
42285
44348
  cssProps
42286
44349
  };
42287
44350
  }
44351
+ /**
44352
+ * Whether a lowered StyleX value carries `!important`. Values are stored either
44353
+ * as plain strings (e.g. `"red !important"`) or as AST string/template literals.
44354
+ */
44355
+ function cssValueIsImportant(value) {
44356
+ if (typeof value === "string") return value.includes("!important");
44357
+ if (!value || typeof value !== "object") return false;
44358
+ const node = value;
44359
+ if ((node.type === "StringLiteral" || node.type === "Literal") && typeof node.value === "string") return node.value.includes("!important");
44360
+ if (node.type === "TemplateLiteral" && Array.isArray(node.quasis)) return node.quasis.some((q) => (q?.value?.cooked ?? q?.value?.raw ?? "").includes("!important"));
44361
+ return false;
44362
+ }
42288
44363
  /** Negates a `when` condition string (e.g. `$active` → `!$active`, `!$x` → `$x`). */
42289
44364
  function negateWhen(when) {
44365
+ if (when.startsWith("!(") && when.endsWith(")")) return when.slice(2, -1);
42290
44366
  if (when.startsWith("!")) return when.slice(1);
44367
+ if (when.includes(" || ") || when.includes(" && ")) return `!(${when})`;
42291
44368
  if (when.includes(" === ")) return when.replace(" === ", " !== ");
42292
44369
  if (when.includes(" !== ")) return when.replace(" !== ", " === ");
42293
44370
  return `!${when}`;
@@ -44774,6 +46851,10 @@ function wrappedComponentAcceptsSxProp(ctx, componentLocalName, visiting = /* @_
44774
46851
  visiting.delete(componentLocalName);
44775
46852
  return true;
44776
46853
  }
46854
+ if (localStyledDecl?.needsWrapperComponent && !localStyledDecl.skipTransform && localStyledDecl.supportsExternalStyles) {
46855
+ visiting.delete(componentLocalName);
46856
+ return true;
46857
+ }
44777
46858
  const componentInterface = wrappedComponentInterfaceFor(ctx, componentLocalName);
44778
46859
  if (componentInterface !== void 0) {
44779
46860
  visiting.delete(componentLocalName);
@@ -45021,8 +47102,9 @@ function rewriteJsxStep(ctx) {
45021
47102
  const mergeArgs = matchedCombinedStyleKey ? void 0 : opening.__promotedMergeArgs;
45022
47103
  const baseMember = j.memberExpression(j.identifier(ctx.stylesIdentifier ?? "styles"), j.identifier(baseStyleKey));
45023
47104
  const baseExpr = mergeArgs ? j.callExpression(baseMember, mergeArgs) : baseMember;
47105
+ const rendersLocalWrapperBase = decl.base.kind === "component" && decl.base.ident === finalTag && (ctx.styledDecls?.some((d) => d.localName === finalTag && d.needsWrapperComponent && !d.skipTransform) ?? false);
45024
47106
  const styleArgs = [
45025
- ...decl.extendsStyleKey ? [j.memberExpression(j.identifier(ctx.stylesIdentifier ?? "styles"), j.identifier(decl.extendsStyleKey))] : [],
47107
+ ...decl.extendsStyleKey && !rendersLocalWrapperBase ? [j.memberExpression(j.identifier(ctx.stylesIdentifier ?? "styles"), j.identifier(decl.extendsStyleKey))] : [],
45026
47108
  ...extraMixinArgs,
45027
47109
  ...decl.skipBaseStyleRef ? [] : [baseExpr],
45028
47110
  ...extraAfterBaseArgs
@@ -45106,7 +47188,8 @@ function rewriteJsxStep(ctx) {
45106
47188
  }
45107
47189
  }
45108
47190
  if (!hasTemplateVariant) {
45109
- if ((n.startsWith("$") || renamedTransientValues?.has(n)) && decl.base.kind === "intrinsic") return;
47191
+ const shouldStripRenamedTransient = renamedTransientValues?.has(n) && (decl.base.kind === "intrinsic" || styleFnProps.has(n) || variantProps.has(n));
47192
+ if (n.startsWith("$") || shouldStripRenamedTransient) return;
45110
47193
  output.push(attr);
45111
47194
  return;
45112
47195
  }