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.
- package/dist/transform.mjs +1582 -260
- package/package.json +1 -1
package/dist/transform.mjs
CHANGED
|
@@ -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
|
|
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) =>
|
|
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 =
|
|
10551
|
+
const targetRule = findRecoveredRule(selector, recoveryAtRules);
|
|
10076
10552
|
if (!targetRule) return;
|
|
10077
|
-
|
|
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
|
-
|
|
10088
|
-
|
|
10089
|
-
|
|
10090
|
-
|
|
10091
|
-
|
|
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)
|
|
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
|
|
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
|
-
|
|
15304
|
-
const
|
|
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 (
|
|
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 (
|
|
15318
|
-
|
|
15319
|
-
|
|
15320
|
-
|
|
15321
|
-
|
|
15322
|
-
|
|
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
|
|
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())
|
|
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())
|
|
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))
|
|
34772
|
-
|
|
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)
|
|
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
|
-
},
|
|
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)
|
|
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)
|
|
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)
|
|
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)
|
|
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
|
-
|
|
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
|
}
|