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

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.
Files changed (2) hide show
  1. package/dist/transform.mjs +1582 -260
  2. package/package.json +1 -1
@@ -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.
@@ -408,6 +491,16 @@ function cssDeclarationToStylexDeclarations(decl) {
408
491
  if (decl.value.kind === "interpolated") return expandInterpolatedBorder(prop, "", decl.value);
409
492
  return borderShorthandToStylex(raw, "");
410
493
  }
494
+ if (prop === "border-radius" && decl.value.kind === "static") {
495
+ const expanded = borderRadiusShorthandToStylex(decl.valueRaw.trim());
496
+ if (expanded.length > 0) return expanded.map(({ prop, value }) => ({
497
+ prop,
498
+ value: {
499
+ kind: "static",
500
+ value
501
+ }
502
+ }));
503
+ }
411
504
  const borderDirectionMatch = prop.match(/^border-(top|right|bottom|left)$/);
412
505
  if (borderDirectionMatch) {
413
506
  const direction = borderDirectionMatch[1];
@@ -444,6 +537,28 @@ function normalizeGridLineSlashSpacing(stylexProp, value) {
444
537
  value: normalizeUnescapedSlashSpacing(value.value)
445
538
  };
446
539
  }
540
+ function borderRadiusShorthandToStylex(raw) {
541
+ const expanded = expandBorderRadiusShorthandValue(raw);
542
+ if (!expanded) return [];
543
+ return [
544
+ {
545
+ prop: "borderTopLeftRadius",
546
+ value: expanded.topLeft
547
+ },
548
+ {
549
+ prop: "borderTopRightRadius",
550
+ value: expanded.topRight
551
+ },
552
+ {
553
+ prop: "borderBottomRightRadius",
554
+ value: expanded.bottomRight
555
+ },
556
+ {
557
+ prop: "borderBottomLeftRadius",
558
+ value: expanded.bottomLeft
559
+ }
560
+ ];
561
+ }
447
562
  function normalizeUnescapedSlashSpacing(value) {
448
563
  let output = "";
449
564
  for (let index = 0; index < value.length; index++) {
@@ -5137,6 +5252,299 @@ function buildChildStyleObjectList(childKeys, resolvedStyleObjects) {
5137
5252
  return childStyleObjects;
5138
5253
  }
5139
5254
  //#endregion
5255
+ //#region src/internal/lower-rules/style-object-normalization.ts
5256
+ function expandStyleObjectShorthands(styleObj) {
5257
+ const borderRadius = staticStringValue(styleObj.borderRadius);
5258
+ if (borderRadius === null) return styleObj;
5259
+ const expanded = expandBorderRadiusShorthandValue(borderRadius);
5260
+ if (!expanded) return styleObj;
5261
+ return expandBorderRadiusInStyleObject(styleObj, expanded);
5262
+ }
5263
+ /**
5264
+ * Resolves a style value to a static string when possible: plain strings,
5265
+ * string-literal AST nodes, and expression-free template literals.
5266
+ */
5267
+ function staticStringValue(value) {
5268
+ if (typeof value === "string") return value;
5269
+ if (!value || typeof value !== "object") return null;
5270
+ const node = value;
5271
+ if ((node.type === "Literal" || node.type === "StringLiteral") && typeof node.value === "string") return node.value;
5272
+ if (node.type === "TemplateLiteral" && node.expressions?.length === 0) {
5273
+ const quasi = node.quasis?.[0];
5274
+ return quasi?.value?.cooked ?? quasi?.value?.raw ?? null;
5275
+ }
5276
+ return null;
5277
+ }
5278
+ //#endregion
5279
+ //#region src/internal/lower-rules/variant-utils.ts
5280
+ /**
5281
+ * Inverts a "when" condition string for the opposite variant branch.
5282
+ * E.g., "!$active" -> "$active", "$x === true" -> "$x !== true"
5283
+ */
5284
+ function invertWhen(when) {
5285
+ if (when.startsWith("!(") && when.endsWith(")")) return when.slice(2, -1);
5286
+ if (when.startsWith("!")) return when.slice(1);
5287
+ const match = when.match(/^(.+)\s+(===|!==)\s+(.+)$/);
5288
+ if (match) {
5289
+ const [, propName, op, rhs] = match;
5290
+ return `${propName} ${op === "===" ? "!==" : "==="} ${rhs}`;
5291
+ }
5292
+ if (!when.includes(" ")) return `!${when}`;
5293
+ return null;
5294
+ }
5295
+ function buildPseudoMediaPropValue(args) {
5296
+ const { j, valueExpr, pseudos, media } = args;
5297
+ const pseudoList = pseudos ?? [];
5298
+ const hasPseudos = pseudoList.length > 0;
5299
+ if (!media && !hasPseudos) return valueExpr;
5300
+ if (media && hasPseudos) {
5301
+ 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)])));
5302
+ return j.objectExpression([j.property("init", j.identifier("default"), j.literal(null)), ...pseudoProps]);
5303
+ }
5304
+ if (media) return j.objectExpression([j.property("init", j.identifier("default"), j.literal(null)), j.property("init", j.literal(media), valueExpr)]);
5305
+ const pseudoProps = pseudoList.map((ps) => j.property("init", j.literal(ps), valueExpr));
5306
+ return j.objectExpression([j.property("init", j.identifier("default"), j.literal(null)), ...pseudoProps]);
5307
+ }
5308
+ const createPropTestHelpers = (bindings) => {
5309
+ const paramName = bindings.kind === "simple" ? bindings.paramName : null;
5310
+ const getMemberExpressionSource = (node) => {
5311
+ const info = extractRootAndPath(node);
5312
+ if (!info) return null;
5313
+ if (info.path.length === 0) return info.rootName;
5314
+ return `${info.rootName}.${info.path.join(".")}`;
5315
+ };
5316
+ const readPropAccess = (node) => {
5317
+ const info = extractRootAndPath(node);
5318
+ if (!info) return null;
5319
+ if (paramName && info.rootName === paramName) {
5320
+ if (info.path.length === 0) return null;
5321
+ const [propRoot, ...rest] = info.path;
5322
+ if (!propRoot) return null;
5323
+ if (propRoot === "theme") return null;
5324
+ return {
5325
+ propName: propRoot,
5326
+ whenName: [propRoot, ...rest].join(".")
5327
+ };
5328
+ }
5329
+ if (bindings.kind === "destructured") {
5330
+ const propName = resolveIdentifierToPropName(info.rootNode, bindings);
5331
+ if (!propName) return null;
5332
+ return {
5333
+ propName,
5334
+ whenName: info.path.length > 0 ? `${propName}.${info.path.join(".")}` : propName
5335
+ };
5336
+ }
5337
+ return null;
5338
+ };
5339
+ const parseTestInfo = (test) => {
5340
+ if (!test || typeof test !== "object") return null;
5341
+ if (test.type === "Identifier" && bindings.kind === "destructured") {
5342
+ const propAccess = readPropAccess(test);
5343
+ return propAccess ? {
5344
+ when: propAccess.whenName,
5345
+ propName: propAccess.propName
5346
+ } : null;
5347
+ }
5348
+ if (isMemberExpression(test)) {
5349
+ const propAccess = readPropAccess(test);
5350
+ return propAccess ? {
5351
+ when: propAccess.whenName,
5352
+ propName: propAccess.propName
5353
+ } : null;
5354
+ }
5355
+ if (test.type === "UnaryExpression" && test.operator === "!" && test.argument) {
5356
+ const propAccess = readPropAccess(test.argument);
5357
+ return propAccess ? {
5358
+ when: `!${propAccess.whenName}`,
5359
+ propName: propAccess.propName
5360
+ } : null;
5361
+ }
5362
+ if (test.type === "BinaryExpression" && (test.operator === "===" || test.operator === "!==")) {
5363
+ const left = test.left;
5364
+ const getRhsValue = () => {
5365
+ const rhsTyped = test.right;
5366
+ if (rhsTyped.type === "Identifier" && rhsTyped.name === "undefined") return "undefined";
5367
+ const rhs = literalToStaticValue(test.right);
5368
+ if (rhs === null) return getMemberExpressionSource(test.right);
5369
+ return JSON.stringify(rhs);
5370
+ };
5371
+ if (bindings.kind === "destructured" && left.type === "Identifier") {
5372
+ const propAccess = readPropAccess(left);
5373
+ const rhsValue = getRhsValue();
5374
+ if (!propAccess || rhsValue === null) return null;
5375
+ return {
5376
+ when: `${propAccess.whenName} ${test.operator} ${rhsValue}`,
5377
+ propName: propAccess.propName
5378
+ };
5379
+ }
5380
+ if (isMemberExpression(left)) {
5381
+ const propAccess = readPropAccess(left);
5382
+ const rhsValue = getRhsValue();
5383
+ if (!propAccess || rhsValue === null) return null;
5384
+ return {
5385
+ when: `${propAccess.whenName} ${test.operator} ${rhsValue}`,
5386
+ propName: propAccess.propName
5387
+ };
5388
+ }
5389
+ }
5390
+ return null;
5391
+ };
5392
+ /**
5393
+ * Parse chained && / || conditions, returning a combined TestInfo.
5394
+ *
5395
+ * Supported patterns:
5396
+ * props.a && props.b → { when: 'a && b' }
5397
+ * props.$a || props.$b → { when: '$a || $b' }
5398
+ * props.$a && (props.$b || $c) → { when: '$a && $b || $c' }
5399
+ * !(props.$a || props.$b) → { when: '!($a || $b)' }
5400
+ *
5401
+ * Bails (returns null) on || wrapping && children to avoid ambiguous
5402
+ * serialization: "a && b || c" would be reparsed as "a && (b || c)"
5403
+ * by parseVariantWhenToAst, which splits on && first.
5404
+ */
5405
+ const parseChainedTestInfo = (test) => {
5406
+ const simple = parseTestInfo(test);
5407
+ if (simple) return simple;
5408
+ if (!test || typeof test !== "object") return null;
5409
+ if (test.type === "UnaryExpression" && test.operator === "!" && test.argument) {
5410
+ const innerInfo = parseChainedTestInfo(test.argument);
5411
+ if (innerInfo) {
5412
+ const allProps = innerInfo.allPropNames ?? (innerInfo.propName ? [innerInfo.propName] : []);
5413
+ return {
5414
+ when: `!(${innerInfo.when})`,
5415
+ propName: innerInfo.propName,
5416
+ allPropNames: allProps
5417
+ };
5418
+ }
5419
+ }
5420
+ if (test.type === "LogicalExpression" && (test.operator === "&&" || test.operator === "||")) {
5421
+ const leftInfo = parseChainedTestInfo(test.left);
5422
+ const rightInfo = parseChainedTestInfo(test.right);
5423
+ if (leftInfo && rightInfo) {
5424
+ if (test.operator === "||" && (leftInfo.when.includes(" && ") || rightInfo.when.includes(" && "))) return null;
5425
+ if (hasOperatorInsideParens(leftInfo.when, test.operator) || hasOperatorInsideParens(rightInfo.when, test.operator)) return null;
5426
+ const combinedWhen = `${leftInfo.when} ${test.operator} ${rightInfo.when}`;
5427
+ const leftProps = leftInfo.allPropNames ?? (leftInfo.propName ? [leftInfo.propName] : []);
5428
+ const rightProps = rightInfo.allPropNames ?? (rightInfo.propName ? [rightInfo.propName] : []);
5429
+ const allPropNames = [...new Set([...leftProps, ...rightProps])];
5430
+ return {
5431
+ when: combinedWhen,
5432
+ propName: rightInfo.propName,
5433
+ allPropNames
5434
+ };
5435
+ }
5436
+ }
5437
+ return null;
5438
+ };
5439
+ return {
5440
+ parseTestInfo,
5441
+ parseChainedTestInfo
5442
+ };
5443
+ };
5444
+ /**
5445
+ * Per-decl snapshot of the base style object's entries at the moment each
5446
+ * variant (`when`) first received styles. Captures the source position of
5447
+ * conditional blocks relative to base declarations: keys missing from a
5448
+ * variant's snapshot — or whose value changed since — were (re)declared after
5449
+ * that variant in the original CSS.
5450
+ */
5451
+ const variantBaseKeySnapshots = /* @__PURE__ */ new WeakMap();
5452
+ const variantSourceOrders = /* @__PURE__ */ new WeakMap();
5453
+ function getVariantBaseKeySnapshot(decl, when) {
5454
+ return variantBaseKeySnapshots.get(decl)?.get(when);
5455
+ }
5456
+ function getVariantSourceOrder(decl, when) {
5457
+ return variantSourceOrders.get(decl)?.get(when);
5458
+ }
5459
+ function renameVariantSourceOrderConditions(decl, renameWhen) {
5460
+ const sourceOrders = variantSourceOrders.get(decl);
5461
+ if (!sourceOrders) return;
5462
+ const renamed = /* @__PURE__ */ new Map();
5463
+ for (const [when, sourceOrder] of sourceOrders) {
5464
+ const renamedWhen = renameWhen(when);
5465
+ if (!renamed.has(renamedWhen)) renamed.set(renamedWhen, sourceOrder);
5466
+ }
5467
+ variantSourceOrders.set(decl, renamed);
5468
+ }
5469
+ const createVariantApplier = (args) => {
5470
+ const { decl, variantBuckets, variantStyleKeys, baseStyleObj, conditionStyleObjs, getCurrentSourceOrder } = args;
5471
+ const dropAllTestInfoProps = (testInfo) => {
5472
+ const propsToCheck = testInfo.allPropNames ?? (testInfo.propName ? [testInfo.propName] : []);
5473
+ for (const prop of propsToCheck) if (prop && !prop.startsWith("$")) ensureShouldForwardPropDrop(decl, prop);
5474
+ };
5475
+ return (testInfo, consStyle) => {
5476
+ const when = testInfo.when;
5477
+ if (baseStyleObj) {
5478
+ const snapshots = variantBaseKeySnapshots.get(decl) ?? /* @__PURE__ */ new Map();
5479
+ if (!snapshots.has(when)) {
5480
+ snapshots.set(when, createBaseKeySnapshot(baseStyleObj, conditionStyleObjs));
5481
+ variantBaseKeySnapshots.set(decl, snapshots);
5482
+ const sourceOrder = getCurrentSourceOrder?.();
5483
+ if (sourceOrder !== void 0) {
5484
+ const sourceOrders = variantSourceOrders.get(decl) ?? /* @__PURE__ */ new Map();
5485
+ sourceOrders.set(when, sourceOrder);
5486
+ variantSourceOrders.set(decl, sourceOrders);
5487
+ }
5488
+ }
5489
+ }
5490
+ const existingBucket = variantBuckets.get(when);
5491
+ const nextBucket = existingBucket ? { ...existingBucket } : {};
5492
+ mergeStyleObjects(nextBucket, expandStyleObjectShorthands(consStyle));
5493
+ variantBuckets.set(when, nextBucket);
5494
+ variantStyleKeys[when] ??= styleKeyWithSuffix(decl.styleKey, when);
5495
+ dropAllTestInfoProps(testInfo);
5496
+ };
5497
+ };
5498
+ function createBaseKeySnapshot(baseStyleObj, conditionStyleObjs) {
5499
+ const snapshot = new Map(Object.entries(baseStyleObj).map(([key, value]) => [key, cloneSnapshotValue(value)]));
5500
+ for (const conditionStyleObj of conditionStyleObjs ?? []) for (const [key, value] of Object.entries(conditionStyleObj)) mergeSnapshotConditionMap(snapshot, key, value);
5501
+ return snapshot;
5502
+ }
5503
+ function mergeSnapshotConditionMap(snapshot, key, value) {
5504
+ const existing = snapshot.get(key);
5505
+ const next = cloneSnapshotValue(value);
5506
+ if (!isSnapshotPlainMap(next)) {
5507
+ snapshot.set(key, next);
5508
+ return;
5509
+ }
5510
+ if (isSnapshotPlainMap(existing)) {
5511
+ mergeStyleObjects(existing, next);
5512
+ return;
5513
+ }
5514
+ if (existing !== void 0 && (next.default === null || next.default === void 0)) next.default = cloneSnapshotValue(existing);
5515
+ snapshot.set(key, next);
5516
+ }
5517
+ /**
5518
+ * Clones plain condition-map values for snapshots so later in-place merges
5519
+ * into the base style object cannot retroactively alter what the snapshot
5520
+ * recorded. AST nodes are kept by reference — redeclarations replace them.
5521
+ */
5522
+ function cloneSnapshotValue(value) {
5523
+ if (!isSnapshotPlainMap(value)) return value;
5524
+ const cloned = {};
5525
+ for (const [key, entryValue] of Object.entries(value)) cloned[key] = cloneSnapshotValue(entryValue);
5526
+ return cloned;
5527
+ }
5528
+ function isSnapshotPlainMap(value) {
5529
+ return !!value && typeof value === "object" && !Array.isArray(value) && typeof value.type !== "string";
5530
+ }
5531
+ /**
5532
+ * Returns true if the string contains the given operator (`&&` or `||`)
5533
+ * inside parenthesized groups. Used to detect when strings like
5534
+ * `"!($b && $c)"` or `"!($b || $c)"` that would be broken by the naive
5535
+ * split in `parseVariantWhenToAst`.
5536
+ */
5537
+ function hasOperatorInsideParens(when, operator) {
5538
+ let depth = 0;
5539
+ for (let i = 0; i < when.length; i++) {
5540
+ const ch = when[i];
5541
+ if (ch === "(") depth++;
5542
+ else if (ch === ")") depth--;
5543
+ else if (depth > 0 && when[i] === operator[0] && when.startsWith(operator, i)) return true;
5544
+ }
5545
+ return false;
5546
+ }
5547
+ //#endregion
5140
5548
  //#region src/internal/utilities/style-composition-plan.ts
5141
5549
  function buildStyleKeySequence(ctx, decl, options) {
5142
5550
  const entries = [];
@@ -5280,7 +5688,8 @@ function buildVariantAndStyleFnEntries(decl) {
5280
5688
  styleKey,
5281
5689
  patchable: true,
5282
5690
  contributes: false,
5283
- source: "variant"
5691
+ source: "variant",
5692
+ sourceOrder: getVariantSourceOrder(decl, when)
5284
5693
  }
5285
5694
  }));
5286
5695
  const styleFnEntries = (decl.styleFnFromProps ?? []).map((styleFn) => ({
@@ -5332,12 +5741,14 @@ function buildVariantDimensionEntries(decl) {
5332
5741
  styleObj,
5333
5742
  patchable: true,
5334
5743
  contributes: false,
5335
- source: "variant"
5744
+ source: "variant",
5745
+ sourceOrder: dimension.sourceOrder
5336
5746
  }));
5337
5747
  if (dimension.fallbackFnKey) entries.push({
5338
5748
  styleKey: dimension.fallbackFnKey,
5339
5749
  patchable: true,
5340
- source: "styleFn"
5750
+ source: "styleFn",
5751
+ sourceOrder: dimension.sourceOrder
5341
5752
  });
5342
5753
  if (dimension.sourceOrder === void 0) {
5343
5754
  immediate.push(...entries);
@@ -5462,6 +5873,29 @@ function buildEnumVariantEntries(decl) {
5462
5873
  }))];
5463
5874
  }
5464
5875
  //#endregion
5876
+ //#region src/internal/lower-rules/condition-source-order.ts
5877
+ /**
5878
+ * Source-order metadata for pseudo/media condition maps.
5879
+ * Core concepts: non-emitted metadata and CSS cascade comparisons.
5880
+ */
5881
+ const conditionSourceOrders = /* @__PURE__ */ new WeakMap();
5882
+ function setConditionSourceOrder(map, condition, sourceOrder) {
5883
+ if (sourceOrder === void 0) return;
5884
+ const orders = conditionSourceOrders.get(map) ?? /* @__PURE__ */ new Map();
5885
+ orders.set(condition, sourceOrder);
5886
+ conditionSourceOrders.set(map, orders);
5887
+ }
5888
+ function getConditionSourceOrder(map, condition) {
5889
+ return conditionSourceOrders.get(map)?.get(condition);
5890
+ }
5891
+ function copyConditionSourceOrders(target, source) {
5892
+ const sourceOrders = conditionSourceOrders.get(source);
5893
+ if (!sourceOrders) return;
5894
+ const targetOrders = conditionSourceOrders.get(target) ?? /* @__PURE__ */ new Map();
5895
+ for (const [condition, sourceOrder] of sourceOrders) targetOrders.set(condition, sourceOrder);
5896
+ conditionSourceOrders.set(target, targetOrders);
5897
+ }
5898
+ //#endregion
5465
5899
  //#region src/internal/utilities/conditional-style-defaults.ts
5466
5900
  const FLAT_ERASES_CONDITIONAL_WARNING = "Flat StyleX value would erase earlier conditional property states";
5467
5901
  function flatStylexValueErasureExample(prop) {
@@ -5486,11 +5920,11 @@ function defaultInferenceFromPropertyShape(shape) {
5486
5920
  if (shape.kind === "conditionalMap") return shape.defaultValue;
5487
5921
  return shape;
5488
5922
  }
5489
- function patchFlatValueAgainstPriorPropertyShape(styleObj, prop, earlier, laterSource = "mixin") {
5923
+ function patchFlatValueAgainstPriorPropertyShape(styleObj, prop, earlier, laterSource = "mixin", laterSourceOrder) {
5490
5924
  if (earlier.kind !== "conditionalMap") return "safe";
5491
5925
  const current = inferPropertyShapeFromValue(styleObj[prop]);
5492
5926
  if (current.kind !== "flat") return "safe";
5493
- const preservedConditions = staticConditionsPreservedByLaterFlat(earlier, laterSource);
5927
+ const preservedConditions = staticConditionsPreservedByLaterFlat(earlier, laterSource, laterSourceOrder);
5494
5928
  if (!preservedConditions) return "bail";
5495
5929
  if (Object.keys(preservedConditions).length === 0) return "safe";
5496
5930
  styleObj[prop] = {
@@ -5558,7 +5992,7 @@ function patchConditionalDefaultsForSequence(args) {
5558
5992
  const earlier = shapes.get(prop) ?? { kind: "absent" };
5559
5993
  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
5994
  contributionSource = patchTarget;
5561
- if (patchFlatValueAgainstPriorPropertyShape(patchTarget, prop, earlier, entry.source) !== "bail") continue;
5995
+ if (patchFlatValueAgainstPriorPropertyShape(patchTarget, prop, earlier, entry.source, entry.sourceOrder) !== "bail") continue;
5562
5996
  ctx.warnings.push({
5563
5997
  severity: "warning",
5564
5998
  type: FLAT_ERASES_CONDITIONAL_WARNING,
@@ -5784,6 +6218,7 @@ function inferPropertyShapeFromValue(value) {
5784
6218
  const defaultValue = value.default;
5785
6219
  const conditionKeys = Object.keys(value).filter(isStyleConditionKey$1);
5786
6220
  const staticConditions = readStaticConditionValues(value, conditionKeys);
6221
+ const conditionSourceOrders = readConditionSourceOrders(value, conditionKeys);
5787
6222
  return {
5788
6223
  kind: "conditionalMap",
5789
6224
  defaultValue: isStaticStyleValue(defaultValue) ? defaultValue === null ? { kind: "absent" } : {
@@ -5791,7 +6226,8 @@ function inferPropertyShapeFromValue(value) {
5791
6226
  value: defaultValue
5792
6227
  } : { kind: "dynamic" },
5793
6228
  conditionKeys,
5794
- ...staticConditions ? { staticConditions } : {}
6229
+ ...staticConditions ? { staticConditions } : {},
6230
+ ...conditionSourceOrders ? { conditionSourceOrders } : {}
5795
6231
  };
5796
6232
  }
5797
6233
  return { kind: "dynamic" };
@@ -5806,9 +6242,21 @@ function readStaticConditionValues(value, conditionKeys) {
5806
6242
  }
5807
6243
  return conditions;
5808
6244
  }
5809
- function staticConditionsPreservedByLaterFlat(earlier, laterSource) {
6245
+ function readConditionSourceOrders(value, conditionKeys) {
6246
+ const orders = {};
6247
+ for (const key of conditionKeys) {
6248
+ const sourceOrder = getConditionSourceOrder(value, key);
6249
+ if (sourceOrder !== void 0) orders[key] = sourceOrder;
6250
+ }
6251
+ return Object.keys(orders).length ? orders : void 0;
6252
+ }
6253
+ function staticConditionsPreservedByLaterFlat(earlier, laterSource, laterSourceOrder) {
5810
6254
  const minSpecificity = conditionSpecificityNeededToOutrankFlatSource(laterSource);
5811
- const preservedKeys = earlier.conditionKeys.filter((key) => conditionSpecificity(key) > minSpecificity);
6255
+ const preservedKeys = earlier.conditionKeys.filter((key) => {
6256
+ const conditionSourceOrder = earlier.conditionSourceOrders?.[key];
6257
+ if (laterSourceOrder !== void 0 && conditionSourceOrder !== void 0 && conditionSourceOrder <= laterSourceOrder) return false;
6258
+ return conditionSpecificity(key) > minSpecificity;
6259
+ });
5812
6260
  if (preservedKeys.length === 0) return {};
5813
6261
  if (!earlier.staticConditions) return;
5814
6262
  const preserved = {};
@@ -8191,6 +8639,7 @@ function applyTransientPropRenames(decl, renames) {
8191
8639
  for (const [when, order] of Object.entries(decl.variantSourceOrder)) updated[renamePropsInWhenString(when, renames)] = order;
8192
8640
  decl.variantSourceOrder = updated;
8193
8641
  }
8642
+ renameVariantSourceOrderConditions(decl, (when) => renamePropsInWhenString(when, renames));
8194
8643
  if (decl.styleFnFromProps) for (const sf of decl.styleFnFromProps) {
8195
8644
  sf.jsxProp = renames.get(sf.jsxProp) ?? sf.jsxProp;
8196
8645
  if (sf.propsObjectKey) sf.propsObjectKey = renames.get(sf.propsObjectKey) ?? sf.propsObjectKey;
@@ -9553,6 +10002,12 @@ function validateSxRestrictedWrappedComponentStyles(ctx, styledDecls) {
9553
10002
  if (!rejectedProperty) {
9554
10003
  const disallowedProperty = allowed ? findSxDisallowedStyleProperty(style, allowed) : null;
9555
10004
  if (!disallowedProperty) continue;
10005
+ /**
10006
+ * Keep this as a warning instead of bailing. Some component wrappers expose
10007
+ * narrow style APIs (for example icon `color` props instead of raw `fill`
10008
+ * styles), but the generated output is still localized and manually fixable
10009
+ * by the migration author.
10010
+ */
9556
10011
  ctx.warnings.push({
9557
10012
  severity: "warning",
9558
10013
  type: "Wrapped component sx prop does not accept generated StyleX property",
@@ -9974,6 +10429,26 @@ function normalizeStylisAstToIR(stylisAst, slots, options = {}) {
9974
10429
  rules.push(created);
9975
10430
  return created;
9976
10431
  };
10432
+ const recoveredSelectorAliases = (selector) => {
10433
+ const normalized = normalizeRecoveredSelector(selector);
10434
+ const aliases = [normalized];
10435
+ const withoutLeadingAmpersands = splitTopLevelSelectorList(normalized).map((part) => part.startsWith("&") && part.length > 1 ? part.slice(1) : part).join(",");
10436
+ if (withoutLeadingAmpersands && withoutLeadingAmpersands !== normalized) aliases.push(withoutLeadingAmpersands);
10437
+ return aliases;
10438
+ };
10439
+ const findRecoveredRule = (selector, stack) => {
10440
+ const aliases = recoveredSelectorAliases(selector);
10441
+ for (const alias of aliases) {
10442
+ const rule = findRule(alias, stack);
10443
+ if (rule) return rule;
10444
+ }
10445
+ for (const rule of rules) {
10446
+ if (!sameArray(rule.atRuleStack, stack)) continue;
10447
+ const normalizedRuleSelector = rule.selector.replace(/^(?:__SC_EXPR_\d+__\s*)+/, "").trim();
10448
+ if (aliases.includes(normalizedRuleSelector)) return rule;
10449
+ }
10450
+ };
10451
+ const ensureRecoveredRule = (selector, stack) => findRecoveredRule(selector, stack) ?? ensureRule(normalizeRecoveredSelector(selector), stack);
9977
10452
  const visit = (node) => {
9978
10453
  if (!node) return;
9979
10454
  if (Array.isArray(node)) {
@@ -10069,12 +10544,19 @@ function normalizeStylisAstToIR(stylisAst, slots, options = {}) {
10069
10544
  const selectorStack = [];
10070
10545
  const recoveryAtRuleStack = [];
10071
10546
  const rawDeclarationCountByRule = /* @__PURE__ */ new WeakMap();
10547
+ let rawSourceOrder = 0;
10072
10548
  const recordRawDeclarations = (trimmed, selector, recoveryAtRules) => {
10073
10549
  const decls = parseDeclarations(trimmed, slotByPlaceholder);
10074
10550
  if (!decls.length) return;
10075
- const targetRule = findRule(normalizeRecoveredSelector(selector), recoveryAtRules);
10551
+ const targetRule = findRecoveredRule(selector, recoveryAtRules);
10076
10552
  if (!targetRule) return;
10077
- rawDeclarationCountByRule.set(targetRule, (rawDeclarationCountByRule.get(targetRule) ?? 0) + decls.length);
10553
+ const rawDeclarationCount = rawDeclarationCountByRule.get(targetRule) ?? 0;
10554
+ for (let i = 0; i < decls.length; i++) {
10555
+ const targetDecl = targetRule.declarations[rawDeclarationCount + i];
10556
+ if (targetDecl) targetDecl.sourceOrder ??= rawSourceOrder;
10557
+ rawSourceOrder++;
10558
+ }
10559
+ rawDeclarationCountByRule.set(targetRule, rawDeclarationCount + decls.length);
10078
10560
  };
10079
10561
  const recoverPlaceholder = (trimmed, selector, recoveryAtRules) => {
10080
10562
  const m = trimmed.match(placeholderLineRe);
@@ -10084,11 +10566,18 @@ function normalizeStylisAstToIR(stylisAst, slots, options = {}) {
10084
10566
  const mapped = slotByPlaceholder.get(placeholder);
10085
10567
  if (mapped === void 0) return false;
10086
10568
  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);
10569
+ const existingSlotDecl = (() => {
10570
+ for (const r of rules) for (const decl of r.declarations) {
10571
+ if (decl.value.kind !== "interpolated") continue;
10572
+ if (decl.value.parts.some((p) => p.kind === "slot" && p.slotId === mapped)) return decl;
10573
+ }
10574
+ return null;
10575
+ })();
10576
+ if (existingSlotDecl) {
10577
+ existingSlotDecl.sourceOrder ??= rawSourceOrder++;
10578
+ return false;
10579
+ }
10580
+ const targetRule = ensureRecoveredRule(selector, recoveryAtRules);
10092
10581
  const decl = {
10093
10582
  property: "",
10094
10583
  value: {
@@ -10099,7 +10588,8 @@ function normalizeStylisAstToIR(stylisAst, slots, options = {}) {
10099
10588
  }]
10100
10589
  },
10101
10590
  important: false,
10102
- valueRaw: placeholder
10591
+ valueRaw: placeholder,
10592
+ sourceOrder: rawSourceOrder++
10103
10593
  };
10104
10594
  if (shouldPreserveRawDeclarationPosition) {
10105
10595
  const rawDeclarationCount = rawDeclarationCountByRule.get(targetRule) ?? 0;
@@ -13266,6 +13756,10 @@ function isNumericStylexExpression(value, options = {}) {
13266
13756
  if (!value) return false;
13267
13757
  if (value.type === "NumericLiteral" || value.type === "Literal" && typeof value.value === "number") return true;
13268
13758
  if (value.type === "Identifier") return options.numericIdentifiers?.has(value.name) ?? false;
13759
+ if (value.type === "MemberExpression") {
13760
+ const rootName = memberExpressionRootIdentifier(value);
13761
+ return rootName ? options.numericIdentifiers?.has(rootName) ?? false : false;
13762
+ }
13269
13763
  if (value.type === "UnaryExpression") return (value.operator === "-" || value.operator === "+") && isNumericStylexExpression(value.argument, options);
13270
13764
  if (value.type === "BinaryExpression") return [
13271
13765
  "+",
@@ -13283,17 +13777,170 @@ function isNumericStylexExpression(value, options = {}) {
13283
13777
  function isExpressionNode(value) {
13284
13778
  return Boolean(value && typeof value === "object" && typeof value.type === "string");
13285
13779
  }
13780
+ function memberExpressionRootIdentifier(value) {
13781
+ if (value.type === "Identifier") return value.name;
13782
+ if (value.type !== "MemberExpression") return null;
13783
+ return memberExpressionRootIdentifier(value.object);
13784
+ }
13785
+ //#endregion
13786
+ //#region src/internal/utilities/stylex-import-source.ts
13787
+ /**
13788
+ * Matches StyleX sidecar/token module sources like "./tokens.stylex" or
13789
+ * "../vars.stylex.ts". By StyleX convention these modules only export
13790
+ * `defineVars`/`defineConsts` values and plain constants — never components —
13791
+ * so they can be ignored when tracing styled-component dependencies.
13792
+ */
13793
+ function isStylexImportSource(source) {
13794
+ return /\.stylex(?:\.[cm]?[jt]sx?)?$/u.test(source);
13795
+ }
13796
+ //#endregion
13797
+ //#region src/internal/utilities/stylex-numeric-imports.ts
13798
+ /**
13799
+ * Resolves local `.stylex` imports whose exported values are proven numeric.
13800
+ */
13801
+ function collectNumericStylexImportBindings(args) {
13802
+ const identifiers = /* @__PURE__ */ new Set();
13803
+ const exportCache = /* @__PURE__ */ new Map();
13804
+ for (const binding of args.bindings) {
13805
+ if (!isStylexImportSource(binding.source.value)) continue;
13806
+ const cacheKey = `${binding.source.kind}\0${binding.source.value}`;
13807
+ let numericExports = exportCache.get(cacheKey);
13808
+ if (!numericExports) {
13809
+ numericExports = collectNumericStylexExportNames(args.j, args.filePath, binding.source);
13810
+ exportCache.set(cacheKey, numericExports);
13811
+ }
13812
+ if (numericExports.has(binding.importedName)) identifiers.add(binding.localName);
13813
+ }
13814
+ return identifiers;
13815
+ }
13816
+ function resolveStylexImportFile(filePath, source) {
13817
+ const sourceValue = source.value;
13818
+ if (!isStylexImportSource(sourceValue)) return null;
13819
+ if (source.kind === "specifier" && !sourceValue.startsWith(".")) return null;
13820
+ const basePath = source.kind === "absolutePath" || isAbsolute(sourceValue) ? sourceValue : join(dirname(filePath), sourceValue);
13821
+ return (/\.[cm]?[jt]sx?$/.test(basePath) ? [basePath] : [
13822
+ `${basePath}.ts`,
13823
+ `${basePath}.tsx`,
13824
+ `${basePath}.js`,
13825
+ `${basePath}.jsx`
13826
+ ]).find((candidate) => existsSync(candidate)) ?? null;
13827
+ }
13828
+ function collectNumericStylexExportNames(j, filePath, source) {
13829
+ const resolvedPath = resolveStylexImportFile(filePath, source);
13830
+ if (!resolvedPath) return /* @__PURE__ */ new Set();
13831
+ let root;
13832
+ try {
13833
+ root = j(readFileSync(resolvedPath, "utf8"));
13834
+ } catch {
13835
+ return /* @__PURE__ */ new Set();
13836
+ }
13837
+ const localNumericBindings = /* @__PURE__ */ new Map();
13838
+ const exportedNumericNames = /* @__PURE__ */ new Set();
13839
+ root.find(j.VariableDeclarator).forEach((path) => {
13840
+ if (!isImmutableTopLevelVariableDeclaratorPath$1(path)) return;
13841
+ const id = path.node.id;
13842
+ if (id?.type !== "Identifier" || !id.name) return;
13843
+ localNumericBindings.set(id.name, isNumericStylexExportValue(path.node.init));
13844
+ });
13845
+ root.find(j.ExportNamedDeclaration).forEach((path) => {
13846
+ const declaration = path.node.declaration;
13847
+ if (declaration?.type === "VariableDeclaration") {
13848
+ const variableDeclaration = declaration;
13849
+ for (const decl of variableDeclaration.declarations ?? []) {
13850
+ const id = decl.id;
13851
+ if (id?.type === "Identifier" && id.name && isNumericStylexExportValue(decl.init)) exportedNumericNames.add(id.name);
13852
+ }
13853
+ }
13854
+ for (const specifier of path.node.specifiers ?? []) {
13855
+ const localName = exportSpecifierLocalName(specifier);
13856
+ const exportedName = exportSpecifierExportedName(specifier);
13857
+ if (localName && exportedName && localNumericBindings.get(localName) === true) exportedNumericNames.add(exportedName);
13858
+ }
13859
+ });
13860
+ root.find(j.ExportDefaultDeclaration).forEach((path) => {
13861
+ if (isNumericStylexExportValue(path.node.declaration)) exportedNumericNames.add("default");
13862
+ });
13863
+ return exportedNumericNames;
13864
+ }
13865
+ function exportSpecifierLocalName(specifier) {
13866
+ return specifier.local?.name ?? specifier.local?.value ?? null;
13867
+ }
13868
+ function exportSpecifierExportedName(specifier) {
13869
+ return specifier.exported?.name ?? specifier.exported?.value ?? null;
13870
+ }
13871
+ function isNumericStylexExportValue(value) {
13872
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
13873
+ const node = value;
13874
+ if (node.type === "NumericLiteral" || node.type === "Literal" && typeof node.value === "number") return true;
13875
+ if (node.type === "UnaryExpression") return (node.operator === "-" || node.operator === "+") && isNumericStylexExportValue(node.argument);
13876
+ if (node.type === "TSAsExpression" || node.type === "TSSatisfiesExpression" || node.type === "TSNonNullExpression" || node.type === "ParenthesizedExpression") return isNumericStylexExportValue(node.expression);
13877
+ if (node.type === "CallExpression" && isStylexDefineConstsCall(node.callee)) return isNumericStylexExportValue(node.arguments?.[0]);
13878
+ if (node.type !== "ObjectExpression" || !Array.isArray(node.properties)) return false;
13879
+ return node.properties.every((property) => {
13880
+ if (!property || typeof property !== "object" || Array.isArray(property)) return false;
13881
+ const prop = property;
13882
+ return (prop.type === "Property" || prop.type === "ObjectProperty") && isNumericStylexExportValue(prop.value);
13883
+ });
13884
+ }
13885
+ function isStylexDefineConstsCall(callee) {
13886
+ if (!callee || typeof callee !== "object" || Array.isArray(callee)) return false;
13887
+ const node = callee;
13888
+ if (node.type === "Identifier") return node.name === "defineConsts";
13889
+ return node.type === "MemberExpression" && node.computed !== true && node.property?.type === "Identifier" && node.property.name === "defineConsts";
13890
+ }
13891
+ function isImmutableTopLevelVariableDeclaratorPath$1(path) {
13892
+ const declaration = path.parentPath?.node;
13893
+ if (declaration?.type !== "VariableDeclaration" || declaration.kind !== "const") return false;
13894
+ let current = path.parentPath;
13895
+ while (current && typeof current === "object") {
13896
+ const node = current.node;
13897
+ if (node?.type === "Program") return true;
13898
+ if (node?.type === "FunctionDeclaration" || node?.type === "FunctionExpression" || node?.type === "ArrowFunctionExpression" || node?.type === "ClassDeclaration" || node?.type === "ClassExpression") return false;
13899
+ current = current.parentPath;
13900
+ }
13901
+ return false;
13902
+ }
13286
13903
  //#endregion
13287
13904
  //#region src/internal/lower-rules/inline-styles.ts
13288
13905
  function getImportedStylexIdentifiers(importMap, resolverImports) {
13289
13906
  const identifiers = /* @__PURE__ */ new Set();
13290
- for (const [localName, importEntry] of importMap) if (importEntry?.source?.value?.includes(".stylex")) identifiers.add(localName);
13907
+ for (const [localName, importEntry] of importMap) {
13908
+ const sourceValue = importEntry?.source?.value;
13909
+ if (typeof sourceValue === "string" && isStylexImportSource(sourceValue)) identifiers.add(localName);
13910
+ }
13291
13911
  for (const importSpec of resolverImports.values()) {
13292
- if (!importSpec.from.value.includes(".stylex")) continue;
13912
+ if (!isStylexImportSource(importSpec.from.value)) continue;
13293
13913
  for (const name of importSpec.names) identifiers.add(name.local ?? name.imported);
13294
13914
  }
13295
13915
  return identifiers;
13296
13916
  }
13917
+ function getNumericImportedStylexIdentifiers(j, filePath, importMap, resolverImports) {
13918
+ const bindings = [];
13919
+ for (const [localName, importEntry] of importMap) {
13920
+ const source = importEntry?.source;
13921
+ const sourceValue = source?.value;
13922
+ const importedName = importEntry?.importedName;
13923
+ if (!source || typeof sourceValue !== "string" || !importedName) continue;
13924
+ bindings.push({
13925
+ localName,
13926
+ importedName,
13927
+ source: "kind" in source ? source : {
13928
+ kind: "specifier",
13929
+ value: sourceValue
13930
+ }
13931
+ });
13932
+ }
13933
+ for (const importSpec of resolverImports.values()) for (const name of importSpec.names) bindings.push({
13934
+ localName: name.local ?? name.imported,
13935
+ importedName: name.imported,
13936
+ source: importSpec.from
13937
+ });
13938
+ return collectNumericStylexImportBindings({
13939
+ j,
13940
+ filePath,
13941
+ bindings
13942
+ });
13943
+ }
13297
13944
  function buildTemplateWithStaticParts(j, expr, prefix, suffix, multilineContext) {
13298
13945
  if (!prefix && !suffix) return expr;
13299
13946
  const staticValue = literalToStaticValue(expr);
@@ -15045,6 +15692,7 @@ function exportedBindingDependsOnLocalNames(args) {
15045
15692
  const targets = collectExportTargets(parsed, args.exportedName, args.includeDefault);
15046
15693
  if (targets.localNames.size === 0 && targets.nodes.length === 0) return true;
15047
15694
  const dependencyNames = expandLocalDependencyNames(parsed, args.localNames);
15695
+ if (args.memberPath !== void 0 && args.memberPath.length > 0) return staticMemberDependsOnLocalNames(parsed, targets, args.memberPath, dependencyNames);
15048
15696
  for (const localName of targets.localNames) {
15049
15697
  if (dependencyNames.has(localName)) return true;
15050
15698
  const node = findLocalBindingNode(parsed, localName);
@@ -15053,6 +15701,94 @@ function exportedBindingDependsOnLocalNames(args) {
15053
15701
  for (const node of targets.nodes) if (nodeReferencesLocalNames(exportedNodeBody(node), dependencyNames)) return true;
15054
15702
  return false;
15055
15703
  }
15704
+ /**
15705
+ * Dependency check for `Exported.Member` consumers: locate static member
15706
+ * assignments (`Root.Member = Value`, or `Member:` properties in the root's
15707
+ * object-literal / `Object.assign` initializer) and test the assigned values.
15708
+ * Returns true (dependent) when the member cannot be proven independent.
15709
+ */
15710
+ function staticMemberDependsOnLocalNames(program, targets, memberPath, dependencyNames) {
15711
+ const memberName = memberPath[0];
15712
+ if (memberPath.length !== 1 || memberName === void 0 || targets.nodes.length > 0) return true;
15713
+ const memberValues = collectStaticMemberValues(program, expandAliasNamesBothWays(program, targets.localNames), memberName);
15714
+ if (memberValues.hasUnknownSource || memberValues.values.length === 0) return true;
15715
+ return memberValues.values.some((value) => nodeReferencesLocalNames(value, dependencyNames));
15716
+ }
15717
+ /**
15718
+ * Expand a name set across identity aliases in both directions, so member
15719
+ * assignments written on any alias of the export (e.g. `CustomSelect.Option = X`
15720
+ * behind `export const Public = CustomSelect`) are found.
15721
+ */
15722
+ function expandAliasNamesBothWays(program, initialNames) {
15723
+ const aliases = collectIdentityAliases(program);
15724
+ const expanded = new Set(initialNames);
15725
+ let changed = true;
15726
+ while (changed) {
15727
+ changed = false;
15728
+ for (const [aliasName, targetName] of aliases) if (expanded.has(aliasName) !== expanded.has(targetName)) {
15729
+ expanded.add(aliasName);
15730
+ expanded.add(targetName);
15731
+ changed = true;
15732
+ }
15733
+ }
15734
+ return expanded;
15735
+ }
15736
+ function collectStaticMemberValues(program, rootNames, memberName) {
15737
+ const result = {
15738
+ values: [],
15739
+ hasUnknownSource: false
15740
+ };
15741
+ for (const stmt of programBody(program)) {
15742
+ if (stmt.type !== "ExpressionStatement") continue;
15743
+ const assignedValue = staticMemberAssignmentValue(stmt.expression, rootNames, memberName);
15744
+ if (assignedValue) result.values.push(assignedValue);
15745
+ }
15746
+ for (const binding of localBindings(program)) if (rootNames.has(binding.name)) {
15747
+ const bindingValues = objectLiteralMemberValues(unwrapTransparentExpression(binding.node), memberName);
15748
+ result.values.push(...bindingValues.values);
15749
+ result.hasUnknownSource ||= bindingValues.hasUnknownSource;
15750
+ }
15751
+ return result;
15752
+ }
15753
+ /** Value assigned by a `Root.Member = Value` statement, if `expression` is one. */
15754
+ function staticMemberAssignmentValue(expression, rootNames, memberName) {
15755
+ if (expression?.type !== "AssignmentExpression" || expression.operator !== "=") return;
15756
+ const left = expression.left;
15757
+ if (left?.type !== "MemberExpression" || left.computed === true) return;
15758
+ const objectName = nodeName(left.object);
15759
+ const propertyName = nodeName(left.property);
15760
+ if (!objectName || !rootNames.has(objectName) || propertyName !== memberName) return;
15761
+ return expression.right;
15762
+ }
15763
+ /** `Member:` property values in an object-literal or `Object.assign(...)` initializer. */
15764
+ function objectLiteralMemberValues(init, memberName) {
15765
+ const result = {
15766
+ values: [],
15767
+ hasUnknownSource: false
15768
+ };
15769
+ if (init.type === "ObjectExpression") collectObjectExpressionMemberValues(init, memberName, result);
15770
+ else if (init.type === "CallExpression" && isObjectAssignCallee(init.callee)) for (const arg of astArray(init.arguments)) if (arg.type === "ObjectExpression") collectObjectExpressionMemberValues(arg, memberName, result);
15771
+ else {
15772
+ result.hasUnknownSource = true;
15773
+ result.values = [];
15774
+ }
15775
+ return result;
15776
+ }
15777
+ function collectObjectExpressionMemberValues(objectNode, memberName, result) {
15778
+ for (const property of astArray(objectNode.properties)) if ((property.type === "ObjectProperty" || property.type === "Property") && property.computed !== true && nodeName(property.key) === memberName) {
15779
+ const value = property.value;
15780
+ if (value) {
15781
+ result.values = [value];
15782
+ result.hasUnknownSource = false;
15783
+ }
15784
+ } else if (property.type === "SpreadElement" || property.type === "SpreadProperty") {
15785
+ result.hasUnknownSource = true;
15786
+ result.values = [];
15787
+ }
15788
+ }
15789
+ function isObjectAssignCallee(callee) {
15790
+ return callee?.type === "MemberExpression" && callee.computed !== true && nodeName(callee.object) === "Object" && nodeName(callee.property) === "assign";
15791
+ }
15056
15792
  function parseProgram$1(source) {
15057
15793
  for (const parserName of ["tsx", "babel"]) try {
15058
15794
  const ast = createPrepassParser(parserName).parse(source);
@@ -15300,8 +16036,10 @@ function detectCascadeConflictStep(ctx) {
15300
16036
  if (decl.skipTransform) continue;
15301
16037
  if (decl.base.kind !== "component") continue;
15302
16038
  const baseIdent = decl.base.ident;
15303
- if (localStyledNames.has(baseIdent)) continue;
15304
- const importEntry = importMap.get(baseIdent);
16039
+ const baseImportLocalName = rootLocalName(baseIdent);
16040
+ const baseMemberPath = baseIdent.split(".").slice(1);
16041
+ if (localStyledNames.has(baseIdent) || localStyledNames.has(baseImportLocalName)) continue;
16042
+ const importEntry = importMap.get(baseImportLocalName);
15305
16043
  if (!importEntry || importEntry.source.kind !== "absolutePath") continue;
15306
16044
  if (skipImportedRoots) continue;
15307
16045
  const importedPath = importEntry.source.value;
@@ -15309,17 +16047,36 @@ function detectCascadeConflictStep(ctx) {
15309
16047
  path: importedPath,
15310
16048
  importedName: importEntry.importedName
15311
16049
  };
15312
- if (transformedComponents && transformedComponentExists(transformedComponents, definition.path, definition.importedName, definition.importedName === "default")) continue;
15313
- if (ctx.options.transformMode === "leavesOnly" && ctx.options.globalLeafKeys?.size) {
16050
+ if (baseMemberPath.length === 0 && ctx.options.transformMode === "leavesOnly" && ctx.options.globalLeafKeys?.size) {
15314
16051
  if (globalLeafKeyExists(ctx.options.globalLeafKeys, definition.path, definition.importedName, definition.importedName === "default")) continue;
15315
16052
  }
15316
16053
  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;
16054
+ if (transformedComponents && transformedComponentExists(transformedComponents, definition.path, definition.importedName, definition.importedName === "default") && bindingIsIndependentOfRemainingStyledDefinitions(ctx, {
16055
+ sourcePath: definition.path,
16056
+ bindingName: definition.importedName,
16057
+ memberPath: baseMemberPath,
16058
+ styledDefinitions: styledDefinitions ? {
16059
+ ...styledDefinitions,
16060
+ names: unconvertedStyledDefinitionNames(styledDefinitions, transformedComponents)
16061
+ } : void 0
16062
+ })) continue;
16063
+ if (!styledDefinitions) {
16064
+ if (bindingIsIndependentOfRemainingStyledDefinitions(ctx, {
16065
+ sourcePath: definition.path,
16066
+ bindingName: definition.importedName,
16067
+ memberPath: baseMemberPath,
16068
+ styledDefinitions: void 0
16069
+ })) continue;
16070
+ } else if (transformedComponents && transformedComponentsHasPath(transformedComponents, styledDefinitions.path) && bindingIsIndependentOfRemainingStyledDefinitions(ctx, {
16071
+ sourcePath: styledDefinitions.path,
16072
+ bindingName: definition.importedName,
16073
+ memberPath: baseMemberPath,
16074
+ styledDefinitions: {
16075
+ ...styledDefinitions,
16076
+ names: unconvertedStyledDefinitionNames(styledDefinitions, transformedComponents)
16077
+ }
16078
+ })) continue;
16079
+ if (styledDefinitions && canSkipCascadeForStylexExport(ctx, styledDefinitions, definition.importedName, baseMemberPath)) continue;
15323
16080
  ctx.warnings.push({
15324
16081
  severity: "warning",
15325
16082
  type: CASCADE_CONFLICT_WARNING,
@@ -15328,7 +16085,7 @@ function detectCascadeConflictStep(ctx) {
15328
16085
  component: decl.localName,
15329
16086
  base: baseIdent,
15330
16087
  importedPath,
15331
- definitionPath: styledDefinitions.path
16088
+ definitionPath: styledDefinitions?.path ?? definition.path
15332
16089
  }
15333
16090
  });
15334
16091
  foundCascadeConflict = true;
@@ -15348,6 +16105,19 @@ function resolveImportedDefinition(ctx, importedPath, importedName) {
15348
16105
  importedName: resolved.exportedName
15349
16106
  } : null;
15350
16107
  }
16108
+ /**
16109
+ * Import sources the codemod itself emits into transformed files (the adapter's
16110
+ * style-merger helper). These never carry styled-component exports.
16111
+ */
16112
+ function generatedImportSources(ctx) {
16113
+ const sources = /* @__PURE__ */ new Set();
16114
+ const mergerSource = ctx.adapter.styleMerger?.importSource?.value;
16115
+ if (typeof mergerSource === "string" && mergerSource.length > 0) sources.add(mergerSource);
16116
+ return sources;
16117
+ }
16118
+ function rootLocalName(componentName) {
16119
+ return componentName.split(".")[0] ?? componentName;
16120
+ }
15351
16121
  /** Common TypeScript/JavaScript file extensions to try when matching import paths to styledDefFiles keys. */
15352
16122
  const EXTENSIONS = [
15353
16123
  ".tsx",
@@ -15432,17 +16202,19 @@ function componentExportExistsByDirectScan(importedPath, bindingName) {
15432
16202
  }
15433
16203
  return false;
15434
16204
  }
15435
- function canSkipCascadeForStylexExport(ctx, styledDefinitions, bindingName) {
15436
- return componentExportExists(ctx.options.crossFileInfo?.stylexComponentFiles, styledDefinitions.path, bindingName) && bindingIsIndependentOfStyledDefinitions(ctx, styledDefinitions, bindingName);
16205
+ function canSkipCascadeForStylexExport(ctx, styledDefinitions, bindingName, memberPath) {
16206
+ return componentExportExists(ctx.options.crossFileInfo?.stylexComponentFiles, styledDefinitions.path, bindingName) && bindingIsIndependentOfStyledDefinitions(ctx, styledDefinitions, bindingName, memberPath);
15437
16207
  }
15438
- function bindingIsIndependentOfStyledDefinitions(ctx, styledDefinitions, bindingName) {
15439
- if (bindingDependsOnStyledDefinitions(styledDefinitions, bindingName)) return false;
16208
+ function bindingIsIndependentOfStyledDefinitions(ctx, styledDefinitions, bindingName, memberPath) {
16209
+ if (bindingDependsOnStyledDefinitions(styledDefinitions, bindingName, memberPath)) return false;
15440
16210
  return !bindingDependsOnImportedStyledDefinitions({
15441
16211
  bindingName,
16212
+ memberPath,
15442
16213
  sourcePath: styledDefinitions.path,
15443
16214
  styledDefFiles: ctx.options.crossFileInfo?.styledDefFiles,
15444
16215
  stylexComponentFiles: ctx.options.crossFileInfo?.stylexComponentFiles,
15445
- resolveModule: ctx.options.resolveModule
16216
+ resolveModule: ctx.options.resolveModule,
16217
+ ignoredImportSources: generatedImportSources(ctx)
15446
16218
  });
15447
16219
  }
15448
16220
  function transformedComponentExists(transformedComponents, importedPath, bindingName, allowDefaultFallback) {
@@ -15466,15 +16238,31 @@ function transformedNamesForPath(transformedComponents, filePath) {
15466
16238
  if (transformedNames) return transformedNames;
15467
16239
  }
15468
16240
  }
15469
- function bindingDependsOnStyledDefinitions(styledDefinitions, bindingName) {
16241
+ function bindingDependsOnStyledDefinitions(styledDefinitions, bindingName, memberPath = []) {
16242
+ if (styledDefinitions.names.size === 0) return false;
15470
16243
  const source = tryReadFile(styledDefinitions.path);
15471
16244
  return source ? exportedBindingDependsOnLocalNames({
15472
16245
  source,
15473
16246
  exportedName: bindingName,
15474
16247
  includeDefault: bindingName === "default",
15475
- localNames: styledDefinitions.names
16248
+ localNames: styledDefinitions.names,
16249
+ memberPath
15476
16250
  }) : true;
15477
16251
  }
16252
+ function bindingIsIndependentOfRemainingStyledDefinitions(ctx, args) {
16253
+ if (args.styledDefinitions && bindingDependsOnStyledDefinitions(args.styledDefinitions, args.bindingName, args.memberPath)) return false;
16254
+ if (!args.styledDefinitions && args.memberPath.length === 0) return true;
16255
+ if (!args.styledDefinitions && !tryReadFile(args.sourcePath)) return true;
16256
+ return !bindingDependsOnImportedStyledDefinitions({
16257
+ bindingName: args.bindingName,
16258
+ memberPath: args.memberPath,
16259
+ sourcePath: args.sourcePath,
16260
+ styledDefFiles: ctx.options.crossFileInfo?.styledDefFiles,
16261
+ stylexComponentFiles: ctx.options.crossFileInfo?.stylexComponentFiles,
16262
+ resolveModule: ctx.options.resolveModule,
16263
+ ignoredImportSources: generatedImportSources(ctx)
16264
+ });
16265
+ }
15478
16266
  function bindingDependsOnImportedStyledDefinitions(args) {
15479
16267
  const visitKey = `${args.sourcePath}:${args.bindingName}`;
15480
16268
  if (args.visited?.has(visitKey)) return true;
@@ -15491,18 +16279,20 @@ function bindingDependsOnImportedStyledDefinitions(args) {
15491
16279
  source,
15492
16280
  exportedName: args.bindingName,
15493
16281
  includeDefault: args.bindingName === "default",
15494
- localNames: importedStyledNames
16282
+ localNames: importedStyledNames,
16283
+ memberPath: args.memberPath ?? []
15495
16284
  });
15496
16285
  }
15497
16286
  function collectImportedStyledLocalNames(args) {
15498
16287
  const source = tryReadFile(args.sourcePath);
15499
16288
  const program = source ? parseProgram(source) : null;
15500
- if (!program) return null;
16289
+ if (!source || !program) return null;
15501
16290
  const importNodes = [];
15502
16291
  walkForImportsAndTemplates(program, importNodes, []);
15503
16292
  const importMap = buildImportMapFromNodes(importNodes);
15504
16293
  const importedStyledNames = /* @__PURE__ */ new Set();
15505
16294
  for (const [localName, importEntry] of importMap) {
16295
+ if (args.ignoredImportSources?.has(importEntry.source) || isStylexImportSource(importEntry.source)) continue;
15506
16296
  if (!args.resolveModule) {
15507
16297
  if (isRelativeSpecifier(importEntry.source)) importedStyledNames.add(localName);
15508
16298
  continue;
@@ -15513,37 +16303,59 @@ function collectImportedStyledLocalNames(args) {
15513
16303
  continue;
15514
16304
  }
15515
16305
  const styledDefinitions = args.styledDefFiles && resolveStyledDefFile(resolvedPath, args.styledDefFiles) || scanFileForStyledDefs(resolvedPath, importEntry.importedName, args.resolveModule);
16306
+ const memberPath = exportedMemberReferencesImportedRoot({
16307
+ source,
16308
+ bindingName: args.bindingName,
16309
+ memberPath: args.memberPath ?? [],
16310
+ localName
16311
+ }) ? args.memberPath : void 0;
15516
16312
  recordImportedStyledNameIfNeeded(importedStyledNames, localName, {
15517
16313
  bindingName: importEntry.importedName,
16314
+ memberPath,
15518
16315
  styledDefinitions,
15519
16316
  styledDefFiles: args.styledDefFiles,
15520
16317
  stylexComponentFiles: args.stylexComponentFiles,
15521
16318
  resolveModule: args.resolveModule,
16319
+ ignoredImportSources: args.ignoredImportSources,
15522
16320
  visited: args.visited
15523
16321
  });
15524
16322
  }
15525
16323
  return importedStyledNames;
15526
16324
  }
16325
+ function exportedMemberReferencesImportedRoot(args) {
16326
+ if (args.memberPath.length === 0) return false;
16327
+ return exportedBindingDependsOnLocalNames({
16328
+ source: args.source,
16329
+ exportedName: args.bindingName,
16330
+ includeDefault: args.bindingName === "default",
16331
+ localNames: new Set([args.localName]),
16332
+ memberPath: args.memberPath
16333
+ });
16334
+ }
15527
16335
  function recordImportedStyledNameIfNeeded(importedStyledNames, localName, args) {
15528
16336
  if (importedBindingShouldCountAsStyled(args)) importedStyledNames.add(localName);
15529
16337
  }
15530
16338
  function importedBindingShouldCountAsStyled(args) {
15531
16339
  return !!args.styledDefinitions && !importedBindingIsIndependentStylex({
15532
16340
  bindingName: args.bindingName,
16341
+ memberPath: args.memberPath,
15533
16342
  styledDefinitions: args.styledDefinitions,
15534
16343
  styledDefFiles: args.styledDefFiles,
15535
16344
  stylexComponentFiles: args.stylexComponentFiles,
15536
16345
  resolveModule: args.resolveModule,
16346
+ ignoredImportSources: args.ignoredImportSources,
15537
16347
  visited: args.visited
15538
16348
  });
15539
16349
  }
15540
16350
  function importedBindingIsIndependentStylex(args) {
15541
- return componentExportExists(args.stylexComponentFiles, args.styledDefinitions.path, args.bindingName) && !bindingDependsOnStyledDefinitions(args.styledDefinitions, args.bindingName) && !bindingDependsOnImportedStyledDefinitions({
16351
+ return componentExportExists(args.stylexComponentFiles, args.styledDefinitions.path, args.bindingName) && !bindingDependsOnStyledDefinitions(args.styledDefinitions, args.bindingName, args.memberPath ?? []) && !bindingDependsOnImportedStyledDefinitions({
15542
16352
  bindingName: args.bindingName,
16353
+ memberPath: args.memberPath,
15543
16354
  sourcePath: args.styledDefinitions.path,
15544
16355
  styledDefFiles: args.styledDefFiles,
15545
16356
  stylexComponentFiles: args.stylexComponentFiles,
15546
16357
  resolveModule: args.resolveModule,
16358
+ ignoredImportSources: args.ignoredImportSources,
15547
16359
  visited: args.visited
15548
16360
  });
15549
16361
  }
@@ -17297,7 +18109,7 @@ function emitStylesAndImports(ctx) {
17297
18109
  }
17298
18110
  const nonEmptyStyleEntries = [...resolvedStyleObjects.entries()].filter(([k]) => !emptyStyleKeys.has(k) && !preservedCssHelperStyleKeys.has(k));
17299
18111
  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));
18112
+ const prop = j.property("init", j.identifier(k), v && typeof v === "object" && !isAstNode$1(v) ? objectToAst(j, normalizeStyleObjectForEmission(v)) : literalToAst(j, v));
17301
18113
  const comments = styleKeyToComments.get(k);
17302
18114
  if (comments && comments.length > 0) prop.comments = comments.map((c) => ({
17303
18115
  ...c,
@@ -17396,10 +18208,13 @@ function emitStylesAndImports(ctx) {
17396
18208
  function emitVariantDimensionDecl(j, dimension) {
17397
18209
  const properties = Object.entries(dimension.variants).map(([variantValue, styles]) => {
17398
18210
  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));
18211
+ return j.property("init", key, styles && typeof styles === "object" && !isAstNode$1(styles) ? objectToAst(j, normalizeStyleObjectForEmission(styles)) : literalToAst(j, styles));
17400
18212
  });
17401
18213
  return j.variableDeclaration("const", [j.variableDeclarator(j.identifier(dimension.variantObjectName), j.callExpression(j.memberExpression(j.identifier("stylex"), j.identifier("create")), [j.objectExpression(properties)]))]);
17402
18214
  }
18215
+ function normalizeStyleObjectForEmission(styleObj) {
18216
+ return expandStyleObjectShorthands(styleObj);
18217
+ }
17403
18218
  /**
17404
18219
  * Returns true when `s` is a canonical numeric string (round-trips through Number).
17405
18220
  * Rejects non-canonical forms like "08", "0x10", "1e2" where `String(Number(s)) !== s`,
@@ -17954,7 +18769,28 @@ function normalizeResolvedNumericPxValues(ctx) {
17954
18769
  for (const [key, value] of ctx.resolvedStyleObjects) ctx.resolvedStyleObjects.set(key, normalizeStylexNumericPxValue(ctx, value, void 0, rootNumericIdentifiers));
17955
18770
  }
17956
18771
  function collectRootNumericConstantNames(ctx) {
17957
- const names = /* @__PURE__ */ new Set();
18772
+ const importBindings = [];
18773
+ ctx.root.find(ctx.j.ImportDeclaration).forEach((path) => {
18774
+ const sourceValue = path.node.source.value;
18775
+ if (typeof sourceValue !== "string" || !isStylexImportSource(sourceValue)) return;
18776
+ for (const specifier of path.node.specifiers ?? []) {
18777
+ const localName = specifier.local?.name;
18778
+ const importedName = importSpecifierExportName(specifier);
18779
+ if (localName && importedName) importBindings.push({
18780
+ localName,
18781
+ importedName,
18782
+ source: {
18783
+ kind: "specifier",
18784
+ value: sourceValue
18785
+ }
18786
+ });
18787
+ }
18788
+ });
18789
+ const names = collectNumericStylexImportBindings({
18790
+ j: ctx.j,
18791
+ filePath: ctx.file.path,
18792
+ bindings: importBindings
18793
+ });
17958
18794
  ctx.root.find(ctx.j.VariableDeclarator).forEach((path) => {
17959
18795
  if (!isImmutableTopLevelVariableDeclaratorPath(path)) return;
17960
18796
  const node = path.node;
@@ -17964,6 +18800,12 @@ function collectRootNumericConstantNames(ctx) {
17964
18800
  });
17965
18801
  return names;
17966
18802
  }
18803
+ function importSpecifierExportName(specifier) {
18804
+ const node = specifier;
18805
+ if (node.type === "ImportDefaultSpecifier") return "default";
18806
+ if (node.type !== "ImportSpecifier") return null;
18807
+ return node.imported?.name ?? node.imported?.value ?? null;
18808
+ }
17967
18809
  function isImmutableTopLevelVariableDeclaratorPath(path) {
17968
18810
  const declaration = path.parentPath?.node;
17969
18811
  if (declaration?.type !== "VariableDeclaration" || declaration.kind !== "const") return false;
@@ -17998,6 +18840,10 @@ function isNumericExpressionNode(value, numericIdentifiers) {
17998
18840
  const node = value;
17999
18841
  if (node.type === "NumericLiteral" || node.type === "Literal" && typeof node.value === "number") return true;
18000
18842
  if (node.type === "Identifier") return Boolean(node.name && numericIdentifiers.has(node.name));
18843
+ if (node.type === "MemberExpression") {
18844
+ const rootName = memberExpressionRootName(node);
18845
+ return Boolean(rootName && numericIdentifiers.has(rootName));
18846
+ }
18001
18847
  if (node.type === "UnaryExpression") return (node.operator === "-" || node.operator === "+") && isNumericExpressionNode(node.argument, numericIdentifiers);
18002
18848
  if (node.type === "BinaryExpression") return [
18003
18849
  "+",
@@ -18010,6 +18856,11 @@ function isNumericExpressionNode(value, numericIdentifiers) {
18010
18856
  if (node.type === "ParenthesizedExpression" || node.type === "TSAsExpression") return isNumericExpressionNode(node.expression, numericIdentifiers);
18011
18857
  return false;
18012
18858
  }
18859
+ function memberExpressionRootName(node) {
18860
+ if (node.type === "Identifier") return node.name ?? null;
18861
+ if (node.type !== "MemberExpression" || !node.object || typeof node.object !== "object") return null;
18862
+ return memberExpressionRootName(node.object);
18863
+ }
18013
18864
  function normalizeStylexNumericPxValue(ctx, value, currentProp, numericIdentifiers) {
18014
18865
  if (!value || typeof value !== "object") return value;
18015
18866
  if (Array.isArray(value)) return value.map((entry) => normalizeStylexNumericPxValue(ctx, entry, currentProp, numericIdentifiers));
@@ -18763,7 +19614,7 @@ function groupVariantBucketsIntoDimensions(variantBuckets, variantStyleKeys, bas
18763
19614
  }
18764
19615
  const { conditionWhen } = conditionGroup;
18765
19616
  for (const v of variants) {
18766
- variantMap[v.value] = v.styles;
19617
+ variantMap[v.value] = expandStyleObjectShorthands(v.styles);
18767
19618
  for (const cssProp of Object.keys(v.styles)) allOverriddenProps.add(cssProp);
18768
19619
  }
18769
19620
  const defaultStyles = {};
@@ -18775,10 +19626,10 @@ function groupVariantBucketsIntoDimensions(variantBuckets, variantStyleKeys, bas
18775
19626
  const remainingValues = unionValues.map(String).filter((v) => !explicitValues.has(v));
18776
19627
  if (remainingValues.length === 1 && remainingValues[0]) {
18777
19628
  defaultValue = remainingValues[0];
18778
- variantMap[defaultValue] = defaultStyles;
19629
+ variantMap[defaultValue] = expandStyleObjectShorthands(defaultStyles);
18779
19630
  } else {
18780
19631
  defaultValue = "default";
18781
- variantMap["default"] = defaultStyles;
19632
+ variantMap["default"] = expandStyleObjectShorthands(defaultStyles);
18782
19633
  }
18783
19634
  }
18784
19635
  const firstVariantForProps = variants[0];
@@ -18816,7 +19667,7 @@ function groupVariantBucketsIntoDimensions(variantBuckets, variantStyleKeys, bas
18816
19667
  else merged[cssProp] = boolValue;
18817
19668
  }
18818
19669
  for (const [cssProp, boolValue] of Object.entries(overlappingBoolStyles)) if (!(cssProp in merged)) merged[cssProp] = boolValue;
18819
- disabledVariantMap[variantValue] = merged;
19670
+ disabledVariantMap[variantValue] = expandStyleObjectShorthands(merged);
18820
19671
  }
18821
19672
  dimensions.push({
18822
19673
  propName,
@@ -25497,204 +26348,6 @@ function getTransformedComponentNames(ctx) {
25497
26348
  return names && names.length > 0 ? names : void 0;
25498
26349
  }
25499
26350
  //#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
26351
  //#region src/internal/lower-rules/slot-utils.ts
25699
26352
  /**
25700
26353
  * Locate the slot interpolation in a `${...}` value and return its
@@ -28666,7 +29319,7 @@ function tryHandleInterpolatedStringValue(args) {
28666
29319
  if (!entries.length) return false;
28667
29320
  for (const entry of entries) {
28668
29321
  const usesExpr = entry.value.includes(`__SC_EXPR_${slotId}__`);
28669
- setValue(entry.prop, usesExpr ? maybeOmitPxUnitFromStylexValue(j, tl, entry.prop, d.important) : 0);
29322
+ setValue(entry.prop, usesExpr ? maybeOmitPxUnitFromStylexValue(j, tl, entry.prop, d.important, { numericIdentifiers: args.numericIdentifiers }) : 0);
28670
29323
  }
28671
29324
  return true;
28672
29325
  }
@@ -28733,7 +29386,7 @@ function tryHandleInterpolatedStringValue(args) {
28733
29386
  const outputs = cssDeclarationToStylexDeclarations(d);
28734
29387
  for (let i = 0; i < outputs.length; i++) {
28735
29388
  const out = outputs[i];
28736
- setValue(out.prop, maybeOmitPxUnitFromStylexValue(j, tl, out.prop, d.important));
29389
+ setValue(out.prop, maybeOmitPxUnitFromStylexValue(j, tl, out.prop, d.important, { numericIdentifiers: args.numericIdentifiers }));
28737
29390
  if (i === 0 && (d.leadingComment || d.leadingLineComment)) addPropComments(styleObj, out.prop, {
28738
29391
  leading: d.leadingComment,
28739
29392
  leadingLine: d.leadingLineComment
@@ -33270,6 +33923,7 @@ function createDeclProcessingState(state, decl) {
33270
33923
  const styleFnDecls = /* @__PURE__ */ new Map();
33271
33924
  const attrBuckets = /* @__PURE__ */ new Map();
33272
33925
  const observedVariantFallbackFns = /* @__PURE__ */ new Map();
33926
+ let currentDeclarationSourceOrder;
33273
33927
  const inlineStyleProps = [];
33274
33928
  const localVarValues = /* @__PURE__ */ new Map();
33275
33929
  const cssHelperPropValues = /* @__PURE__ */ new Map();
@@ -33333,7 +33987,10 @@ function createDeclProcessingState(state, decl) {
33333
33987
  const applyVariant = createVariantApplier({
33334
33988
  decl,
33335
33989
  variantBuckets,
33336
- variantStyleKeys
33990
+ variantStyleKeys,
33991
+ baseStyleObj: styleObj,
33992
+ conditionStyleObjs: [perPropPseudo, perPropMedia],
33993
+ getCurrentSourceOrder: () => currentDeclarationSourceOrder
33337
33994
  });
33338
33995
  const dropAllTestInfoProps = (testInfo) => {
33339
33996
  const propsToCheck = testInfo.allPropNames ?? (testInfo.propName ? [testInfo.propName] : []);
@@ -33484,6 +34141,10 @@ function createDeclProcessingState(state, decl) {
33484
34141
  styleFnDecls,
33485
34142
  attrBuckets,
33486
34143
  observedVariantFallbackFns,
34144
+ getCurrentDeclarationSourceOrder: () => currentDeclarationSourceOrder,
34145
+ setCurrentDeclarationSourceOrder: (sourceOrder) => {
34146
+ currentDeclarationSourceOrder = sourceOrder;
34147
+ },
33487
34148
  inlineStyleProps,
33488
34149
  localVarValues,
33489
34150
  cssHelperPropValues,
@@ -33572,8 +34233,29 @@ function finalizeDeclProcessing(ctx) {
33572
34233
  }
33573
34234
  }
33574
34235
  for (const [sel, obj] of Object.entries(nestedSelectors)) styleObj[sel] = obj;
34236
+ const baseRawEntries = Object.entries(styleObj);
34237
+ resolveBoxShorthandConflicts(styleObj);
33575
34238
  resolveDirectionalConflicts(styleObj);
34239
+ expandMultiValueBorderRadius(styleObj);
33576
34240
  warnOpaqueShorthands(styleObj, decl, warnings);
34241
+ for (const bucket of variantBuckets.values()) {
34242
+ resolveBoxShorthandConflicts(bucket);
34243
+ resolveDirectionalConflicts(bucket, { skipNullishShorthandDefault: true });
34244
+ expandMultiValueBorderRadius(bucket);
34245
+ warnOpaqueShorthands(bucket, decl, warnings);
34246
+ }
34247
+ const variantBucketObjects = [...variantBuckets.values()];
34248
+ harmonizeShorthandExpansion([
34249
+ styleObj,
34250
+ ...variantBucketObjects,
34251
+ ...extraStyleObjects.values()
34252
+ ], {
34253
+ baseStyleObj: styleObj,
34254
+ inheritBaseLateSides: new Set(variantBucketObjects),
34255
+ baseRawEntries,
34256
+ bucketBaseKeySnapshot: bucketSnapshotLookup(decl, variantBuckets),
34257
+ bucketSourceOrder: bucketSourceOrderLookup(decl, variantBuckets)
34258
+ });
33577
34259
  registerLocalStylexVarFallbacks(state, decl, styleObj);
33578
34260
  const varsToDrop = /* @__PURE__ */ new Set();
33579
34261
  const staticInlineStyleProps = decl.staticInlineStyleProps ?? [];
@@ -33755,13 +34437,21 @@ function finalizeDeclProcessing(ctx) {
33755
34437
  const oldKey = decl.styleKey;
33756
34438
  decl.styleKey = baseKey;
33757
34439
  resolvedStyleObjects.delete(oldKey);
34440
+ expandMultiValueBorderRadius(styleObj);
33758
34441
  resolvedStyleObjects.set(baseKey, styleObj);
33759
- for (const [k, v] of extraStyleObjects.entries()) resolvedStyleObjects.set(k, v);
34442
+ for (const [k, v] of extraStyleObjects.entries()) {
34443
+ expandMultiValueBorderRadius(v);
34444
+ resolvedStyleObjects.set(k, v);
34445
+ }
33760
34446
  for (const c of cases) resolvedStyleObjects.set(c.styleKey, { backgroundColor: c.value });
33761
34447
  decl.needsWrapperComponent = true;
33762
34448
  } else {
34449
+ expandMultiValueBorderRadius(styleObj);
33763
34450
  resolvedStyleObjects.set(decl.styleKey, styleObj);
33764
- for (const [k, v] of extraStyleObjects.entries()) resolvedStyleObjects.set(k, v);
34451
+ for (const [k, v] of extraStyleObjects.entries()) {
34452
+ expandMultiValueBorderRadius(v);
34453
+ resolvedStyleObjects.set(k, v);
34454
+ }
33765
34455
  }
33766
34456
  {
33767
34457
  const isPseudoOrMediaMap = (v) => {
@@ -33847,8 +34537,22 @@ function finalizeDeclProcessing(ctx) {
33847
34537
  extraStyleObjects,
33848
34538
  attrBuckets
33849
34539
  });
34540
+ const remainingBucketObjects = [...remainingBuckets.values()];
34541
+ harmonizeShorthandExpansion([
34542
+ styleObj,
34543
+ ...remainingBucketObjects,
34544
+ ...extraStyleObjects.values(),
34545
+ ...attrBuckets.values()
34546
+ ], {
34547
+ baseStyleObj: styleObj,
34548
+ inheritBaseLateSides: new Set(remainingBucketObjects),
34549
+ baseRawEntries,
34550
+ bucketBaseKeySnapshot: bucketSnapshotLookup(decl, remainingBuckets),
34551
+ bucketSourceOrder: bucketSourceOrderLookup(decl, remainingBuckets)
34552
+ });
33850
34553
  for (const [when, obj] of remainingBuckets.entries()) {
33851
34554
  const key = remainingStyleKeys[when];
34555
+ expandMultiValueBorderRadius(obj);
33852
34556
  resolvedStyleObjects.set(key, obj);
33853
34557
  }
33854
34558
  for (const [k, v] of attrBuckets.entries()) resolvedStyleObjects.set(k, v);
@@ -34768,8 +35472,10 @@ function replaceIdentifierInAst(j, node, oldName) {
34768
35472
  function mergeConditionBucket(styleObj, bucket) {
34769
35473
  for (const [prop, map] of Object.entries(bucket)) {
34770
35474
  const existing = styleObj[prop];
34771
- if (existing && typeof existing === "object" && !isAstNode$1(existing) && !Array.isArray(existing)) mergeStyleObjects(existing, map);
34772
- else {
35475
+ if (existing && typeof existing === "object" && !isAstNode$1(existing) && !Array.isArray(existing)) {
35476
+ mergeStyleObjects(existing, map);
35477
+ copyConditionSourceOrders(existing, map);
35478
+ } else {
34773
35479
  if (existing !== void 0 && (map.default === null || map.default === void 0)) map.default = existing;
34774
35480
  styleObj[prop] = map;
34775
35481
  }
@@ -34855,6 +35561,23 @@ const AXIS_PAIRS = [
34855
35561
  end: "marginRight"
34856
35562
  }
34857
35563
  ];
35564
+ const BOX_SHORTHAND_CONFLICTS = [{
35565
+ shorthand: "padding",
35566
+ top: "paddingTop",
35567
+ right: "paddingRight",
35568
+ bottom: "paddingBottom",
35569
+ left: "paddingLeft",
35570
+ block: "paddingBlock",
35571
+ inline: "paddingInline"
35572
+ }, {
35573
+ shorthand: "margin",
35574
+ top: "marginTop",
35575
+ right: "marginRight",
35576
+ bottom: "marginBottom",
35577
+ left: "marginLeft",
35578
+ block: "marginBlock",
35579
+ inline: "marginInline"
35580
+ }];
34858
35581
  const LOGICAL_SIDE_PAIRS = [
34859
35582
  {
34860
35583
  logical: "paddingBlockStart",
@@ -34897,6 +35620,94 @@ function isMediaOrPseudoMap(v) {
34897
35620
  const keys = Object.keys(v);
34898
35621
  return keys.includes("default") || keys.some((k) => k.startsWith(":") || k.startsWith("@"));
34899
35622
  }
35623
+ function resolveBoxShorthandConflicts(styleObj) {
35624
+ for (const config of BOX_SHORTHAND_CONFLICTS) {
35625
+ const shorthandVal = styleObj[config.shorthand];
35626
+ if (shorthandVal === void 0) continue;
35627
+ const sideProps = [
35628
+ config.top,
35629
+ config.right,
35630
+ config.bottom,
35631
+ config.left,
35632
+ config.block,
35633
+ config.inline
35634
+ ];
35635
+ if (!sideProps.some((prop) => prop in styleObj)) continue;
35636
+ const entries = Object.entries(styleObj);
35637
+ const shorthandIndex = entries.findIndex(([key]) => key === config.shorthand);
35638
+ recordLateSideOverrides(styleObj, config, entries, shorthandIndex);
35639
+ const replacements = {
35640
+ [config.top]: resolveBoxSideConflictValue({
35641
+ shorthandVal,
35642
+ shorthandIndex,
35643
+ longhandVal: styleObj[config.top],
35644
+ longhandIndex: entries.findIndex(([key]) => key === config.top),
35645
+ axisVal: styleObj[config.block],
35646
+ axisIndex: entries.findIndex(([key]) => key === config.block)
35647
+ }),
35648
+ [config.right]: resolveBoxSideConflictValue({
35649
+ shorthandVal,
35650
+ shorthandIndex,
35651
+ longhandVal: styleObj[config.right],
35652
+ longhandIndex: entries.findIndex(([key]) => key === config.right),
35653
+ axisVal: styleObj[config.inline],
35654
+ axisIndex: entries.findIndex(([key]) => key === config.inline)
35655
+ }),
35656
+ [config.bottom]: resolveBoxSideConflictValue({
35657
+ shorthandVal,
35658
+ shorthandIndex,
35659
+ longhandVal: styleObj[config.bottom],
35660
+ longhandIndex: entries.findIndex(([key]) => key === config.bottom),
35661
+ axisVal: styleObj[config.block],
35662
+ axisIndex: entries.findIndex(([key]) => key === config.block)
35663
+ }),
35664
+ [config.left]: resolveBoxSideConflictValue({
35665
+ shorthandVal,
35666
+ shorthandIndex,
35667
+ longhandVal: styleObj[config.left],
35668
+ longhandIndex: entries.findIndex(([key]) => key === config.left),
35669
+ axisVal: styleObj[config.inline],
35670
+ axisIndex: entries.findIndex(([key]) => key === config.inline)
35671
+ })
35672
+ };
35673
+ for (const key of Object.keys(styleObj)) delete styleObj[key];
35674
+ for (const [key, val] of entries) if (key === config.shorthand) {
35675
+ styleObj[config.top] = replacements[config.top];
35676
+ styleObj[config.right] = replacements[config.right];
35677
+ styleObj[config.bottom] = replacements[config.bottom];
35678
+ styleObj[config.left] = replacements[config.left];
35679
+ } else if (sideProps.includes(key)) continue;
35680
+ else styleObj[key] = val;
35681
+ }
35682
+ }
35683
+ function resolveBoxSideConflictValue(args) {
35684
+ const { shorthandVal, shorthandIndex, longhandVal, longhandIndex, axisVal, axisIndex } = args;
35685
+ const base = latestIndexedValue([{
35686
+ value: axisVal,
35687
+ index: axisIndex
35688
+ }, {
35689
+ value: longhandVal,
35690
+ index: longhandIndex
35691
+ }]);
35692
+ if (!isMediaOrPseudoMap(shorthandVal)) {
35693
+ if (!base || shorthandIndex > base.index) return shorthandVal;
35694
+ if (isMediaOrPseudoMap(base.value)) return mergeScalarDefaultIntoLonghand(base.value, shorthandVal);
35695
+ return base.value;
35696
+ }
35697
+ const defaultValue = shorthandVal.default != null && (!base || shorthandIndex > base.index) ? shorthandVal.default : base?.value ?? shorthandVal.default ?? null;
35698
+ if (base && base.index > shorthandIndex && isMediaOrPseudoMap(base.value)) return computeMergedLonghand(base.value, shorthandVal);
35699
+ const result = { default: defaultValue };
35700
+ for (const [condition, conditionValue] of Object.entries(shorthandVal)) if (condition !== "default" && conditionValue != null) result[condition] = conditionValue;
35701
+ return result;
35702
+ }
35703
+ function latestIndexedValue(candidates) {
35704
+ let latest = null;
35705
+ for (const candidate of candidates) {
35706
+ if (candidate.index < 0 || candidate.value === void 0) continue;
35707
+ if (!latest || candidate.index > latest.index) latest = candidate;
35708
+ }
35709
+ return latest;
35710
+ }
34900
35711
  /**
34901
35712
  * Resolves conflicts between directional shorthand properties (e.g., `paddingBlock`)
34902
35713
  * and their individual longhand overrides (e.g., `paddingBottom`).
@@ -34913,10 +35724,11 @@ function isMediaOrPseudoMap(v) {
34913
35724
  * Property ordering is preserved: the split longhands replace the shorthand's
34914
35725
  * position in the object to maintain a natural CSS property order.
34915
35726
  */
34916
- function resolveDirectionalConflicts(styleObj) {
35727
+ function resolveDirectionalConflicts(styleObj, options) {
34917
35728
  for (const { shorthand, start, end } of AXIS_PAIRS) {
34918
35729
  const shorthandVal = styleObj[shorthand];
34919
35730
  if (shorthandVal === void 0) continue;
35731
+ if (options?.skipNullishShorthandDefault === true && hasNullishDefault(shorthandVal)) continue;
34920
35732
  const hasStart = start in styleObj;
34921
35733
  const hasEnd = end in styleObj;
34922
35734
  if (!hasStart && !hasEnd) continue;
@@ -34966,6 +35778,464 @@ function resolveLogicalSideConflicts(styleObj) {
34966
35778
  else styleObj[key] = val;
34967
35779
  }
34968
35780
  }
35781
+ const BORDER_RADIUS_CORNER_PROPS = [
35782
+ "borderTopLeftRadius",
35783
+ "borderTopRightRadius",
35784
+ "borderBottomRightRadius",
35785
+ "borderBottomLeftRadius"
35786
+ ];
35787
+ function harmonizeShorthandExpansion(styleObjs, options) {
35788
+ harmonizeBoxShorthandExpansion(styleObjs, options);
35789
+ harmonizeBorderRadiusExpansion(styleObjs, options);
35790
+ }
35791
+ /** Resolve a bucket object back to its `when` snapshot recorded during decl processing. */
35792
+ function bucketSnapshotLookup(decl, buckets) {
35793
+ const whenByObject = /* @__PURE__ */ new Map();
35794
+ for (const [when, obj] of buckets.entries()) whenByObject.set(obj, when);
35795
+ return (styleObj) => {
35796
+ const when = whenByObject.get(styleObj);
35797
+ return when === void 0 ? void 0 : getVariantBaseKeySnapshot(decl, when);
35798
+ };
35799
+ }
35800
+ function bucketSourceOrderLookup(decl, buckets) {
35801
+ const whenByObject = /* @__PURE__ */ new Map();
35802
+ for (const [when, obj] of buckets.entries()) whenByObject.set(obj, when);
35803
+ return (styleObj) => {
35804
+ const when = whenByObject.get(styleObj);
35805
+ return when === void 0 ? void 0 : getVariantSourceOrder(decl, when);
35806
+ };
35807
+ }
35808
+ /**
35809
+ * StyleX priorities put side longhands (`paddingTop`) above axis shorthands
35810
+ * (`paddingBlock`) above box shorthands (`padding`) regardless of application
35811
+ * order. When the declaration family mixes these levels across style objects
35812
+ * (e.g. the base expanded `padding: 4px; padding-top: 2px` into side longhands
35813
+ * while a variant kept `padding: 8px`), a later-applied lower-level value can
35814
+ * never override an earlier higher-level one. Expand statically expandable
35815
+ * shorthand/axis values to side longhands in every object so overrides resolve
35816
+ * through plain per-property merging.
35817
+ */
35818
+ /**
35819
+ * Side props whose longhand was declared after the box shorthand (per style
35820
+ * object). A variant carrying the same shorthand must not override these sides
35821
+ * when it gets expanded to longhands — the later longhand wins over the
35822
+ * variant's shorthand in the original CSS cascade too.
35823
+ */
35824
+ const lateSideOverrides = /* @__PURE__ */ new WeakMap();
35825
+ function recordLateSideOverrides(styleObj, config, entries, shorthandIndex) {
35826
+ const lateSides = /* @__PURE__ */ new Set();
35827
+ const markIfLate = (prop, ...sides) => {
35828
+ const index = entries.findIndex(([key]) => key === prop);
35829
+ if (index <= shorthandIndex) return;
35830
+ const value = entries[index]?.[1];
35831
+ if (isMediaOrPseudoMap(value) && hasNullishDefault(value)) return;
35832
+ for (const side of sides) lateSides.add(side);
35833
+ };
35834
+ markIfLate(config.top, config.top);
35835
+ markIfLate(config.right, config.right);
35836
+ markIfLate(config.bottom, config.bottom);
35837
+ markIfLate(config.left, config.left);
35838
+ markIfLate(config.block, config.top, config.bottom);
35839
+ markIfLate(config.inline, config.left, config.right);
35840
+ if (lateSides.size === 0) return;
35841
+ const byShorthand = lateSideOverrides.get(styleObj) ?? /* @__PURE__ */ new Map();
35842
+ byShorthand.set(config.shorthand, lateSides);
35843
+ lateSideOverrides.set(styleObj, byShorthand);
35844
+ }
35845
+ /**
35846
+ * Sides of `config` whose base longhand/axis declaration is absent from the
35847
+ * variant's base-key snapshot — i.e. it was declared after the variant block
35848
+ * in source order and must keep winning over the variant's shorthand.
35849
+ * Conditional-only values (nullish default) never suppress: their default
35850
+ * still falls back to the variant's shorthand.
35851
+ */
35852
+ function baseSidesDeclaredAfterSnapshot(baseRawEntries, snapshot, config) {
35853
+ const lateSides = /* @__PURE__ */ new Set();
35854
+ const sidesByKey = boxSidesByKey(config);
35855
+ for (const [key, value] of baseRawEntries) {
35856
+ const sides = sidesByKey.get(key);
35857
+ if (!sides || !declaredAfterSnapshot(snapshot, key, value)) continue;
35858
+ if (isMediaOrPseudoMap(value) && hasNullishDefault(value)) continue;
35859
+ for (const side of sides) lateSides.add(side);
35860
+ }
35861
+ return lateSides;
35862
+ }
35863
+ function boxSidesByKey(config) {
35864
+ return new Map([
35865
+ [config.top, [config.top]],
35866
+ [config.right, [config.right]],
35867
+ [config.bottom, [config.bottom]],
35868
+ [config.left, [config.left]],
35869
+ [config.block, [config.top, config.bottom]],
35870
+ [config.inline, [config.left, config.right]]
35871
+ ]);
35872
+ }
35873
+ /**
35874
+ * Base side/axis condition entries that were added after the variant snapshot.
35875
+ * Later pseudo/media condition classes target the same property, and a flat
35876
+ * variant value would replace the base map entirely in `stylex.props()`.
35877
+ */
35878
+ function conditionalBaseSidesAfterSnapshot(baseRawEntries, snapshot, variantSourceOrder, config) {
35879
+ const conditionMaps = /* @__PURE__ */ new Map();
35880
+ const sidesByKey = boxSidesByKey(config);
35881
+ for (const [key, value] of baseRawEntries) {
35882
+ const sides = sidesByKey.get(key);
35883
+ const changedConditions = changedConditionEntriesAfterSnapshot(snapshot, variantSourceOrder, key, value);
35884
+ if (!sides || !changedConditions) continue;
35885
+ for (const side of sides) mergeConditionMapForSide(conditionMaps, side, changedConditions);
35886
+ }
35887
+ return conditionMaps;
35888
+ }
35889
+ function mergeConditionMapForSide(conditionMaps, side, changedConditions) {
35890
+ const existing = conditionMaps.get(side);
35891
+ if (existing) {
35892
+ mergeStyleObjects(existing, changedConditions);
35893
+ return;
35894
+ }
35895
+ conditionMaps.set(side, { ...changedConditions });
35896
+ }
35897
+ function changedConditionEntriesAfterSnapshot(snapshot, variantSourceOrder, key, value) {
35898
+ if (!isMediaOrPseudoMap(value) || !hasNullishDefault(value)) return null;
35899
+ const snapshotHasKey = snapshot?.has(key) ?? false;
35900
+ const snapshotValue = snapshotHasKey ? snapshot?.get(key) : void 0;
35901
+ const snapshotMap = isMediaOrPseudoMap(snapshotValue) ? snapshotValue : null;
35902
+ const changed = {};
35903
+ for (const [condition, conditionValue] of Object.entries(value)) {
35904
+ if (condition === "default" || conditionValue == null) continue;
35905
+ const conditionSourceOrder = getConditionSourceOrder(value, condition);
35906
+ if (variantSourceOrder !== void 0 && conditionSourceOrder !== void 0) {
35907
+ if (conditionSourceOrder <= variantSourceOrder) continue;
35908
+ changed[condition] = conditionValue;
35909
+ continue;
35910
+ }
35911
+ if (snapshotHasKey && snapshotMap && condition in snapshotMap && styleValuesEquivalent(snapshotMap[condition], conditionValue)) continue;
35912
+ changed[condition] = conditionValue;
35913
+ }
35914
+ return Object.keys(changed).length ? changed : null;
35915
+ }
35916
+ /**
35917
+ * Merges base condition entries into a variant's expanded side value, keeping
35918
+ * the variant in control of the default. Follows the same convention as
35919
+ * computeMergedLonghand: condition entries win over the flat value.
35920
+ */
35921
+ function mergeBaseConditionsIntoSideValue(variantValue, baseConditionMap) {
35922
+ if (!baseConditionMap) return variantValue;
35923
+ const merged = isMediaOrPseudoMap(variantValue) ? { ...variantValue } : { default: variantValue };
35924
+ for (const [condition, conditionValue] of Object.entries(baseConditionMap)) {
35925
+ if (condition === "default" || conditionValue == null || condition in merged) continue;
35926
+ merged[condition] = conditionValue;
35927
+ }
35928
+ return merged;
35929
+ }
35930
+ /**
35931
+ * A base entry was (re)declared after the variant's snapshot when its key was
35932
+ * absent at snapshot time, or its value changed since — a redeclaration after
35933
+ * the variant block replaces the value in the base style object.
35934
+ */
35935
+ function declaredAfterSnapshot(snapshot, key, value) {
35936
+ return !snapshot.has(key) || !styleValuesEquivalent(snapshot.get(key), value);
35937
+ }
35938
+ /**
35939
+ * Structural equality for snapshot comparison: condition maps are compared by
35940
+ * entries (snapshots clone them, and base merges may replace or mutate the map
35941
+ * object), everything else by identity.
35942
+ */
35943
+ function styleValuesEquivalent(a, b) {
35944
+ if (Object.is(a, b)) return true;
35945
+ if (!isPlainStyleValueMap(a) || !isPlainStyleValueMap(b)) return false;
35946
+ const aEntries = Object.entries(a);
35947
+ if (aEntries.length !== Object.keys(b).length) return false;
35948
+ return aEntries.every(([key, value]) => key in b && styleValuesEquivalent(value, b[key]));
35949
+ }
35950
+ function isPlainStyleValueMap(value) {
35951
+ return !!value && typeof value === "object" && !Array.isArray(value) && typeof value.type !== "string";
35952
+ }
35953
+ function harmonizeBoxShorthandExpansion(styleObjs, options) {
35954
+ for (const config of BOX_SHORTHAND_CONFLICTS) {
35955
+ const levels = /* @__PURE__ */ new Set();
35956
+ for (const obj of styleObjs) {
35957
+ if (config.shorthand in obj) levels.add("shorthand");
35958
+ if (config.block in obj || config.inline in obj) levels.add("axis");
35959
+ if (boxSideProps(config).some((prop) => prop in obj)) levels.add("side");
35960
+ }
35961
+ if (levels.size < 2) continue;
35962
+ const baseLateSides = options?.baseStyleObj ? lateSideOverrides.get(options.baseStyleObj)?.get(config.shorthand) : void 0;
35963
+ const conditionalSidesFor = (styleObj) => {
35964
+ if (!options?.inheritBaseLateSides?.has(styleObj) || !options.baseRawEntries) return;
35965
+ return conditionalBaseSidesAfterSnapshot(options.baseRawEntries, options.bucketBaseKeySnapshot?.(styleObj), options.bucketSourceOrder?.(styleObj), config);
35966
+ };
35967
+ const lateSidesFor = (styleObj) => {
35968
+ const localLateSides = lateSideOverrides.get(styleObj)?.get(config.shorthand);
35969
+ if (!options?.inheritBaseLateSides?.has(styleObj)) return localLateSides ?? /* @__PURE__ */ new Set();
35970
+ const snapshot = options.bucketBaseKeySnapshot?.(styleObj);
35971
+ const inheritedLateSides = snapshot && options.baseRawEntries ? baseSidesDeclaredAfterSnapshot(options.baseRawEntries, snapshot, config) : baseLateSides ?? /* @__PURE__ */ new Set();
35972
+ if (!inheritedLateSides.size) return localLateSides ?? /* @__PURE__ */ new Set();
35973
+ if (!localLateSides?.size) return inheritedLateSides;
35974
+ return new Set([...inheritedLateSides, ...localLateSides]);
35975
+ };
35976
+ const targetLevel = levels.has("side") ? "side" : "axis";
35977
+ for (const obj of styleObjs) if (targetLevel === "side") expandBoxLevelsToSides(obj, config, lateSidesFor(obj), conditionalSidesFor(obj));
35978
+ else expandBoxShorthandToAxis(obj, config, lateSidesFor(obj));
35979
+ }
35980
+ }
35981
+ function boxSideProps(config) {
35982
+ return [
35983
+ config.top,
35984
+ config.right,
35985
+ config.bottom,
35986
+ config.left
35987
+ ];
35988
+ }
35989
+ /**
35990
+ * Expands a pure shorthand-level or axis-level style object to side longhands
35991
+ * in place. Mixed-level objects were already reconciled per-object by
35992
+ * resolveBoxShorthandConflicts / resolveDirectionalConflicts and are left
35993
+ * untouched, as are values that cannot be expanded statically.
35994
+ */
35995
+ function expandBoxLevelsToSides(styleObj, config, lateSides, conditionalSides) {
35996
+ const hasSide = boxSideProps(config).some((prop) => prop in styleObj);
35997
+ const shorthandVal = styleObj[config.shorthand];
35998
+ const withoutLateSides = (replacements) => replacements.filter(([sideProp]) => !lateSides.has(sideProp)).map(([sideProp, value]) => [sideProp, mergeBaseConditionsIntoSideValue(value, conditionalSides?.get(sideProp))]);
35999
+ if (shorthandVal !== void 0) {
36000
+ if (hasSide || config.block in styleObj || config.inline in styleObj) return;
36001
+ const expanded = expandBoxShorthandValueToSides(shorthandVal);
36002
+ if (!expanded) return;
36003
+ replaceStyleKeyInPlace(styleObj, config.shorthand, withoutLateSides([
36004
+ [config.top, expanded.top],
36005
+ [config.right, expanded.right],
36006
+ [config.bottom, expanded.bottom],
36007
+ [config.left, expanded.left]
36008
+ ]));
36009
+ return;
36010
+ }
36011
+ if (hasSide) return;
36012
+ if (getUseLogicalProperties()) return;
36013
+ if (config.block in styleObj) {
36014
+ const blockVal = styleObj[config.block];
36015
+ replaceStyleKeyInPlace(styleObj, config.block, withoutLateSides([[config.top, blockVal], [config.bottom, cloneBoxValue(blockVal)]]));
36016
+ }
36017
+ if (config.inline in styleObj) {
36018
+ const inlineVal = styleObj[config.inline];
36019
+ replaceStyleKeyInPlace(styleObj, config.inline, withoutLateSides([[config.left, inlineVal], [config.right, cloneBoxValue(inlineVal)]]));
36020
+ }
36021
+ }
36022
+ /**
36023
+ * Expands a box shorthand to the axis pair (`paddingBlock`/`paddingInline`)
36024
+ * when the family's highest conflicting level is the axis level. Values with
36025
+ * 3-4 parts cannot be represented per-axis and are left untouched.
36026
+ */
36027
+ function expandBoxShorthandToAxis(styleObj, config, lateSides) {
36028
+ const shorthandVal = styleObj[config.shorthand];
36029
+ if (shorthandVal === void 0 || config.block in styleObj || config.inline in styleObj || boxSideProps(config).some((prop) => prop in styleObj)) return;
36030
+ const expanded = expandBoxShorthandValueToAxis(shorthandVal);
36031
+ if (!expanded) return;
36032
+ const replacements = [];
36033
+ if (!lateSides.has(config.top) && !lateSides.has(config.bottom)) replacements.push([config.block, expanded.block]);
36034
+ if (!lateSides.has(config.left) && !lateSides.has(config.right)) replacements.push([config.inline, expanded.inline]);
36035
+ replaceStyleKeyInPlace(styleObj, config.shorthand, replacements);
36036
+ }
36037
+ function expandBoxShorthandValueToAxis(value) {
36038
+ if (typeof value === "number") return {
36039
+ block: value,
36040
+ inline: value
36041
+ };
36042
+ const staticString = typeof value === "string" ? value : staticStringValue(value);
36043
+ if (staticString !== null) {
36044
+ const parts = splitCssValueWhitespace(staticString.trim());
36045
+ const block = parts[0];
36046
+ if (block === void 0 || parts.length > 2) return null;
36047
+ return {
36048
+ block,
36049
+ inline: parts[1] ?? block
36050
+ };
36051
+ }
36052
+ if (!isMediaOrPseudoMap(value)) return null;
36053
+ const block = {};
36054
+ const inline = {};
36055
+ for (const [condition, conditionValue] of Object.entries(value)) {
36056
+ if (conditionValue == null) {
36057
+ block[condition] = conditionValue;
36058
+ inline[condition] = conditionValue;
36059
+ continue;
36060
+ }
36061
+ if (isMediaOrPseudoMap(conditionValue)) return null;
36062
+ const expanded = expandBoxShorthandValueToAxis(conditionValue);
36063
+ if (!expanded) return null;
36064
+ block[condition] = expanded.block;
36065
+ inline[condition] = expanded.inline;
36066
+ }
36067
+ return {
36068
+ block,
36069
+ inline
36070
+ };
36071
+ }
36072
+ function expandBoxShorthandValueToSides(value) {
36073
+ if (typeof value === "number") return {
36074
+ top: value,
36075
+ right: value,
36076
+ bottom: value,
36077
+ left: value
36078
+ };
36079
+ const staticString = typeof value === "string" ? value : staticStringValue(value);
36080
+ if (staticString !== null) return expandBoxShorthandStringToSides(staticString);
36081
+ if (!isMediaOrPseudoMap(value)) return null;
36082
+ const top = {};
36083
+ const right = {};
36084
+ const bottom = {};
36085
+ const left = {};
36086
+ for (const [condition, conditionValue] of Object.entries(value)) {
36087
+ if (conditionValue == null) {
36088
+ top[condition] = conditionValue;
36089
+ right[condition] = conditionValue;
36090
+ bottom[condition] = conditionValue;
36091
+ left[condition] = conditionValue;
36092
+ continue;
36093
+ }
36094
+ if (isMediaOrPseudoMap(conditionValue)) return null;
36095
+ const expanded = expandBoxShorthandValueToSides(conditionValue);
36096
+ if (!expanded) return null;
36097
+ top[condition] = expanded.top;
36098
+ right[condition] = expanded.right;
36099
+ bottom[condition] = expanded.bottom;
36100
+ left[condition] = expanded.left;
36101
+ }
36102
+ return {
36103
+ top,
36104
+ right,
36105
+ bottom,
36106
+ left
36107
+ };
36108
+ }
36109
+ /** CSS box expansion: 1-4 whitespace-separated values to top/right/bottom/left. */
36110
+ function expandBoxShorthandStringToSides(raw) {
36111
+ const parts = splitCssValueWhitespace(raw.trim());
36112
+ const top = parts[0];
36113
+ if (top === void 0 || parts.length > 4) return null;
36114
+ const right = parts[1] ?? top;
36115
+ return {
36116
+ top,
36117
+ right,
36118
+ bottom: parts[2] ?? top,
36119
+ left: parts[3] ?? right
36120
+ };
36121
+ }
36122
+ function replaceStyleKeyInPlace(styleObj, key, replacements) {
36123
+ const entries = Object.entries(styleObj);
36124
+ for (const existingKey of Object.keys(styleObj)) delete styleObj[existingKey];
36125
+ for (const [entryKey, entryValue] of entries) if (entryKey === key) for (const [replacementKey, replacementValue] of replacements) styleObj[replacementKey] = replacementValue;
36126
+ else styleObj[entryKey] = entryValue;
36127
+ }
36128
+ function cloneBoxValue(value) {
36129
+ if (isAstNode$1(value)) return cloneAstNode(value);
36130
+ if (isMediaOrPseudoMap(value)) {
36131
+ const cloned = {};
36132
+ for (const [condition, conditionValue] of Object.entries(value)) cloned[condition] = cloneBoxValue(conditionValue);
36133
+ return cloned;
36134
+ }
36135
+ return value;
36136
+ }
36137
+ /**
36138
+ * StyleX gives longhand properties priority over shorthands regardless of
36139
+ * application order, so a `borderRadius` shorthand in one style object can
36140
+ * never override corner longhands applied from another (e.g. a variant's
36141
+ * `borderRadius: 4px` losing to base corner longhands expanded from
36142
+ * `border-radius: 16px 0`). When any style object in the declaration family
36143
+ * carries corner longhands, expand sibling single-value `borderRadius`
36144
+ * shorthands too so cascade overrides keep working.
36145
+ */
36146
+ function harmonizeBorderRadiusExpansion(styleObjs, options) {
36147
+ if (!styleObjs.some((obj) => BORDER_RADIUS_CORNER_PROPS.some((prop) => prop in obj))) return;
36148
+ for (const obj of styleObjs) expandMultiValueBorderRadius(obj, {
36149
+ includeSingleValue: true,
36150
+ omitCorners: lateBaseCornersFor(obj, options),
36151
+ mergeBaseConditionCorners: conditionalBaseCornersFor(obj, options)
36152
+ });
36153
+ }
36154
+ /**
36155
+ * Corners whose base longhand was (re)declared after the variant block in
36156
+ * source order — those keep winning over the variant's expanded borderRadius,
36157
+ * so the variant must not emit them.
36158
+ */
36159
+ function lateBaseCornersFor(styleObj, options) {
36160
+ if (!options?.inheritBaseLateSides?.has(styleObj) || !options.baseRawEntries) return;
36161
+ const snapshot = options.bucketBaseKeySnapshot?.(styleObj);
36162
+ if (!snapshot) return;
36163
+ const lateCorners = /* @__PURE__ */ new Set();
36164
+ for (const [key, value] of options.baseRawEntries) {
36165
+ if (!BORDER_RADIUS_CORNER_PROPS.includes(key)) continue;
36166
+ if (!declaredAfterSnapshot(snapshot, key, value)) continue;
36167
+ if (isMediaOrPseudoMap(value) && hasNullishDefault(value)) continue;
36168
+ lateCorners.add(key);
36169
+ }
36170
+ return lateCorners;
36171
+ }
36172
+ /** Conditional-only base corner entries a variant's expanded borderRadius must preserve. */
36173
+ function conditionalBaseCornersFor(styleObj, options) {
36174
+ if (!options?.inheritBaseLateSides?.has(styleObj) || !options.baseRawEntries) return;
36175
+ const snapshot = options.bucketBaseKeySnapshot?.(styleObj);
36176
+ const variantSourceOrder = options.bucketSourceOrder?.(styleObj);
36177
+ const conditionMaps = /* @__PURE__ */ new Map();
36178
+ for (const [key, value] of options.baseRawEntries) {
36179
+ if (!BORDER_RADIUS_CORNER_PROPS.includes(key)) continue;
36180
+ const changedConditions = changedConditionEntriesAfterSnapshot(snapshot, variantSourceOrder, key, value);
36181
+ if (!changedConditions) continue;
36182
+ conditionMaps.set(key, changedConditions);
36183
+ }
36184
+ return conditionMaps;
36185
+ }
36186
+ function expandMultiValueBorderRadius(styleObj, options) {
36187
+ const value = styleObj.borderRadius;
36188
+ if (value === void 0) return;
36189
+ const expanded = expandBorderRadiusValue(value, options);
36190
+ if (!expanded) return;
36191
+ const next = expandBorderRadiusInStyleObject(styleObj, expanded, { omitCorners: options?.omitCorners });
36192
+ for (const [corner, conditionMap] of options?.mergeBaseConditionCorners ?? []) if (corner in next) next[corner] = mergeBaseConditionsIntoSideValue(next[corner], conditionMap);
36193
+ for (const key of Object.keys(styleObj)) delete styleObj[key];
36194
+ Object.assign(styleObj, next);
36195
+ }
36196
+ function expandBorderRadiusValue(value, options) {
36197
+ const staticExpanded = expandStaticBorderRadiusValue(value, options);
36198
+ if (staticExpanded) return staticExpanded;
36199
+ if (!isMediaOrPseudoMap(value)) return null;
36200
+ const topLeft = {};
36201
+ const topRight = {};
36202
+ const bottomRight = {};
36203
+ const bottomLeft = {};
36204
+ let changed = false;
36205
+ for (const [condition, conditionValue] of Object.entries(value)) {
36206
+ if (conditionValue == null) {
36207
+ topLeft[condition] = conditionValue;
36208
+ topRight[condition] = conditionValue;
36209
+ bottomRight[condition] = conditionValue;
36210
+ bottomLeft[condition] = conditionValue;
36211
+ continue;
36212
+ }
36213
+ const expanded = expandStaticBorderRadiusValue(conditionValue, options);
36214
+ if (!expanded) return null;
36215
+ changed = true;
36216
+ topLeft[condition] = expanded.topLeft;
36217
+ topRight[condition] = expanded.topRight;
36218
+ bottomRight[condition] = expanded.bottomRight;
36219
+ bottomLeft[condition] = expanded.bottomLeft;
36220
+ }
36221
+ return changed || options?.includeSingleValue === true ? {
36222
+ topLeft,
36223
+ topRight,
36224
+ bottomRight,
36225
+ bottomLeft
36226
+ } : null;
36227
+ }
36228
+ function expandStaticBorderRadiusValue(value, options) {
36229
+ if (typeof value === "number") return options?.includeSingleValue === true ? {
36230
+ topLeft: value,
36231
+ topRight: value,
36232
+ bottomRight: value,
36233
+ bottomLeft: value
36234
+ } : null;
36235
+ const staticString = typeof value === "string" ? value : staticStringValue(value);
36236
+ if (staticString === null) return null;
36237
+ return expandBorderRadiusShorthandValue(staticString, options);
36238
+ }
34969
36239
  function resolveDirectionalConflictValue(args) {
34970
36240
  const { shorthandVal, longhandVal, hasLonghand, shorthandIndex, longhandIndex } = args;
34971
36241
  if (!hasLonghand || longhandIndex < 0) return cloneDirectionalValue(shorthandVal);
@@ -35006,7 +36276,10 @@ function computeMergedLonghand(longhandVal, shorthandMap, options) {
35006
36276
  }
35007
36277
  function shouldUseShorthandMapEntry(args) {
35008
36278
  const { key, longhandMap, shorthandMap, shorthandOverrides } = args;
35009
- if (!shorthandOverrides) return !(key in longhandMap);
36279
+ if (!shorthandOverrides) {
36280
+ if (key === "default" && hasNullishDefault(longhandMap)) return true;
36281
+ return !(key in longhandMap);
36282
+ }
35010
36283
  if (key !== "default") return true;
35011
36284
  return !hasNullishDefault(shorthandMap) || hasNullishDefault(longhandMap);
35012
36285
  }
@@ -36929,7 +38202,7 @@ function handleInterpolatedDeclaration(args) {
36929
38202
  applyVariant({
36930
38203
  when: formatObservedVariantCondition(jsxProp, value),
36931
38204
  propName: jsxProp
36932
- }, { [stylexProp]: emitStaticObservedValue(value, stylexProp, observedValues !== null, staticParts) });
38205
+ }, staticVariantStyleObject(stylexProp, emitStaticObservedValue(value, stylexProp, observedValues !== null, staticParts)));
36933
38206
  }
36934
38207
  if (observedValues) {
36935
38208
  const numericIdentifiers = numericIdentifierSetForJsxProp(jsxProp, ctx.findJsxPropTsType);
@@ -37527,6 +38800,21 @@ function handleInterpolatedDeclaration(args) {
37527
38800
  bail = true;
37528
38801
  return { bail: true };
37529
38802
  }
38803
+ if (!isStylexImportSource(imp.source.value) && hasRuntimeImport(resolveValueResult.imports)) {
38804
+ warnings.push({
38805
+ severity: "warning",
38806
+ type: "Unsupported interpolation: call expression",
38807
+ loc: getNodeLocStart(expr) ?? decl.loc,
38808
+ context: {
38809
+ localName: decl.localName,
38810
+ importedName: imp.importedName,
38811
+ source: imp.source.value,
38812
+ path: info.path.length ? info.path.join(".") : void 0
38813
+ }
38814
+ });
38815
+ bail = true;
38816
+ return { bail: true };
38817
+ }
37530
38818
  const exprAst = parseExpr(resolveValueResult.expr);
37531
38819
  if (!exprAst) {
37532
38820
  warnings.push({
@@ -37613,6 +38901,7 @@ function handleInterpolatedDeclaration(args) {
37613
38901
  addImport,
37614
38902
  resolveImportedValueExpr,
37615
38903
  resolveThemeValue,
38904
+ numericIdentifiers: getNumericImportedStylexIdentifiers(j, filePath, importMap, resolverImports),
37616
38905
  setStyleValue: (prop, value) => applyResolvedPropValue(prop, value, null)
37617
38906
  })) continue;
37618
38907
  if (bail) break;
@@ -39244,6 +40533,17 @@ function emitStaticObservedValue(value, stylexProp, isObservedNumeric, staticPar
39244
40533
  if (staticParts.prefix || staticParts.suffix) return `${staticParts.prefix}${value}${staticParts.suffix}`;
39245
40534
  return getNumericCssEmissionMode(stylexProp) === "stylexNumber" ? value : String(value);
39246
40535
  }
40536
+ function staticVariantStyleObject(stylexProp, value) {
40537
+ if (stylexProp !== "borderRadius" || typeof value !== "string") return { [stylexProp]: value };
40538
+ const expanded = expandBorderRadiusShorthandValue(value);
40539
+ if (!expanded) return { [stylexProp]: value };
40540
+ return {
40541
+ borderTopLeftRadius: expanded.topLeft,
40542
+ borderTopRightRadius: expanded.topRight,
40543
+ borderBottomRightRadius: expanded.bottomRight,
40544
+ borderBottomLeftRadius: expanded.bottomLeft
40545
+ };
40546
+ }
39247
40547
  function buildRuntimeObservedValueExpr(j, stylexProp, valueExpr, staticParts, numericIdentifiers = /* @__PURE__ */ new Set()) {
39248
40548
  if (canOmitPxUnitForStylexNumber(stylexProp, staticParts.prefix, staticParts.suffix) && isNumericStylexExpression(valueExpr, { numericIdentifiers })) return staticParts.prefix === "-" ? j.unaryExpression("-", valueExpr, true) : valueExpr;
39249
40549
  if (!staticParts.prefix && !staticParts.suffix) {
@@ -40235,6 +41535,9 @@ function tryHandleMultiSlotTernary(ctx, d) {
40235
41535
  decl.needsWrapperComponent = true;
40236
41536
  return true;
40237
41537
  }
41538
+ function hasRuntimeImport(imports) {
41539
+ return (imports ?? []).some((imp) => !isStylexImportSource(imp.from.value));
41540
+ }
40238
41541
  /**
40239
41542
  * If any variant `when` condition references the styled-components theme object,
40240
41543
  * mark the declaration as needing the `useTheme()` hook so the emitted wrapper
@@ -40809,6 +42112,7 @@ function processRuleDeclarations(args) {
40809
42112
  const { ctx, rule, allRules, media, pseudos, pseudoElement, attrTarget, resolvedSelectorMedia, applyResolvedPropValue } = args;
40810
42113
  const { state } = ctx;
40811
42114
  for (const d of rule.declarations) {
42115
+ ctx.setCurrentDeclarationSourceOrder(d.sourceOrder);
40812
42116
  if (d.property && d.property.includes("__SC_EXPR_")) {
40813
42117
  const resolvedProperty = resolveInterpolatedPropertyName(d.property, ctx);
40814
42118
  if (resolvedProperty === null) {
@@ -41573,6 +42877,9 @@ function processDeclRules(ctx) {
41573
42877
  sourceProperties[prop] = sourceCssProperty;
41574
42878
  }
41575
42879
  };
42880
+ const noteConditionSourceOrder = (target, condition) => {
42881
+ setConditionSourceOrder(target, condition, ctx.getCurrentDeclarationSourceOrder());
42882
+ };
41576
42883
  if (attrTarget) {
41577
42884
  if (attrPseudoElement) {
41578
42885
  const nested = attrTarget[attrPseudoElement] ?? {};
@@ -41607,7 +42914,10 @@ function processDeclRules(ctx) {
41607
42914
  }
41608
42915
  const current = existing[media];
41609
42916
  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;
42917
+ for (const ps of pseudos) {
42918
+ mediaMap[ps] = value;
42919
+ noteConditionSourceOrder(mediaMap, ps);
42920
+ }
41611
42921
  existing[media] = mediaMap;
41612
42922
  } else {
41613
42923
  perPropPseudo[prop] ??= {};
@@ -41624,6 +42934,7 @@ function processDeclRules(ctx) {
41624
42934
  existing[ps] = { default: current !== void 0 ? current : fallbackDefault };
41625
42935
  } else if (!("default" in current)) current.default = getConditionDefaultValue(prop);
41626
42936
  existing[ps][media] = value;
42937
+ noteConditionSourceOrder(existing[ps], media);
41627
42938
  }
41628
42939
  }
41629
42940
  return;
@@ -41704,6 +43015,7 @@ function processDeclRules(ctx) {
41704
43015
  const currentMediaValue = existing[media];
41705
43016
  if (currentMediaValue && typeof currentMediaValue === "object" && !Array.isArray(currentMediaValue) && !isAstNode$1(currentMediaValue)) currentMediaValue.default = value;
41706
43017
  else existing[media] = value;
43018
+ noteConditionSourceOrder(existing, media);
41707
43019
  patchEarlierDynamicConditionValues(prop, media, value);
41708
43020
  return;
41709
43021
  }
@@ -41719,10 +43031,16 @@ function processDeclRules(ctx) {
41719
43031
  const peTarget = nestedSelectors[pseudoElement];
41720
43032
  noteSourceCssProperty(peTarget);
41721
43033
  const existingVal = peTarget[prop];
41722
- if (typeof existingVal === "object" && existingVal !== null && "default" in existingVal) for (const ps of pseudos) existingVal[ps] = value;
43034
+ if (typeof existingVal === "object" && existingVal !== null && "default" in existingVal) for (const ps of pseudos) {
43035
+ existingVal[ps] = value;
43036
+ noteConditionSourceOrder(existingVal, ps);
43037
+ }
41723
43038
  else {
41724
43039
  const pseudoMap = { default: existingVal ?? getConditionDefaultValue(prop) };
41725
- for (const ps of pseudos) pseudoMap[ps] = value;
43040
+ for (const ps of pseudos) {
43041
+ pseudoMap[ps] = value;
43042
+ noteConditionSourceOrder(pseudoMap, ps);
43043
+ }
41726
43044
  peTarget[prop] = pseudoMap;
41727
43045
  }
41728
43046
  return;
@@ -41735,7 +43053,10 @@ function processDeclRules(ctx) {
41735
43053
  const existingVal = styleObj[prop];
41736
43054
  existing.default = existingVal !== void 0 ? existingVal : getConditionDefaultValue(prop);
41737
43055
  }
41738
- for (const ps of pseudos) existing[ps] = value;
43056
+ for (const ps of pseudos) {
43057
+ existing[ps] = value;
43058
+ noteConditionSourceOrder(existing, ps);
43059
+ }
41739
43060
  return;
41740
43061
  }
41741
43062
  const pseudoElementsToApply = pseudoElement ? [pseudoElement] : pseudoElementsList;
@@ -45106,7 +46427,8 @@ function rewriteJsxStep(ctx) {
45106
46427
  }
45107
46428
  }
45108
46429
  if (!hasTemplateVariant) {
45109
- if ((n.startsWith("$") || renamedTransientValues?.has(n)) && decl.base.kind === "intrinsic") return;
46430
+ const shouldStripRenamedTransient = renamedTransientValues?.has(n) && (decl.base.kind === "intrinsic" || styleFnProps.has(n) || variantProps.has(n));
46431
+ if (n.startsWith("$") || shouldStripRenamedTransient) return;
45110
46432
  output.push(attr);
45111
46433
  return;
45112
46434
  }