styled-components-to-stylex-codemod 0.0.52 → 0.0.54
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/{ast-walk-BOXS-DT7.mjs → ast-walk-CCXrDCKY.mjs} +4 -3
- package/dist/{bridge-consumer-patcher-BlOkZiEv.mjs → bridge-consumer-patcher-DDcYZM_G.mjs} +1 -1
- package/dist/{compute-leaf-set-ghdXvfbp.mjs → compute-leaf-set-u51kTofH.mjs} +1 -1
- package/dist/{forwarded-as-consumer-patcher-CPBlZAjY.mjs → forwarded-as-consumer-patcher-Bva_36Gy.mjs} +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +6 -6
- package/dist/{prop-usage-SADzZJdX.mjs → prop-usage-DyWABApg.mjs} +1 -1
- package/dist/{run-prepass-CWnoXqI6.mjs → run-prepass-DRjZWWHF.mjs} +4 -4
- package/dist/{string-utils-BYTEHwNg.mjs → string-utils-Bo3cWgss.mjs} +2 -1
- package/dist/{transform-types-BIv4-1OO.d.mts → transform-types-BGGNjb8R.d.mts} +1 -1
- package/dist/transform.d.mts +1 -1
- package/dist/transform.mjs +2343 -368
- package/dist/{transient-prop-consumer-patcher-DpfimNca.mjs → transient-prop-consumer-patcher-DSd7uVA6.mjs} +1 -1
- package/package.json +1 -1
package/dist/transform.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { t as createModuleResolver } from "./resolve-imports-DgSAddIF.mjs";
|
|
2
2
|
import { a as isDirectionalResult, n as mergeMarkerDeclarations, o as assertValidAdapter, r as DEFAULT_THEME_HOOK, t as transformedComponentAcceptsSx } from "./sx-surface-CEPFSTO1.mjs";
|
|
3
|
-
import { a as findImportSource, c as resolveBarrelReExportBinding, d as UNSUPPORTED_SHOULD_FORWARD_PROP_WARNING, l as CASCADE_CONFLICT_WARNING, n as createPrepassParser, o as getReExportedSourceName, r as fileExports, t as walkAst, u as Logger } from "./ast-walk-
|
|
3
|
+
import { a as findImportSource, c as resolveBarrelReExportBinding, d as PARTIAL_MIGRATION_INCOMPLETE_WARNING, f as UNSUPPORTED_SHOULD_FORWARD_PROP_WARNING, l as CASCADE_CONFLICT_WARNING, n as createPrepassParser, o as getReExportedSourceName, r as fileExports, t as walkAst, u as Logger } from "./ast-walk-CCXrDCKY.mjs";
|
|
4
4
|
import { n as resolveExistingFilePath, r as toRealPath, t as isRelativeSpecifier } from "./path-utils-BC4U8X_q.mjs";
|
|
5
|
-
import { a as
|
|
5
|
+
import { a as hasTopLevelMatch, c as isPrettierIgnoreComment, d as isValidIdentifierName, f as kebabToCamelCase, g as sanitizeIdentifier, h as normalizeWhitespace, i as getCommentBody, l as isSingleBackgroundComponent, m as lowerFirst, n as capitalize$1, o as isBackgroundImageValue, p as looksLikeLength, r as escapeRegex, s as isJSDocBlockComment, t as camelToKebabCase, u as isStyleSectionMarkerComment } from "./string-utils-Bo3cWgss.mjs";
|
|
6
6
|
import { a as terminateStandaloneInterpolationStatements, i as parseStyledTemplateLiteral, n as isTemplatePlaceholderInSelectorContext, r as PLACEHOLDER_RE } from "./selector-context-heuristic-LVizWWOR.mjs";
|
|
7
|
-
import { _ as walkForImportsAndTemplates, a as mergeComponentPropUsage, i as getExhaustiveObservedStaticValues, n as createComponentPropUsageInfo, o as readStaticJsxLiteral, r as formatObservedVariantCondition, s as collectStylexExportNames, t as KNOWN_NON_ELEMENT_PROPS, u as buildImportMapFromNodes } from "./prop-usage-
|
|
7
|
+
import { _ as walkForImportsAndTemplates, a as mergeComponentPropUsage, i as getExhaustiveObservedStaticValues, n as createComponentPropUsageInfo, o as readStaticJsxLiteral, r as formatObservedVariantCondition, s as collectStylexExportNames, t as KNOWN_NON_ELEMENT_PROPS, u as buildImportMapFromNodes } from "./prop-usage-DyWABApg.mjs";
|
|
8
8
|
import { createRequire } from "node:module";
|
|
9
9
|
import jscodeshift from "jscodeshift";
|
|
10
10
|
import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
@@ -351,24 +351,33 @@ const UNSUPPORTED_STYLEX_CSS_PROPS = new Set([
|
|
|
351
351
|
"all",
|
|
352
352
|
"scroll-margin-block",
|
|
353
353
|
"scroll-margin-block-start",
|
|
354
|
-
"scroll-margin-block-end"
|
|
355
|
-
"scroll-margin-inline",
|
|
356
|
-
"scroll-margin-inline-start",
|
|
357
|
-
"scroll-margin-inline-end",
|
|
358
|
-
"scroll-padding-block",
|
|
359
|
-
"scroll-padding-block-start",
|
|
360
|
-
"scroll-padding-block-end",
|
|
361
|
-
"scroll-padding-inline",
|
|
362
|
-
"scroll-padding-inline-start",
|
|
363
|
-
"scroll-padding-inline-end"
|
|
354
|
+
"scroll-margin-block-end"
|
|
364
355
|
]);
|
|
365
356
|
/**
|
|
357
|
+
* Logical scroll shorthands that expand to Start/End longhands. StyleX's
|
|
358
|
+
* valid-styles rule accepts only the longhand forms.
|
|
359
|
+
*/
|
|
360
|
+
const LOGICAL_SCROLL_AXIS_SHORTHANDS = {
|
|
361
|
+
"scroll-margin-inline": "scrollMarginInline",
|
|
362
|
+
"scroll-padding-block": "scrollPaddingBlock",
|
|
363
|
+
"scroll-padding-inline": "scrollPaddingInline"
|
|
364
|
+
};
|
|
365
|
+
/**
|
|
366
366
|
* Returns true if the CSS property is a shorthand that StyleX cannot express directly
|
|
367
367
|
* and requires expansion (e.g., `padding`, `margin`, `border`, `background`).
|
|
368
368
|
*/
|
|
369
369
|
function isCssShorthandProperty(cssProp) {
|
|
370
370
|
return cssProp in DIRECTIONAL_SHORTHAND_MAP || cssProp === "border" || /^border-(top|right|bottom|left)$/.test(cssProp) || cssProp === "background";
|
|
371
371
|
}
|
|
372
|
+
/**
|
|
373
|
+
* True for the logical scroll axis shorthands (`scroll-margin-inline`,
|
|
374
|
+
* `scroll-padding-block`, `scroll-padding-inline`). StyleX accepts only their
|
|
375
|
+
* Start/End longhands, so a static value is expanded; a dynamic value cannot be
|
|
376
|
+
* split losslessly and must bail.
|
|
377
|
+
*/
|
|
378
|
+
function isLogicalScrollAxisShorthand(cssProp) {
|
|
379
|
+
return cssProp.trim() in LOGICAL_SCROLL_AXIS_SHORTHANDS;
|
|
380
|
+
}
|
|
372
381
|
function isUnsupportedStylexProperty(cssProp) {
|
|
373
382
|
return UNSUPPORTED_STYLEX_CSS_PROPS.has(cssProp.trim());
|
|
374
383
|
}
|
|
@@ -394,6 +403,111 @@ function resolveBackgroundStylexPropForVariants(values) {
|
|
|
394
403
|
if (hasGradient && hasColor) return null;
|
|
395
404
|
return hasGradient ? "backgroundImage" : "backgroundColor";
|
|
396
405
|
}
|
|
406
|
+
/**
|
|
407
|
+
* Expands a static multi-component `background` shorthand (single layer) into
|
|
408
|
+
* the full set of StyleX background longhands, e.g.
|
|
409
|
+
* `#fff url(a.svg) no-repeat center / cover`. Components omitted from the
|
|
410
|
+
* shorthand are emitted at their CSS initial value (e.g. `backgroundColor:
|
|
411
|
+
* transparent`), reproducing the shorthand's reset semantics so the expansion
|
|
412
|
+
* fully overrides any background longhand inherited from a merged/extended base.
|
|
413
|
+
*
|
|
414
|
+
* Returns null when the value cannot be expanded losslessly: multiple layers
|
|
415
|
+
* (top-level commas), unrecognized tokens, duplicate components, or fewer than
|
|
416
|
+
* two explicit components (single components keep the single-longhand path).
|
|
417
|
+
*/
|
|
418
|
+
function expandBackgroundShorthandComponents(rawValue) {
|
|
419
|
+
const value = rawValue.trim();
|
|
420
|
+
if (!value || hasTopLevelMatch(value, /,/)) return null;
|
|
421
|
+
const tokens = tokenizeBackgroundValue(value);
|
|
422
|
+
if (!tokens) return null;
|
|
423
|
+
let color;
|
|
424
|
+
let image;
|
|
425
|
+
let attachment;
|
|
426
|
+
const repeatTokens = [];
|
|
427
|
+
const positionTokens = [];
|
|
428
|
+
const sizeTokens = [];
|
|
429
|
+
const boxTokens = [];
|
|
430
|
+
let inSizeMode = false;
|
|
431
|
+
for (const token of tokens) {
|
|
432
|
+
if (token === "/") {
|
|
433
|
+
if (inSizeMode || positionTokens.length === 0) return null;
|
|
434
|
+
inSizeMode = true;
|
|
435
|
+
continue;
|
|
436
|
+
}
|
|
437
|
+
if (inSizeMode) {
|
|
438
|
+
if (sizeTokens.length >= 2 || !isBackgroundSizeToken(token)) return null;
|
|
439
|
+
sizeTokens.push(token);
|
|
440
|
+
continue;
|
|
441
|
+
}
|
|
442
|
+
if (token === "none" || isBackgroundImageValue(token)) {
|
|
443
|
+
if (image !== void 0) return null;
|
|
444
|
+
image = token;
|
|
445
|
+
continue;
|
|
446
|
+
}
|
|
447
|
+
if (isCssColorToken(token)) {
|
|
448
|
+
if (color !== void 0) return null;
|
|
449
|
+
color = token;
|
|
450
|
+
continue;
|
|
451
|
+
}
|
|
452
|
+
if (BACKGROUND_REPEAT_KEYWORDS.has(token)) {
|
|
453
|
+
if (repeatTokens.length >= 2) return null;
|
|
454
|
+
repeatTokens.push(token);
|
|
455
|
+
continue;
|
|
456
|
+
}
|
|
457
|
+
if (BACKGROUND_ATTACHMENT_KEYWORDS.has(token)) {
|
|
458
|
+
if (attachment !== void 0) return null;
|
|
459
|
+
attachment = token;
|
|
460
|
+
continue;
|
|
461
|
+
}
|
|
462
|
+
if (BACKGROUND_BOX_KEYWORDS.has(token)) {
|
|
463
|
+
if (boxTokens.length >= 2) return null;
|
|
464
|
+
boxTokens.push(token);
|
|
465
|
+
continue;
|
|
466
|
+
}
|
|
467
|
+
if (isBackgroundPositionToken(token)) {
|
|
468
|
+
if (positionTokens.length >= 2) return null;
|
|
469
|
+
positionTokens.push(token);
|
|
470
|
+
continue;
|
|
471
|
+
}
|
|
472
|
+
return null;
|
|
473
|
+
}
|
|
474
|
+
if (inSizeMode && sizeTokens.length === 0) return null;
|
|
475
|
+
if ((color !== void 0 ? 1 : 0) + (image !== void 0 ? 1 : 0) + (attachment !== void 0 ? 1 : 0) + (repeatTokens.length ? 1 : 0) + (positionTokens.length ? 1 : 0) + (sizeTokens.length ? 1 : 0) + (boxTokens.length ? 1 : 0) < 2) return null;
|
|
476
|
+
return [
|
|
477
|
+
{
|
|
478
|
+
prop: "backgroundColor",
|
|
479
|
+
value: color ?? "transparent"
|
|
480
|
+
},
|
|
481
|
+
{
|
|
482
|
+
prop: "backgroundImage",
|
|
483
|
+
value: image ?? "none"
|
|
484
|
+
},
|
|
485
|
+
{
|
|
486
|
+
prop: "backgroundRepeat",
|
|
487
|
+
value: repeatTokens.length ? repeatTokens.join(" ") : "repeat"
|
|
488
|
+
},
|
|
489
|
+
{
|
|
490
|
+
prop: "backgroundAttachment",
|
|
491
|
+
value: attachment ?? "scroll"
|
|
492
|
+
},
|
|
493
|
+
{
|
|
494
|
+
prop: "backgroundPosition",
|
|
495
|
+
value: positionTokens.length ? positionTokens.join(" ") : "0% 0%"
|
|
496
|
+
},
|
|
497
|
+
{
|
|
498
|
+
prop: "backgroundSize",
|
|
499
|
+
value: sizeTokens.length ? sizeTokens.join(" ") : "auto"
|
|
500
|
+
},
|
|
501
|
+
{
|
|
502
|
+
prop: "backgroundOrigin",
|
|
503
|
+
value: boxTokens[0] ?? "padding-box"
|
|
504
|
+
},
|
|
505
|
+
{
|
|
506
|
+
prop: "backgroundClip",
|
|
507
|
+
value: boxTokens[1] ?? boxTokens[0] ?? "border-box"
|
|
508
|
+
}
|
|
509
|
+
];
|
|
510
|
+
}
|
|
397
511
|
function parseInterpolatedBorderStaticParts(args) {
|
|
398
512
|
const { prop, prefix, suffix } = args;
|
|
399
513
|
const borderMatch = prop.match(/^border(-top|-right|-bottom|-left)?$/);
|
|
@@ -464,6 +578,28 @@ function cssDeclarationToStylexDeclarations(decl) {
|
|
|
464
578
|
}
|
|
465
579
|
}));
|
|
466
580
|
}
|
|
581
|
+
const logicalScrollAxis = LOGICAL_SCROLL_AXIS_SHORTHANDS[prop];
|
|
582
|
+
if (logicalScrollAxis && decl.value.kind === "static") {
|
|
583
|
+
const values = splitCssValueWhitespace(decl.valueRaw.trim());
|
|
584
|
+
if (values.length >= 1 && values.length <= 2) {
|
|
585
|
+
const start = values[0];
|
|
586
|
+
const end = values[1] ?? start;
|
|
587
|
+
const withImportant = (value) => decl.important ? `${value} !important` : value;
|
|
588
|
+
return [{
|
|
589
|
+
prop: `${logicalScrollAxis}Start`,
|
|
590
|
+
value: {
|
|
591
|
+
kind: "static",
|
|
592
|
+
value: withImportant(start)
|
|
593
|
+
}
|
|
594
|
+
}, {
|
|
595
|
+
prop: `${logicalScrollAxis}End`,
|
|
596
|
+
value: {
|
|
597
|
+
kind: "static",
|
|
598
|
+
value: withImportant(end)
|
|
599
|
+
}
|
|
600
|
+
}];
|
|
601
|
+
}
|
|
602
|
+
}
|
|
467
603
|
if (prop === "background") {
|
|
468
604
|
const rawVal = (decl.valueRaw ?? "").trim();
|
|
469
605
|
if (rawVal === "none") return [{
|
|
@@ -482,6 +618,22 @@ function cssDeclarationToStylexDeclarations(decl) {
|
|
|
482
618
|
}];
|
|
483
619
|
}
|
|
484
620
|
if (prop === "display" && decl.value.kind === "static" && decl.valueRaw.trim() === "wrap") return [];
|
|
621
|
+
if (prop === "overflow" && decl.value.kind === "static") {
|
|
622
|
+
const tokens = decl.valueRaw.trim().split(/\s+/);
|
|
623
|
+
if (tokens.length === 2) return [{
|
|
624
|
+
prop: "overflowX",
|
|
625
|
+
value: {
|
|
626
|
+
kind: "static",
|
|
627
|
+
value: tokens[0]
|
|
628
|
+
}
|
|
629
|
+
}, {
|
|
630
|
+
prop: "overflowY",
|
|
631
|
+
value: {
|
|
632
|
+
kind: "static",
|
|
633
|
+
value: tokens[1]
|
|
634
|
+
}
|
|
635
|
+
}];
|
|
636
|
+
}
|
|
485
637
|
if (prop === "animation" && decl.value.kind === "static" && decl.valueRaw.trim() === "none") return [{
|
|
486
638
|
prop: "animationName",
|
|
487
639
|
value: decl.value
|
|
@@ -729,6 +881,87 @@ function classifyBorderTokens(tokens) {
|
|
|
729
881
|
color
|
|
730
882
|
};
|
|
731
883
|
}
|
|
884
|
+
const BACKGROUND_REPEAT_KEYWORDS = new Set([
|
|
885
|
+
"repeat",
|
|
886
|
+
"repeat-x",
|
|
887
|
+
"repeat-y",
|
|
888
|
+
"no-repeat",
|
|
889
|
+
"space",
|
|
890
|
+
"round"
|
|
891
|
+
]);
|
|
892
|
+
const BACKGROUND_ATTACHMENT_KEYWORDS = new Set([
|
|
893
|
+
"scroll",
|
|
894
|
+
"fixed",
|
|
895
|
+
"local"
|
|
896
|
+
]);
|
|
897
|
+
const BACKGROUND_BOX_KEYWORDS = new Set([
|
|
898
|
+
"border-box",
|
|
899
|
+
"padding-box",
|
|
900
|
+
"content-box"
|
|
901
|
+
]);
|
|
902
|
+
const BACKGROUND_POSITION_KEYWORDS = new Set([
|
|
903
|
+
"left",
|
|
904
|
+
"right",
|
|
905
|
+
"top",
|
|
906
|
+
"bottom",
|
|
907
|
+
"center"
|
|
908
|
+
]);
|
|
909
|
+
const CSS_COLOR_FUNCTION_RE = /^(?:rgb|rgba|hsl|hsla|hwb|lab|lch|oklab|oklch|color)\(/i;
|
|
910
|
+
const CSS_NAMED_COLORS = new Set("aliceblue antiquewhite aqua aquamarine azure beige bisque black blanchedalmond blue blueviolet brown burlywood cadetblue chartreuse chocolate coral cornflowerblue cornsilk crimson cyan darkblue darkcyan darkgoldenrod darkgray darkgreen darkgrey darkkhaki darkmagenta darkolivegreen darkorange darkorchid darkred darksalmon darkseagreen darkslateblue darkslategray darkslategrey darkturquoise darkviolet deeppink deepskyblue dimgray dimgrey dodgerblue firebrick floralwhite forestgreen fuchsia gainsboro ghostwhite gold goldenrod gray green greenyellow grey honeydew hotpink indianred indigo ivory khaki lavender lavenderblush lawngreen lemonchiffon lightblue lightcoral lightcyan lightgoldenrodyellow lightgray lightgreen lightgrey lightpink lightsalmon lightseagreen lightskyblue lightslategray lightslategrey lightsteelblue lightyellow lime limegreen linen magenta maroon mediumaquamarine mediumblue mediumorchid mediumpurple mediumseagreen mediumslateblue mediumspringgreen mediumturquoise mediumvioletred midnightblue mintcream mistyrose moccasin navajowhite navy oldlace olive olivedrab orange orangered orchid palegoldenrod palegreen paleturquoise palevioletred papayawhip peachpuff peru pink plum powderblue purple rebeccapurple red rosybrown royalblue saddlebrown salmon sandybrown seagreen seashell sienna silver skyblue slateblue slategray slategrey snow springgreen steelblue tan teal thistle tomato turquoise violet wheat white whitesmoke yellow yellowgreen transparent currentcolor".split(" "));
|
|
911
|
+
function isCssColorToken(token) {
|
|
912
|
+
if (token.startsWith("#")) return /^#(?:[0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(token);
|
|
913
|
+
if (CSS_COLOR_FUNCTION_RE.test(token)) return true;
|
|
914
|
+
return CSS_NAMED_COLORS.has(token.toLowerCase());
|
|
915
|
+
}
|
|
916
|
+
function isBackgroundPositionToken(token) {
|
|
917
|
+
return BACKGROUND_POSITION_KEYWORDS.has(token.toLowerCase()) || /^-?\d*\.?\d+(?:[a-z%]*)$/i.test(token) || /^calc\(/i.test(token);
|
|
918
|
+
}
|
|
919
|
+
function isBackgroundSizeToken(token) {
|
|
920
|
+
const lower = token.toLowerCase();
|
|
921
|
+
return lower === "cover" || lower === "contain" || lower === "auto" || /^-?\d*\.?\d+(?:[a-z%]*)$/i.test(token) || /^calc\(/i.test(token);
|
|
922
|
+
}
|
|
923
|
+
/**
|
|
924
|
+
* Splits a background shorthand value into top-level tokens, keeping function
|
|
925
|
+
* calls intact and emitting `/` (position/size separator) as its own token.
|
|
926
|
+
* Returns null for values containing placeholders or unbalanced parens.
|
|
927
|
+
*/
|
|
928
|
+
function tokenizeBackgroundValue(value) {
|
|
929
|
+
if (value.includes("__SC_EXPR_")) return null;
|
|
930
|
+
const tokens = [];
|
|
931
|
+
let current = "";
|
|
932
|
+
let depth = 0;
|
|
933
|
+
const flush = () => {
|
|
934
|
+
if (current) {
|
|
935
|
+
tokens.push(current);
|
|
936
|
+
current = "";
|
|
937
|
+
}
|
|
938
|
+
};
|
|
939
|
+
for (const c of value) {
|
|
940
|
+
if (c === "(") {
|
|
941
|
+
depth++;
|
|
942
|
+
current += c;
|
|
943
|
+
continue;
|
|
944
|
+
}
|
|
945
|
+
if (c === ")") {
|
|
946
|
+
depth = Math.max(0, depth - 1);
|
|
947
|
+
current += c;
|
|
948
|
+
continue;
|
|
949
|
+
}
|
|
950
|
+
if (depth === 0 && /\s/.test(c)) {
|
|
951
|
+
flush();
|
|
952
|
+
continue;
|
|
953
|
+
}
|
|
954
|
+
if (depth === 0 && c === "/") {
|
|
955
|
+
flush();
|
|
956
|
+
tokens.push("/");
|
|
957
|
+
continue;
|
|
958
|
+
}
|
|
959
|
+
current += c;
|
|
960
|
+
}
|
|
961
|
+
if (depth !== 0) return null;
|
|
962
|
+
flush();
|
|
963
|
+
return tokens.length ? tokens : null;
|
|
964
|
+
}
|
|
732
965
|
//#endregion
|
|
733
966
|
//#region src/internal/transform-parse-expr.ts
|
|
734
967
|
function parseExpr(api, exprSource) {
|
|
@@ -761,7 +994,7 @@ function createResolveAdapterSafe(args) {
|
|
|
761
994
|
*/
|
|
762
995
|
const resolveValueCore = (ctx) => {
|
|
763
996
|
if (bailRef.value) return;
|
|
764
|
-
if (ctx.kind === "importedValue" && isStylexFileSource(ctx.source)) return stylexImportPassthrough(ctx.importedName, ctx.source, ctx.path);
|
|
997
|
+
if (ctx.kind === "importedValue" && isStylexFileSource$1(ctx.source)) return stylexImportPassthrough(ctx.importedName, ctx.source, ctx.path);
|
|
765
998
|
const res = adapter.resolveValue(ctx);
|
|
766
999
|
if (res === void 0 && ctx.kind !== "cssVariable") {
|
|
767
1000
|
bailRef.value = true;
|
|
@@ -779,7 +1012,7 @@ function createResolveAdapterSafe(args) {
|
|
|
779
1012
|
};
|
|
780
1013
|
const resolveCallSafe = (ctx) => {
|
|
781
1014
|
if (bailRef.value) return;
|
|
782
|
-
if (isStylexFileSource(ctx.calleeSource)) return stylexImportPassthrough(ctx.calleeImportedName, ctx.calleeSource, ctx.calleeMemberPath?.join("."));
|
|
1015
|
+
if (isStylexFileSource$1(ctx.calleeSource)) return stylexImportPassthrough(ctx.calleeImportedName, ctx.calleeSource, ctx.calleeMemberPath?.join("."));
|
|
783
1016
|
const res = adapter.resolveCall(ctx);
|
|
784
1017
|
if (res === void 0) {
|
|
785
1018
|
bailRef.value = true;
|
|
@@ -788,7 +1021,7 @@ function createResolveAdapterSafe(args) {
|
|
|
788
1021
|
return res;
|
|
789
1022
|
};
|
|
790
1023
|
const resolveSelectorSafe = (ctx) => {
|
|
791
|
-
if (isStylexFileSource(ctx.source)) return {
|
|
1024
|
+
if (isStylexFileSource$1(ctx.source)) return {
|
|
792
1025
|
kind: "media",
|
|
793
1026
|
...stylexImportPassthrough(ctx.importedName, ctx.source, ctx.path)
|
|
794
1027
|
};
|
|
@@ -802,10 +1035,10 @@ function createResolveAdapterSafe(args) {
|
|
|
802
1035
|
bailRef
|
|
803
1036
|
};
|
|
804
1037
|
}
|
|
805
|
-
const STYLEX_FILE_RE = /\.stylex(\.\w+)?$/;
|
|
1038
|
+
const STYLEX_FILE_RE$1 = /\.stylex(\.\w+)?$/;
|
|
806
1039
|
/** Imports from `.stylex` files are already StyleX-compatible and need no adapter resolution. */
|
|
807
|
-
function isStylexFileSource(source) {
|
|
808
|
-
return STYLEX_FILE_RE.test(source.value);
|
|
1040
|
+
function isStylexFileSource$1(source) {
|
|
1041
|
+
return STYLEX_FILE_RE$1.test(source.value);
|
|
809
1042
|
}
|
|
810
1043
|
/** Build a passthrough result that preserves the original import reference from a `.stylex` file. */
|
|
811
1044
|
function stylexImportPassthrough(importedName, source, path) {
|
|
@@ -1334,10 +1567,12 @@ function collectPatternBindingNames$2(node, names) {
|
|
|
1334
1567
|
*
|
|
1335
1568
|
* Returns null for non-literal or dynamic nodes.
|
|
1336
1569
|
*/
|
|
1337
|
-
function literalToStaticValue(node) {
|
|
1570
|
+
function literalToStaticValue(node, options = {}) {
|
|
1338
1571
|
if (!node || typeof node !== "object") return null;
|
|
1572
|
+
const allowCssTaggedTemplates = options.allowCssTaggedTemplates ?? true;
|
|
1573
|
+
const allowStaticArrowFunctions = options.allowStaticArrowFunctions ?? true;
|
|
1339
1574
|
const type = node.type;
|
|
1340
|
-
if (type === "TSAsExpression" || type === "TSSatisfiesExpression") return literalToStaticValue(node.expression);
|
|
1575
|
+
if (type === "TSAsExpression" || type === "TSSatisfiesExpression") return literalToStaticValue(node.expression, options);
|
|
1341
1576
|
if (type === "StringLiteral") return node.value;
|
|
1342
1577
|
if (type === "BooleanLiteral") return node.value;
|
|
1343
1578
|
if (type === "Literal") {
|
|
@@ -1348,25 +1583,53 @@ function literalToStaticValue(node) {
|
|
|
1348
1583
|
if (type === "UnaryExpression") {
|
|
1349
1584
|
const n = node;
|
|
1350
1585
|
if (n.prefix && (n.operator === "-" || n.operator === "+")) {
|
|
1351
|
-
const argVal = literalToStaticValue(n.argument);
|
|
1586
|
+
const argVal = literalToStaticValue(n.argument, options);
|
|
1352
1587
|
if (typeof argVal === "number") return n.operator === "-" ? -argVal : argVal;
|
|
1353
1588
|
}
|
|
1354
1589
|
}
|
|
1355
1590
|
if (type === "TemplateLiteral") {
|
|
1356
1591
|
const n = node;
|
|
1357
|
-
if (!n.expressions || n.expressions.length === 0)
|
|
1592
|
+
if (!n.expressions || n.expressions.length === 0) {
|
|
1593
|
+
const quasis = n.quasis ?? [];
|
|
1594
|
+
const parts = [];
|
|
1595
|
+
for (const q of quasis) {
|
|
1596
|
+
const cooked = q.value?.cooked;
|
|
1597
|
+
if (cooked == null) return null;
|
|
1598
|
+
parts.push(cooked);
|
|
1599
|
+
}
|
|
1600
|
+
return parts.join("");
|
|
1601
|
+
}
|
|
1358
1602
|
}
|
|
1359
|
-
if (type === "TaggedTemplateExpression") {
|
|
1603
|
+
if (type === "TaggedTemplateExpression" && allowCssTaggedTemplates) {
|
|
1360
1604
|
const n = node;
|
|
1361
|
-
if (n.tag?.type === "Identifier" && n.tag.name === "css") return literalToStaticValue(n.quasi);
|
|
1605
|
+
if (n.tag?.type === "Identifier" && n.tag.name === "css") return literalToStaticValue(n.quasi, options);
|
|
1362
1606
|
}
|
|
1363
|
-
if (type === "ArrowFunctionExpression") {
|
|
1607
|
+
if (type === "ArrowFunctionExpression" && allowStaticArrowFunctions) {
|
|
1364
1608
|
const n = node;
|
|
1365
|
-
if (!n.params || n.params.length === 0) return literalToStaticValue(n.body);
|
|
1609
|
+
if (!n.params || n.params.length === 0) return literalToStaticValue(n.body, options);
|
|
1366
1610
|
}
|
|
1367
1611
|
return null;
|
|
1368
1612
|
}
|
|
1369
1613
|
/**
|
|
1614
|
+
* Extracts a static literal value from an AST node, distinguishing null literals
|
|
1615
|
+
* from extraction failure. Returns `undefined` when the node is not a recognized
|
|
1616
|
+
* static literal, and the actual value (including `null`) otherwise.
|
|
1617
|
+
*
|
|
1618
|
+
* Function expressions are not coerced by default: a function-valued expression
|
|
1619
|
+
* is runtime data, even if its body is a static literal.
|
|
1620
|
+
*/
|
|
1621
|
+
function extractStaticLiteralValue(node, options = {}) {
|
|
1622
|
+
if (!node || typeof node !== "object") return;
|
|
1623
|
+
const typed = node;
|
|
1624
|
+
if (typed.type === "TSAsExpression" || typed.type === "TSSatisfiesExpression") return extractStaticLiteralValue(typed.expression, options);
|
|
1625
|
+
if (typed.type === "NullLiteral" || typed.type === "Literal" && typed.value === null) return null;
|
|
1626
|
+
const v = literalToStaticValue(node, {
|
|
1627
|
+
...options,
|
|
1628
|
+
allowStaticArrowFunctions: options.allowStaticArrowFunctions ?? false
|
|
1629
|
+
});
|
|
1630
|
+
return v !== null ? v : void 0;
|
|
1631
|
+
}
|
|
1632
|
+
/**
|
|
1370
1633
|
* Converts an AST literal node to a string value.
|
|
1371
1634
|
* Returns null if the node is not a string literal.
|
|
1372
1635
|
*/
|
|
@@ -1741,6 +2004,11 @@ function toSuffixFromProp(propName) {
|
|
|
1741
2004
|
return suffixes.join("");
|
|
1742
2005
|
}
|
|
1743
2006
|
}
|
|
2007
|
+
const defaultTruthyMatch = trimmed.match(/^(.+?) === undefined \|\| (.+)$/);
|
|
2008
|
+
if (defaultTruthyMatch) {
|
|
2009
|
+
const lhs = defaultTruthyMatch[1].replace(/^\$/, "");
|
|
2010
|
+
if (lhs === defaultTruthyMatch[2].replace(/^\$/, "")) return toSuffixFromProp(lhs);
|
|
2011
|
+
}
|
|
1744
2012
|
if (trimmed.includes(" || ")) {
|
|
1745
2013
|
const parts = trimmed.split(" || ").map((s) => s.trim()).filter(Boolean);
|
|
1746
2014
|
if (parts.length) {
|
|
@@ -3498,7 +3766,7 @@ function specifierExportedName(spec) {
|
|
|
3498
3766
|
* - Disjunction: `"a || b"` → `a || b`
|
|
3499
3767
|
* - Grouped negation: `"!(a || b)"` → `!(a || b)`
|
|
3500
3768
|
*/
|
|
3501
|
-
function parseVariantWhenToAst(j, when, booleanProps, knownProps) {
|
|
3769
|
+
function parseVariantWhenToAst(j, when, booleanProps, knownProps, nonPropRoots) {
|
|
3502
3770
|
const buildMemberExpr = (raw) => {
|
|
3503
3771
|
if (!raw.includes(".")) return null;
|
|
3504
3772
|
const parts = raw.split(".").map((part) => part.trim()).filter(Boolean);
|
|
@@ -3533,7 +3801,7 @@ function parseVariantWhenToAst(j, when, booleanProps, knownProps) {
|
|
|
3533
3801
|
}
|
|
3534
3802
|
const memberExpr = buildMemberExpr(trimmedRaw);
|
|
3535
3803
|
if (memberExpr) return {
|
|
3536
|
-
propName: root && root !== "theme" && isConditionPropIdentifier(root) ? root : null,
|
|
3804
|
+
propName: root && root !== "theme" && !nonPropRoots?.has(root) && isConditionPropIdentifier(root) ? root : null,
|
|
3537
3805
|
expr: memberExpr
|
|
3538
3806
|
};
|
|
3539
3807
|
return {
|
|
@@ -3542,7 +3810,7 @@ function parseVariantWhenToAst(j, when, booleanProps, knownProps) {
|
|
|
3542
3810
|
};
|
|
3543
3811
|
}
|
|
3544
3812
|
return {
|
|
3545
|
-
propName: trimmedRaw === "theme" || !isConditionPropIdentifier(trimmedRaw) ? null : trimmedRaw,
|
|
3813
|
+
propName: trimmedRaw === "theme" || nonPropRoots?.has(trimmedRaw) || !isConditionPropIdentifier(trimmedRaw) ? null : trimmedRaw,
|
|
3546
3814
|
expr: j.identifier(trimmedRaw)
|
|
3547
3815
|
};
|
|
3548
3816
|
};
|
|
@@ -3553,7 +3821,7 @@ function parseVariantWhenToAst(j, when, booleanProps, knownProps) {
|
|
|
3553
3821
|
isBoolean: true
|
|
3554
3822
|
};
|
|
3555
3823
|
if (trimmed.startsWith("!(") && trimmed.endsWith(")")) {
|
|
3556
|
-
const innerParsed = parseVariantWhenToAst(j, trimmed.slice(2, -1).trim(), booleanProps, knownProps);
|
|
3824
|
+
const innerParsed = parseVariantWhenToAst(j, trimmed.slice(2, -1).trim(), booleanProps, knownProps, nonPropRoots);
|
|
3557
3825
|
return {
|
|
3558
3826
|
cond: j.unaryExpression("!", innerParsed.cond),
|
|
3559
3827
|
props: innerParsed.props,
|
|
@@ -3561,7 +3829,7 @@ function parseVariantWhenToAst(j, when, booleanProps, knownProps) {
|
|
|
3561
3829
|
};
|
|
3562
3830
|
}
|
|
3563
3831
|
if (trimmed.includes("&&")) {
|
|
3564
|
-
const parsed = trimmed.split("&&").map((s) => s.trim()).filter(Boolean).map((p) => parseVariantWhenToAst(j, p, booleanProps, knownProps));
|
|
3832
|
+
const parsed = trimmed.split("&&").map((s) => s.trim()).filter(Boolean).map((p) => parseVariantWhenToAst(j, p, booleanProps, knownProps, nonPropRoots));
|
|
3565
3833
|
const firstParsed = parsed[0];
|
|
3566
3834
|
if (!firstParsed) return {
|
|
3567
3835
|
cond: j.identifier("true"),
|
|
@@ -3575,7 +3843,7 @@ function parseVariantWhenToAst(j, when, booleanProps, knownProps) {
|
|
|
3575
3843
|
};
|
|
3576
3844
|
}
|
|
3577
3845
|
if (trimmed.includes(" || ")) {
|
|
3578
|
-
const parsed = trimmed.split(" || ").map((s) => s.trim()).filter(Boolean).map((p) => parseVariantWhenToAst(j, p, booleanProps, knownProps));
|
|
3846
|
+
const parsed = trimmed.split(" || ").map((s) => s.trim()).filter(Boolean).map((p) => parseVariantWhenToAst(j, p, booleanProps, knownProps, nonPropRoots));
|
|
3579
3847
|
const firstParsedOr = parsed[0];
|
|
3580
3848
|
if (!firstParsedOr) return {
|
|
3581
3849
|
cond: j.identifier("true"),
|
|
@@ -3589,7 +3857,7 @@ function parseVariantWhenToAst(j, when, booleanProps, knownProps) {
|
|
|
3589
3857
|
};
|
|
3590
3858
|
}
|
|
3591
3859
|
if (trimmed.startsWith("!")) {
|
|
3592
|
-
const innerParsed = parseVariantWhenToAst(j, trimmed.slice(1).trim(), booleanProps, knownProps);
|
|
3860
|
+
const innerParsed = parseVariantWhenToAst(j, trimmed.slice(1).trim(), booleanProps, knownProps, nonPropRoots);
|
|
3593
3861
|
return {
|
|
3594
3862
|
cond: j.unaryExpression("!", innerParsed.cond),
|
|
3595
3863
|
props: innerParsed.props,
|
|
@@ -3718,8 +3986,8 @@ function isConditionPropIdentifier(name, knownProps) {
|
|
|
3718
3986
|
* function's parameter destructuring.
|
|
3719
3987
|
*/
|
|
3720
3988
|
function collectConditionProps(j, args) {
|
|
3721
|
-
const { when, destructureProps, booleanProps, knownProps } = args;
|
|
3722
|
-
const parsed = parseVariantWhenToAst(j, when, booleanProps, knownProps);
|
|
3989
|
+
const { when, destructureProps, booleanProps, knownProps, nonPropRoots } = args;
|
|
3990
|
+
const parsed = parseVariantWhenToAst(j, when, booleanProps, knownProps, nonPropRoots);
|
|
3723
3991
|
if (destructureProps) {
|
|
3724
3992
|
for (const p of parsed.props) if (p && !destructureProps.includes(p)) destructureProps.push(p);
|
|
3725
3993
|
}
|
|
@@ -4052,6 +4320,7 @@ function buildResolvedHandlerResult(result, cssProperty, payload) {
|
|
|
4052
4320
|
type: "resolvedValue",
|
|
4053
4321
|
expr: result.expr,
|
|
4054
4322
|
imports: result.imports,
|
|
4323
|
+
cssValueText: result.expr,
|
|
4055
4324
|
...payload
|
|
4056
4325
|
} : {
|
|
4057
4326
|
type: "resolvedStyles",
|
|
@@ -4627,6 +4896,19 @@ function getPropertyNameFromKey(key) {
|
|
|
4627
4896
|
* Core concepts: deep merge semantics, AST node detection, and media query resolution.
|
|
4628
4897
|
*/
|
|
4629
4898
|
/**
|
|
4899
|
+
* Marks an emitted AST value node as proven to be a single CSS token (e.g. a
|
|
4900
|
+
* numeric stylex const that had a unit suffix). Shorthand properties holding
|
|
4901
|
+
* such values cannot expand to multiple tokens, so the opaque-shorthand
|
|
4902
|
+
* warning does not apply to them.
|
|
4903
|
+
*/
|
|
4904
|
+
function markProvenSingleTokenValue(node) {
|
|
4905
|
+
if (node && typeof node === "object") provenSingleTokenValues.add(node);
|
|
4906
|
+
}
|
|
4907
|
+
function isProvenSingleTokenValue(node) {
|
|
4908
|
+
return !!node && typeof node === "object" && provenSingleTokenValues.has(node);
|
|
4909
|
+
}
|
|
4910
|
+
const provenSingleTokenValues = /* @__PURE__ */ new WeakSet();
|
|
4911
|
+
/**
|
|
4630
4912
|
* Tries to resolve a CallExpression via the adapter's `resolveCall`.
|
|
4631
4913
|
* Shared by both css-helper and process-rules slot resolution.
|
|
4632
4914
|
*
|
|
@@ -5284,6 +5566,10 @@ function staticStringValue(value) {
|
|
|
5284
5566
|
function invertWhen(when) {
|
|
5285
5567
|
if (when.startsWith("!(") && when.endsWith(")")) return when.slice(2, -1);
|
|
5286
5568
|
if (when.startsWith("!")) return when.slice(1);
|
|
5569
|
+
if (when.includes(" || ") || when.includes(" && ")) {
|
|
5570
|
+
if (when.includes(" || ") && when.includes(" && ")) return null;
|
|
5571
|
+
return `!(${when})`;
|
|
5572
|
+
}
|
|
5287
5573
|
const match = when.match(/^(.+)\s+(===|!==)\s+(.+)$/);
|
|
5288
5574
|
if (match) {
|
|
5289
5575
|
const [, propName, op, rhs] = match;
|
|
@@ -5336,31 +5622,46 @@ const createPropTestHelpers = (bindings) => {
|
|
|
5336
5622
|
}
|
|
5337
5623
|
return null;
|
|
5338
5624
|
};
|
|
5625
|
+
const applyDefaultToTruthyWhen = (whenName, propName) => {
|
|
5626
|
+
if (bindings.kind !== "destructured" || !bindings.defaults?.has(propName)) return whenName;
|
|
5627
|
+
if (whenName !== propName) return null;
|
|
5628
|
+
const defaultValue = literalToStaticValue(bindings.defaults.get(propName));
|
|
5629
|
+
if (defaultValue === null) return null;
|
|
5630
|
+
return defaultValue ? `${whenName} === undefined || ${whenName}` : whenName;
|
|
5631
|
+
};
|
|
5339
5632
|
const parseTestInfo = (test) => {
|
|
5340
5633
|
if (!test || typeof test !== "object") return null;
|
|
5341
5634
|
if (test.type === "Identifier" && bindings.kind === "destructured") {
|
|
5342
5635
|
const propAccess = readPropAccess(test);
|
|
5343
|
-
|
|
5344
|
-
|
|
5636
|
+
if (!propAccess) return null;
|
|
5637
|
+
const when = applyDefaultToTruthyWhen(propAccess.whenName, propAccess.propName);
|
|
5638
|
+
return when === null ? null : {
|
|
5639
|
+
when,
|
|
5345
5640
|
propName: propAccess.propName
|
|
5346
|
-
}
|
|
5641
|
+
};
|
|
5347
5642
|
}
|
|
5348
5643
|
if (isMemberExpression(test)) {
|
|
5349
5644
|
const propAccess = readPropAccess(test);
|
|
5350
|
-
|
|
5351
|
-
|
|
5645
|
+
if (!propAccess) return null;
|
|
5646
|
+
const when = applyDefaultToTruthyWhen(propAccess.whenName, propAccess.propName);
|
|
5647
|
+
return when === null ? null : {
|
|
5648
|
+
when,
|
|
5352
5649
|
propName: propAccess.propName
|
|
5353
|
-
}
|
|
5650
|
+
};
|
|
5354
5651
|
}
|
|
5355
5652
|
if (test.type === "UnaryExpression" && test.operator === "!" && test.argument) {
|
|
5356
5653
|
const propAccess = readPropAccess(test.argument);
|
|
5357
|
-
|
|
5358
|
-
|
|
5654
|
+
if (!propAccess) return null;
|
|
5655
|
+
const truthyWhen = applyDefaultToTruthyWhen(propAccess.whenName, propAccess.propName);
|
|
5656
|
+
if (truthyWhen === null) return null;
|
|
5657
|
+
return {
|
|
5658
|
+
when: truthyWhen === propAccess.whenName ? `!${truthyWhen}` : `!(${truthyWhen})`,
|
|
5359
5659
|
propName: propAccess.propName
|
|
5360
|
-
}
|
|
5660
|
+
};
|
|
5361
5661
|
}
|
|
5362
5662
|
if (test.type === "BinaryExpression" && (test.operator === "===" || test.operator === "!==")) {
|
|
5363
5663
|
const left = test.left;
|
|
5664
|
+
const operator = test.operator;
|
|
5364
5665
|
const getRhsValue = () => {
|
|
5365
5666
|
const rhsTyped = test.right;
|
|
5366
5667
|
if (rhsTyped.type === "Identifier" && rhsTyped.name === "undefined") return "undefined";
|
|
@@ -5368,12 +5669,28 @@ const createPropTestHelpers = (bindings) => {
|
|
|
5368
5669
|
if (rhs === null) return getMemberExpressionSource(test.right);
|
|
5369
5670
|
return JSON.stringify(rhs);
|
|
5370
5671
|
};
|
|
5672
|
+
const buildBinaryWhen = (propAccess, rhsValue) => {
|
|
5673
|
+
const base = `${propAccess.whenName} ${operator} ${rhsValue}`;
|
|
5674
|
+
if (bindings.kind !== "destructured" || !bindings.defaults?.has(propAccess.propName)) return base;
|
|
5675
|
+
if (propAccess.whenName !== propAccess.propName || rhsValue === "undefined") return null;
|
|
5676
|
+
const defaultValue = literalToStaticValue(bindings.defaults.get(propAccess.propName));
|
|
5677
|
+
if (defaultValue === null) return null;
|
|
5678
|
+
let rhsStatic;
|
|
5679
|
+
try {
|
|
5680
|
+
rhsStatic = JSON.parse(rhsValue);
|
|
5681
|
+
} catch {
|
|
5682
|
+
return null;
|
|
5683
|
+
}
|
|
5684
|
+
if (defaultValue !== rhsStatic) return base;
|
|
5685
|
+
return operator === "===" ? `${propAccess.whenName} === undefined || ${base}` : `${propAccess.whenName} !== undefined && ${base}`;
|
|
5686
|
+
};
|
|
5371
5687
|
if (bindings.kind === "destructured" && left.type === "Identifier") {
|
|
5372
5688
|
const propAccess = readPropAccess(left);
|
|
5373
5689
|
const rhsValue = getRhsValue();
|
|
5374
5690
|
if (!propAccess || rhsValue === null) return null;
|
|
5375
|
-
|
|
5376
|
-
|
|
5691
|
+
const when = buildBinaryWhen(propAccess, rhsValue);
|
|
5692
|
+
return when === null ? null : {
|
|
5693
|
+
when,
|
|
5377
5694
|
propName: propAccess.propName
|
|
5378
5695
|
};
|
|
5379
5696
|
}
|
|
@@ -5381,8 +5698,9 @@ const createPropTestHelpers = (bindings) => {
|
|
|
5381
5698
|
const propAccess = readPropAccess(left);
|
|
5382
5699
|
const rhsValue = getRhsValue();
|
|
5383
5700
|
if (!propAccess || rhsValue === null) return null;
|
|
5384
|
-
|
|
5385
|
-
|
|
5701
|
+
const when = buildBinaryWhen(propAccess, rhsValue);
|
|
5702
|
+
return when === null ? null : {
|
|
5703
|
+
when,
|
|
5386
5704
|
propName: propAccess.propName
|
|
5387
5705
|
};
|
|
5388
5706
|
}
|
|
@@ -8513,10 +8831,10 @@ function collectDeclPropNames(root, j, decl, filter) {
|
|
|
8513
8831
|
const addIfMatch = (name) => {
|
|
8514
8832
|
if (filter(name)) result.add(name);
|
|
8515
8833
|
};
|
|
8516
|
-
for (const when of Object.keys(decl.variantStyleKeys ?? {})) for (const p of parseVariantWhenToAst(j, when).props) addIfMatch(p);
|
|
8834
|
+
for (const when of Object.keys(decl.variantStyleKeys ?? {})) for (const p of parseVariantWhenToAst(j, when, void 0, void 0, decl.nonPropConditionRoots).props) addIfMatch(p);
|
|
8517
8835
|
for (const sf of decl.styleFnFromProps ?? []) {
|
|
8518
8836
|
addIfMatch(sf.jsxProp);
|
|
8519
|
-
if (sf.conditionWhen) for (const p of parseVariantWhenToAst(j, sf.conditionWhen).props) addIfMatch(p);
|
|
8837
|
+
if (sf.conditionWhen) for (const p of parseVariantWhenToAst(j, sf.conditionWhen, void 0, void 0, decl.nonPropConditionRoots).props) addIfMatch(p);
|
|
8520
8838
|
}
|
|
8521
8839
|
for (const isp of decl.inlineStyleProps ?? []) addIfMatch(isp.jsxProp ?? isp.prop);
|
|
8522
8840
|
for (const cv of decl.compoundVariants ?? []) if (cv.kind === "3branch" || cv.kind === "4branch") {
|
|
@@ -12070,8 +12388,9 @@ function collectStyledDeclsImpl(args) {
|
|
|
12070
12388
|
const key = prop.key.type === "Identifier" ? prop.key.name : prop.key.type === "StringLiteral" ? prop.key.value : null;
|
|
12071
12389
|
if (!key) continue;
|
|
12072
12390
|
const v = prop.value;
|
|
12073
|
-
|
|
12074
|
-
|
|
12391
|
+
const literalValue = literalStaticValueFromNode(v);
|
|
12392
|
+
if (literalValue !== void 0) {
|
|
12393
|
+
out.staticAttrs[key] = literalValue;
|
|
12075
12394
|
continue;
|
|
12076
12395
|
}
|
|
12077
12396
|
if (key === "as" && v.type === "Identifier" && v.name !== "undefined") {
|
|
@@ -13034,12 +13353,7 @@ function getAttrsParamInfo(params) {
|
|
|
13034
13353
|
};
|
|
13035
13354
|
}
|
|
13036
13355
|
function literalStaticValueFromNode(node) {
|
|
13037
|
-
|
|
13038
|
-
const typed = node;
|
|
13039
|
-
if (typed.type === "StringLiteral" || typed.type === "NumericLiteral") return typeof typed.value === "string" || typeof typed.value === "number" ? typed.value : void 0;
|
|
13040
|
-
if (typed.type === "BooleanLiteral") return typeof typed.value === "boolean" ? typed.value : void 0;
|
|
13041
|
-
if (typed.type === "Literal" && (typeof typed.value === "string" || typeof typed.value === "number" || typeof typed.value === "boolean")) return typed.value;
|
|
13042
|
-
if (typed.type === "TSAsExpression" || typed.type === "TSSatisfiesExpression") return literalStaticValueFromNode(typed.expression);
|
|
13356
|
+
return extractStaticLiteralValue(node, { allowCssTaggedTemplates: false });
|
|
13043
13357
|
}
|
|
13044
13358
|
function isStaticAttrExpression$1(node, attrsParamInfo) {
|
|
13045
13359
|
if (!node || typeof node !== "object") return false;
|
|
@@ -14521,10 +14835,13 @@ function tryHandleAnimation(args) {
|
|
|
14521
14835
|
for (let segmentIndex = 0; segmentIndex < segments.length; segmentIndex++) {
|
|
14522
14836
|
const tokens = segments[segmentIndex];
|
|
14523
14837
|
if (!tokens.length) return false;
|
|
14524
|
-
const
|
|
14525
|
-
|
|
14838
|
+
const nameIdx = tokens.findIndex((t) => {
|
|
14839
|
+
const slotMatch = t.match(/^__SC_EXPR_(\d+)__$/);
|
|
14840
|
+
return slotMatch ? getKeyframeFromSlot(Number(slotMatch[1])) !== null : false;
|
|
14841
|
+
});
|
|
14842
|
+
if (nameIdx === -1) return false;
|
|
14843
|
+
const m = tokens.splice(nameIdx, 1)[0].match(/^__SC_EXPR_(\d+)__$/);
|
|
14526
14844
|
const kf = getKeyframeFromSlot(Number(m[1]));
|
|
14527
|
-
if (!kf) return false;
|
|
14528
14845
|
animNames.push({
|
|
14529
14846
|
kind: "ident",
|
|
14530
14847
|
name: kf
|
|
@@ -17815,6 +18132,44 @@ function insertImportDeclarationNearStylex(root, decl) {
|
|
|
17815
18132
|
insertAfterLastImport(body, decl);
|
|
17816
18133
|
}
|
|
17817
18134
|
//#endregion
|
|
18135
|
+
//#region src/internal/utilities/inline-keyframes-liveness.ts
|
|
18136
|
+
function pruneUnusedInlineKeyframes(args) {
|
|
18137
|
+
const { state, emittedStyleValues, styledDecls } = args;
|
|
18138
|
+
const inlineKeyframes = state.inlineKeyframes;
|
|
18139
|
+
if (!inlineKeyframes || inlineKeyframes.size === 0) return;
|
|
18140
|
+
const referenced = collectReferencedInlineKeyframes(inlineKeyframes, emittedStyleValues);
|
|
18141
|
+
collectReferencedTransformedVariantKeyframes(inlineKeyframes, styledDecls, referenced);
|
|
18142
|
+
deleteUnreferencedInlineKeyframes(state, referenced);
|
|
18143
|
+
}
|
|
18144
|
+
function collectReferencedInlineKeyframes(inlineKeyframes, values) {
|
|
18145
|
+
const referenced = /* @__PURE__ */ new Set();
|
|
18146
|
+
for (const value of values) collectReferencedInlineKeyframeNames(inlineKeyframes, value, referenced);
|
|
18147
|
+
return referenced;
|
|
18148
|
+
}
|
|
18149
|
+
function collectReferencedTransformedVariantKeyframes(inlineKeyframes, styledDecls, referenced) {
|
|
18150
|
+
for (const decl of styledDecls) {
|
|
18151
|
+
if (decl.skipTransform) continue;
|
|
18152
|
+
for (const dimension of decl.variantDimensions ?? []) collectReferencedInlineKeyframeNames(inlineKeyframes, dimension.variants, referenced);
|
|
18153
|
+
for (const variant of decl.staticBooleanVariants ?? []) collectReferencedInlineKeyframeNames(inlineKeyframes, variant.styles, referenced);
|
|
18154
|
+
for (const combined of decl.callSiteCombinedStyles ?? []) collectReferencedInlineKeyframeNames(inlineKeyframes, combined.styles, referenced);
|
|
18155
|
+
}
|
|
18156
|
+
}
|
|
18157
|
+
function collectReferencedInlineKeyframeNames(inlineKeyframes, value, referenced) {
|
|
18158
|
+
const identifiers = /* @__PURE__ */ new Set();
|
|
18159
|
+
collectIdentifiers(value, identifiers);
|
|
18160
|
+
for (const name of identifiers) if (inlineKeyframes.has(name)) referenced.add(name);
|
|
18161
|
+
}
|
|
18162
|
+
function deleteUnreferencedInlineKeyframes(state, referenced) {
|
|
18163
|
+
const inlineKeyframes = state.inlineKeyframes;
|
|
18164
|
+
if (!inlineKeyframes) return;
|
|
18165
|
+
for (const name of inlineKeyframes.keys()) if (!referenced.has(name)) inlineKeyframes.delete(name);
|
|
18166
|
+
if (!state.inlineKeyframeNameMap) return;
|
|
18167
|
+
for (const [cssName, jsName] of state.inlineKeyframeNameMap.entries()) if (!inlineKeyframes.has(jsName)) {
|
|
18168
|
+
state.inlineKeyframeNameMap.delete(cssName);
|
|
18169
|
+
state.keyframesNames.delete(cssName);
|
|
18170
|
+
}
|
|
18171
|
+
}
|
|
18172
|
+
//#endregion
|
|
17818
18173
|
//#region src/internal/emit-styles.ts
|
|
17819
18174
|
/**
|
|
17820
18175
|
* CSS shorthands that must NEVER appear as property names in stylex.create() output.
|
|
@@ -18140,6 +18495,11 @@ function emitStylesAndImports(ctx) {
|
|
|
18140
18495
|
stylesDecl.leadingComments = deduped;
|
|
18141
18496
|
stylesDecl.comments = deduped;
|
|
18142
18497
|
}
|
|
18498
|
+
pruneUnusedInlineKeyframes({
|
|
18499
|
+
state: ctx,
|
|
18500
|
+
emittedStyleValues: nonEmptyStyleEntries.map(([, value]) => value),
|
|
18501
|
+
styledDecls
|
|
18502
|
+
});
|
|
18143
18503
|
const inlineKeyframeDecls = [];
|
|
18144
18504
|
if (ctx.inlineKeyframes && ctx.inlineKeyframes.size > 0) for (const [name, frames] of ctx.inlineKeyframes) {
|
|
18145
18505
|
const kfDecl = j.variableDeclaration("const", [j.variableDeclarator(j.identifier(name), j.callExpression(j.memberExpression(j.identifier("stylex"), j.identifier("keyframes")), [objectToAst(j, frames)]))]);
|
|
@@ -19966,7 +20326,10 @@ function buildStaticAttrsFromRecord(j, staticAttrs, options) {
|
|
|
19966
20326
|
}
|
|
19967
20327
|
function buildStaticAttrFromValue(j, key, value, options) {
|
|
19968
20328
|
const booleanTrueAsShorthand = options?.booleanTrueAsShorthand ?? true;
|
|
19969
|
-
if (typeof value === "string")
|
|
20329
|
+
if (typeof value === "string") {
|
|
20330
|
+
if (stringNeedsExpressionContainer(value)) return j.jsxAttribute(j.jsxIdentifier(key), j.jsxExpressionContainer(j.literal(value)));
|
|
20331
|
+
return j.jsxAttribute(j.jsxIdentifier(key), j.literal(value));
|
|
20332
|
+
}
|
|
19970
20333
|
if (typeof value === "boolean") return j.jsxAttribute(j.jsxIdentifier(key), value && booleanTrueAsShorthand ? null : j.jsxExpressionContainer(j.booleanLiteral(value)));
|
|
19971
20334
|
if (typeof value === "number") return j.jsxAttribute(j.jsxIdentifier(key), j.jsxExpressionContainer(j.literal(value)));
|
|
19972
20335
|
if (value === void 0) return j.jsxAttribute(j.jsxIdentifier(key), j.jsxExpressionContainer(j.identifier("undefined")));
|
|
@@ -19978,6 +20341,15 @@ function isStaticAttrExpression(value) {
|
|
|
19978
20341
|
return !!value && typeof value === "object" && typeof value.type === "string";
|
|
19979
20342
|
}
|
|
19980
20343
|
/**
|
|
20344
|
+
* Check if a string contains characters that require escaping in a JS string literal.
|
|
20345
|
+
* Such strings must be emitted as JSX expression containers (`attr={"value"}`) rather
|
|
20346
|
+
* than direct JSX string attributes (`attr="value"`), because JSX string attributes
|
|
20347
|
+
* don't interpret JS escape sequences - they're literal strings.
|
|
20348
|
+
*/
|
|
20349
|
+
function stringNeedsExpressionContainer(value) {
|
|
20350
|
+
return /[\u0000-\u001f\\]/.test(value);
|
|
20351
|
+
}
|
|
20352
|
+
/**
|
|
19981
20353
|
* Build all attrs from attrsInfo in the correct order:
|
|
19982
20354
|
* defaultAttrs, conditionalAttrs, invertedBoolAttrs, staticAttrs
|
|
19983
20355
|
*/
|
|
@@ -20459,7 +20831,7 @@ function buildVariantDimensionLookups(j, args) {
|
|
|
20459
20831
|
}
|
|
20460
20832
|
}
|
|
20461
20833
|
function hasStyleSourceOrder(d) {
|
|
20462
|
-
return !!(d.variantSourceOrder && Object.keys(d.variantSourceOrder).length > 0) || (d.pseudoAliasSelectors ?? []).some((entry) => entry.sourceOrder !== void 0);
|
|
20834
|
+
return !!(d.variantSourceOrder && Object.keys(d.variantSourceOrder).length > 0) || (d.pseudoAliasSelectors ?? []).some((entry) => entry.sourceOrder !== void 0) || (d.needsUseThemeHook ?? []).some((entry) => entry.sourceOrder !== void 0);
|
|
20463
20835
|
}
|
|
20464
20836
|
/**
|
|
20465
20837
|
* Sort ordered entries by source order and append them to styleArgs.
|
|
@@ -20653,7 +21025,8 @@ function buildVariantStyleExprs(opts) {
|
|
|
20653
21025
|
when: positiveWhen,
|
|
20654
21026
|
destructureProps,
|
|
20655
21027
|
booleanProps,
|
|
20656
|
-
...knownProps ? { knownProps } : {}
|
|
21028
|
+
...knownProps ? { knownProps } : {},
|
|
21029
|
+
nonPropRoots: d.nonPropConditionRoots
|
|
20657
21030
|
});
|
|
20658
21031
|
if (onNewDestructureProp && prevLengthRef && destructureProps) for (let i = prevLengthRef.value; i < destructureProps.length; i++) onNewDestructureProp(destructureProps[i]);
|
|
20659
21032
|
const isCurrentPositive = areEquivalentWhen(when, positiveWhen);
|
|
@@ -20668,7 +21041,8 @@ function buildVariantStyleExprs(opts) {
|
|
|
20668
21041
|
when,
|
|
20669
21042
|
destructureProps,
|
|
20670
21043
|
booleanProps,
|
|
20671
|
-
...knownProps ? { knownProps } : {}
|
|
21044
|
+
...knownProps ? { knownProps } : {},
|
|
21045
|
+
nonPropRoots: d.nonPropConditionRoots
|
|
20672
21046
|
});
|
|
20673
21047
|
if (onNewDestructureProp && prevLengthRef && destructureProps) for (let i = prevLengthRef.value; i < destructureProps.length; i++) onNewDestructureProp(destructureProps[i]);
|
|
20674
21048
|
const styleExpr = styleRef(j, stylesIdentifier, variantKey);
|
|
@@ -20684,7 +21058,8 @@ function buildVariantStyleExprs(opts) {
|
|
|
20684
21058
|
when,
|
|
20685
21059
|
destructureProps,
|
|
20686
21060
|
booleanProps,
|
|
20687
|
-
...knownProps ? { knownProps } : {}
|
|
21061
|
+
...knownProps ? { knownProps } : {},
|
|
21062
|
+
nonPropRoots: d.nonPropConditionRoots
|
|
20688
21063
|
});
|
|
20689
21064
|
const styleExpr = styleRef(j, stylesIdentifier, variantKey);
|
|
20690
21065
|
pushExpr(emitter.makeConditionalStyleExpr({
|
|
@@ -20698,7 +21073,7 @@ function buildVariantStyleExprs(opts) {
|
|
|
20698
21073
|
* Appends conditional style args driven by theme boolean props (e.g., `theme.isDark`).
|
|
20699
21074
|
* Returns `true` if the hook is needed (and calls `markNeedsUseThemeImport`).
|
|
20700
21075
|
*/
|
|
20701
|
-
function appendThemeBooleanStyleArgs(hooks, styleArgs, j, stylesIdentifier, markNeedsUseThemeImport) {
|
|
21076
|
+
function appendThemeBooleanStyleArgs(hooks, styleArgs, j, stylesIdentifier, markNeedsUseThemeImport, orderedEntries) {
|
|
20702
21077
|
if (!hooks || hooks.length === 0) return false;
|
|
20703
21078
|
markNeedsUseThemeImport();
|
|
20704
21079
|
for (const entry of hooks) {
|
|
@@ -20706,7 +21081,12 @@ function appendThemeBooleanStyleArgs(hooks, styleArgs, j, stylesIdentifier, mark
|
|
|
20706
21081
|
const trueExpr = entry.trueStyleKey ? styleRef(j, stylesIdentifier, entry.trueStyleKey) : j.identifier("undefined");
|
|
20707
21082
|
const falseExpr = entry.falseStyleKey ? styleRef(j, stylesIdentifier, entry.falseStyleKey) : j.identifier("undefined");
|
|
20708
21083
|
const condition = entry.conditionExpr ? cloneAstNode(entry.conditionExpr) : j.memberExpression(j.identifier("theme"), j.identifier(entry.themeProp));
|
|
20709
|
-
|
|
21084
|
+
const finalExpr = j.conditionalExpression(condition, trueExpr, falseExpr);
|
|
21085
|
+
if (orderedEntries && entry.sourceOrder !== void 0) orderedEntries.push({
|
|
21086
|
+
order: entry.sourceOrder,
|
|
21087
|
+
expr: finalExpr
|
|
21088
|
+
});
|
|
21089
|
+
else styleArgs.push(finalExpr);
|
|
20710
21090
|
}
|
|
20711
21091
|
return true;
|
|
20712
21092
|
}
|
|
@@ -20791,11 +21171,12 @@ function appendAllPseudoStyleArgs(d, styleArgs, j, stylesIdentifier, orderedEntr
|
|
|
20791
21171
|
* and emit-component.
|
|
20792
21172
|
*/
|
|
20793
21173
|
function buildAllVariantAndStyleExprs(opts) {
|
|
20794
|
-
const { d, emitter, j, stylesIdentifier, styleArgs, destructureProps, propDefaults, compoundVariantKeys, afterVariantStyleArgs, enableComplementaryMerging, buildCompoundVariantExpressions } = opts;
|
|
21174
|
+
const { d, emitter, j, stylesIdentifier, styleArgs, destructureProps, propDefaults, compoundVariantKeys, afterVariantStyleArgs, enableComplementaryMerging, markNeedsUseThemeImport, buildCompoundVariantExpressions } = opts;
|
|
20795
21175
|
const booleanProps = collectBooleanPropNames(d);
|
|
20796
21176
|
const knownProps = collectKnownConditionPropNames(emitter, d);
|
|
20797
21177
|
const hasSourceOrder = hasStyleSourceOrder(d);
|
|
20798
21178
|
const orderedEntries = [];
|
|
21179
|
+
const needsUseTheme = markNeedsUseThemeImport ? appendThemeBooleanStyleArgs(d.needsUseThemeHook, styleArgs, j, stylesIdentifier, markNeedsUseThemeImport, hasSourceOrder ? orderedEntries : void 0) : false;
|
|
20799
21180
|
buildVariantStyleExprs({
|
|
20800
21181
|
d,
|
|
20801
21182
|
emitter,
|
|
@@ -20834,6 +21215,7 @@ function buildAllVariantAndStyleExprs(opts) {
|
|
|
20834
21215
|
});
|
|
20835
21216
|
mergeOrderedEntries(orderedEntries, styleArgs);
|
|
20836
21217
|
if (afterVariantStyleArgs && afterVariantStyleArgs.length > 0) styleArgs.push(...afterVariantStyleArgs);
|
|
21218
|
+
return needsUseTheme;
|
|
20837
21219
|
}
|
|
20838
21220
|
/** Builds a `const theme = useTheme();` variable declaration. */
|
|
20839
21221
|
function buildUseThemeDeclaration(j, themeHookLocalName) {
|
|
@@ -22725,7 +23107,7 @@ function emitComponentWrappers(emitter) {
|
|
|
22725
23107
|
}
|
|
22726
23108
|
const needsUseTheme = appendThemeBooleanStyleArgs(d.needsUseThemeHook, styleArgs, j, stylesIdentifier, () => {
|
|
22727
23109
|
needsUseThemeImport = true;
|
|
22728
|
-
});
|
|
23110
|
+
}, hasSourceOrder ? orderedEntries : void 0);
|
|
22729
23111
|
for (const gp of appendAllPseudoStyleArgs(d, styleArgs, j, stylesIdentifier, hasSourceOrder ? orderedEntries : void 0)) if (!destructureProps.includes(gp)) {
|
|
22730
23112
|
destructureProps.push(gp);
|
|
22731
23113
|
styleOnlyConditionProps.add(gp);
|
|
@@ -24437,7 +24819,7 @@ function emitIntrinsicPolymorphicWrappers(ctx) {
|
|
|
24437
24819
|
}) : [];
|
|
24438
24820
|
const { beforeBase: extraStyleArgs, afterBase: extraStyleArgsAfterBase, afterVariants: afterVariantStyleArgs } = emitter.buildInterleavedExtraStyleArgs(d, propsArgExprs);
|
|
24439
24821
|
const styleArgs = buildInitialStyleArgs(j, stylesIdentifier, d, extraStyleArgs, extraStyleArgsAfterBase);
|
|
24440
|
-
buildAllVariantAndStyleExprs({
|
|
24822
|
+
const needsUseTheme = buildAllVariantAndStyleExprs({
|
|
24441
24823
|
d,
|
|
24442
24824
|
emitter,
|
|
24443
24825
|
j,
|
|
@@ -24447,6 +24829,7 @@ function emitIntrinsicPolymorphicWrappers(ctx) {
|
|
|
24447
24829
|
propDefaults,
|
|
24448
24830
|
compoundVariantKeys: collectCompoundVariantKeys(d.compoundVariants),
|
|
24449
24831
|
afterVariantStyleArgs,
|
|
24832
|
+
markNeedsUseThemeImport: () => ctx.markNeedsUseThemeImport(),
|
|
24450
24833
|
buildCompoundVariantExpressions
|
|
24451
24834
|
});
|
|
24452
24835
|
const isVoidTag = VOID_TAGS.has(tagName);
|
|
@@ -24470,6 +24853,7 @@ function emitIntrinsicPolymorphicWrappers(ctx) {
|
|
|
24470
24853
|
dynamicAttrs: d.attrsInfo?.dynamicAttrs ?? [],
|
|
24471
24854
|
staticAttrs: d.attrsInfo?.staticAttrs ?? {}
|
|
24472
24855
|
});
|
|
24856
|
+
const destructurePropsForPattern = needsUseTheme ? destructureProps.filter((name) => name !== "theme") : destructureProps;
|
|
24473
24857
|
const patternProps = emitter.buildDestructurePatternProps({
|
|
24474
24858
|
baseProps: [
|
|
24475
24859
|
...allowAsProp ? [j.property.from({
|
|
@@ -24484,7 +24868,7 @@ function emitIntrinsicPolymorphicWrappers(ctx) {
|
|
|
24484
24868
|
...allowStyleProp ? [ctx.patternProp("style", styleId)] : [],
|
|
24485
24869
|
...allowSxProp ? [ctx.patternProp("sx", sxId)] : []
|
|
24486
24870
|
],
|
|
24487
|
-
destructureProps,
|
|
24871
|
+
destructureProps: destructurePropsForPattern,
|
|
24488
24872
|
propDefaults,
|
|
24489
24873
|
includeRest: true,
|
|
24490
24874
|
restId
|
|
@@ -24504,7 +24888,7 @@ function emitIntrinsicPolymorphicWrappers(ctx) {
|
|
|
24504
24888
|
allowClassNameProp,
|
|
24505
24889
|
allowStyleProp,
|
|
24506
24890
|
allowSxProp,
|
|
24507
|
-
inlineStyleProps: [],
|
|
24891
|
+
inlineStyleProps: d.inlineStyleProps ?? [],
|
|
24508
24892
|
staticStyleExpr: attrsInfoWithoutForwardedAsStatic?.attrsStaticStyleExpr,
|
|
24509
24893
|
staticClassNameExpr,
|
|
24510
24894
|
isIntrinsicElement: false
|
|
@@ -24529,6 +24913,7 @@ function emitIntrinsicPolymorphicWrappers(ctx) {
|
|
|
24529
24913
|
childrenExpr: childrenId
|
|
24530
24914
|
});
|
|
24531
24915
|
const fnBodyStmts = [declStmt];
|
|
24916
|
+
if (needsUseTheme) fnBodyStmts.push(buildUseThemeDeclaration(j, emitter.themeHookLocalName));
|
|
24532
24917
|
if (merging.sxDecl) fnBodyStmts.push(merging.sxDecl);
|
|
24533
24918
|
fnBodyStmts.push(j.returnStatement(jsx));
|
|
24534
24919
|
const polymorphicFnTypeParams = emitTypes && allowAsProp ? buildPolymorphicTypeParams(j, tagName) : void 0;
|
|
@@ -24569,7 +24954,8 @@ function emitShouldForwardPropWrappers(ctx) {
|
|
|
24569
24954
|
for (const when of Object.keys(d.variantStyleKeys ?? {})) {
|
|
24570
24955
|
const { props } = emitter.collectConditionProps({
|
|
24571
24956
|
when,
|
|
24572
|
-
...knownConditionProps ? { knownProps: knownConditionProps } : {}
|
|
24957
|
+
...knownConditionProps ? { knownProps: knownConditionProps } : {},
|
|
24958
|
+
nonPropRoots: d.nonPropConditionRoots
|
|
24573
24959
|
});
|
|
24574
24960
|
for (const p of props) if (p) extraProps.add(p);
|
|
24575
24961
|
}
|
|
@@ -24691,12 +25077,12 @@ function emitShouldForwardPropWrappers(ctx) {
|
|
|
24691
25077
|
const propsArgExprs = d.extraStylexPropsArgs ? emitter.buildExtraStylexPropsExprEntries({ entries: d.extraStylexPropsArgs }) : [];
|
|
24692
25078
|
const { beforeBase: extraStyleArgs, afterBase: extraStyleArgsAfterBase, afterVariants: afterVariantStyleArgs } = emitter.buildInterleavedExtraStyleArgs(d, propsArgExprs);
|
|
24693
25079
|
const styleArgs = buildInitialStyleArgs(j, stylesIdentifier, d, extraStyleArgs, extraStyleArgsAfterBase);
|
|
24694
|
-
const needsUseTheme = appendThemeBooleanStyleArgs(d.needsUseThemeHook, styleArgs, j, stylesIdentifier, () => ctx.markNeedsUseThemeImport());
|
|
24695
25080
|
const compoundVariantKeys = collectCompoundVariantKeys(d.compoundVariants);
|
|
24696
25081
|
const booleanProps = collectBooleanPropNames(d);
|
|
24697
25082
|
const knownProps = collectKnownConditionPropNames(emitter, d);
|
|
24698
25083
|
const hasSourceOrder = hasStyleSourceOrder(d);
|
|
24699
25084
|
const orderedEntries = [];
|
|
25085
|
+
const needsUseTheme = appendThemeBooleanStyleArgs(d.needsUseThemeHook, styleArgs, j, stylesIdentifier, () => ctx.markNeedsUseThemeImport(), hasSourceOrder ? orderedEntries : void 0);
|
|
24700
25086
|
const pseudoGuardProps = appendAllPseudoStyleArgs(d, styleArgs, j, stylesIdentifier, hasSourceOrder ? orderedEntries : void 0);
|
|
24701
25087
|
buildVariantStyleExprs({
|
|
24702
25088
|
d,
|
|
@@ -24715,7 +25101,8 @@ function emitShouldForwardPropWrappers(ctx) {
|
|
|
24715
25101
|
if (compoundVariantKeys.has(when)) continue;
|
|
24716
25102
|
const { props } = emitter.collectConditionProps({
|
|
24717
25103
|
when,
|
|
24718
|
-
...knownProps ? { knownProps } : {}
|
|
25104
|
+
...knownProps ? { knownProps } : {},
|
|
25105
|
+
nonPropRoots: d.nonPropConditionRoots
|
|
24719
25106
|
});
|
|
24720
25107
|
for (const p of props) if (p && !dropProps.includes(p)) dropProps.push(p);
|
|
24721
25108
|
}
|
|
@@ -24726,7 +25113,8 @@ function emitShouldForwardPropWrappers(ctx) {
|
|
|
24726
25113
|
for (const extra of d.extraStylexPropsArgs) if (extra.when) {
|
|
24727
25114
|
const { props } = emitter.collectConditionProps({
|
|
24728
25115
|
when: extra.when,
|
|
24729
|
-
...knownProps ? { knownProps } : {}
|
|
25116
|
+
...knownProps ? { knownProps } : {},
|
|
25117
|
+
nonPropRoots: d.nonPropConditionRoots
|
|
24730
25118
|
});
|
|
24731
25119
|
for (const p of props) if (p && !destructureParts.includes(p)) destructureParts.push(p);
|
|
24732
25120
|
}
|
|
@@ -24760,7 +25148,8 @@ function emitShouldForwardPropWrappers(ctx) {
|
|
|
24760
25148
|
when: p.conditionWhen,
|
|
24761
25149
|
destructureProps: destructureParts,
|
|
24762
25150
|
booleanProps,
|
|
24763
|
-
...knownProps ? { knownProps } : {}
|
|
25151
|
+
...knownProps ? { knownProps } : {},
|
|
25152
|
+
nonPropRoots: d.nonPropConditionRoots
|
|
24764
25153
|
});
|
|
24765
25154
|
expr = emitter.makeConditionalStyleExpr({
|
|
24766
25155
|
cond,
|
|
@@ -25059,7 +25448,8 @@ function emitSimpleWithConfigWrappers(ctx) {
|
|
|
25059
25448
|
if (d.variantStyleKeys) for (const [when] of Object.entries(d.variantStyleKeys)) {
|
|
25060
25449
|
const { props } = emitter.collectConditionProps({
|
|
25061
25450
|
when,
|
|
25062
|
-
...knownProps ? { knownProps } : {}
|
|
25451
|
+
...knownProps ? { knownProps } : {},
|
|
25452
|
+
nonPropRoots: d.nonPropConditionRoots
|
|
25063
25453
|
});
|
|
25064
25454
|
for (const p of props) if (p) variantProps.add(p);
|
|
25065
25455
|
}
|
|
@@ -25073,7 +25463,8 @@ function emitSimpleWithConfigWrappers(ctx) {
|
|
|
25073
25463
|
if (!extra.when) continue;
|
|
25074
25464
|
const { props } = emitter.collectConditionProps({
|
|
25075
25465
|
when: extra.when,
|
|
25076
|
-
...knownProps ? { knownProps } : {}
|
|
25466
|
+
...knownProps ? { knownProps } : {},
|
|
25467
|
+
nonPropRoots: d.nonPropConditionRoots
|
|
25077
25468
|
});
|
|
25078
25469
|
for (const p of props) if (p) extraProps.add(p);
|
|
25079
25470
|
}
|
|
@@ -25389,8 +25780,7 @@ function emitSimpleExportedIntrinsicWrappers(ctx) {
|
|
|
25389
25780
|
}) : [];
|
|
25390
25781
|
const { beforeBase: extraStyleArgs, afterBase: extraStyleArgsAfterBase, afterVariants: afterVariantStyleArgs } = emitter.buildInterleavedExtraStyleArgs(d, propsArgExprs);
|
|
25391
25782
|
const styleArgs = buildInitialStyleArgs(j, stylesIdentifier, d, extraStyleArgs, extraStyleArgsAfterBase);
|
|
25392
|
-
const needsUseTheme =
|
|
25393
|
-
buildAllVariantAndStyleExprs({
|
|
25783
|
+
const needsUseTheme = buildAllVariantAndStyleExprs({
|
|
25394
25784
|
d,
|
|
25395
25785
|
emitter,
|
|
25396
25786
|
j,
|
|
@@ -25401,6 +25791,7 @@ function emitSimpleExportedIntrinsicWrappers(ctx) {
|
|
|
25401
25791
|
compoundVariantKeys: collectCompoundVariantKeys(d.compoundVariants),
|
|
25402
25792
|
afterVariantStyleArgs,
|
|
25403
25793
|
enableComplementaryMerging: true,
|
|
25794
|
+
markNeedsUseThemeImport: () => ctx.markNeedsUseThemeImport(),
|
|
25404
25795
|
buildCompoundVariantExpressions
|
|
25405
25796
|
});
|
|
25406
25797
|
for (const attr of d.attrsInfo?.defaultAttrs ?? []) if (destructureProps.includes(attr.jsxProp) && (typeof attr.value === "string" || typeof attr.value === "number")) propDefaults.set(attr.jsxProp, attr.value);
|
|
@@ -25668,7 +26059,7 @@ function collectPropsUsedOutsideExtraStyleConditionals(j, d, knownProps) {
|
|
|
25668
26059
|
if (name) used.add(name);
|
|
25669
26060
|
};
|
|
25670
26061
|
for (const [when] of Object.entries(d.variantStyleKeys ?? {})) {
|
|
25671
|
-
const parsed = parseVariantWhenToAst(j, when, void 0, knownProps);
|
|
26062
|
+
const parsed = parseVariantWhenToAst(j, when, void 0, knownProps, d.nonPropConditionRoots);
|
|
25672
26063
|
for (const prop of parsed.props) add(prop);
|
|
25673
26064
|
}
|
|
25674
26065
|
for (const dim of d.variantDimensions ?? []) {
|
|
@@ -26348,6 +26739,485 @@ function getTransformedComponentNames(ctx) {
|
|
|
26348
26739
|
return names && names.length > 0 ? names : void 0;
|
|
26349
26740
|
}
|
|
26350
26741
|
//#endregion
|
|
26742
|
+
//#region src/internal/transform-steps/inline-prop-conditional-css-helpers.ts
|
|
26743
|
+
/**
|
|
26744
|
+
* Inlines prop-conditional css`` helpers into consumers so their prop-dependent
|
|
26745
|
+
* styles are preserved. Helpers that cannot be safely inlined are left untouched
|
|
26746
|
+
* (their `${helper}` reference falls through to the existing mixin bail).
|
|
26747
|
+
*/
|
|
26748
|
+
function inlinePropConditionalCssHelpersStep(ctx) {
|
|
26749
|
+
const styledDecls = ctx.styledDecls;
|
|
26750
|
+
const cssHelperNames = ctx.cssHelpers?.cssHelperNames;
|
|
26751
|
+
if (!styledDecls || !cssHelperNames || cssHelperNames.size === 0) return CONTINUE;
|
|
26752
|
+
const declByLocalName = /* @__PURE__ */ new Map();
|
|
26753
|
+
for (const decl of styledDecls) declByLocalName.set(decl.localName, decl);
|
|
26754
|
+
const fullyInlinedHelpers = /* @__PURE__ */ new Set();
|
|
26755
|
+
const retainedHelpers = /* @__PURE__ */ new Set();
|
|
26756
|
+
for (const consumer of styledDecls) {
|
|
26757
|
+
if (consumer.isCssHelper) continue;
|
|
26758
|
+
for (const reference of collectInlinableHelperReferences(consumer, declByLocalName)) {
|
|
26759
|
+
const helperDecl = reference.helperDecl;
|
|
26760
|
+
if (!inlinablePropDependentDeclaration(helperDecl) || inlineWouldContend(reference, consumer)) {
|
|
26761
|
+
retainedHelpers.add(helperDecl.localName);
|
|
26762
|
+
continue;
|
|
26763
|
+
}
|
|
26764
|
+
if (inlineHelperReference(consumer, reference)) {
|
|
26765
|
+
fullyInlinedHelpers.add(helperDecl.localName);
|
|
26766
|
+
ctx.markChanged();
|
|
26767
|
+
} else retainedHelpers.add(helperDecl.localName);
|
|
26768
|
+
}
|
|
26769
|
+
}
|
|
26770
|
+
for (const decl of styledDecls) {
|
|
26771
|
+
if (!decl.isCssHelper) continue;
|
|
26772
|
+
for (const rule of decl.rules) for (const declaration of rule.declarations) {
|
|
26773
|
+
const referencedName = referencedHelperName(declaration, decl);
|
|
26774
|
+
if (referencedName && declByLocalName.get(referencedName)?.isCssHelper) retainedHelpers.add(referencedName);
|
|
26775
|
+
}
|
|
26776
|
+
}
|
|
26777
|
+
for (const decl of styledDecls) if (decl.isCssHelper && fullyInlinedHelpers.has(decl.localName) && !retainedHelpers.has(decl.localName)) decl.rules = [];
|
|
26778
|
+
return CONTINUE;
|
|
26779
|
+
}
|
|
26780
|
+
/**
|
|
26781
|
+
* Finds property-less `${helper}` references (single-slot identifier interpolations)
|
|
26782
|
+
* that sit in the consumer's top-level `&` rule. Only top-level references are returned;
|
|
26783
|
+
* references nested under selectors/at-rules are left for the existing bail path because
|
|
26784
|
+
* merging a helper's own declarations under another selector is not generally safe.
|
|
26785
|
+
*/
|
|
26786
|
+
function collectInlinableHelperReferences(consumer, declByLocalName) {
|
|
26787
|
+
const references = [];
|
|
26788
|
+
for (const rule of consumer.rules) {
|
|
26789
|
+
if (rule.selector.trim() !== "&" || rule.atRuleStack.length > 0) continue;
|
|
26790
|
+
for (const referenceDecl of rule.declarations) {
|
|
26791
|
+
const helperName = referencedHelperName(referenceDecl, consumer);
|
|
26792
|
+
if (!helperName) continue;
|
|
26793
|
+
const helperDecl = declByLocalName.get(helperName);
|
|
26794
|
+
if (helperDecl?.isCssHelper) references.push({
|
|
26795
|
+
rule,
|
|
26796
|
+
referenceDecl,
|
|
26797
|
+
helperDecl
|
|
26798
|
+
});
|
|
26799
|
+
}
|
|
26800
|
+
}
|
|
26801
|
+
return references;
|
|
26802
|
+
}
|
|
26803
|
+
/** Returns the helper identifier name if `d` is a standalone `${identifier}` interpolation. */
|
|
26804
|
+
function referencedHelperName(d, consumer) {
|
|
26805
|
+
if (d.property || d.value.kind !== "interpolated") return null;
|
|
26806
|
+
const parts = d.value.parts;
|
|
26807
|
+
if (parts.length !== 1 || parts[0]?.kind !== "slot") return null;
|
|
26808
|
+
const expr = consumer.templateExpressions[parts[0].slotId];
|
|
26809
|
+
return expr?.type === "Identifier" && typeof expr.name === "string" ? expr.name : null;
|
|
26810
|
+
}
|
|
26811
|
+
/**
|
|
26812
|
+
* Returns the helper's single prop-dependent declaration when the helper is structurally
|
|
26813
|
+
* inlinable — otherwise null. Inlinable means it carries a prop-based interpolation (the case
|
|
26814
|
+
* the mixin path bails on) and is shaped so its declarations can be spliced into the consumer's
|
|
26815
|
+
* `&` block:
|
|
26816
|
+
*
|
|
26817
|
+
* - private (not exported / preserved for cross-file use),
|
|
26818
|
+
* - every rule is the top-level `&` block (no nested selectors, no at-rules),
|
|
26819
|
+
* - no chained mixin references (a property-less `${otherMixin}` / `${parts.reset}` slot)
|
|
26820
|
+
* — those compose as separate style keys whose ordering we cannot preserve by splicing, and
|
|
26821
|
+
* - exactly one prop-dependent declaration. That single dynamic entry is the case the mixin
|
|
26822
|
+
* path bails on, and it has no intra-helper ordering ambiguity. Zero means a plain mixin
|
|
26823
|
+
* (handled by the shared-style-key path); two or more dynamic entries are emitted as
|
|
26824
|
+
* styleFns/variants whose precedence depends on per-declaration source order, which the
|
|
26825
|
+
* splice (which stamps the single reference order on every inlined declaration) cannot
|
|
26826
|
+
* preserve.
|
|
26827
|
+
*
|
|
26828
|
+
* Whether the inline is *override-safe* is decided per reference by `inlineWouldContend`, which
|
|
26829
|
+
* is independent of how the value lowers.
|
|
26830
|
+
*/
|
|
26831
|
+
function inlinablePropDependentDeclaration(helperDecl) {
|
|
26832
|
+
if (helperDecl.isExported || helperDecl.preserveCssHelperDeclaration) return null;
|
|
26833
|
+
let propDependentDeclaration = null;
|
|
26834
|
+
let propDependentCount = 0;
|
|
26835
|
+
for (const rule of helperDecl.rules) {
|
|
26836
|
+
if (rule.selector.trim() !== "&" || rule.atRuleStack.length > 0) return null;
|
|
26837
|
+
for (const declaration of rule.declarations) {
|
|
26838
|
+
if (!declaration.property) return null;
|
|
26839
|
+
if (declarationReadsProps(declaration, helperDecl.templateExpressions)) {
|
|
26840
|
+
propDependentCount += 1;
|
|
26841
|
+
propDependentDeclaration = declaration;
|
|
26842
|
+
}
|
|
26843
|
+
}
|
|
26844
|
+
}
|
|
26845
|
+
return propDependentCount === 1 ? propDependentDeclaration : null;
|
|
26846
|
+
}
|
|
26847
|
+
/**
|
|
26848
|
+
* Splicing is override-safe only when the set of properties the helper sets is disjoint from
|
|
26849
|
+
* every other declaration in the merged block. When a property has a single contributor, however
|
|
26850
|
+
* the inlined value lowers (variant or style function) the result matches styled-components; when
|
|
26851
|
+
* two declarations contend, their relative precedence depends on the lowering path, which the
|
|
26852
|
+
* splice cannot guarantee — so bail. This checks:
|
|
26853
|
+
*
|
|
26854
|
+
* - helper-internal overlap: two helper declarations touching the same leaf (e.g.
|
|
26855
|
+
* `color: ${dyn}; color: red`) have order-dependent precedence the splice may invert;
|
|
26856
|
+
* - helper-vs-consumer overlap: any helper property (its prop-dependent one *or* a static, which
|
|
26857
|
+
* could override an earlier dynamic consumer declaration) overlapping a consumer declaration;
|
|
26858
|
+
* - any property-less consumer declaration — a sibling mixin (`${reset}`) or dynamic block whose
|
|
26859
|
+
* emitted properties are unknown here.
|
|
26860
|
+
*
|
|
26861
|
+
* Every consumer rule is scanned (not just the reference's), so a later top-level `&` rule or a
|
|
26862
|
+
* nested selector/at-rule the consumer authors is included.
|
|
26863
|
+
*/
|
|
26864
|
+
function inlineWouldContend(reference, consumer) {
|
|
26865
|
+
const helperDeclarations = reference.helperDecl.rules.flatMap((rule) => rule.declarations);
|
|
26866
|
+
for (let i = 0; i < helperDeclarations.length; i += 1) for (let j = i + 1; j < helperDeclarations.length; j += 1) if (propertiesConflict(helperDeclarations[i].property, helperDeclarations[j].property)) return true;
|
|
26867
|
+
for (const rule of consumer.rules) for (const declaration of rule.declarations) {
|
|
26868
|
+
if (declaration === reference.referenceDecl) continue;
|
|
26869
|
+
if (!declaration.property) return true;
|
|
26870
|
+
if (helperDeclarations.some((hd) => propertiesConflict(hd.property, declaration.property))) return true;
|
|
26871
|
+
}
|
|
26872
|
+
return false;
|
|
26873
|
+
}
|
|
26874
|
+
/**
|
|
26875
|
+
* Whether two CSS properties can set a common atomic StyleX longhand — i.e. they are equal, or
|
|
26876
|
+
* one is a shorthand whose expansion overlaps the other. Each property is expanded to its set of
|
|
26877
|
+
* atomic leaf longhands (a shorthand to its leaves, a longhand to itself) and the sets are
|
|
26878
|
+
* intersected. This correctly distinguishes overlapping families (`borderColor` vs
|
|
26879
|
+
* `borderTopColor`) from disjoint ones (`borderRadius` vs `border`, `width` vs `padding`).
|
|
26880
|
+
*
|
|
26881
|
+
* Backstop for shorthands the leaf table does not model: most CSS shorthands name their longhands
|
|
26882
|
+
* with their own camelCase prefix (`font` → `fontVariantNumeric`, `overscrollBehavior` →
|
|
26883
|
+
* `overscrollBehaviorX`). When the table cannot vouch for *both* properties (one is neither a known
|
|
26884
|
+
* shorthand nor a known leaf), a word-prefix relationship is treated as contention so an unmodeled
|
|
26885
|
+
* shorthand/longhand pair conservatively bails. Fully-modeled families skip this (so `border` and
|
|
26886
|
+
* `borderRadius`, which share the `border` prefix but are disjoint, still inline).
|
|
26887
|
+
*/
|
|
26888
|
+
function propertiesConflict(a, b) {
|
|
26889
|
+
const stylexA = cssPropertyToStylexProp(a);
|
|
26890
|
+
const stylexB = cssPropertyToStylexProp(b);
|
|
26891
|
+
const leavesA = leafLonghands(stylexA);
|
|
26892
|
+
const leavesB = leafLonghands(stylexB);
|
|
26893
|
+
for (const leaf of leavesA) if (leavesB.has(leaf)) return true;
|
|
26894
|
+
if (isModeledProperty(stylexA) && isModeledProperty(stylexB)) return false;
|
|
26895
|
+
return isWordPrefix(stylexA, stylexB) || isWordPrefix(stylexB, stylexA);
|
|
26896
|
+
}
|
|
26897
|
+
/** Whether the leaf table reliably classifies a StyleX property (a known shorthand or leaf). */
|
|
26898
|
+
function isModeledProperty(stylexProp) {
|
|
26899
|
+
return KNOWN_SHORTHANDS.has(stylexProp) || KNOWN_LEAVES.has(stylexProp);
|
|
26900
|
+
}
|
|
26901
|
+
/** Whether `prefix` is `full` truncated at a camelCase word boundary (`font` ⊂ `fontVariant`). */
|
|
26902
|
+
function isWordPrefix(prefix, full) {
|
|
26903
|
+
if (full.length <= prefix.length || !full.startsWith(prefix)) return false;
|
|
26904
|
+
const next = full[prefix.length] ?? "";
|
|
26905
|
+
return next !== next.toLowerCase() && next === next.toUpperCase();
|
|
26906
|
+
}
|
|
26907
|
+
/**
|
|
26908
|
+
* The atomic physical StyleX longhands a property can set. A shorthand expands to its leaves; a
|
|
26909
|
+
* longhand resolves to itself. A logical longhand resolves to *both* physical sides on its axis
|
|
26910
|
+
* (e.g. `marginInlineStart` → `marginLeft` and `marginRight`) because the writing direction is
|
|
26911
|
+
* unknown — in RTL `inline-start` is the right side — so a logical declaration conservatively
|
|
26912
|
+
* contends with either physical side it could map to.
|
|
26913
|
+
*/
|
|
26914
|
+
function leafLonghands(stylexProp) {
|
|
26915
|
+
const canonical = CSS_ALIASES[stylexProp] ?? stylexProp;
|
|
26916
|
+
if (LOGICAL_LEAF_TO_PHYSICAL[canonical]) return new Set(LOGICAL_LEAF_TO_PHYSICAL[canonical]);
|
|
26917
|
+
const leaves = SHORTHAND_LEAVES[canonical] ?? LOGICAL_TO_PHYSICAL[canonical] ?? [canonical];
|
|
26918
|
+
return new Set(leaves.flatMap(physicalLeaves));
|
|
26919
|
+
}
|
|
26920
|
+
/**
|
|
26921
|
+
* Legacy CSS property aliases → their canonical StyleX property. `cssPropertyToStylexProp` only
|
|
26922
|
+
* camelCases authored names, so an alias and its modern name read as disjoint leaves unless
|
|
26923
|
+
* collapsed here. This is the standard set of legacy name aliases: `word-wrap` for `overflow-wrap`;
|
|
26924
|
+
* `grid-gap`/`grid-row-gap`/`grid-column-gap` for `gap`/`row-gap`/`column-gap`; and
|
|
26925
|
+
* `page-break-before`/`page-break-after`/`page-break-inside` for `break-before`/`break-after`/
|
|
26926
|
+
* `break-inside`.
|
|
26927
|
+
*/
|
|
26928
|
+
const CSS_ALIASES = {
|
|
26929
|
+
wordWrap: "overflowWrap",
|
|
26930
|
+
gridGap: "gap",
|
|
26931
|
+
gridRowGap: "rowGap",
|
|
26932
|
+
gridColumnGap: "columnGap",
|
|
26933
|
+
pageBreakBefore: "breakBefore",
|
|
26934
|
+
pageBreakAfter: "breakAfter",
|
|
26935
|
+
pageBreakInside: "breakInside"
|
|
26936
|
+
};
|
|
26937
|
+
/**
|
|
26938
|
+
* Maps a logical atomic longhand to every physical longhand it could map to under any writing
|
|
26939
|
+
* mode and direction. Flow-relative sides are not just RTL-swapped: in vertical writing modes the
|
|
26940
|
+
* block axis is horizontal and the inline axis is vertical, so a logical side can land on *any*
|
|
26941
|
+
* physical side. The mapping is therefore the full physical family, which is conservative but safe.
|
|
26942
|
+
*/
|
|
26943
|
+
function physicalLeaves(stylexProp) {
|
|
26944
|
+
return LOGICAL_LEAF_TO_PHYSICAL[stylexProp] ?? [stylexProp];
|
|
26945
|
+
}
|
|
26946
|
+
const PHYSICAL_SIDES = [
|
|
26947
|
+
"Top",
|
|
26948
|
+
"Right",
|
|
26949
|
+
"Bottom",
|
|
26950
|
+
"Left"
|
|
26951
|
+
];
|
|
26952
|
+
const BORDER_KINDS = [
|
|
26953
|
+
"Width",
|
|
26954
|
+
"Style",
|
|
26955
|
+
"Color"
|
|
26956
|
+
];
|
|
26957
|
+
const ALL_INSET_SIDES = [
|
|
26958
|
+
"top",
|
|
26959
|
+
"right",
|
|
26960
|
+
"bottom",
|
|
26961
|
+
"left"
|
|
26962
|
+
];
|
|
26963
|
+
const ALL_RADIUS_CORNERS = [
|
|
26964
|
+
"borderTopLeftRadius",
|
|
26965
|
+
"borderTopRightRadius",
|
|
26966
|
+
"borderBottomLeftRadius",
|
|
26967
|
+
"borderBottomRightRadius"
|
|
26968
|
+
];
|
|
26969
|
+
/** Logical atomic longhand → every physical longhand it could map to under any writing mode. */
|
|
26970
|
+
const LOGICAL_LEAF_TO_PHYSICAL = {
|
|
26971
|
+
inlineSize: ["width", "height"],
|
|
26972
|
+
blockSize: ["width", "height"],
|
|
26973
|
+
minInlineSize: ["minWidth", "minHeight"],
|
|
26974
|
+
minBlockSize: ["minWidth", "minHeight"],
|
|
26975
|
+
maxInlineSize: ["maxWidth", "maxHeight"],
|
|
26976
|
+
maxBlockSize: ["maxWidth", "maxHeight"],
|
|
26977
|
+
containIntrinsicInlineSize: ["containIntrinsicWidth", "containIntrinsicHeight"],
|
|
26978
|
+
containIntrinsicBlockSize: ["containIntrinsicWidth", "containIntrinsicHeight"],
|
|
26979
|
+
overflowBlock: ["overflowX", "overflowY"],
|
|
26980
|
+
overflowInline: ["overflowX", "overflowY"],
|
|
26981
|
+
overscrollBehaviorBlock: ["overscrollBehaviorX", "overscrollBehaviorY"],
|
|
26982
|
+
overscrollBehaviorInline: ["overscrollBehaviorX", "overscrollBehaviorY"],
|
|
26983
|
+
borderStartStartRadius: ALL_RADIUS_CORNERS,
|
|
26984
|
+
borderStartEndRadius: ALL_RADIUS_CORNERS,
|
|
26985
|
+
borderEndStartRadius: ALL_RADIUS_CORNERS,
|
|
26986
|
+
borderEndEndRadius: ALL_RADIUS_CORNERS
|
|
26987
|
+
};
|
|
26988
|
+
for (const axis of ["Block", "Inline"]) for (const end of ["Start", "End"]) {
|
|
26989
|
+
for (const base of [
|
|
26990
|
+
"margin",
|
|
26991
|
+
"padding",
|
|
26992
|
+
"scrollMargin",
|
|
26993
|
+
"scrollPadding"
|
|
26994
|
+
]) LOGICAL_LEAF_TO_PHYSICAL[`${base}${axis}${end}`] = PHYSICAL_SIDES.map((side) => `${base}${side}`);
|
|
26995
|
+
LOGICAL_LEAF_TO_PHYSICAL[`inset${axis}${end}`] = ALL_INSET_SIDES;
|
|
26996
|
+
for (const kind of BORDER_KINDS) LOGICAL_LEAF_TO_PHYSICAL[`border${axis}${end}${kind}`] = PHYSICAL_SIDES.map((side) => `border${side}${kind}`);
|
|
26997
|
+
}
|
|
26998
|
+
/**
|
|
26999
|
+
* StyleX shorthand → its atomic leaf longhands (in physical form). Used to decide whether two
|
|
27000
|
+
* declarations contend for the same property. Mid-level shorthands (`borderTop`, `borderColor`,
|
|
27001
|
+
* `borderBlock`) are included so intersection captures partial overlap (e.g. `border` vs
|
|
27002
|
+
* `borderTopColor`). Directional families (margin/padding/inset/border) are generated for both
|
|
27003
|
+
* their physical and logical names; logical leaves are normalized to physical via `toPhysicalLeaf`.
|
|
27004
|
+
*/
|
|
27005
|
+
const SHORTHAND_LEAVES = {
|
|
27006
|
+
gap: ["rowGap", "columnGap"],
|
|
27007
|
+
overflow: ["overflowX", "overflowY"],
|
|
27008
|
+
overscrollBehavior: ["overscrollBehaviorX", "overscrollBehaviorY"],
|
|
27009
|
+
containIntrinsicSize: ["containIntrinsicWidth", "containIntrinsicHeight"],
|
|
27010
|
+
textEmphasis: ["textEmphasisStyle", "textEmphasisColor"],
|
|
27011
|
+
mask: [
|
|
27012
|
+
"maskImage",
|
|
27013
|
+
"maskMode",
|
|
27014
|
+
"maskRepeat",
|
|
27015
|
+
"maskPosition",
|
|
27016
|
+
"maskClip",
|
|
27017
|
+
"maskOrigin",
|
|
27018
|
+
"maskSize",
|
|
27019
|
+
"maskComposite"
|
|
27020
|
+
],
|
|
27021
|
+
offset: [
|
|
27022
|
+
"offsetPath",
|
|
27023
|
+
"offsetDistance",
|
|
27024
|
+
"offsetRotate",
|
|
27025
|
+
"offsetAnchor",
|
|
27026
|
+
"offsetPosition"
|
|
27027
|
+
],
|
|
27028
|
+
borderRadius: [
|
|
27029
|
+
"borderTopLeftRadius",
|
|
27030
|
+
"borderTopRightRadius",
|
|
27031
|
+
"borderBottomRightRadius",
|
|
27032
|
+
"borderBottomLeftRadius"
|
|
27033
|
+
],
|
|
27034
|
+
borderImage: [
|
|
27035
|
+
"borderImageSource",
|
|
27036
|
+
"borderImageSlice",
|
|
27037
|
+
"borderImageWidth",
|
|
27038
|
+
"borderImageOutset",
|
|
27039
|
+
"borderImageRepeat"
|
|
27040
|
+
],
|
|
27041
|
+
outline: [
|
|
27042
|
+
"outlineWidth",
|
|
27043
|
+
"outlineStyle",
|
|
27044
|
+
"outlineColor"
|
|
27045
|
+
],
|
|
27046
|
+
font: [
|
|
27047
|
+
"fontStyle",
|
|
27048
|
+
"fontVariant",
|
|
27049
|
+
"fontWeight",
|
|
27050
|
+
"fontStretch",
|
|
27051
|
+
"fontSize",
|
|
27052
|
+
"lineHeight",
|
|
27053
|
+
"fontFamily"
|
|
27054
|
+
],
|
|
27055
|
+
background: [
|
|
27056
|
+
"backgroundColor",
|
|
27057
|
+
"backgroundImage",
|
|
27058
|
+
"backgroundPositionX",
|
|
27059
|
+
"backgroundPositionY",
|
|
27060
|
+
"backgroundSize",
|
|
27061
|
+
"backgroundRepeat",
|
|
27062
|
+
"backgroundOrigin",
|
|
27063
|
+
"backgroundClip",
|
|
27064
|
+
"backgroundAttachment"
|
|
27065
|
+
],
|
|
27066
|
+
backgroundPosition: ["backgroundPositionX", "backgroundPositionY"],
|
|
27067
|
+
flex: [
|
|
27068
|
+
"flexGrow",
|
|
27069
|
+
"flexShrink",
|
|
27070
|
+
"flexBasis"
|
|
27071
|
+
],
|
|
27072
|
+
flexFlow: ["flexDirection", "flexWrap"],
|
|
27073
|
+
placeItems: ["alignItems", "justifyItems"],
|
|
27074
|
+
placeContent: ["alignContent", "justifyContent"],
|
|
27075
|
+
placeSelf: ["alignSelf", "justifySelf"],
|
|
27076
|
+
gridArea: [
|
|
27077
|
+
"gridRowStart",
|
|
27078
|
+
"gridColumnStart",
|
|
27079
|
+
"gridRowEnd",
|
|
27080
|
+
"gridColumnEnd"
|
|
27081
|
+
],
|
|
27082
|
+
gridColumn: ["gridColumnStart", "gridColumnEnd"],
|
|
27083
|
+
gridRow: ["gridRowStart", "gridRowEnd"],
|
|
27084
|
+
gridTemplate: [
|
|
27085
|
+
"gridTemplateRows",
|
|
27086
|
+
"gridTemplateColumns",
|
|
27087
|
+
"gridTemplateAreas"
|
|
27088
|
+
],
|
|
27089
|
+
grid: [
|
|
27090
|
+
"gridTemplateRows",
|
|
27091
|
+
"gridTemplateColumns",
|
|
27092
|
+
"gridTemplateAreas",
|
|
27093
|
+
"gridAutoRows",
|
|
27094
|
+
"gridAutoColumns",
|
|
27095
|
+
"gridAutoFlow"
|
|
27096
|
+
],
|
|
27097
|
+
columns: ["columnWidth", "columnCount"],
|
|
27098
|
+
columnRule: [
|
|
27099
|
+
"columnRuleWidth",
|
|
27100
|
+
"columnRuleStyle",
|
|
27101
|
+
"columnRuleColor"
|
|
27102
|
+
],
|
|
27103
|
+
transition: [
|
|
27104
|
+
"transitionProperty",
|
|
27105
|
+
"transitionDuration",
|
|
27106
|
+
"transitionTimingFunction",
|
|
27107
|
+
"transitionDelay"
|
|
27108
|
+
],
|
|
27109
|
+
animation: [
|
|
27110
|
+
"animationName",
|
|
27111
|
+
"animationDuration",
|
|
27112
|
+
"animationTimingFunction",
|
|
27113
|
+
"animationDelay",
|
|
27114
|
+
"animationIterationCount",
|
|
27115
|
+
"animationDirection",
|
|
27116
|
+
"animationFillMode",
|
|
27117
|
+
"animationPlayState"
|
|
27118
|
+
],
|
|
27119
|
+
textDecoration: [
|
|
27120
|
+
"textDecorationLine",
|
|
27121
|
+
"textDecorationStyle",
|
|
27122
|
+
"textDecorationColor",
|
|
27123
|
+
"textDecorationThickness"
|
|
27124
|
+
],
|
|
27125
|
+
whiteSpace: ["whiteSpaceCollapse", "textWrapMode"],
|
|
27126
|
+
textWrap: ["textWrapMode", "textWrapStyle"],
|
|
27127
|
+
listStyle: [
|
|
27128
|
+
"listStyleType",
|
|
27129
|
+
"listStylePosition",
|
|
27130
|
+
"listStyleImage"
|
|
27131
|
+
]
|
|
27132
|
+
};
|
|
27133
|
+
const borderLeaf = (side, kind) => `border${side}${kind}`;
|
|
27134
|
+
const ALL_BORDER_LEAVES = PHYSICAL_SIDES.flatMap((side) => BORDER_KINDS.map((kind) => borderLeaf(side, kind)));
|
|
27135
|
+
for (const base of [
|
|
27136
|
+
"margin",
|
|
27137
|
+
"padding",
|
|
27138
|
+
"scrollMargin",
|
|
27139
|
+
"scrollPadding"
|
|
27140
|
+
]) {
|
|
27141
|
+
const allSides = PHYSICAL_SIDES.map((side) => `${base}${side}`);
|
|
27142
|
+
SHORTHAND_LEAVES[base] = allSides;
|
|
27143
|
+
SHORTHAND_LEAVES[`${base}Block`] = allSides;
|
|
27144
|
+
SHORTHAND_LEAVES[`${base}Inline`] = allSides;
|
|
27145
|
+
}
|
|
27146
|
+
SHORTHAND_LEAVES.inset = ALL_INSET_SIDES;
|
|
27147
|
+
SHORTHAND_LEAVES.insetBlock = ALL_INSET_SIDES;
|
|
27148
|
+
SHORTHAND_LEAVES.insetInline = ALL_INSET_SIDES;
|
|
27149
|
+
SHORTHAND_LEAVES.border = [...ALL_BORDER_LEAVES, ...SHORTHAND_LEAVES.borderImage];
|
|
27150
|
+
SHORTHAND_LEAVES.borderBlock = ALL_BORDER_LEAVES;
|
|
27151
|
+
SHORTHAND_LEAVES.borderInline = ALL_BORDER_LEAVES;
|
|
27152
|
+
for (const side of PHYSICAL_SIDES) SHORTHAND_LEAVES[`border${side}`] = BORDER_KINDS.map((kind) => borderLeaf(side, kind));
|
|
27153
|
+
for (const kind of BORDER_KINDS) {
|
|
27154
|
+
const allOfKind = PHYSICAL_SIDES.map((side) => borderLeaf(side, kind));
|
|
27155
|
+
SHORTHAND_LEAVES[`border${kind}`] = allOfKind;
|
|
27156
|
+
SHORTHAND_LEAVES[`borderBlock${kind}`] = allOfKind;
|
|
27157
|
+
SHORTHAND_LEAVES[`borderInline${kind}`] = allOfKind;
|
|
27158
|
+
}
|
|
27159
|
+
for (const axis of ["Block", "Inline"]) for (const end of ["Start", "End"]) SHORTHAND_LEAVES[`border${axis}${end}`] = ALL_BORDER_LEAVES;
|
|
27160
|
+
const KNOWN_SHORTHANDS = new Set(Object.keys(SHORTHAND_LEAVES));
|
|
27161
|
+
const KNOWN_LEAVES = /* @__PURE__ */ new Set();
|
|
27162
|
+
for (const leaves of Object.values(SHORTHAND_LEAVES)) for (const leaf of leaves) KNOWN_LEAVES.add(leaf);
|
|
27163
|
+
for (const leaves of Object.values(LOGICAL_LEAF_TO_PHYSICAL)) for (const leaf of leaves) KNOWN_LEAVES.add(leaf);
|
|
27164
|
+
/** True when a declaration's interpolated value reads a non-theme component prop. */
|
|
27165
|
+
function declarationReadsProps(declaration, templateExpressions) {
|
|
27166
|
+
if (declaration.value.kind !== "interpolated") return false;
|
|
27167
|
+
for (const part of declaration.value.parts) if (part.kind === "slot" && expressionReadsNonThemeProps(templateExpressions[part.slotId])) return true;
|
|
27168
|
+
return false;
|
|
27169
|
+
}
|
|
27170
|
+
/** Mirrors the mixin-bail detection: an arrow/function interpolation that reads non-theme props. */
|
|
27171
|
+
function expressionReadsNonThemeProps(expr) {
|
|
27172
|
+
const node = expr;
|
|
27173
|
+
if (!node || node.type !== "ArrowFunctionExpression" && node.type !== "FunctionExpression") return false;
|
|
27174
|
+
const propsUsed = new Set([...collectPropsFromArrowFn(node), ...collectPropsFromArrowFnDestructured(node)]);
|
|
27175
|
+
propsUsed.delete("theme");
|
|
27176
|
+
return propsUsed.size > 0;
|
|
27177
|
+
}
|
|
27178
|
+
/**
|
|
27179
|
+
* Splices the helper's `&`-block declarations into the consumer at the reference site,
|
|
27180
|
+
* remapping the helper's interpolation slots onto freshly-appended consumer template
|
|
27181
|
+
* expressions. Returns false (without mutating) when the reference is no longer present.
|
|
27182
|
+
*/
|
|
27183
|
+
function inlineHelperReference(consumer, reference) {
|
|
27184
|
+
const { rule, referenceDecl, helperDecl } = reference;
|
|
27185
|
+
const declIndex = rule.declarations.indexOf(referenceDecl);
|
|
27186
|
+
if (declIndex === -1) return false;
|
|
27187
|
+
const slotOffset = consumer.templateExpressions.length;
|
|
27188
|
+
const inheritedSourceOrder = referenceDecl.sourceOrder;
|
|
27189
|
+
const inlinedDecls = helperDecl.rules.flatMap((helperRule) => helperRule.declarations.map((d) => remapDeclaration(d, slotOffset, inheritedSourceOrder)));
|
|
27190
|
+
for (const expr of helperDecl.templateExpressions) consumer.templateExpressions.push(cloneAstNode(expr));
|
|
27191
|
+
rule.declarations.splice(declIndex, 1, ...inlinedDecls);
|
|
27192
|
+
return true;
|
|
27193
|
+
}
|
|
27194
|
+
/** Deep-clones a CSS declaration, offsetting every interpolation slot id by `slotOffset`. */
|
|
27195
|
+
function remapDeclaration(d, slotOffset, sourceOrder) {
|
|
27196
|
+
const value = d.value.kind === "interpolated" ? {
|
|
27197
|
+
kind: "interpolated",
|
|
27198
|
+
parts: d.value.parts.map((part) => part.kind === "slot" ? {
|
|
27199
|
+
kind: "slot",
|
|
27200
|
+
slotId: part.slotId + slotOffset
|
|
27201
|
+
} : {
|
|
27202
|
+
kind: "static",
|
|
27203
|
+
value: part.value
|
|
27204
|
+
})
|
|
27205
|
+
} : {
|
|
27206
|
+
kind: "static",
|
|
27207
|
+
value: d.value.value
|
|
27208
|
+
};
|
|
27209
|
+
return {
|
|
27210
|
+
...d,
|
|
27211
|
+
value,
|
|
27212
|
+
valueRaw: offsetPlaceholders(d.valueRaw, slotOffset),
|
|
27213
|
+
sourceOrder
|
|
27214
|
+
};
|
|
27215
|
+
}
|
|
27216
|
+
/** Rewrites `__SC_EXPR_<n>__` placeholders in a raw value string by adding `slotOffset`. */
|
|
27217
|
+
function offsetPlaceholders(valueRaw, slotOffset) {
|
|
27218
|
+
return valueRaw.replace(/__SC_EXPR_(\d+)__/g, (_, n) => `__SC_EXPR_${Number(n) + slotOffset}__`);
|
|
27219
|
+
}
|
|
27220
|
+
//#endregion
|
|
26351
27221
|
//#region src/internal/lower-rules/slot-utils.ts
|
|
26352
27222
|
/**
|
|
26353
27223
|
* Locate the slot interpolation in a `${...}` value and return its
|
|
@@ -26772,8 +27642,45 @@ function tryResolveConditionalValue(node, ctx) {
|
|
|
26772
27642
|
const buildRuntimeCallResult = () => runtimeCallState.info ? {
|
|
26773
27643
|
type: "runtimeCallOnly",
|
|
26774
27644
|
resolveCallContext: runtimeCallState.info.resolveCallContext,
|
|
26775
|
-
resolveCallResult: runtimeCallState.info.resolveCallResult
|
|
27645
|
+
resolveCallResult: runtimeCallState.info.resolveCallResult,
|
|
27646
|
+
...runtimeCallState.info.cssValueText ? { cssValueText: runtimeCallState.info.cssValueText } : {}
|
|
26776
27647
|
} : null;
|
|
27648
|
+
const markAsRuntimeCall = (call) => {
|
|
27649
|
+
runtimeCallState.info = {
|
|
27650
|
+
resolveCallContext: {
|
|
27651
|
+
callSiteFilePath: ctx.filePath,
|
|
27652
|
+
calleeImportedName: "<local>",
|
|
27653
|
+
calleeSource: {
|
|
27654
|
+
kind: "specifier",
|
|
27655
|
+
value: ctx.filePath
|
|
27656
|
+
},
|
|
27657
|
+
args: [],
|
|
27658
|
+
...call.loc?.start ? { loc: {
|
|
27659
|
+
line: call.loc.start.line,
|
|
27660
|
+
column: call.loc.start.column
|
|
27661
|
+
} } : {}
|
|
27662
|
+
},
|
|
27663
|
+
resolveCallResult: { preserveRuntimeCall: true }
|
|
27664
|
+
};
|
|
27665
|
+
};
|
|
27666
|
+
const markFirstRuntimeCallInBranch = (branch) => {
|
|
27667
|
+
const pending = [branch];
|
|
27668
|
+
const seen = /* @__PURE__ */ new Set();
|
|
27669
|
+
while (pending.length > 0) {
|
|
27670
|
+
const current = pending.pop();
|
|
27671
|
+
if (!current || typeof current !== "object" || seen.has(current)) continue;
|
|
27672
|
+
seen.add(current);
|
|
27673
|
+
if (isCallExpressionNode(current)) {
|
|
27674
|
+
markAsRuntimeCall(current);
|
|
27675
|
+
return;
|
|
27676
|
+
}
|
|
27677
|
+
const node = current;
|
|
27678
|
+
if (node.type === "BinaryExpression" || node.type === "LogicalExpression") pending.push(node.left, node.right);
|
|
27679
|
+
else if (node.type === "TemplateLiteral") pending.push(...node.expressions ?? []);
|
|
27680
|
+
else if (node.type === "ConditionalExpression") pending.push(node.test, node.consequent, node.alternate);
|
|
27681
|
+
else if (node.expression) pending.push(node.expression);
|
|
27682
|
+
}
|
|
27683
|
+
};
|
|
26777
27684
|
const body = getFunctionBodyExpr(expr);
|
|
26778
27685
|
if (!body || body.type !== "ConditionalExpression") return null;
|
|
26779
27686
|
const checkThemeBooleanTest = (test) => {
|
|
@@ -26820,93 +27727,41 @@ function tryResolveConditionalValue(node, ctx) {
|
|
|
26820
27727
|
}
|
|
26821
27728
|
return null;
|
|
26822
27729
|
};
|
|
26823
|
-
const resolveThemeBranchValue = (branch) => {
|
|
26824
|
-
const themeInfo = resolveThemeFromMemberExpr(branch);
|
|
26825
|
-
if (!themeInfo) return null;
|
|
26826
|
-
const res = (ctx.resolveValueOptional ?? ctx.resolveValue)({
|
|
26827
|
-
kind: "theme",
|
|
26828
|
-
path: themeInfo.path,
|
|
26829
|
-
filePath: ctx.filePath,
|
|
26830
|
-
loc: getNodeLocStart(branch) ?? void 0
|
|
26831
|
-
});
|
|
26832
|
-
if (!res) return null;
|
|
26833
|
-
const astNode = parseExpr(ctx.api, res.expr);
|
|
26834
|
-
if (!astNode) return null;
|
|
26835
|
-
return {
|
|
26836
|
-
astNode,
|
|
26837
|
-
imports: res.imports
|
|
26838
|
-
};
|
|
26839
|
-
};
|
|
26840
|
-
const themeBoolInfo = checkThemeBooleanTest(body.test);
|
|
26841
|
-
if (themeBoolInfo && node.css.property) {
|
|
26842
|
-
const { consequent, alternate } = body;
|
|
26843
|
-
const trueBranch = themeBoolInfo.isNegated ? alternate : consequent;
|
|
26844
|
-
const falseBranch = themeBoolInfo.isNegated ? consequent : alternate;
|
|
26845
|
-
const trueRaw = literalToStaticValue(trueBranch);
|
|
26846
|
-
const falseRaw = literalToStaticValue(falseBranch);
|
|
26847
|
-
let trueValue = trueRaw !== null && typeof trueRaw !== "boolean" ? trueRaw : null;
|
|
26848
|
-
let falseValue = falseRaw !== null && typeof falseRaw !== "boolean" ? falseRaw : null;
|
|
26849
|
-
const trueImports = [];
|
|
26850
|
-
const falseImports = [];
|
|
26851
|
-
if (trueValue === null) {
|
|
26852
|
-
const resolved = resolveThemeBranchValue(trueBranch);
|
|
26853
|
-
if (resolved) {
|
|
26854
|
-
trueValue = resolved.astNode;
|
|
26855
|
-
trueImports.push(...resolved.imports);
|
|
26856
|
-
}
|
|
26857
|
-
}
|
|
26858
|
-
if (falseValue === null) {
|
|
26859
|
-
const resolved = resolveThemeBranchValue(falseBranch);
|
|
26860
|
-
if (resolved) {
|
|
26861
|
-
falseValue = resolved.astNode;
|
|
26862
|
-
falseImports.push(...resolved.imports);
|
|
26863
|
-
}
|
|
26864
|
-
}
|
|
26865
|
-
if (trueValue !== null && falseValue !== null) return {
|
|
26866
|
-
type: "splitThemeBooleanVariants",
|
|
26867
|
-
cssProp: node.css.property,
|
|
26868
|
-
themeProp: themeBoolInfo.themeProp,
|
|
26869
|
-
trueValue,
|
|
26870
|
-
falseValue,
|
|
26871
|
-
trueImports,
|
|
26872
|
-
falseImports
|
|
26873
|
-
};
|
|
26874
|
-
const inlineStyleFallback = tryBuildThemeBooleanInlineStyleFallback({
|
|
26875
|
-
trueValue,
|
|
26876
|
-
falseValue,
|
|
26877
|
-
trueImports,
|
|
26878
|
-
falseImports,
|
|
26879
|
-
trueBranch,
|
|
26880
|
-
falseBranch,
|
|
26881
|
-
themeBoolInfo,
|
|
26882
|
-
cssProp: node.css.property,
|
|
26883
|
-
paramName,
|
|
26884
|
-
info
|
|
26885
|
-
});
|
|
26886
|
-
if (inlineStyleFallback) return inlineStyleFallback;
|
|
26887
|
-
}
|
|
26888
27730
|
const expectedUsage = node.css.property ? "create" : "props";
|
|
26889
|
-
const branchToExpr = (b) => {
|
|
27731
|
+
const branchToExpr = (b, mode = "default") => {
|
|
27732
|
+
const resolveValue = mode === "optional" ? ctx.resolveValueOptional ?? ctx.resolveValue : ctx.resolveValue;
|
|
27733
|
+
const resolverCtx = mode === "optional" ? {
|
|
27734
|
+
...ctx,
|
|
27735
|
+
resolveValue,
|
|
27736
|
+
resolveCall: ctx.resolveCallOptional ?? ctx.resolveCall
|
|
27737
|
+
} : ctx;
|
|
26890
27738
|
const v = literalToStaticValue(b);
|
|
26891
27739
|
if (v !== null) {
|
|
26892
27740
|
if (typeof v === "boolean") return null;
|
|
26893
27741
|
return {
|
|
26894
27742
|
usage: "create",
|
|
26895
27743
|
expr: typeof v === "string" ? JSON.stringify(v) : String(v),
|
|
26896
|
-
imports: []
|
|
27744
|
+
imports: [],
|
|
27745
|
+
...typeof v === "string" ? { cssValueText: v } : {}
|
|
26897
27746
|
};
|
|
26898
27747
|
}
|
|
26899
27748
|
if (!b || typeof b !== "object") return null;
|
|
26900
27749
|
if (b.type === "BinaryExpression") {
|
|
26901
27750
|
const binary = b;
|
|
26902
27751
|
if (isCssCalcOperator$1(binary.operator)) {
|
|
26903
|
-
const left = branchToExpr(binary.left);
|
|
26904
|
-
const right = branchToExpr(binary.right);
|
|
26905
|
-
if (left && right && left.usage === expectedUsage && right.usage === expectedUsage && (left.imports.length > 0 || right.imports.length > 0) && isCssCalcSafeOperand(left) && isCssCalcSafeOperand(right))
|
|
26906
|
-
|
|
26907
|
-
|
|
26908
|
-
|
|
26909
|
-
|
|
27752
|
+
const left = branchToExpr(binary.left, mode);
|
|
27753
|
+
const right = branchToExpr(binary.right, mode);
|
|
27754
|
+
if (left && right && left.usage === expectedUsage && right.usage === expectedUsage && (left.imports.length > 0 || right.imports.length > 0) && isCssCalcSafeOperand(left) && isCssCalcSafeOperand(right)) {
|
|
27755
|
+
if (left.dynamicArgUsage || right.dynamicArgUsage) {
|
|
27756
|
+
markFirstRuntimeCallInBranch(left.dynamicArgUsage ? binary.left : binary.right);
|
|
27757
|
+
return null;
|
|
27758
|
+
}
|
|
27759
|
+
return {
|
|
27760
|
+
usage: expectedUsage,
|
|
27761
|
+
expr: buildCssCalcExprSource(left, binary.operator, right),
|
|
27762
|
+
imports: [...left.imports, ...right.imports]
|
|
27763
|
+
};
|
|
27764
|
+
}
|
|
26910
27765
|
}
|
|
26911
27766
|
}
|
|
26912
27767
|
const callHasThemeArg = (call) => (call.arguments ?? []).some((arg) => {
|
|
@@ -26921,28 +27776,17 @@ function tryResolveConditionalValue(node, ctx) {
|
|
|
26921
27776
|
}
|
|
26922
27777
|
return false;
|
|
26923
27778
|
});
|
|
26924
|
-
const markAsRuntimeCall = (call) => {
|
|
26925
|
-
runtimeCallState.info = {
|
|
26926
|
-
resolveCallContext: {
|
|
26927
|
-
callSiteFilePath: ctx.filePath,
|
|
26928
|
-
calleeImportedName: "<local>",
|
|
26929
|
-
calleeSource: {
|
|
26930
|
-
kind: "specifier",
|
|
26931
|
-
value: ctx.filePath
|
|
26932
|
-
},
|
|
26933
|
-
args: [],
|
|
26934
|
-
...call.loc?.start ? { loc: {
|
|
26935
|
-
line: call.loc.start.line,
|
|
26936
|
-
column: call.loc.start.column
|
|
26937
|
-
} } : {}
|
|
26938
|
-
},
|
|
26939
|
-
resolveCallResult: { preserveRuntimeCall: true }
|
|
26940
|
-
};
|
|
26941
|
-
};
|
|
26942
27779
|
const resolveCallExpr = (call, cssProperty) => {
|
|
26943
|
-
const res = resolveImportedHelperCall(call,
|
|
27780
|
+
const res = resolveImportedHelperCall(call, resolverCtx, propsParamName, cssProperty, themeBindingName);
|
|
26944
27781
|
if (res.kind === "resolved") {
|
|
26945
|
-
if ("expr" in res.result)
|
|
27782
|
+
if ("expr" in res.result) {
|
|
27783
|
+
if ("preserveRuntimeCall" in res.result && res.result.preserveRuntimeCall) runtimeCallState.info = {
|
|
27784
|
+
resolveCallContext: res.resolveCallContext,
|
|
27785
|
+
resolveCallResult: res.resolveCallResult,
|
|
27786
|
+
cssValueText: res.result.expr
|
|
27787
|
+
};
|
|
27788
|
+
return res.result;
|
|
27789
|
+
}
|
|
26946
27790
|
if ("preserveRuntimeCall" in res.result && res.result.preserveRuntimeCall) {
|
|
26947
27791
|
runtimeCallState.info = {
|
|
26948
27792
|
resolveCallContext: res.resolveCallContext,
|
|
@@ -26954,10 +27798,17 @@ function tryResolveConditionalValue(node, ctx) {
|
|
|
26954
27798
|
if (isCallExpressionNode(call.callee)) {
|
|
26955
27799
|
const inner = call.callee;
|
|
26956
27800
|
const outerArgs = call.arguments ?? [];
|
|
26957
|
-
if (outerArgs.length === 1 && outerArgs[0]
|
|
26958
|
-
const innerRes = resolveImportedHelperCall(inner,
|
|
27801
|
+
if (outerArgs.length === 1 && isCurrentCurriedHelperContextArg(outerArgs[0], propsParamName, themeBindingName)) {
|
|
27802
|
+
const innerRes = resolveImportedHelperCall(inner, resolverCtx, propsParamName, cssProperty, themeBindingName);
|
|
26959
27803
|
if (innerRes.kind === "resolved") {
|
|
26960
|
-
if ("expr" in innerRes.result)
|
|
27804
|
+
if ("expr" in innerRes.result) {
|
|
27805
|
+
if ("preserveRuntimeCall" in innerRes.result && innerRes.result.preserveRuntimeCall) runtimeCallState.info = {
|
|
27806
|
+
resolveCallContext: innerRes.resolveCallContext,
|
|
27807
|
+
resolveCallResult: innerRes.resolveCallResult,
|
|
27808
|
+
cssValueText: innerRes.result.expr
|
|
27809
|
+
};
|
|
27810
|
+
return innerRes.result;
|
|
27811
|
+
}
|
|
26961
27812
|
if ("preserveRuntimeCall" in innerRes.result && innerRes.result.preserveRuntimeCall) {
|
|
26962
27813
|
runtimeCallState.info = {
|
|
26963
27814
|
resolveCallContext: innerRes.resolveCallContext,
|
|
@@ -26971,9 +27822,10 @@ function tryResolveConditionalValue(node, ctx) {
|
|
|
26971
27822
|
if (callHasThemeArg(call)) markAsRuntimeCall(call);
|
|
26972
27823
|
return null;
|
|
26973
27824
|
};
|
|
27825
|
+
let templateHasDynamicArgUsage = false;
|
|
26974
27826
|
const templateResult = resolveTemplateLiteralExpressions(b, (expr) => {
|
|
26975
27827
|
const themeInfo = resolveThemeFromMemberExpr(expr);
|
|
26976
|
-
if (themeInfo) return
|
|
27828
|
+
if (themeInfo) return resolveValue({
|
|
26977
27829
|
kind: "theme",
|
|
26978
27830
|
path: themeInfo.path,
|
|
26979
27831
|
filePath: ctx.filePath,
|
|
@@ -26981,6 +27833,10 @@ function tryResolveConditionalValue(node, ctx) {
|
|
|
26981
27833
|
}) ?? null;
|
|
26982
27834
|
if (isCallExpressionNode(expr)) {
|
|
26983
27835
|
const callRes = resolveCallExpr(expr, node.css.property);
|
|
27836
|
+
if (callRes?.dynamicArgUsage) {
|
|
27837
|
+
templateHasDynamicArgUsage = true;
|
|
27838
|
+
markAsRuntimeCall(expr);
|
|
27839
|
+
}
|
|
26984
27840
|
return callRes ? {
|
|
26985
27841
|
expr: callRes.expr,
|
|
26986
27842
|
imports: callRes.imports
|
|
@@ -26988,22 +27844,29 @@ function tryResolveConditionalValue(node, ctx) {
|
|
|
26988
27844
|
}
|
|
26989
27845
|
return null;
|
|
26990
27846
|
});
|
|
26991
|
-
if (templateResult)
|
|
26992
|
-
|
|
26993
|
-
|
|
26994
|
-
|
|
27847
|
+
if (templateResult) {
|
|
27848
|
+
if (templateHasDynamicArgUsage && runtimeCallState.info) runtimeCallState.info.cssValueText = templateResult.expr;
|
|
27849
|
+
return {
|
|
27850
|
+
usage: "create",
|
|
27851
|
+
...templateResult,
|
|
27852
|
+
cssValueText: templateResult.expr,
|
|
27853
|
+
...templateHasDynamicArgUsage ? { dynamicArgUsage: "call" } : {}
|
|
27854
|
+
};
|
|
27855
|
+
}
|
|
26995
27856
|
if (isCallExpressionNode(b)) {
|
|
26996
27857
|
const resolved = resolveCallExpr(b, node.css.property);
|
|
26997
27858
|
if (resolved) return {
|
|
26998
27859
|
usage: isAdapterResultCssValue(resolved, node.css.property) ? "create" : "props",
|
|
26999
27860
|
expr: resolved.expr,
|
|
27000
|
-
imports: resolved.imports
|
|
27861
|
+
imports: resolved.imports,
|
|
27862
|
+
cssValueText: resolved.expr,
|
|
27863
|
+
...resolved.dynamicArgUsage ? { dynamicArgUsage: resolved.dynamicArgUsage } : {}
|
|
27001
27864
|
};
|
|
27002
27865
|
return null;
|
|
27003
27866
|
}
|
|
27004
27867
|
const themeInfo = resolveThemeFromMemberExpr(b);
|
|
27005
27868
|
if (themeInfo) {
|
|
27006
|
-
const res =
|
|
27869
|
+
const res = resolveValue({
|
|
27007
27870
|
kind: "theme",
|
|
27008
27871
|
path: themeInfo.path,
|
|
27009
27872
|
filePath: ctx.filePath,
|
|
@@ -27013,14 +27876,15 @@ function tryResolveConditionalValue(node, ctx) {
|
|
|
27013
27876
|
return {
|
|
27014
27877
|
usage: expectedUsage,
|
|
27015
27878
|
expr: res.expr,
|
|
27016
|
-
imports: res.imports
|
|
27879
|
+
imports: res.imports,
|
|
27880
|
+
cssValueText: res.expr
|
|
27017
27881
|
};
|
|
27018
27882
|
}
|
|
27019
27883
|
const importedInfo = extractRootAndPath(b);
|
|
27020
27884
|
if (importedInfo) {
|
|
27021
27885
|
const imp = ctx.resolveImport(importedInfo.rootName, importedInfo.rootNode);
|
|
27022
27886
|
if (imp) {
|
|
27023
|
-
const res =
|
|
27887
|
+
const res = resolveValue({
|
|
27024
27888
|
kind: "importedValue",
|
|
27025
27889
|
importedName: imp.importedName,
|
|
27026
27890
|
source: imp.source,
|
|
@@ -27031,7 +27895,8 @@ function tryResolveConditionalValue(node, ctx) {
|
|
|
27031
27895
|
if (res) return {
|
|
27032
27896
|
usage: expectedUsage,
|
|
27033
27897
|
expr: res.expr,
|
|
27034
|
-
imports: res.imports
|
|
27898
|
+
imports: res.imports,
|
|
27899
|
+
cssValueText: res.expr
|
|
27035
27900
|
};
|
|
27036
27901
|
}
|
|
27037
27902
|
}
|
|
@@ -27040,6 +27905,106 @@ function tryResolveConditionalValue(node, ctx) {
|
|
|
27040
27905
|
const getBranch = (value) => {
|
|
27041
27906
|
return branchToExpr(value);
|
|
27042
27907
|
};
|
|
27908
|
+
const getBranchOptional = (value) => {
|
|
27909
|
+
return branchToExpr(value, "optional");
|
|
27910
|
+
};
|
|
27911
|
+
const isEmptyCssInterpolationBranch = (value) => isEmptyCssBranch(value);
|
|
27912
|
+
const resolveThemeBooleanStyleValue = (branch) => {
|
|
27913
|
+
if (isEmptyCssBranch(branch)) return null;
|
|
27914
|
+
const raw = literalToStaticValue(branch);
|
|
27915
|
+
if (raw !== null && typeof raw !== "boolean") return {
|
|
27916
|
+
value: raw,
|
|
27917
|
+
imports: [],
|
|
27918
|
+
...typeof raw === "string" ? { cssValueText: raw } : {}
|
|
27919
|
+
};
|
|
27920
|
+
const themeInfo = resolveThemeFromMemberExpr(branch);
|
|
27921
|
+
if (themeInfo) {
|
|
27922
|
+
const res = (ctx.resolveValueOptional ?? ctx.resolveValue)({
|
|
27923
|
+
kind: "theme",
|
|
27924
|
+
path: themeInfo.path,
|
|
27925
|
+
filePath: ctx.filePath,
|
|
27926
|
+
loc: getNodeLocStart(branch) ?? void 0
|
|
27927
|
+
});
|
|
27928
|
+
if (!res) return null;
|
|
27929
|
+
const astNode = parseExpr(ctx.api, res.expr);
|
|
27930
|
+
return astNode ? {
|
|
27931
|
+
value: astNode,
|
|
27932
|
+
imports: res.imports,
|
|
27933
|
+
cssValueText: res.expr
|
|
27934
|
+
} : null;
|
|
27935
|
+
}
|
|
27936
|
+
const resolved = getBranchOptional(branch);
|
|
27937
|
+
if (!resolved || resolved.usage !== "create") return null;
|
|
27938
|
+
if (resolved.dynamicArgUsage) {
|
|
27939
|
+
if (isCallExpressionNode(branch)) markAsRuntimeCall(branch);
|
|
27940
|
+
return null;
|
|
27941
|
+
}
|
|
27942
|
+
const astNode = parseExpr(ctx.api, resolved.expr);
|
|
27943
|
+
return astNode ? {
|
|
27944
|
+
value: astNode,
|
|
27945
|
+
imports: resolved.imports,
|
|
27946
|
+
cssValueText: resolved.cssValueText ?? resolved.expr
|
|
27947
|
+
} : null;
|
|
27948
|
+
};
|
|
27949
|
+
const themeBoolInfo = checkThemeBooleanTest(body.test);
|
|
27950
|
+
if (themeBoolInfo && node.css.property) {
|
|
27951
|
+
const { consequent, alternate } = body;
|
|
27952
|
+
const trueBranch = themeBoolInfo.isNegated ? alternate : consequent;
|
|
27953
|
+
const falseBranch = themeBoolInfo.isNegated ? consequent : alternate;
|
|
27954
|
+
let runtimeCallBranch = null;
|
|
27955
|
+
const noteRuntimeCallBranch = (branch, before) => {
|
|
27956
|
+
if (runtimeCallState.info === before) return;
|
|
27957
|
+
runtimeCallBranch = runtimeCallBranch && runtimeCallBranch !== branch ? "both" : branch;
|
|
27958
|
+
};
|
|
27959
|
+
const beforeTrueResolve = runtimeCallState.info;
|
|
27960
|
+
const trueResolved = resolveThemeBooleanStyleValue(trueBranch);
|
|
27961
|
+
noteRuntimeCallBranch("true", beforeTrueResolve);
|
|
27962
|
+
const beforeFalseResolve = runtimeCallState.info;
|
|
27963
|
+
const falseResolved = resolveThemeBooleanStyleValue(falseBranch);
|
|
27964
|
+
noteRuntimeCallBranch("false", beforeFalseResolve);
|
|
27965
|
+
const trueValue = trueResolved?.value ?? null;
|
|
27966
|
+
const falseValue = falseResolved?.value ?? null;
|
|
27967
|
+
const trueImports = trueResolved?.imports ?? [];
|
|
27968
|
+
const falseImports = falseResolved?.imports ?? [];
|
|
27969
|
+
const trueCssValueText = trueResolved?.cssValueText;
|
|
27970
|
+
const falseCssValueText = falseResolved?.cssValueText;
|
|
27971
|
+
if (trueValue !== null && falseValue !== null) {
|
|
27972
|
+
const runtimeCallInfo = runtimeCallState.info;
|
|
27973
|
+
return {
|
|
27974
|
+
type: "splitThemeBooleanVariants",
|
|
27975
|
+
cssProp: node.css.property,
|
|
27976
|
+
themeProp: themeBoolInfo.themeProp,
|
|
27977
|
+
trueValue,
|
|
27978
|
+
falseValue,
|
|
27979
|
+
trueImports,
|
|
27980
|
+
falseImports,
|
|
27981
|
+
...trueCssValueText ? { trueCssValueText } : {},
|
|
27982
|
+
...falseCssValueText ? { falseCssValueText } : {},
|
|
27983
|
+
...runtimeCallInfo?.resolveCallResult ? { runtimeResolveCallResult: runtimeCallInfo.resolveCallResult } : {},
|
|
27984
|
+
...runtimeCallInfo?.cssValueText ? { runtimeCssValueText: runtimeCallInfo.cssValueText } : {}
|
|
27985
|
+
};
|
|
27986
|
+
}
|
|
27987
|
+
if (trueValue === null !== (falseValue === null) && isEmptyCssInterpolationBranch(trueValue === null ? trueBranch : falseBranch)) return null;
|
|
27988
|
+
const inlineStyleFallback = tryBuildThemeBooleanInlineStyleFallback({
|
|
27989
|
+
trueValue,
|
|
27990
|
+
falseValue,
|
|
27991
|
+
trueImports,
|
|
27992
|
+
falseImports,
|
|
27993
|
+
trueBranch,
|
|
27994
|
+
falseBranch,
|
|
27995
|
+
themeBoolInfo,
|
|
27996
|
+
cssProp: node.css.property,
|
|
27997
|
+
paramName,
|
|
27998
|
+
info
|
|
27999
|
+
});
|
|
28000
|
+
if (inlineStyleFallback) {
|
|
28001
|
+
if (inlineStyleFallback.type === "splitThemeBooleanWithInlineStyleFallback") {
|
|
28002
|
+
const resolvedRuntimeBranch = inlineStyleFallback.resolvedBranchIsTrue ? "true" : "false";
|
|
28003
|
+
if (runtimeCallBranch === resolvedRuntimeBranch || runtimeCallBranch === "both") return null;
|
|
28004
|
+
}
|
|
28005
|
+
return inlineStyleFallback;
|
|
28006
|
+
}
|
|
28007
|
+
}
|
|
27043
28008
|
const buildOneSidedVariantResult = (args) => {
|
|
27044
28009
|
const { cons, alt, alternate, truthyWhen } = args;
|
|
27045
28010
|
if (!cons || alt || !isEmptyCssBranch(alternate)) return null;
|
|
@@ -27268,43 +28233,47 @@ function tryResolveConditionalValue(node, ctx) {
|
|
|
27268
28233
|
}
|
|
27269
28234
|
if (info?.kind === "themeBinding" && test.type === "Identifier" && typeof test.name === "string" && isDestructuredFromParam(expr, test.name)) {
|
|
27270
28235
|
const destructuredProp = test.name;
|
|
27271
|
-
const
|
|
27272
|
-
|
|
27273
|
-
|
|
27274
|
-
|
|
27275
|
-
|
|
27276
|
-
|
|
27277
|
-
|
|
27278
|
-
|
|
27279
|
-
|
|
27280
|
-
|
|
27281
|
-
|
|
27282
|
-
|
|
27283
|
-
|
|
27284
|
-
|
|
27285
|
-
|
|
27286
|
-
|
|
27287
|
-
|
|
27288
|
-
|
|
27289
|
-
|
|
27290
|
-
|
|
27291
|
-
|
|
27292
|
-
|
|
27293
|
-
|
|
28236
|
+
const whens = destructuredBooleanWhens(destructuredProp, getArrowFnParamBindings(expr));
|
|
28237
|
+
if (whens) {
|
|
28238
|
+
const cons = getBranch(consequent);
|
|
28239
|
+
const alt = getBranch(alternate);
|
|
28240
|
+
if (cons && alt) {
|
|
28241
|
+
if (new Set([cons.usage, alt.usage]).size === 1) {
|
|
28242
|
+
const usage = cons.usage;
|
|
28243
|
+
const variants = [{
|
|
28244
|
+
nameHint: "truthy",
|
|
28245
|
+
when: whens.truthy,
|
|
28246
|
+
expr: cons.expr,
|
|
28247
|
+
imports: cons.imports
|
|
28248
|
+
}, {
|
|
28249
|
+
nameHint: "falsy",
|
|
28250
|
+
when: whens.falsy,
|
|
28251
|
+
expr: alt.expr,
|
|
28252
|
+
imports: alt.imports
|
|
28253
|
+
}];
|
|
28254
|
+
return usage === "props" ? {
|
|
28255
|
+
type: "splitVariantsResolvedStyles",
|
|
28256
|
+
variants
|
|
28257
|
+
} : {
|
|
28258
|
+
type: "splitVariantsResolvedValue",
|
|
28259
|
+
variants
|
|
28260
|
+
};
|
|
28261
|
+
}
|
|
27294
28262
|
}
|
|
28263
|
+
const oneSided = buildOneSidedVariantResult({
|
|
28264
|
+
cons,
|
|
28265
|
+
alt,
|
|
28266
|
+
alternate,
|
|
28267
|
+
truthyWhen: whens.truthy
|
|
28268
|
+
});
|
|
28269
|
+
if (oneSided) return oneSided;
|
|
28270
|
+
if (!cons || !alt) return buildRuntimeCallResult();
|
|
27295
28271
|
}
|
|
27296
|
-
const oneSided = buildOneSidedVariantResult({
|
|
27297
|
-
cons,
|
|
27298
|
-
alt,
|
|
27299
|
-
alternate,
|
|
27300
|
-
truthyWhen: destructuredProp
|
|
27301
|
-
});
|
|
27302
|
-
if (oneSided) return oneSided;
|
|
27303
|
-
if (!cons || !alt) return buildRuntimeCallResult();
|
|
27304
28272
|
}
|
|
27305
28273
|
if (paramBindings?.kind === "destructured" && test.type === "Identifier" && typeof test.name === "string") {
|
|
27306
28274
|
const resolvedProp = resolveIdentifierToPropName(test, paramBindings);
|
|
27307
|
-
|
|
28275
|
+
const resolvedWhens = resolvedProp ? destructuredBooleanWhens(resolvedProp, paramBindings) : null;
|
|
28276
|
+
if (resolvedProp && resolvedWhens) {
|
|
27308
28277
|
const cons = getBranch(consequent);
|
|
27309
28278
|
const alt = getBranch(alternate);
|
|
27310
28279
|
if (cons && alt) {
|
|
@@ -27312,12 +28281,12 @@ function tryResolveConditionalValue(node, ctx) {
|
|
|
27312
28281
|
const usage = cons.usage;
|
|
27313
28282
|
const variants = [{
|
|
27314
28283
|
nameHint: "truthy",
|
|
27315
|
-
when:
|
|
28284
|
+
when: resolvedWhens.truthy,
|
|
27316
28285
|
expr: cons.expr,
|
|
27317
28286
|
imports: cons.imports
|
|
27318
28287
|
}, {
|
|
27319
28288
|
nameHint: "falsy",
|
|
27320
|
-
when:
|
|
28289
|
+
when: resolvedWhens.falsy,
|
|
27321
28290
|
expr: alt.expr,
|
|
27322
28291
|
imports: alt.imports
|
|
27323
28292
|
}];
|
|
@@ -27342,7 +28311,7 @@ function tryResolveConditionalValue(node, ctx) {
|
|
|
27342
28311
|
cons,
|
|
27343
28312
|
alt,
|
|
27344
28313
|
alternate,
|
|
27345
|
-
truthyWhen:
|
|
28314
|
+
truthyWhen: resolvedWhens.truthy
|
|
27346
28315
|
});
|
|
27347
28316
|
if (oneSided) return oneSided;
|
|
27348
28317
|
if (!cons || !alt) return buildRuntimeCallResult();
|
|
@@ -27419,6 +28388,8 @@ function tryResolveConditionalCssBlock(node, ctx) {
|
|
|
27419
28388
|
const { left, right } = body;
|
|
27420
28389
|
const testProp = paramName ? getSinglePropFromMemberExpr(left, paramName) : bindings?.kind === "destructured" ? resolveIdentifierToPropName(left, bindings) : null;
|
|
27421
28390
|
if (!testProp) return null;
|
|
28391
|
+
const whens = destructuredBooleanWhens(testProp, bindings);
|
|
28392
|
+
if (!whens) return null;
|
|
27422
28393
|
const cssText = literalToString(right);
|
|
27423
28394
|
if (cssText !== null && cssText !== void 0) {
|
|
27424
28395
|
const style = parseCssDeclarationBlock(cssText);
|
|
@@ -27427,7 +28398,7 @@ function tryResolveConditionalCssBlock(node, ctx) {
|
|
|
27427
28398
|
type: "splitVariants",
|
|
27428
28399
|
variants: [{
|
|
27429
28400
|
nameHint: "truthy",
|
|
27430
|
-
when:
|
|
28401
|
+
when: whens.truthy,
|
|
27431
28402
|
style
|
|
27432
28403
|
}]
|
|
27433
28404
|
};
|
|
@@ -27435,7 +28406,7 @@ function tryResolveConditionalCssBlock(node, ctx) {
|
|
|
27435
28406
|
if (!paramName) return null;
|
|
27436
28407
|
return resolveThemeTemplateToCssVariant(right, paramName, ctx, {
|
|
27437
28408
|
nameHint: "truthy",
|
|
27438
|
-
when:
|
|
28409
|
+
when: whens.truthy
|
|
27439
28410
|
});
|
|
27440
28411
|
}
|
|
27441
28412
|
function tryResolveConditionalCssBlockTernary(node, ctx) {
|
|
@@ -27752,6 +28723,21 @@ function isDestructuredFromParam(arrowFn, name) {
|
|
|
27752
28723
|
return p.key?.type === "Identifier" && p.key.name === name;
|
|
27753
28724
|
});
|
|
27754
28725
|
}
|
|
28726
|
+
function isCurrentCurriedHelperContextArg(arg, propsParamName, themeBindingName) {
|
|
28727
|
+
if (!arg || typeof arg !== "object") return false;
|
|
28728
|
+
const node = arg;
|
|
28729
|
+
if (node.type === "Identifier") return node.name === propsParamName || node.name === themeBindingName;
|
|
28730
|
+
if (node.type !== "ObjectExpression" || node.properties?.length !== 1) return false;
|
|
28731
|
+
const property = node.properties[0];
|
|
28732
|
+
if (property.type !== "Property" && property.type !== "ObjectProperty" || property.computed || property.key?.type !== "Identifier" || property.key.name !== "theme") return false;
|
|
28733
|
+
const value = property.value;
|
|
28734
|
+
if (value?.type === "Identifier" && value.name === themeBindingName) return true;
|
|
28735
|
+
if (propsParamName) {
|
|
28736
|
+
const valuePath = getMemberPathFromIdentifier(property.value, propsParamName);
|
|
28737
|
+
return valuePath?.length === 1 && valuePath[0] === "theme";
|
|
28738
|
+
}
|
|
28739
|
+
return false;
|
|
28740
|
+
}
|
|
27755
28741
|
/**
|
|
27756
28742
|
* Parses a template literal that contains a simple prop-based ternary expression.
|
|
27757
28743
|
* Supports patterns like: `background: ${props.$primary ? "red" : "blue"}`
|
|
@@ -27800,7 +28786,6 @@ function tryBuildThemeBooleanInlineStyleFallback(args) {
|
|
|
27800
28786
|
type: "splitThemeBooleanWithInlineStyleFallback",
|
|
27801
28787
|
cssProp,
|
|
27802
28788
|
themeProp: themeBoolInfo.themeProp,
|
|
27803
|
-
isNegated: themeBoolInfo.isNegated,
|
|
27804
28789
|
resolvedValue: resolvedBranchIsTrue ? trueValue : falseValue,
|
|
27805
28790
|
resolvedImports: resolvedBranchIsTrue ? trueImports : falseImports,
|
|
27806
28791
|
resolvedBranchIsTrue,
|
|
@@ -27887,6 +28872,35 @@ function replaceThemeRefsWithHookVar(expr, paramName, info) {
|
|
|
27887
28872
|
};
|
|
27888
28873
|
return replace(cloned);
|
|
27889
28874
|
}
|
|
28875
|
+
/**
|
|
28876
|
+
* Builds truthy/falsy `when` condition strings for a destructured boolean-ish prop,
|
|
28877
|
+
* accounting for destructuring defaults. A default applies only when the prop is
|
|
28878
|
+
* `undefined`, so a statically-truthy default means the truthy branch must also
|
|
28879
|
+
* apply when the prop is unset (`prop === undefined || prop`).
|
|
28880
|
+
*
|
|
28881
|
+
* Returns null when the prop has a default whose truthiness cannot be determined
|
|
28882
|
+
* statically — callers should fall back to other handlers instead of emitting a
|
|
28883
|
+
* condition that ignores the default.
|
|
28884
|
+
*/
|
|
28885
|
+
function destructuredBooleanWhens(propName, bindings) {
|
|
28886
|
+
if (bindings?.kind !== "destructured" || !bindings.defaults?.has(propName)) return {
|
|
28887
|
+
truthy: propName,
|
|
28888
|
+
falsy: `!${propName}`
|
|
28889
|
+
};
|
|
28890
|
+
const defaultValue = literalToStaticValue(bindings.defaults.get(propName));
|
|
28891
|
+
if (defaultValue === null) return null;
|
|
28892
|
+
if (defaultValue) {
|
|
28893
|
+
const truthy = `${propName} === undefined || ${propName}`;
|
|
28894
|
+
return {
|
|
28895
|
+
truthy,
|
|
28896
|
+
falsy: `!(${truthy})`
|
|
28897
|
+
};
|
|
28898
|
+
}
|
|
28899
|
+
return {
|
|
28900
|
+
truthy: propName,
|
|
28901
|
+
falsy: `!${propName}`
|
|
28902
|
+
};
|
|
28903
|
+
}
|
|
27890
28904
|
//#endregion
|
|
27891
28905
|
//#region src/internal/builtin-handlers.ts
|
|
27892
28906
|
/**
|
|
@@ -28154,20 +29168,6 @@ function tryResolveArrowFnCallWithConditionalArgs(node, ctx) {
|
|
|
28154
29168
|
};
|
|
28155
29169
|
}
|
|
28156
29170
|
/**
|
|
28157
|
-
* Extracts a static literal value from an AST node, distinguishing null literals
|
|
28158
|
-
* from extraction failure. Returns `undefined` when the node is not a recognized
|
|
28159
|
-
* static literal, and the actual value (including `null`) otherwise.
|
|
28160
|
-
*/
|
|
28161
|
-
function extractStaticLiteralValue(node) {
|
|
28162
|
-
if (!node || typeof node !== "object") return;
|
|
28163
|
-
const type = node.type;
|
|
28164
|
-
if (type === "ArrowFunctionExpression" || type === "FunctionExpression") return;
|
|
28165
|
-
if (type === "NullLiteral") return null;
|
|
28166
|
-
if (type === "Literal" && node.value === null) return null;
|
|
28167
|
-
const v = literalToStaticValue(node);
|
|
28168
|
-
return v !== null ? v : void 0;
|
|
28169
|
-
}
|
|
28170
|
-
/**
|
|
28171
29171
|
* Extracts the prop name from a conditional expression's test node.
|
|
28172
29172
|
*
|
|
28173
29173
|
* Supports:
|
|
@@ -29370,6 +30370,13 @@ function tryHandleInterpolatedStringValue(args) {
|
|
|
29370
30370
|
}
|
|
29371
30371
|
return true;
|
|
29372
30372
|
}
|
|
30373
|
+
if (tryHandleTwoValueShorthandLeadingExpression({
|
|
30374
|
+
decl,
|
|
30375
|
+
d,
|
|
30376
|
+
resolveImportedValueExpr,
|
|
30377
|
+
addImport,
|
|
30378
|
+
setValue
|
|
30379
|
+
})) return true;
|
|
29373
30380
|
const tl = buildInterpolatedTemplate({
|
|
29374
30381
|
j,
|
|
29375
30382
|
decl,
|
|
@@ -29386,7 +30393,9 @@ function tryHandleInterpolatedStringValue(args) {
|
|
|
29386
30393
|
const outputs = cssDeclarationToStylexDeclarations(d);
|
|
29387
30394
|
for (let i = 0; i < outputs.length; i++) {
|
|
29388
30395
|
const out = outputs[i];
|
|
29389
|
-
|
|
30396
|
+
const emitted = maybeOmitPxUnitFromStylexValue(j, tl, out.prop, d.important, { numericIdentifiers: args.numericIdentifiers });
|
|
30397
|
+
if (emitted !== tl && hasSingleSlotUnitSuffix(d.value)) markProvenSingleTokenValue(emitted);
|
|
30398
|
+
setValue(out.prop, emitted);
|
|
29390
30399
|
if (i === 0 && (d.leadingComment || d.leadingLineComment)) addPropComments(styleObj, out.prop, {
|
|
29391
30400
|
leading: d.leadingComment,
|
|
29392
30401
|
leadingLine: d.leadingLineComment
|
|
@@ -29394,6 +30403,48 @@ function tryHandleInterpolatedStringValue(args) {
|
|
|
29394
30403
|
}
|
|
29395
30404
|
return true;
|
|
29396
30405
|
}
|
|
30406
|
+
function tryHandleTwoValueShorthandLeadingExpression(args) {
|
|
30407
|
+
const { decl, d, resolveImportedValueExpr, addImport, setValue } = args;
|
|
30408
|
+
const prop = (d.property ?? "").trim();
|
|
30409
|
+
if (prop !== "padding" && prop !== "margin") return false;
|
|
30410
|
+
if (!resolveImportedValueExpr || d.value?.kind !== "interpolated") return false;
|
|
30411
|
+
const parts = d.value.parts ?? [];
|
|
30412
|
+
if (parts.length !== 2 || parts[0]?.kind !== "slot" || parts[1]?.kind !== "static") return false;
|
|
30413
|
+
const slotId = parts[0].slotId;
|
|
30414
|
+
if (slotId === void 0) return false;
|
|
30415
|
+
const suffixMatch = (parts[1].value ?? "").match(/^([a-zA-Z%]+)\s+(.+)$/);
|
|
30416
|
+
if (!suffixMatch) return false;
|
|
30417
|
+
const expr = decl.templateExpressions[slotId];
|
|
30418
|
+
if (!expr || expr.type === "ArrowFunctionExpression") return false;
|
|
30419
|
+
const resolved = resolveImportedValueExpr(expr, {
|
|
30420
|
+
allowCssCalc: true,
|
|
30421
|
+
cssCalcUnit: suffixMatch[1]
|
|
30422
|
+
});
|
|
30423
|
+
if (!resolved || "bail" in resolved || !resolved.skipStaticWrap) return false;
|
|
30424
|
+
const entries = splitDirectionalProperty({
|
|
30425
|
+
prop,
|
|
30426
|
+
rawValue: (d.valueRaw ?? "").trim(),
|
|
30427
|
+
important: d.important,
|
|
30428
|
+
useLogical: getUseLogicalProperties()
|
|
30429
|
+
});
|
|
30430
|
+
if (!entries.length) return false;
|
|
30431
|
+
for (const imp of resolved.imports ?? []) addImport?.(imp);
|
|
30432
|
+
const placeholder = `__SC_EXPR_${slotId}__`;
|
|
30433
|
+
for (const entry of entries) {
|
|
30434
|
+
if (!entry.value.includes(placeholder)) {
|
|
30435
|
+
setValue(entry.prop, normalizeWhitespace(entry.value));
|
|
30436
|
+
continue;
|
|
30437
|
+
}
|
|
30438
|
+
if (resolvedValueCarriesUnit(resolved.resolved)) {
|
|
30439
|
+
setValue(entry.prop, resolved.resolved);
|
|
30440
|
+
continue;
|
|
30441
|
+
}
|
|
30442
|
+
const literalValue = literalToStaticValue(resolved.resolved);
|
|
30443
|
+
if (literalValue === null || typeof literalValue === "boolean") return false;
|
|
30444
|
+
setValue(entry.prop, normalizeWhitespace(entry.value.replace(placeholder, String(literalValue))));
|
|
30445
|
+
}
|
|
30446
|
+
return true;
|
|
30447
|
+
}
|
|
29397
30448
|
function buildInterpolatedTemplate(args) {
|
|
29398
30449
|
const { j, decl, cssValue, resolveCallExpr, resolveImportedValueExpr, addImport, multiline } = args;
|
|
29399
30450
|
if (!cssValue || cssValue.kind !== "interpolated") return null;
|
|
@@ -29403,17 +30454,23 @@ function buildInterpolatedTemplate(args) {
|
|
|
29403
30454
|
let allStatic = true;
|
|
29404
30455
|
const quasis = [];
|
|
29405
30456
|
let q = "";
|
|
30457
|
+
let staticPrefixToConsume = "";
|
|
29406
30458
|
for (let partIndex = 0; partIndex < parts.length; partIndex++) {
|
|
29407
30459
|
const part = parts[partIndex];
|
|
29408
30460
|
if (part.kind === "static") {
|
|
29409
|
-
|
|
29410
|
-
|
|
30461
|
+
const rawValue = part.value ?? "";
|
|
30462
|
+
const value = staticPrefixToConsume && rawValue.startsWith(staticPrefixToConsume) ? rawValue.slice(staticPrefixToConsume.length) : rawValue;
|
|
30463
|
+
staticPrefixToConsume = "";
|
|
30464
|
+
q += value;
|
|
30465
|
+
fullStaticValue += value;
|
|
29411
30466
|
continue;
|
|
29412
30467
|
}
|
|
29413
30468
|
if (part.kind === "slot") {
|
|
29414
30469
|
const expr = decl.templateExpressions[part.slotId];
|
|
29415
30470
|
if (!expr || expr.type === "ArrowFunctionExpression") return null;
|
|
29416
|
-
|
|
30471
|
+
const adjacentUnit = getAdjacentUnitAfterParts(parts, partIndex);
|
|
30472
|
+
const negateResolvedUnit = Boolean(adjacentUnit && q.endsWith("-"));
|
|
30473
|
+
if (expr.type === "CallExpression" && resolveCallExpr && !adjacentUnit) {
|
|
29417
30474
|
const resolved = resolveCallExpr(expr);
|
|
29418
30475
|
if (resolved) {
|
|
29419
30476
|
if (hasAdjacentUnitInParts(parts, partIndex)) return null;
|
|
@@ -29424,18 +30481,17 @@ function buildInterpolatedTemplate(args) {
|
|
|
29424
30481
|
for (const imp of resolved.imports ?? []) addImport?.(imp);
|
|
29425
30482
|
continue;
|
|
29426
30483
|
}
|
|
29427
|
-
quasis.push(j.templateElement({
|
|
29428
|
-
raw: q,
|
|
29429
|
-
cooked: q
|
|
29430
|
-
}, false));
|
|
29431
|
-
q = "";
|
|
29432
30484
|
allStatic = false;
|
|
29433
30485
|
for (const imp of resolved.imports ?? []) addImport?.(imp);
|
|
29434
|
-
exprs
|
|
30486
|
+
q = appendExpressionToTemplate(j, quasis, exprs, q, resolved.resolved);
|
|
29435
30487
|
continue;
|
|
29436
30488
|
}
|
|
29437
30489
|
}
|
|
29438
|
-
const importedResolved = resolveImportedValueExpr?.(expr
|
|
30490
|
+
const importedResolved = resolveImportedValueExpr?.(expr, adjacentUnit ? {
|
|
30491
|
+
allowCssCalc: true,
|
|
30492
|
+
cssCalcUnit: adjacentUnit,
|
|
30493
|
+
negate: negateResolvedUnit
|
|
30494
|
+
} : void 0);
|
|
29439
30495
|
if (importedResolved) {
|
|
29440
30496
|
if ("bail" in importedResolved) return null;
|
|
29441
30497
|
const resolved = importedResolved;
|
|
@@ -29443,7 +30499,13 @@ function buildInterpolatedTemplate(args) {
|
|
|
29443
30499
|
for (const imp of resolved.imports ?? []) addImport?.(imp);
|
|
29444
30500
|
return resolved.resolved;
|
|
29445
30501
|
}
|
|
29446
|
-
if (hasAdjacentUnitInParts(parts, partIndex) && !hasSingleSlotUnitSuffix(cssValue))
|
|
30502
|
+
if (hasAdjacentUnitInParts(parts, partIndex) && !hasSingleSlotUnitSuffix(cssValue)) {
|
|
30503
|
+
if (!adjacentUnit || !resolved.skipStaticWrap) return null;
|
|
30504
|
+
if (resolvedValueCarriesUnit(resolved.resolved)) {
|
|
30505
|
+
staticPrefixToConsume = adjacentUnit;
|
|
30506
|
+
if (negateResolvedUnit) q = q.slice(0, -1);
|
|
30507
|
+
}
|
|
30508
|
+
}
|
|
29447
30509
|
if (resolved.resolved?.type === "StringLiteral" || resolved.resolved?.type === "Literal" && typeof resolved.resolved.value === "string") {
|
|
29448
30510
|
const strValue = resolved.resolved.value;
|
|
29449
30511
|
q += strValue;
|
|
@@ -29451,14 +30513,9 @@ function buildInterpolatedTemplate(args) {
|
|
|
29451
30513
|
for (const imp of resolved.imports ?? []) addImport?.(imp);
|
|
29452
30514
|
continue;
|
|
29453
30515
|
}
|
|
29454
|
-
quasis.push(j.templateElement({
|
|
29455
|
-
raw: q,
|
|
29456
|
-
cooked: q
|
|
29457
|
-
}, false));
|
|
29458
|
-
q = "";
|
|
29459
30516
|
allStatic = false;
|
|
29460
30517
|
for (const imp of resolved.imports ?? []) addImport?.(imp);
|
|
29461
|
-
exprs
|
|
30518
|
+
q = appendExpressionToTemplate(j, quasis, exprs, q, resolved.resolved);
|
|
29462
30519
|
continue;
|
|
29463
30520
|
}
|
|
29464
30521
|
const literalValue = literalToStaticValue(expr);
|
|
@@ -29491,6 +30548,39 @@ function buildInterpolatedTemplate(args) {
|
|
|
29491
30548
|
stylisValueRaw: multiline.stylisValueRaw
|
|
29492
30549
|
});
|
|
29493
30550
|
}
|
|
30551
|
+
function resolvedValueCarriesUnit(node) {
|
|
30552
|
+
if (!node || typeof node !== "object") return false;
|
|
30553
|
+
if (node.type === "NumericLiteral" || node.type === "Literal" && typeof node.value === "number") return false;
|
|
30554
|
+
if (node.type === "StringLiteral" || node.type === "Literal" && typeof node.value === "string") return /[a-zA-Z%]$/.test(String(node.value));
|
|
30555
|
+
return true;
|
|
30556
|
+
}
|
|
30557
|
+
const CSS_UNIT_PATTERN = /^(?:px|rem|em|ex|ch|cap|ic|lh|rlh|vw|vh|vi|vb|vmin|vmax|svw|svh|lvw|lvh|dvw|dvh|cqw|cqh|cqi|cqb|cqmin|cqmax|cm|mm|q|in|pt|pc|fr|%)$/i;
|
|
30558
|
+
function getAdjacentUnitAfterParts(parts, slotIndex) {
|
|
30559
|
+
const candidate = (parts[slotIndex + 1]?.kind === "static" ? parts[slotIndex + 1]?.value ?? "" : "").match(/^([a-zA-Z%]+)/)?.[1];
|
|
30560
|
+
return candidate && CSS_UNIT_PATTERN.test(candidate) ? candidate : null;
|
|
30561
|
+
}
|
|
30562
|
+
function appendExpressionToTemplate(j, quasis, expressions, currentQuasi, expression) {
|
|
30563
|
+
if (expression?.type !== "TemplateLiteral") {
|
|
30564
|
+
quasis.push(j.templateElement({
|
|
30565
|
+
raw: currentQuasi,
|
|
30566
|
+
cooked: currentQuasi
|
|
30567
|
+
}, false));
|
|
30568
|
+
expressions.push(expression);
|
|
30569
|
+
return "";
|
|
30570
|
+
}
|
|
30571
|
+
const nestedQuasis = expression.quasis ?? [];
|
|
30572
|
+
const nestedExpressions = expression.expressions ?? [];
|
|
30573
|
+
currentQuasi += nestedQuasis[0]?.value?.raw ?? nestedQuasis[0]?.value?.cooked ?? "";
|
|
30574
|
+
for (let index = 0; index < nestedExpressions.length; index++) {
|
|
30575
|
+
quasis.push(j.templateElement({
|
|
30576
|
+
raw: currentQuasi,
|
|
30577
|
+
cooked: currentQuasi
|
|
30578
|
+
}, false));
|
|
30579
|
+
expressions.push(nestedExpressions[index]);
|
|
30580
|
+
currentQuasi = nestedQuasis[index + 1]?.value?.raw ?? nestedQuasis[index + 1]?.value?.cooked ?? "";
|
|
30581
|
+
}
|
|
30582
|
+
return currentQuasi;
|
|
30583
|
+
}
|
|
29494
30584
|
function hasAdjacentUnitInParts(parts, slotIndex) {
|
|
29495
30585
|
const before = parts[slotIndex - 1]?.kind === "static" ? parts[slotIndex - 1]?.value ?? "" : "";
|
|
29496
30586
|
const after = parts[slotIndex + 1]?.kind === "static" ? parts[slotIndex + 1]?.value ?? "" : "";
|
|
@@ -33494,7 +34584,12 @@ const createValuePatternHandlers = (ctx) => {
|
|
|
33494
34584
|
callArg,
|
|
33495
34585
|
condition: "always"
|
|
33496
34586
|
});
|
|
33497
|
-
} else styleFnFromProps.push({
|
|
34587
|
+
} else if (expr.body.operator === "||") styleFnFromProps.push({
|
|
34588
|
+
fnKey,
|
|
34589
|
+
jsxProp,
|
|
34590
|
+
condition: "truthy"
|
|
34591
|
+
});
|
|
34592
|
+
else styleFnFromProps.push({
|
|
33498
34593
|
fnKey,
|
|
33499
34594
|
jsxProp
|
|
33500
34595
|
});
|
|
@@ -34201,6 +35296,89 @@ function createDeclProcessingState(state, decl) {
|
|
|
34201
35296
|
};
|
|
34202
35297
|
}
|
|
34203
35298
|
//#endregion
|
|
35299
|
+
//#region src/internal/lower-rules/validate-decl-conflicts.ts
|
|
35300
|
+
/**
|
|
35301
|
+
* Returns the name of an imported runtime-condition root (recorded in
|
|
35302
|
+
* `nonPropConditionRoots`) that also appears as a genuine component prop. Such a
|
|
35303
|
+
* collision is unrepresentable: the decl-wide non-prop marking suppresses
|
|
35304
|
+
* destructuring of the prop, so a prop-based variant would silently read the
|
|
35305
|
+
* imported binding instead. Covers both typed props and props inferred from
|
|
35306
|
+
* `props.<name>` usage in styling.
|
|
35307
|
+
*
|
|
35308
|
+
* `variantWhens` must be sourced from the in-progress finalize state, since
|
|
35309
|
+
* `decl.variantStyleKeys` is not assigned until later in finalize.
|
|
35310
|
+
*/
|
|
35311
|
+
function findImportedRootPropCollision(decl, variantWhens) {
|
|
35312
|
+
const roots = decl.nonPropConditionRoots;
|
|
35313
|
+
if (!roots || roots.size === 0) return null;
|
|
35314
|
+
const directProps = collectDirectPropReferences(decl);
|
|
35315
|
+
for (const root of roots) {
|
|
35316
|
+
if (directProps.has(root)) return root;
|
|
35317
|
+
const bareRef = new RegExp(`(?:^|[^\\w.])${escapeRegex(root)}(?:$|[^\\w.])`);
|
|
35318
|
+
if (variantWhens.some((when) => bareRef.test(when))) return root;
|
|
35319
|
+
}
|
|
35320
|
+
return null;
|
|
35321
|
+
}
|
|
35322
|
+
/**
|
|
35323
|
+
* Returns true when the component declares both a logical scroll longhand
|
|
35324
|
+
* (e.g. `scroll-padding-inline-start`) and a physical scroll side
|
|
35325
|
+
* (e.g. `scroll-padding-left`) in the same scroll family. StyleX's
|
|
35326
|
+
* logical/physical conflict normalization resolves these to physical sides
|
|
35327
|
+
* assuming horizontal-tb LTR, but the logical-to-physical mapping depends on
|
|
35328
|
+
* `writing-mode`/`direction` (e.g. `inline-start` is the right side in RTL),
|
|
35329
|
+
* so any such mix may silently preserve or override the wrong side — bail.
|
|
35330
|
+
*/
|
|
35331
|
+
function hasConflictingLogicalPhysicalScrollProps(decl) {
|
|
35332
|
+
for (const family of SCROLL_FAMILIES) {
|
|
35333
|
+
let hasLogical = false;
|
|
35334
|
+
let hasPhysical = false;
|
|
35335
|
+
for (const rule of decl.rules) for (const declaration of rule.declarations) {
|
|
35336
|
+
const prop = declaration.property?.trim();
|
|
35337
|
+
if (!prop) continue;
|
|
35338
|
+
const camel = kebabToCamel(prop);
|
|
35339
|
+
if (!camel.startsWith(family)) continue;
|
|
35340
|
+
const side = camel.slice(family.length);
|
|
35341
|
+
if (/^(?:Inline|Block)/.test(side)) hasLogical = true;
|
|
35342
|
+
else if (side === "" || /^(?:Top|Right|Bottom|Left)$/.test(side)) hasPhysical = true;
|
|
35343
|
+
}
|
|
35344
|
+
if (hasLogical && hasPhysical) return true;
|
|
35345
|
+
}
|
|
35346
|
+
return false;
|
|
35347
|
+
}
|
|
35348
|
+
const SCROLL_FAMILIES = ["scrollMargin", "scrollPadding"];
|
|
35349
|
+
function collectDirectPropReferences(decl) {
|
|
35350
|
+
const props = /* @__PURE__ */ new Set();
|
|
35351
|
+
const add = (name) => {
|
|
35352
|
+
if (name && !name.startsWith("__")) props.add(name);
|
|
35353
|
+
};
|
|
35354
|
+
for (const name of decl.typeScriptExplicitPropNames ?? []) add(name);
|
|
35355
|
+
for (const entry of decl.styleFnFromProps ?? []) {
|
|
35356
|
+
add(entry.jsxProp);
|
|
35357
|
+
for (const extra of entry.extraCallArgs ?? []) add(extra.jsxProp);
|
|
35358
|
+
}
|
|
35359
|
+
for (const entry of decl.inlineStyleProps ?? []) add(entry.jsxProp);
|
|
35360
|
+
for (const dim of decl.variantDimensions ?? []) {
|
|
35361
|
+
add(dim.propName);
|
|
35362
|
+
add(dim.namespaceBooleanProp);
|
|
35363
|
+
}
|
|
35364
|
+
for (const cv of decl.compoundVariants ?? []) {
|
|
35365
|
+
add(cv.outerProp);
|
|
35366
|
+
add(cv.innerProp);
|
|
35367
|
+
}
|
|
35368
|
+
const attrs = decl.attrsInfo;
|
|
35369
|
+
if (attrs) {
|
|
35370
|
+
for (const entry of attrs.defaultAttrs ?? []) add(entry.jsxProp);
|
|
35371
|
+
for (const entry of attrs.dynamicAttrs ?? []) add(entry.jsxProp);
|
|
35372
|
+
for (const entry of attrs.conditionalAttrs ?? []) add(entry.jsxProp);
|
|
35373
|
+
for (const entry of attrs.invertedBoolAttrs ?? []) add(entry.jsxProp);
|
|
35374
|
+
for (const entry of attrs.attrsDynamicStyles ?? []) add(entry.jsxProp);
|
|
35375
|
+
}
|
|
35376
|
+
return props;
|
|
35377
|
+
}
|
|
35378
|
+
function kebabToCamel(prop) {
|
|
35379
|
+
return prop.replace(/-([a-z])/g, (_, ch) => ch.toUpperCase());
|
|
35380
|
+
}
|
|
35381
|
+
//#endregion
|
|
34204
35382
|
//#region src/internal/lower-rules/finalize-decl.ts
|
|
34205
35383
|
/**
|
|
34206
35384
|
* Finalizes per-declaration style objects after rule processing.
|
|
@@ -34209,6 +35387,14 @@ function createDeclProcessingState(state, decl) {
|
|
|
34209
35387
|
function finalizeDeclProcessing(ctx) {
|
|
34210
35388
|
const { state, decl, styleObj, perPropPseudo, perPropMedia, perPropComputedMedia, nestedSelectors, variantBuckets, variantStyleKeys, variantSourceOrder, extraStyleObjects, styleFnFromProps, styleFnDecls, attrBuckets, observedVariantFallbackFns, inlineStyleProps, localVarValues, cssHelperPropValues } = ctx;
|
|
34211
35389
|
const { rewriteCssVarsInStyleObject, rewriteCssVarsInAstNode, relationOverridePseudoBuckets, relationOverrides, ancestorSelectorParents, resolvedStyleObjects, warnings } = state;
|
|
35390
|
+
if (findImportedRootPropCollision(decl, Object.keys(variantStyleKeys ?? {}))) {
|
|
35391
|
+
state.bailUnsupported(decl, "Imported runtime condition root collides with a component prop of the same name");
|
|
35392
|
+
return;
|
|
35393
|
+
}
|
|
35394
|
+
if (hasConflictingLogicalPhysicalScrollProps(decl)) {
|
|
35395
|
+
state.bailUnsupported(decl, "Mixed logical and physical scroll properties cannot be normalized without a known writing-mode");
|
|
35396
|
+
return;
|
|
35397
|
+
}
|
|
34212
35398
|
mergeConditionBucket(styleObj, perPropPseudo);
|
|
34213
35399
|
mergeConditionBucket(styleObj, perPropMedia);
|
|
34214
35400
|
for (const [prop, entry] of perPropComputedMedia) {
|
|
@@ -36309,7 +37495,7 @@ const OPAQUE_SHORTHAND_PROPS = new Set([
|
|
|
36309
37495
|
function warnOpaqueShorthands(styleObj, decl, warnings) {
|
|
36310
37496
|
for (const prop of OPAQUE_SHORTHAND_PROPS) {
|
|
36311
37497
|
const val = styleObj[prop];
|
|
36312
|
-
if (val !== void 0 && isAstNode$1(val)) warnings.push({
|
|
37498
|
+
if (val !== void 0 && isAstNode$1(val) && !isProvenSingleTokenValue(val)) warnings.push({
|
|
36313
37499
|
severity: "warning",
|
|
36314
37500
|
type: "Shorthand property has an opaque value that StyleX will expand to longhands — use `directional` in resolveValue to return separate longhand tokens",
|
|
36315
37501
|
loc: decl.loc,
|
|
@@ -36907,10 +38093,11 @@ function tryHandleInterpolatedBorder(ctx, args) {
|
|
|
36907
38093
|
{
|
|
36908
38094
|
const slotIndices = [];
|
|
36909
38095
|
for (let i = 0; i < tokens.length; i++) {
|
|
36910
|
-
const m = tokens[i].match(/^__SC_EXPR_(\d+)__
|
|
38096
|
+
const m = tokens[i].match(/^__SC_EXPR_(\d+)__(?:([a-zA-Z%]+))?$/);
|
|
36911
38097
|
if (m?.[1]) slotIndices.push({
|
|
36912
38098
|
idx: i,
|
|
36913
|
-
slotId: Number(m[1])
|
|
38099
|
+
slotId: Number(m[1]),
|
|
38100
|
+
...m[2] ? { unit: m[2] } : {}
|
|
36914
38101
|
});
|
|
36915
38102
|
}
|
|
36916
38103
|
if (slotIndices.length === 2 && tokens.length === 3) {
|
|
@@ -36938,7 +38125,7 @@ function tryHandleInterpolatedBorder(ctx, args) {
|
|
|
36938
38125
|
return true;
|
|
36939
38126
|
}
|
|
36940
38127
|
const shouldSwap = slot0Role === "color" || slot1Role === "width";
|
|
36941
|
-
const widthAst = shouldSwap ? slot1Ast : slot0Ast;
|
|
38128
|
+
const widthAst = withBorderWidthUnit(shouldSwap ? slot1Ast : slot0Ast, shouldSwap ? slot1.unit : slot0.unit);
|
|
36942
38129
|
const colorAst = shouldSwap ? slot0Ast : slot1Ast;
|
|
36943
38130
|
applyResolvedPropValue(widthProp, widthAst);
|
|
36944
38131
|
applyResolvedPropValue(styleProp, middleStyle);
|
|
@@ -36985,6 +38172,11 @@ function tryHandleInterpolatedBorder(ctx, args) {
|
|
|
36985
38172
|
if (width) applyResolvedPropValue(widthProp, width);
|
|
36986
38173
|
if (style) applyResolvedPropValue(styleProp, style);
|
|
36987
38174
|
if (color) applyResolvedPropValue(colorProp, color);
|
|
38175
|
+
const stripConsumedStaticParts = () => {
|
|
38176
|
+
const value = d.value;
|
|
38177
|
+
if (!staticRaw || value?.kind !== "interpolated" || !Array.isArray(value.parts)) return;
|
|
38178
|
+
for (const part of value.parts) if (part?.kind === "static") part.value = "";
|
|
38179
|
+
};
|
|
36988
38180
|
const hasStaticWidthOrStyle = Boolean(width || style);
|
|
36989
38181
|
const targetProp = interpolationTarget === "color" ? colorProp : interpolationTarget === "width" ? widthProp : styleProp;
|
|
36990
38182
|
const targetCssProperty = interpolationTarget === "width" ? directionLower ? `border-${directionLower}-width` : "border-width" : interpolationTarget === "style" ? directionLower ? `border-${directionLower}-style` : "border-style" : directionLower ? `border-${directionLower}-color` : "border-color";
|
|
@@ -37046,6 +38238,7 @@ function tryHandleInterpolatedBorder(ctx, args) {
|
|
|
37046
38238
|
const alt = expr.body.alternate;
|
|
37047
38239
|
if (isMemberExpression(cons) || isMemberExpression(alt)) {
|
|
37048
38240
|
d.property = targetCssProperty;
|
|
38241
|
+
stripConsumedStaticParts();
|
|
37049
38242
|
return false;
|
|
37050
38243
|
}
|
|
37051
38244
|
}
|
|
@@ -37242,6 +38435,7 @@ function tryHandleInterpolatedBorder(ctx, args) {
|
|
|
37242
38435
|
if (expr?.type === "ArrowFunctionExpression") {
|
|
37243
38436
|
if (expr.body?.type === "MemberExpression") {
|
|
37244
38437
|
d.property = targetCssProperty;
|
|
38438
|
+
stripConsumedStaticParts();
|
|
37245
38439
|
return false;
|
|
37246
38440
|
}
|
|
37247
38441
|
}
|
|
@@ -37298,6 +38492,16 @@ function classifyBorderSlotRole(ast) {
|
|
|
37298
38492
|
if ((node.type === "StringLiteral" || node.type === "Literal") && typeof node.value === "string") return looksLikeLength(node.value) ? "width" : "color";
|
|
37299
38493
|
return null;
|
|
37300
38494
|
}
|
|
38495
|
+
function withBorderWidthUnit(expr, unit) {
|
|
38496
|
+
if (!unit) return expr;
|
|
38497
|
+
const staticValue = literalToStaticValue(expr);
|
|
38498
|
+
if (typeof staticValue === "number") return `${staticValue}${unit}`;
|
|
38499
|
+
if (typeof staticValue === "string" && looksLikeLength(staticValue)) {
|
|
38500
|
+
const trimmed = staticValue.trim();
|
|
38501
|
+
return /[a-zA-Z%]$/.test(trimmed) || Number.parseFloat(trimmed) === 0 ? staticValue : `${staticValue}${unit}`;
|
|
38502
|
+
}
|
|
38503
|
+
return expr;
|
|
38504
|
+
}
|
|
37301
38505
|
function hasConflictingEarlierVariant(variantBuckets, borderEntries) {
|
|
37302
38506
|
const borderProps = borderEntries.map(([prop]) => prop);
|
|
37303
38507
|
return variantBuckets.some((bucket) => Object.keys(bucket).some((variantProp) => borderProps.some((borderProp) => borderLonghandsConflict(variantProp, borderProp))));
|
|
@@ -37318,6 +38522,61 @@ function parseBorderLonghand(prop) {
|
|
|
37318
38522
|
};
|
|
37319
38523
|
}
|
|
37320
38524
|
//#endregion
|
|
38525
|
+
//#region src/internal/lower-rules/important-values.ts
|
|
38526
|
+
function appendImportantToStyleValue(j, valueAst, important) {
|
|
38527
|
+
if (!important) return valueAst;
|
|
38528
|
+
if (typeof valueAst === "string") return valueAst.includes("!important") ? valueAst : `${valueAst} !important`;
|
|
38529
|
+
if (typeof valueAst === "number") return `${valueAst} !important`;
|
|
38530
|
+
if (!valueAst || typeof valueAst !== "object") return valueAst;
|
|
38531
|
+
const node = valueAst;
|
|
38532
|
+
if (node.type === "ExpressionStatement") return appendImportantToStyleValue(j, node.expression, important);
|
|
38533
|
+
if (node.type === "StringLiteral" || node.type === "Literal" || node.type === "NumericLiteral") {
|
|
38534
|
+
if (typeof node.value === "string") return node.value.includes("!important") ? valueAst : j.literal(`${node.value} !important`);
|
|
38535
|
+
if (typeof node.value === "number") return j.literal(`${node.value} !important`);
|
|
38536
|
+
return valueAst;
|
|
38537
|
+
}
|
|
38538
|
+
if (node.type === "TemplateLiteral" && Array.isArray(node.quasis)) return appendImportantToTemplateLiteral(j, node.quasis, node.expressions, valueAst);
|
|
38539
|
+
return j.templateLiteral([j.templateElement({
|
|
38540
|
+
raw: "",
|
|
38541
|
+
cooked: ""
|
|
38542
|
+
}, false), j.templateElement({
|
|
38543
|
+
raw: " !important",
|
|
38544
|
+
cooked: " !important"
|
|
38545
|
+
}, true)], [valueAst]);
|
|
38546
|
+
}
|
|
38547
|
+
function cssValueIsImportant(value) {
|
|
38548
|
+
if (typeof value === "string") return value.includes("!important");
|
|
38549
|
+
if (!value || typeof value !== "object") return false;
|
|
38550
|
+
const node = value;
|
|
38551
|
+
if (node.type === "ExpressionStatement") return cssValueIsImportant(node.expression);
|
|
38552
|
+
if ((node.type === "StringLiteral" || node.type === "Literal") && typeof node.value === "string") return node.value.includes("!important");
|
|
38553
|
+
if (node.type === "TemplateLiteral" && Array.isArray(node.quasis)) return node.quasis.some((q) => {
|
|
38554
|
+
const raw = q?.value?.raw ?? "";
|
|
38555
|
+
const cooked = q?.value?.cooked ?? "";
|
|
38556
|
+
return raw.includes("!important") || cooked.includes("!important");
|
|
38557
|
+
});
|
|
38558
|
+
return false;
|
|
38559
|
+
}
|
|
38560
|
+
function appendImportantToTemplateLiteral(j, quasis, expressions, originalValue) {
|
|
38561
|
+
const lastIndex = quasis.length - 1;
|
|
38562
|
+
const last = quasis[lastIndex];
|
|
38563
|
+
const lastRaw = last?.value?.raw ?? last?.value?.cooked ?? "";
|
|
38564
|
+
const lastCooked = last?.value?.cooked ?? last?.value?.raw ?? "";
|
|
38565
|
+
if (lastRaw.includes("!important") || lastCooked.includes("!important")) return originalValue;
|
|
38566
|
+
const importantQuasis = quasis.map((quasi, i) => {
|
|
38567
|
+
const raw = quasi?.value?.raw ?? quasi?.value?.cooked ?? "";
|
|
38568
|
+
const cooked = quasi?.value?.cooked ?? quasi?.value?.raw ?? "";
|
|
38569
|
+
return i === lastIndex ? j.templateElement({
|
|
38570
|
+
raw: `${raw} !important`,
|
|
38571
|
+
cooked: `${cooked} !important`
|
|
38572
|
+
}, true) : j.templateElement({
|
|
38573
|
+
raw,
|
|
38574
|
+
cooked
|
|
38575
|
+
}, false);
|
|
38576
|
+
});
|
|
38577
|
+
return j.templateLiteral(importantQuasis, expressions ?? []);
|
|
38578
|
+
}
|
|
38579
|
+
//#endregion
|
|
37321
38580
|
//#region src/internal/lower-rules/interpolated-variant-resolvers.ts
|
|
37322
38581
|
function handleSplitVariantsResolvedValue(ctx) {
|
|
37323
38582
|
const { j, decl, d, res, styleObj, variantBuckets, variantStyleKeys, pseudos, media, resolvedSelectorMedia, parseExpr, resolverImports, warnings, setBail, bailUnsupported } = ctx;
|
|
@@ -37435,7 +38694,8 @@ function handleSplitVariantsResolvedValue(ctx) {
|
|
|
37435
38694
|
target[prop] = map;
|
|
37436
38695
|
return map;
|
|
37437
38696
|
};
|
|
37438
|
-
const applyWithContext = (prop,
|
|
38697
|
+
const applyWithContext = (prop, valueAstRaw) => {
|
|
38698
|
+
const valueAst = appendImportantToStyleValue(j, valueAstRaw, d.important);
|
|
37439
38699
|
if (media) {
|
|
37440
38700
|
const map = getOrCreateConditionMap(prop);
|
|
37441
38701
|
map[media] = valueAst;
|
|
@@ -38025,7 +39285,7 @@ function emitPseudoMediaStyleFnFromProps(args) {
|
|
|
38025
39285
|
//#endregion
|
|
38026
39286
|
//#region src/internal/lower-rules/rule-interpolated-declaration.ts
|
|
38027
39287
|
function handleInterpolatedDeclaration(args) {
|
|
38028
|
-
const { ctx, rule, allRules, d, media, pseudos, pseudoElement, attrTarget, resolvedSelectorMedia, applyResolvedPropValue } = args;
|
|
39288
|
+
const { ctx, rule, allRules, d, media, pseudos, pseudoElement, attrTarget, resolvedSelectorMedia, hasAncestorAttributeScope, applyResolvedPropValue } = args;
|
|
38029
39289
|
const { state, decl, styleObj, perPropPseudo, variantBuckets, variantStyleKeys, variantSourceOrder, observedVariantFallbackFns, extraStyleObjects, styleFnFromProps, styleFnDecls, inlineStyleProps, cssHelperPropValues, tryHandleMappedFunctionColor, tryHandleLogicalOrDefault, tryHandleConditionalPropCoalesceWithTheme, tryHandleEnumIfChainValue, tryHandleThemeIndexedLookup, handlerContext, componentInfo, tryHandlePropertyTernaryTemplateLiteral, tryHandleCssHelperFunctionSwitchBlock, tryHandleCssHelperConditionalBlock, findJsxPropTsType, findJsxPropTsTypeForVariantExtraction, annotateParamFromJsxProp, isJsxPropOptional, applyVariant, getBaseStyleTarget, notifyResolvedStylesArg } = ctx;
|
|
38030
39290
|
const hasStaticPropsBeforeResolvedStylesArg = () => Object.keys(styleObj).length > 0 || getBaseStyleTarget() !== styleObj;
|
|
38031
39291
|
const annotateScalarParams = (params, propNames) => {
|
|
@@ -38037,7 +39297,7 @@ function handleInterpolatedDeclaration(args) {
|
|
|
38037
39297
|
if (isJsxPropOptional(propName)) addUndefinedToParamType(j, param);
|
|
38038
39298
|
});
|
|
38039
39299
|
};
|
|
38040
|
-
const { api, j, filePath, warnings, resolverImports, keyframesNames, parseExpr, resolveValue, resolveCall, importMap, cssHelperNames, cssHelperObjectMembers, declByLocalName, cssHelperValuesByKey, staticPropertyValues, warnPropInlineStyle, applyCssHelperMixin, hasLocalThemeBinding, resolveThemeValue, resolveThemeValueFromFn, getOrCreateLocalStylexVar, resolveImportInScope, resolveImportForExpr } = state;
|
|
39300
|
+
const { api, j, filePath, warnings, resolverImports, keyframesNames, parseExpr, resolveValue, resolveCall, importMap, cssHelperNames, cssHelperObjectMembers, declByLocalName, cssHelperValuesByKey, staticPropertyValues, staticIdentifierValues, warnPropInlineStyle, applyCssHelperMixin, hasLocalThemeBinding, resolveThemeValue, resolveThemeValueFromFn, getOrCreateLocalStylexVar, resolveImportInScope, resolveImportForExpr } = state;
|
|
38041
39301
|
const avoidNames = new Set(importMap.keys());
|
|
38042
39302
|
if (state.bail) return;
|
|
38043
39303
|
if (d.value.kind !== "interpolated") return;
|
|
@@ -38385,7 +39645,7 @@ function handleInterpolatedDeclaration(args) {
|
|
|
38385
39645
|
return (observedNumericCssTextProps.has(jsxProp) || isNumberLikeTsType(findJsxPropTsType(jsxProp))) && getNumericCssEmissionMode(stylexProp) === "cssText";
|
|
38386
39646
|
};
|
|
38387
39647
|
const maybeEmitPreservedRuntimeCallOverride = (args) => {
|
|
38388
|
-
const { resolveCallResult, originalExpr, loc } = args;
|
|
39648
|
+
const { resolveCallResult, originalExpr, loc, cssValueText } = args;
|
|
38389
39649
|
if (!resolveCallResult || !("preserveRuntimeCall" in resolveCallResult) || !resolveCallResult.preserveRuntimeCall) return "not-requested";
|
|
38390
39650
|
if (!d.property) {
|
|
38391
39651
|
warnings.push({
|
|
@@ -38429,7 +39689,17 @@ function handleInterpolatedDeclaration(args) {
|
|
|
38429
39689
|
const effectiveSuffix = d.important ? `${suffix} !important` : suffix;
|
|
38430
39690
|
const runtimeCallArg = prefix || effectiveSuffix ? buildTemplateWithStaticParts(j, baseRuntimeExpr, prefix, effectiveSuffix) : baseRuntimeExpr;
|
|
38431
39691
|
if (runtimeExprNeedsTheme) markDeclNeedsUseThemeHook(decl);
|
|
38432
|
-
const
|
|
39692
|
+
const runtimeBackgroundProp = d.property === "background" ? resolveRuntimeBackgroundStylexProp(baseRuntimeExpr, cssValueText) : null;
|
|
39693
|
+
if (runtimeBackgroundProp === "unsupported") {
|
|
39694
|
+
warnings.push({
|
|
39695
|
+
severity: "error",
|
|
39696
|
+
type: "Arrow function: helper call body is not supported",
|
|
39697
|
+
loc
|
|
39698
|
+
});
|
|
39699
|
+
bail = true;
|
|
39700
|
+
return "failed";
|
|
39701
|
+
}
|
|
39702
|
+
const outs = runtimeBackgroundProp ? [{ prop: runtimeBackgroundProp }] : cssDeclarationToStylexDeclarations(d);
|
|
38433
39703
|
if (outs.length !== 1 || !outs[0]?.prop) {
|
|
38434
39704
|
warnings.push({
|
|
38435
39705
|
severity: "error",
|
|
@@ -38439,21 +39709,38 @@ function handleInterpolatedDeclaration(args) {
|
|
|
38439
39709
|
bail = true;
|
|
38440
39710
|
return "failed";
|
|
38441
39711
|
}
|
|
38442
|
-
const
|
|
38443
|
-
const
|
|
38444
|
-
if (
|
|
38445
|
-
|
|
38446
|
-
|
|
38447
|
-
|
|
38448
|
-
|
|
38449
|
-
|
|
39712
|
+
const runtimeProp = outs[0].prop;
|
|
39713
|
+
const runtimeStyle = { [runtimeProp]: runtimeCallArg };
|
|
39714
|
+
if (runtimeBackgroundProp) applyBackgroundShorthandLayerReset(j, runtimeStyle, runtimeBackgroundProp, d.important);
|
|
39715
|
+
if (!subtractLaterStaticOverrides({
|
|
39716
|
+
rule,
|
|
39717
|
+
allRules,
|
|
39718
|
+
currentDecl: d,
|
|
39719
|
+
branchStyles: [runtimeStyle],
|
|
39720
|
+
ignoreUnsafeOverlaps: true
|
|
39721
|
+
})) {
|
|
39722
|
+
warnings.push({
|
|
39723
|
+
severity: "error",
|
|
39724
|
+
type: "Arrow function: helper call body is not supported",
|
|
39725
|
+
loc
|
|
39726
|
+
});
|
|
39727
|
+
bail = true;
|
|
39728
|
+
return "failed";
|
|
38450
39729
|
}
|
|
39730
|
+
if (Object.keys(runtimeStyle).length === 0) return "suppressed";
|
|
39731
|
+
const fnKey = styleKeyWithSuffix(decl.styleKey, runtimeProp);
|
|
39732
|
+
const outParamName = cssPropertyToIdentifier(runtimeProp, avoidNames);
|
|
39733
|
+
const param = j.identifier(outParamName);
|
|
39734
|
+
if (/\.(ts|tsx)$/.test(filePath)) param.typeAnnotation = j.tsTypeAnnotation(j.tsStringKeyword());
|
|
39735
|
+
const body = j.objectExpression(Object.entries(runtimeStyle).map(([prop, value]) => prop === runtimeProp ? makeCssProperty(j, runtimeProp, outParamName) : j.property("init", makeCssPropKey(j, prop), cloneAstNode(value))));
|
|
39736
|
+
styleFnDecls.set(fnKey, j.arrowFunctionExpression([param], body));
|
|
38451
39737
|
const existingIdx = styleFnFromProps.findIndex((entry) => entry.fnKey === fnKey && entry.jsxProp === "__props" && entry.condition === "always");
|
|
38452
39738
|
const newEntry = {
|
|
38453
39739
|
fnKey,
|
|
38454
39740
|
jsxProp: "__props",
|
|
38455
39741
|
condition: "always",
|
|
38456
|
-
callArg: cloneAstNode(runtimeCallArg)
|
|
39742
|
+
callArg: cloneAstNode(runtimeCallArg),
|
|
39743
|
+
sourceOrder: ctx.allocateSourceOrder()
|
|
38457
39744
|
};
|
|
38458
39745
|
if (existingIdx >= 0) styleFnFromProps[existingIdx] = newEntry;
|
|
38459
39746
|
else styleFnFromProps.push(newEntry);
|
|
@@ -38586,7 +39873,10 @@ function handleInterpolatedDeclaration(args) {
|
|
|
38586
39873
|
return null;
|
|
38587
39874
|
};
|
|
38588
39875
|
const allowCssCalcForImportedArithmetic = isEntireInterpolatedValueSingleSlot(d, decl);
|
|
38589
|
-
const resolveImportedValueExpr = (expr,
|
|
39876
|
+
const resolveImportedValueExpr = (expr, options = allowCssCalcForImportedArithmetic) => {
|
|
39877
|
+
const allowCssCalc = typeof options === "boolean" ? options : options.allowCssCalc ?? false;
|
|
39878
|
+
const cssCalcUnit = typeof options === "boolean" ? void 0 : options.cssCalcUnit;
|
|
39879
|
+
const forceNegate = typeof options === "boolean" ? false : options.negate === true;
|
|
38590
39880
|
const resolveChildExpression = (child) => resolveImportedValueExpr(child, false);
|
|
38591
39881
|
const isBailResolution = (result) => Boolean(result && "bail" in result);
|
|
38592
39882
|
const resolvedOrOriginal = (result, original) => result && !isBailResolution(result) ? result.resolved : original;
|
|
@@ -38623,7 +39913,9 @@ function handleInterpolatedDeclaration(args) {
|
|
|
38623
39913
|
prefix: "",
|
|
38624
39914
|
suffix: ""
|
|
38625
39915
|
};
|
|
38626
|
-
|
|
39916
|
+
const calcUnit = cssCalcUnit ?? staticParts.suffix;
|
|
39917
|
+
const hasNegativePrefix = !cssCalcUnit && staticParts.prefix === "-" && /^-?(?:[a-zA-Z%]+)$/.test(staticParts.suffix) && (expr.operator === "+" || expr.operator === "-");
|
|
39918
|
+
if (staticParts.prefix && !hasNegativePrefix && !cssCalcUnit) {
|
|
38627
39919
|
warnings.push({
|
|
38628
39920
|
severity: "warning",
|
|
38629
39921
|
type: "Unsupported interpolation: call expression",
|
|
@@ -38635,7 +39927,9 @@ function handleInterpolatedDeclaration(args) {
|
|
|
38635
39927
|
const calcExpr = buildCssCalcTemplateExpression({
|
|
38636
39928
|
j,
|
|
38637
39929
|
operator: expr.operator,
|
|
38638
|
-
unit: expr.operator === "+" || expr.operator === "-" ?
|
|
39930
|
+
unit: expr.operator === "+" || expr.operator === "-" ? calcUnit : "",
|
|
39931
|
+
negate: forceNegate || hasNegativePrefix,
|
|
39932
|
+
staticIdentifierValues,
|
|
38639
39933
|
left: {
|
|
38640
39934
|
node: resolvedLeft,
|
|
38641
39935
|
allowExpression: Boolean(leftResult)
|
|
@@ -38648,9 +39942,9 @@ function handleInterpolatedDeclaration(args) {
|
|
|
38648
39942
|
if (calcExpr) return {
|
|
38649
39943
|
resolved: calcExpr,
|
|
38650
39944
|
imports,
|
|
38651
|
-
skipStaticWrap:
|
|
39945
|
+
skipStaticWrap: calcUnit !== ""
|
|
38652
39946
|
};
|
|
38653
|
-
if (
|
|
39947
|
+
if (calcUnit && imports.length > 0) return bailResolvedUnitExpression(expr);
|
|
38654
39948
|
}
|
|
38655
39949
|
return {
|
|
38656
39950
|
resolved: j.binaryExpression(expr.operator, resolvedLeft, resolvedRight),
|
|
@@ -38758,7 +40052,25 @@ function handleInterpolatedDeclaration(args) {
|
|
|
38758
40052
|
const imp = calleeInfo ? resolveImportInScope(calleeInfo.rootName, calleeInfo.rootNode) : null;
|
|
38759
40053
|
if (!imp) return null;
|
|
38760
40054
|
const resolvedCall = resolveCallExpr(expr);
|
|
38761
|
-
if (resolvedCall)
|
|
40055
|
+
if (resolvedCall) {
|
|
40056
|
+
if (!cssCalcUnit) return resolvedCall;
|
|
40057
|
+
const literalValue = literalToStaticValue(resolvedCall.resolved);
|
|
40058
|
+
const numericLiteral = typeof literalValue === "number" ? literalValue : typeof literalValue === "string" && literalValue.trim() !== "" && Number.isFinite(Number(literalValue)) ? Number(literalValue) : null;
|
|
40059
|
+
if (numericLiteral !== null) return {
|
|
40060
|
+
resolved: j.literal(`${numericLiteral}${cssCalcUnit}`),
|
|
40061
|
+
imports: resolvedCall.imports,
|
|
40062
|
+
skipStaticWrap: true
|
|
40063
|
+
};
|
|
40064
|
+
if (forceNegate) return {
|
|
40065
|
+
resolved: buildNegatedCssTokenTemplate(j, resolvedCall.resolved),
|
|
40066
|
+
imports: resolvedCall.imports,
|
|
40067
|
+
skipStaticWrap: true
|
|
40068
|
+
};
|
|
40069
|
+
return {
|
|
40070
|
+
...resolvedCall,
|
|
40071
|
+
skipStaticWrap: true
|
|
40072
|
+
};
|
|
40073
|
+
}
|
|
38762
40074
|
warnings.push({
|
|
38763
40075
|
severity: "warning",
|
|
38764
40076
|
type: "Adapter resolveCall returned undefined for helper call",
|
|
@@ -38786,9 +40098,10 @@ function handleInterpolatedDeclaration(args) {
|
|
|
38786
40098
|
};
|
|
38787
40099
|
const resolveValueResult = resolveValue(resolveValueContext);
|
|
38788
40100
|
if (!resolveValueResult) {
|
|
40101
|
+
const isPlainOwnedConstant = info.path.length === 0 && imp.source.kind === "absolutePath" && !isStylexImportSource(imp.source.value);
|
|
38789
40102
|
warnings.push({
|
|
38790
40103
|
severity: "error",
|
|
38791
|
-
type: "Adapter resolveValue returned undefined for imported value",
|
|
40104
|
+
type: isPlainOwnedConstant ? "Imported constant cannot be referenced inside stylex.create() — move it into a `.stylex` defineConsts/defineVars group (or map it via adapter.resolveValue)" : "Adapter resolveValue returned undefined for imported value",
|
|
38792
40105
|
loc: getNodeLocStart(expr) ?? decl.loc,
|
|
38793
40106
|
context: {
|
|
38794
40107
|
localName: decl.localName,
|
|
@@ -38888,7 +40201,8 @@ function handleInterpolatedDeclaration(args) {
|
|
|
38888
40201
|
attrTarget,
|
|
38889
40202
|
resolvedSelectorMedia
|
|
38890
40203
|
})) continue;
|
|
38891
|
-
|
|
40204
|
+
const numericIdentifiers = getNumericImportedStylexIdentifiers(j, filePath, importMap, resolverImports);
|
|
40205
|
+
if (isImportedShorthandUnitValue(d, decl, importMap, numericIdentifiers)) {
|
|
38892
40206
|
bailUnsupportedLocal(decl, "Unsupported interpolation: call expression");
|
|
38893
40207
|
continue;
|
|
38894
40208
|
}
|
|
@@ -38901,7 +40215,7 @@ function handleInterpolatedDeclaration(args) {
|
|
|
38901
40215
|
addImport,
|
|
38902
40216
|
resolveImportedValueExpr,
|
|
38903
40217
|
resolveThemeValue,
|
|
38904
|
-
numericIdentifiers
|
|
40218
|
+
numericIdentifiers,
|
|
38905
40219
|
setStyleValue: (prop, value) => applyResolvedPropValue(prop, value, null)
|
|
38906
40220
|
})) continue;
|
|
38907
40221
|
if (bail) break;
|
|
@@ -38910,9 +40224,31 @@ function handleInterpolatedDeclaration(args) {
|
|
|
38910
40224
|
if (slot) {
|
|
38911
40225
|
const expr = decl.templateExpressions[slot.slotId];
|
|
38912
40226
|
if (tryEmitObservedCssBlockVariantBuckets(expr)) continue;
|
|
40227
|
+
const bailOnPropDependentCssHelper = (helperDecl) => {
|
|
40228
|
+
for (const helperExpr of helperDecl.templateExpressions ?? []) {
|
|
40229
|
+
if (!helperExpr || helperExpr.type !== "ArrowFunctionExpression" && helperExpr.type !== "FunctionExpression") continue;
|
|
40230
|
+
const propsUsed = new Set([...collectPropsFromArrowFn(helperExpr), ...collectPropsFromArrowFnDestructured(helperExpr)]);
|
|
40231
|
+
propsUsed.delete("theme");
|
|
40232
|
+
if (propsUsed.size > 0) {
|
|
40233
|
+
warnings.push({
|
|
40234
|
+
severity: "warning",
|
|
40235
|
+
type: "css helper with prop-based interpolation cannot be reused as a mixin",
|
|
40236
|
+
loc: decl.loc,
|
|
40237
|
+
context: {
|
|
40238
|
+
localName: decl.localName,
|
|
40239
|
+
mixin: helperDecl.localName
|
|
40240
|
+
}
|
|
40241
|
+
});
|
|
40242
|
+
bail = true;
|
|
40243
|
+
return true;
|
|
40244
|
+
}
|
|
40245
|
+
}
|
|
40246
|
+
return false;
|
|
40247
|
+
};
|
|
38913
40248
|
if (expr?.type === "Identifier" && cssHelperNames.has(expr.name)) {
|
|
38914
40249
|
const helperDecl = declByLocalName.get(expr.name);
|
|
38915
40250
|
if (helperDecl) {
|
|
40251
|
+
if (bailOnPropDependentCssHelper(helperDecl)) break;
|
|
38916
40252
|
applyCssHelperMixin(decl, helperDecl, cssHelperPropValues, inlineStyleProps);
|
|
38917
40253
|
continue;
|
|
38918
40254
|
}
|
|
@@ -38921,6 +40257,7 @@ function handleInterpolatedDeclaration(args) {
|
|
|
38921
40257
|
const calleeName = expr.callee.name;
|
|
38922
40258
|
const helperDecl = declByLocalName.get(calleeName);
|
|
38923
40259
|
if (helperDecl?.isCssHelper) {
|
|
40260
|
+
if (bailOnPropDependentCssHelper(helperDecl)) break;
|
|
38924
40261
|
applyCssHelperMixin(decl, helperDecl, cssHelperPropValues, inlineStyleProps);
|
|
38925
40262
|
continue;
|
|
38926
40263
|
}
|
|
@@ -39066,7 +40403,24 @@ function handleInterpolatedDeclaration(args) {
|
|
|
39066
40403
|
})) continue;
|
|
39067
40404
|
if (d.property && d.value.kind === "interpolated" && tryHandleMultiSlotTernary(ctx, d)) continue;
|
|
39068
40405
|
if (tryHandleMultiSlotRuntimeValue(resolveImportedValueExpr)) continue;
|
|
39069
|
-
const
|
|
40406
|
+
const remainingSlotParts = d.value.parts.filter((p) => p.kind === "slot");
|
|
40407
|
+
if (remainingSlotParts.filter((p) => {
|
|
40408
|
+
const slotExpr = decl.templateExpressions[p.slotId];
|
|
40409
|
+
return slotExpr?.type === "ArrowFunctionExpression" || slotExpr?.type === "FunctionExpression";
|
|
40410
|
+
}).length > 1) {
|
|
40411
|
+
warnings.push({
|
|
40412
|
+
severity: "error",
|
|
40413
|
+
type: "Unsupported interpolation: multiple dynamic slots in one declaration",
|
|
40414
|
+
loc: decl.loc,
|
|
40415
|
+
context: {
|
|
40416
|
+
localName: decl.localName,
|
|
40417
|
+
property: d.property
|
|
40418
|
+
}
|
|
40419
|
+
});
|
|
40420
|
+
bail = true;
|
|
40421
|
+
break;
|
|
40422
|
+
}
|
|
40423
|
+
const slotPart = remainingSlotParts[0];
|
|
39070
40424
|
const slotId = slotPart && slotPart.kind === "slot" ? slotPart.slotId : 0;
|
|
39071
40425
|
const expr = decl.templateExpressions[slotId];
|
|
39072
40426
|
const loc = getNodeLocStart(expr);
|
|
@@ -39110,6 +40464,10 @@ function handleInterpolatedDeclaration(args) {
|
|
|
39110
40464
|
bail = true;
|
|
39111
40465
|
break;
|
|
39112
40466
|
}
|
|
40467
|
+
if (hasSourceOrderedThemeStyleOverlap(decl, extraStyleObjects, res.cssText)) {
|
|
40468
|
+
bail = true;
|
|
40469
|
+
continue;
|
|
40470
|
+
}
|
|
39113
40471
|
addResolverImports(res.imports);
|
|
39114
40472
|
const exprAst = parseExpr(res.expr);
|
|
39115
40473
|
if (!exprAst) {
|
|
@@ -39195,7 +40553,9 @@ function handleInterpolatedDeclaration(args) {
|
|
|
39195
40553
|
addResolverImports(res.imports);
|
|
39196
40554
|
const { prefix, suffix } = extractStaticPartsForDecl(d);
|
|
39197
40555
|
const effectiveSuffix = d.important ? `${suffix} !important` : suffix;
|
|
39198
|
-
const
|
|
40556
|
+
const wrappedExpr = wrapExprWithStaticParts(res.expr, prefix, effectiveSuffix);
|
|
40557
|
+
const cssValueTextForClassification = prefix || effectiveSuffix ? wrappedExpr : res.cssValueText;
|
|
40558
|
+
const exprAst = parseExpr(wrappedExpr);
|
|
39199
40559
|
if (!exprAst) {
|
|
39200
40560
|
const resolveCallMeta = res.resolveCallContext && res.resolveCallResult ? {
|
|
39201
40561
|
resolveCallContext: res.resolveCallContext,
|
|
@@ -39217,7 +40577,7 @@ function handleInterpolatedDeclaration(args) {
|
|
|
39217
40577
|
bail = true;
|
|
39218
40578
|
break;
|
|
39219
40579
|
}
|
|
39220
|
-
const outs = cssDeclarationToStylexDeclarations(d);
|
|
40580
|
+
const outs = d.property === "background" && cssValueTextForClassification ? [{ prop: resolveBackgroundStylexProp(cssValueTextForClassification) }] : cssDeclarationToStylexDeclarations(d);
|
|
39221
40581
|
for (let i = 0; i < outs.length; i++) {
|
|
39222
40582
|
const out = outs[i];
|
|
39223
40583
|
const commentSource = i === 0 ? {
|
|
@@ -39225,12 +40585,13 @@ function handleInterpolatedDeclaration(args) {
|
|
|
39225
40585
|
leadingLine: d.leadingLineComment,
|
|
39226
40586
|
trailingLine: d.trailingLineComment
|
|
39227
40587
|
} : null;
|
|
39228
|
-
applyResolvedPropValue(out.prop, exprAst, commentSource);
|
|
40588
|
+
applyResolvedPropValue(out.prop, exprAst, commentSource, d.property);
|
|
39229
40589
|
}
|
|
39230
40590
|
if (maybeEmitPreservedRuntimeCallOverride({
|
|
39231
40591
|
resolveCallResult: res.resolveCallResult,
|
|
39232
40592
|
originalExpr: expr,
|
|
39233
|
-
loc
|
|
40593
|
+
loc,
|
|
40594
|
+
cssValueText: cssValueTextForClassification
|
|
39234
40595
|
}) === "failed") break;
|
|
39235
40596
|
continue;
|
|
39236
40597
|
}
|
|
@@ -39238,43 +40599,89 @@ function handleInterpolatedDeclaration(args) {
|
|
|
39238
40599
|
if (maybeEmitPreservedRuntimeCallOverride({
|
|
39239
40600
|
resolveCallResult: res.resolveCallResult,
|
|
39240
40601
|
originalExpr: expr,
|
|
39241
|
-
loc
|
|
40602
|
+
loc,
|
|
40603
|
+
cssValueText: res.cssValueText
|
|
39242
40604
|
}) === "failed") break;
|
|
39243
40605
|
continue;
|
|
39244
40606
|
}
|
|
39245
40607
|
if (res && res.type === "splitThemeBooleanVariants") {
|
|
40608
|
+
if (pseudos?.length || media || pseudoElement || attrTarget || resolvedSelectorMedia || hasAncestorAttributeScope) {
|
|
40609
|
+
bail = true;
|
|
40610
|
+
continue;
|
|
40611
|
+
}
|
|
39246
40612
|
addResolverImports(res.trueImports);
|
|
39247
40613
|
addResolverImports(res.falseImports);
|
|
39248
|
-
const
|
|
39249
|
-
|
|
39250
|
-
|
|
39251
|
-
if (!entry) {
|
|
39252
|
-
entry = {
|
|
39253
|
-
themeProp: res.themeProp,
|
|
39254
|
-
trueStyleKey,
|
|
39255
|
-
falseStyleKey
|
|
39256
|
-
};
|
|
39257
|
-
decl.needsUseThemeHook.push(entry);
|
|
39258
|
-
extraStyleObjects.set(trueStyleKey, {});
|
|
39259
|
-
extraStyleObjects.set(falseStyleKey, {});
|
|
39260
|
-
}
|
|
39261
|
-
const trueStyle = extraStyleObjects.get(trueStyleKey) ?? {};
|
|
39262
|
-
const falseStyle = extraStyleObjects.get(falseStyleKey) ?? {};
|
|
39263
|
-
if (!applyThemeBooleanValue(j, res.cssProp, res.trueValue, trueStyle)) {
|
|
40614
|
+
const trueStyle = {};
|
|
40615
|
+
const falseStyle = {};
|
|
40616
|
+
if (!applyThemeBooleanValue(j, res.cssProp, res.trueValue, trueStyle, d.important, res.trueCssValueText)) {
|
|
39264
40617
|
bail = true;
|
|
39265
40618
|
continue;
|
|
39266
40619
|
}
|
|
39267
|
-
if (!applyThemeBooleanValue(j, res.cssProp, res.falseValue, falseStyle)) {
|
|
40620
|
+
if (!applyThemeBooleanValue(j, res.cssProp, res.falseValue, falseStyle, d.important, res.falseCssValueText)) {
|
|
39268
40621
|
bail = true;
|
|
39269
40622
|
continue;
|
|
39270
40623
|
}
|
|
39271
|
-
|
|
39272
|
-
|
|
40624
|
+
const { trueKey: baseTrueStyleKey, falseKey: baseFalseStyleKey } = buildThemeStyleKeys(decl.styleKey, res.themeProp);
|
|
40625
|
+
if (!decl.needsUseThemeHook) decl.needsUseThemeHook = [];
|
|
40626
|
+
const latestSourceOrder = getLatestThemeInterleavableSourceOrder({
|
|
40627
|
+
decl,
|
|
40628
|
+
variantSourceOrder,
|
|
40629
|
+
styleFnFromProps
|
|
40630
|
+
});
|
|
40631
|
+
const matchingThemeEntries = decl.needsUseThemeHook.filter((entry) => entry.themeProp === res.themeProp && (entry.trueStyleKey || entry.falseStyleKey));
|
|
40632
|
+
let reusableEntry = null;
|
|
40633
|
+
for (let i = matchingThemeEntries.length - 1; i >= 0; i--) {
|
|
40634
|
+
const entry = matchingThemeEntries[i];
|
|
40635
|
+
if (entry.sourceOrder !== void 0 && entry.sourceOrder === latestSourceOrder) {
|
|
40636
|
+
reusableEntry = entry;
|
|
40637
|
+
break;
|
|
40638
|
+
}
|
|
40639
|
+
}
|
|
40640
|
+
const mergeExtraStyleObject = (styleKey, style) => {
|
|
40641
|
+
const existing = extraStyleObjects.get(styleKey);
|
|
40642
|
+
if (!existing) {
|
|
40643
|
+
extraStyleObjects.set(styleKey, style);
|
|
40644
|
+
return;
|
|
40645
|
+
}
|
|
40646
|
+
const merged = { ...existing };
|
|
40647
|
+
for (const [prop, value] of Object.entries(style)) {
|
|
40648
|
+
if (Object.hasOwn(merged, prop) && cssValueIsImportant(merged[prop]) && !cssValueIsImportant(value)) continue;
|
|
40649
|
+
merged[prop] = value;
|
|
40650
|
+
}
|
|
40651
|
+
extraStyleObjects.set(styleKey, merged);
|
|
40652
|
+
};
|
|
40653
|
+
if (reusableEntry) {
|
|
40654
|
+
const restoredTrueStyleKey = reusableEntry.trueStyleKey ?? restoreThemeStyleKeyFromPairedSide(baseTrueStyleKey, baseFalseStyleKey, reusableEntry.falseStyleKey);
|
|
40655
|
+
const restoredFalseStyleKey = reusableEntry.falseStyleKey ?? restoreThemeStyleKeyFromPairedSide(baseFalseStyleKey, baseTrueStyleKey, reusableEntry.trueStyleKey);
|
|
40656
|
+
reusableEntry.trueStyleKey = restoredTrueStyleKey;
|
|
40657
|
+
reusableEntry.falseStyleKey = restoredFalseStyleKey;
|
|
40658
|
+
mergeExtraStyleObject(restoredTrueStyleKey, trueStyle);
|
|
40659
|
+
mergeExtraStyleObject(restoredFalseStyleKey, falseStyle);
|
|
40660
|
+
} else {
|
|
40661
|
+
const sourceOrder = ctx.allocateSourceOrder();
|
|
40662
|
+
const hasExistingStyleBucketForThemeProp = matchingThemeEntries.length > 0;
|
|
40663
|
+
const trueStyleKey = hasExistingStyleBucketForThemeProp ? styleKeyWithSuffix(baseTrueStyleKey, `theme${sourceOrder}`) : baseTrueStyleKey;
|
|
40664
|
+
const falseStyleKey = hasExistingStyleBucketForThemeProp ? styleKeyWithSuffix(baseFalseStyleKey, `theme${sourceOrder}`) : baseFalseStyleKey;
|
|
40665
|
+
decl.needsUseThemeHook.push({
|
|
40666
|
+
themeProp: res.themeProp,
|
|
40667
|
+
trueStyleKey,
|
|
40668
|
+
falseStyleKey,
|
|
40669
|
+
sourceOrder
|
|
40670
|
+
});
|
|
40671
|
+
extraStyleObjects.set(trueStyleKey, trueStyle);
|
|
40672
|
+
extraStyleObjects.set(falseStyleKey, falseStyle);
|
|
40673
|
+
}
|
|
40674
|
+
if (maybeEmitPreservedRuntimeCallOverride({
|
|
40675
|
+
resolveCallResult: res.runtimeResolveCallResult,
|
|
40676
|
+
originalExpr: expr,
|
|
40677
|
+
loc,
|
|
40678
|
+
cssValueText: res.runtimeCssValueText
|
|
40679
|
+
}) === "failed") break;
|
|
39273
40680
|
decl.needsWrapperComponent = true;
|
|
39274
40681
|
continue;
|
|
39275
40682
|
}
|
|
39276
40683
|
if (res && res.type === "splitThemeBooleanWithInlineStyleFallback") {
|
|
39277
|
-
if (pseudos?.length || media || pseudoElement) {
|
|
40684
|
+
if (pseudos?.length || media || pseudoElement || attrTarget || resolvedSelectorMedia || hasAncestorAttributeScope) {
|
|
39278
40685
|
bail = true;
|
|
39279
40686
|
continue;
|
|
39280
40687
|
}
|
|
@@ -39282,9 +40689,14 @@ function handleInterpolatedDeclaration(args) {
|
|
|
39282
40689
|
bail = true;
|
|
39283
40690
|
continue;
|
|
39284
40691
|
}
|
|
40692
|
+
const stylexDeclarations = cssDeclarationToStylexDeclarations(d);
|
|
40693
|
+
if (hasLaterDeclarationForStylexProps(d, allRules, new Set(stylexDeclarations.map((out) => out.prop).filter(Boolean)))) {
|
|
40694
|
+
bail = true;
|
|
40695
|
+
continue;
|
|
40696
|
+
}
|
|
39285
40697
|
addResolverImports(res.resolvedImports);
|
|
39286
40698
|
if (!decl.needsUseThemeHook) decl.needsUseThemeHook = [];
|
|
39287
|
-
if (!decl.needsUseThemeHook.some((e) => e.themeProp === res.themeProp)) decl.needsUseThemeHook.push({
|
|
40699
|
+
if (!decl.needsUseThemeHook.some((e) => e.themeProp === res.themeProp && e.trueStyleKey === null && e.falseStyleKey === null)) decl.needsUseThemeHook.push({
|
|
39288
40700
|
themeProp: res.themeProp,
|
|
39289
40701
|
trueStyleKey: null,
|
|
39290
40702
|
falseStyleKey: null
|
|
@@ -39292,8 +40704,8 @@ function handleInterpolatedDeclaration(args) {
|
|
|
39292
40704
|
const themeCondition = j.memberExpression(j.identifier("theme"), j.identifier(res.themeProp));
|
|
39293
40705
|
const undefinedExpr = j.identifier("undefined");
|
|
39294
40706
|
const inlineExpr = res.inlineExpr;
|
|
39295
|
-
const conditionalExpr = !res.resolvedBranchIsTrue
|
|
39296
|
-
for (const out of
|
|
40707
|
+
const conditionalExpr = !res.resolvedBranchIsTrue ? j.conditionalExpression(themeCondition, inlineExpr, undefinedExpr) : j.conditionalExpression(themeCondition, undefinedExpr, inlineExpr);
|
|
40708
|
+
for (const out of stylexDeclarations) {
|
|
39297
40709
|
if (!out.prop) continue;
|
|
39298
40710
|
styleObj[out.prop] = res.resolvedValue;
|
|
39299
40711
|
inlineStyleProps.push({
|
|
@@ -39592,11 +41004,11 @@ function handleInterpolatedDeclaration(args) {
|
|
|
39592
41004
|
const scalarDynamic = shouldUseScalarDynamicArgs(d.property, d.valueRaw) && dynamicProps.length > 0 ? scalarizePropsObjectDynamicValue({
|
|
39593
41005
|
j,
|
|
39594
41006
|
valueExpr: dynamicValueExpr,
|
|
39595
|
-
paramName
|
|
41007
|
+
paramName,
|
|
39596
41008
|
propNames: dynamicProps
|
|
39597
41009
|
}) : null;
|
|
39598
41010
|
const dynamicStyleValueExpr = scalarDynamic?.valueExpr ?? dynamicValueExpr;
|
|
39599
|
-
const dynamicStyleParams = scalarDynamic ? scalarDynamic.paramNames.map((propName) => j.identifier(propName)) : [j.identifier(
|
|
41011
|
+
const dynamicStyleParams = scalarDynamic ? scalarDynamic.paramNames.map((propName) => j.identifier(propName)) : [j.identifier(paramName)];
|
|
39600
41012
|
if (scalarDynamic) annotateScalarParams(dynamicStyleParams, scalarDynamic.paramNames);
|
|
39601
41013
|
const callArg = j.objectExpression(dynamicProps.map((name) => {
|
|
39602
41014
|
const prop = j.property("init", j.identifier(name), j.identifier(name));
|
|
@@ -39884,17 +41296,22 @@ function handleInterpolatedDeclaration(args) {
|
|
|
39884
41296
|
const callArg = resolvedCallArg ?? scalarCallArg;
|
|
39885
41297
|
const hasExplicitType = !!decl.propsType;
|
|
39886
41298
|
const isOptional = ctx.isJsxPropOptional(jsxProp);
|
|
41299
|
+
const foldsStaticBaseIntoPseudoDefault = !media && !!pseudos?.length && staticBaseValueWouldFold(styleObj[out.prop]);
|
|
39887
41300
|
styleFnFromProps.push({
|
|
39888
41301
|
fnKey,
|
|
39889
41302
|
jsxProp,
|
|
39890
41303
|
...callArg ? { callArg } : {},
|
|
39891
|
-
...hasExplicitType && !isOptional ? { condition: "always" } : {}
|
|
41304
|
+
...hasExplicitType && !isOptional || foldsStaticBaseIntoPseudoDefault ? { condition: "always" } : {}
|
|
39892
41305
|
});
|
|
39893
41306
|
if (!styleFnDecls.has(fnKey)) {
|
|
39894
41307
|
const param = j.identifier(outParamName);
|
|
39895
41308
|
const valueId = j.identifier(outParamName);
|
|
39896
41309
|
if (jsxProp !== "__props") annotateParamFromJsxProp(param, jsxProp);
|
|
39897
41310
|
if (resolvedCallArg && /\.(ts|tsx)$/.test(filePath)) param.typeAnnotation = j.tsTypeAnnotation(j.tsStringKeyword());
|
|
41311
|
+
if (foldsStaticBaseIntoPseudoDefault && isOptional && jsxProp !== "__props" && /\.(ts|tsx)$/.test(filePath)) {
|
|
41312
|
+
const baseTypeNode = param.typeAnnotation?.typeAnnotation ?? j.tsStringKeyword();
|
|
41313
|
+
param.typeAnnotation = j.tsTypeAnnotation(j.tsUnionType([baseTypeNode, j.tsUndefinedKeyword()]));
|
|
41314
|
+
}
|
|
39898
41315
|
if (jsxProp?.startsWith?.("$")) ensureShouldForwardPropDrop(decl, jsxProp);
|
|
39899
41316
|
const buildValueExpr = () => {
|
|
39900
41317
|
const transformed = (() => {
|
|
@@ -39959,7 +41376,28 @@ function handleInterpolatedDeclaration(args) {
|
|
|
39959
41376
|
};
|
|
39960
41377
|
const valueExpr = buildValueExpr();
|
|
39961
41378
|
const getPropValue = () => {
|
|
41379
|
+
if (!media && !pseudos?.length) return valueExpr;
|
|
41380
|
+
if (!media && pseudos?.length) {
|
|
41381
|
+
const existingStatic = styleObj[out.prop];
|
|
41382
|
+
let defaultValue = j.literal(null);
|
|
41383
|
+
if (existingStatic !== void 0 && existingStatic !== null) if (typeof existingStatic === "object") {
|
|
41384
|
+
if ("type" in existingStatic) {
|
|
41385
|
+
defaultValue = cloneAstNode(existingStatic);
|
|
41386
|
+
delete styleObj[out.prop];
|
|
41387
|
+
}
|
|
41388
|
+
} else {
|
|
41389
|
+
defaultValue = staticValueToLiteral(j, existingStatic);
|
|
41390
|
+
delete styleObj[out.prop];
|
|
41391
|
+
}
|
|
41392
|
+
return j.objectExpression([j.property("init", j.identifier("default"), defaultValue), ...pseudos.map((ps) => j.property("init", j.literal(ps), valueExpr))]);
|
|
41393
|
+
}
|
|
39962
41394
|
if (!media) return valueExpr;
|
|
41395
|
+
if (pseudos?.length) return buildPseudoMediaPropValue({
|
|
41396
|
+
j,
|
|
41397
|
+
valueExpr,
|
|
41398
|
+
pseudos,
|
|
41399
|
+
media
|
|
41400
|
+
});
|
|
39963
41401
|
const existingFn = styleFnDecls.get(fnKey);
|
|
39964
41402
|
let existingValue = null;
|
|
39965
41403
|
if (existingFn?.type === "ArrowFunctionExpression") {
|
|
@@ -40105,13 +41543,23 @@ function handleInterpolatedDeclaration(args) {
|
|
|
40105
41543
|
hint: "Expected: props.x && 'css-string'"
|
|
40106
41544
|
}
|
|
40107
41545
|
};
|
|
40108
|
-
if (op === "||" || op === "??")
|
|
40109
|
-
|
|
40110
|
-
|
|
40111
|
-
|
|
40112
|
-
|
|
40113
|
-
|
|
40114
|
-
|
|
41546
|
+
if (op === "||" || op === "??") {
|
|
41547
|
+
const left = body?.left;
|
|
41548
|
+
if (isMemberExpression(left) && !memberExpressionTouchesTheme(left)) return {
|
|
41549
|
+
type: "Unsupported interpolation: member expression",
|
|
41550
|
+
context: {
|
|
41551
|
+
memberExpression: left?.type,
|
|
41552
|
+
operator: op
|
|
41553
|
+
}
|
|
41554
|
+
};
|
|
41555
|
+
return {
|
|
41556
|
+
type: "Arrow function: indexed theme lookup pattern not matched",
|
|
41557
|
+
context: {
|
|
41558
|
+
property: d.property,
|
|
41559
|
+
operator: op
|
|
41560
|
+
}
|
|
41561
|
+
};
|
|
41562
|
+
}
|
|
40115
41563
|
}
|
|
40116
41564
|
if (bodyType === "CallExpression") return {
|
|
40117
41565
|
type: "Arrow function: helper call body is not supported",
|
|
@@ -40166,6 +41614,18 @@ function handleInterpolatedDeclaration(args) {
|
|
|
40166
41614
|
if (bail) state.markBail();
|
|
40167
41615
|
}
|
|
40168
41616
|
/**
|
|
41617
|
+
* Returns true if any part of a member/identifier chain references `theme`
|
|
41618
|
+
* (e.g. `props.theme.color[x]` or a destructured `theme.color[x]`). Used to
|
|
41619
|
+
* distinguish indexed theme lookups from prop-rooted member accesses.
|
|
41620
|
+
*/
|
|
41621
|
+
function memberExpressionTouchesTheme(node) {
|
|
41622
|
+
if (!node || typeof node !== "object") return false;
|
|
41623
|
+
const n = node;
|
|
41624
|
+
if (n.type === "Identifier") return n.name === "theme";
|
|
41625
|
+
if (isMemberExpression(n)) return memberExpressionTouchesTheme(n.property) || memberExpressionTouchesTheme(n.object);
|
|
41626
|
+
return false;
|
|
41627
|
+
}
|
|
41628
|
+
/**
|
|
40169
41629
|
* Searches the function body for a local variable with the given name whose
|
|
40170
41630
|
* initializer references `fnParamName`. Returns a cloned expression with
|
|
40171
41631
|
* `fnParamName` replaced by `jsxProp`, or null if no such variable is found.
|
|
@@ -40215,6 +41675,17 @@ function resolveDerivedLocalVariable(j, fnBody, fnParamName, localName, jsxProp)
|
|
|
40215
41675
|
function isPseudoElementSelector(pseudoElement) {
|
|
40216
41676
|
return pseudoElement === "::before" || pseudoElement === "::after" || pseudoElement === "::placeholder";
|
|
40217
41677
|
}
|
|
41678
|
+
/**
|
|
41679
|
+
* Whether a base style value for a property would be folded into a pseudo-gated
|
|
41680
|
+
* dynamic style function's `default` (mirrors the fold logic in getPropValue):
|
|
41681
|
+
* plain primitives and AST-node values fold; existing pseudo/media condition
|
|
41682
|
+
* buckets (plain objects without a `type` discriminator) do not.
|
|
41683
|
+
*/
|
|
41684
|
+
function staticBaseValueWouldFold(existingStatic) {
|
|
41685
|
+
if (existingStatic === void 0 || existingStatic === null) return false;
|
|
41686
|
+
if (typeof existingStatic === "object") return "type" in existingStatic;
|
|
41687
|
+
return true;
|
|
41688
|
+
}
|
|
40218
41689
|
function tryHandleLocalCustomPropertyDefinition(args) {
|
|
40219
41690
|
const { j, d, decl, expr, getOrCreateLocalStylexVar, inlineStyleProps } = args;
|
|
40220
41691
|
if (!expr || typeof expr !== "object") return false;
|
|
@@ -40269,16 +41740,45 @@ function tryHandleRuntimeConditionalStaticBranches(ctx, args) {
|
|
|
40269
41740
|
state.bailUnsupported(decl, "Unsupported interpolation: call expression");
|
|
40270
41741
|
return true;
|
|
40271
41742
|
}
|
|
40272
|
-
if (
|
|
41743
|
+
if (!subtractLaterStaticOverrides({
|
|
41744
|
+
rule,
|
|
41745
|
+
allRules,
|
|
41746
|
+
currentDecl: d,
|
|
41747
|
+
branchStyles: [consequentStyle, alternateStyle]
|
|
41748
|
+
})) {
|
|
40273
41749
|
state.bailUnsupported(decl, "Unsupported interpolation: call expression");
|
|
40274
41750
|
return true;
|
|
40275
41751
|
}
|
|
41752
|
+
if (!Object.keys(consequentStyle).length && !Object.keys(alternateStyle).length) return true;
|
|
40276
41753
|
const target = getBaseStyleTarget();
|
|
40277
41754
|
for (const [prop, value] of Object.entries(alternateStyle)) target[prop] = value;
|
|
40278
41755
|
applyVariant({ when }, consequentStyle);
|
|
40279
41756
|
decl.needsWrapperComponent = true;
|
|
41757
|
+
recordNonPropConditionRoots(decl, expr.test);
|
|
40280
41758
|
return true;
|
|
40281
41759
|
}
|
|
41760
|
+
/**
|
|
41761
|
+
* Records the root identifiers of an imported runtime condition on the decl so
|
|
41762
|
+
* wrapper emission treats them as module-scope bindings rather than component
|
|
41763
|
+
* props (which matters for lowercase roots like `browser.isTouchDevice`).
|
|
41764
|
+
*/
|
|
41765
|
+
function recordNonPropConditionRoots(decl, test) {
|
|
41766
|
+
const roots = decl.nonPropConditionRoots ??= /* @__PURE__ */ new Set();
|
|
41767
|
+
const visit = (expr) => {
|
|
41768
|
+
if (expr.type === "LogicalExpression") {
|
|
41769
|
+
visit(expr.left);
|
|
41770
|
+
visit(expr.right);
|
|
41771
|
+
return;
|
|
41772
|
+
}
|
|
41773
|
+
if (expr.type === "UnaryExpression") {
|
|
41774
|
+
visit(expr.argument);
|
|
41775
|
+
return;
|
|
41776
|
+
}
|
|
41777
|
+
const info = extractRootAndPath(expr);
|
|
41778
|
+
if (info && info.path.length > 0) roots.add(info.rootName);
|
|
41779
|
+
};
|
|
41780
|
+
visit(test);
|
|
41781
|
+
}
|
|
40282
41782
|
function buildStaticBranchStyle(d, rawValue) {
|
|
40283
41783
|
if (d.property === "background" && isUnsupportedBackgroundShorthandValue(rawValue)) return null;
|
|
40284
41784
|
const staticDecl = {
|
|
@@ -40303,24 +41803,140 @@ function sameStyleProps(left, right) {
|
|
|
40303
41803
|
const rightKeys = new Set(Object.keys(right));
|
|
40304
41804
|
return leftKeys.length === rightKeys.size && leftKeys.every((key) => rightKeys.has(key));
|
|
40305
41805
|
}
|
|
40306
|
-
|
|
41806
|
+
/**
|
|
41807
|
+
* Removes branch properties that are unconditionally overridden by later static
|
|
41808
|
+
* declarations in the same selector context, so the runtime variant cannot
|
|
41809
|
+
* invert the original CSS cascade. Partially overridden directional props are
|
|
41810
|
+
* narrowed to the longhands that survive the override (e.g. `marginBlock`
|
|
41811
|
+
* overridden by a later `margin-top` becomes `marginBlockEnd`).
|
|
41812
|
+
*
|
|
41813
|
+
* Returns false when a later overlapping declaration cannot be subtracted
|
|
41814
|
+
* safely (conditional at-rule context, dynamic value, property-less helper, or
|
|
41815
|
+
* a multi-token branch value that cannot be split per longhand) — the caller
|
|
41816
|
+
* must bail in that case.
|
|
41817
|
+
*/
|
|
41818
|
+
function subtractLaterStaticOverrides(args) {
|
|
41819
|
+
const { rule, allRules, currentDecl, branchStyles, ignoreUnsafeOverlaps = false } = args;
|
|
40307
41820
|
const currentIndex = rule.declarations.indexOf(currentDecl);
|
|
40308
|
-
if (currentIndex === -1) return
|
|
40309
|
-
|
|
41821
|
+
if (currentIndex === -1) return true;
|
|
41822
|
+
const laterContexts = [{
|
|
41823
|
+
declarations: rule.declarations.slice(currentIndex + 1),
|
|
41824
|
+
unconditional: true
|
|
41825
|
+
}];
|
|
40310
41826
|
const currentRuleIndex = allRules.indexOf(rule);
|
|
40311
|
-
if (currentRuleIndex
|
|
40312
|
-
|
|
40313
|
-
|
|
40314
|
-
|
|
41827
|
+
if (currentRuleIndex !== -1) for (const laterRule of allRules.slice(currentRuleIndex + 1)) {
|
|
41828
|
+
if (laterRule.selector !== rule.selector) continue;
|
|
41829
|
+
laterContexts.push({
|
|
41830
|
+
declarations: laterRule.declarations,
|
|
41831
|
+
unconditional: sameAtRuleStack(laterRule.atRuleStack, rule.atRuleStack)
|
|
41832
|
+
});
|
|
40315
41833
|
}
|
|
40316
|
-
|
|
41834
|
+
const branchProps = () => [...new Set(branchStyles.flatMap((style) => Object.keys(style)))];
|
|
41835
|
+
for (const context of laterContexts) for (const laterDecl of context.declarations) {
|
|
41836
|
+
if (!laterDecl.property) {
|
|
41837
|
+
if (branchProps().length) return false;
|
|
41838
|
+
continue;
|
|
41839
|
+
}
|
|
41840
|
+
if (isBorderShorthandProperty(laterDecl.property)) {
|
|
41841
|
+
const borderProps = new Set(cssDeclarationToStylexDeclarations(laterDecl).map((out) => out.prop));
|
|
41842
|
+
if (branchProps().some((prop) => [...borderProps].some((borderProp) => stylexPropsOverlap(prop, borderProp)))) return false;
|
|
41843
|
+
continue;
|
|
41844
|
+
}
|
|
41845
|
+
if (laterDecl.property.trim() === "background") {
|
|
41846
|
+
const overlapped = branchProps().filter((prop) => prop.startsWith("background"));
|
|
41847
|
+
if (!overlapped.length) continue;
|
|
41848
|
+
if (currentDecl.important && !laterDecl.important) {
|
|
41849
|
+
if (ignoreUnsafeOverlaps) continue;
|
|
41850
|
+
return false;
|
|
41851
|
+
}
|
|
41852
|
+
if (!context.unconditional || laterDecl.value.kind !== "static") {
|
|
41853
|
+
if (ignoreUnsafeOverlaps) continue;
|
|
41854
|
+
return false;
|
|
41855
|
+
}
|
|
41856
|
+
for (const branch of branchStyles) for (const prop of overlapped) delete branch[prop];
|
|
41857
|
+
continue;
|
|
41858
|
+
}
|
|
41859
|
+
for (const out of cssDeclarationToStylexDeclarations(laterDecl)) {
|
|
41860
|
+
const overrideProp = out.prop;
|
|
41861
|
+
const overlapped = branchProps().filter((prop) => stylexPropsOverlap(prop, overrideProp));
|
|
41862
|
+
if (!overlapped.length) continue;
|
|
41863
|
+
if (currentDecl.important && !laterDecl.important) {
|
|
41864
|
+
if (ignoreUnsafeOverlaps) continue;
|
|
41865
|
+
return false;
|
|
41866
|
+
}
|
|
41867
|
+
if (!context.unconditional || laterDecl.value.kind !== "static") {
|
|
41868
|
+
if (ignoreUnsafeOverlaps) continue;
|
|
41869
|
+
return false;
|
|
41870
|
+
}
|
|
41871
|
+
for (const branch of branchStyles) if (!subtractOverrideFromBranch(branch, overlapped, overrideProp)) return false;
|
|
41872
|
+
}
|
|
41873
|
+
}
|
|
41874
|
+
return true;
|
|
40317
41875
|
}
|
|
40318
|
-
function
|
|
40319
|
-
|
|
40320
|
-
|
|
40321
|
-
|
|
41876
|
+
function sameAtRuleStack(left, right) {
|
|
41877
|
+
return left.length === right.length && left.every((entry, i) => entry === right[i]);
|
|
41878
|
+
}
|
|
41879
|
+
/** True for the `border` / `border-<side>` shorthands (not the longhands). */
|
|
41880
|
+
function isBorderShorthandProperty(property) {
|
|
41881
|
+
return /^border(?:-(?:top|right|bottom|left))?$/.test(property.trim());
|
|
41882
|
+
}
|
|
41883
|
+
function subtractOverrideFromBranch(branch, overlappedProps, overrideProp) {
|
|
41884
|
+
const overridePhysical = new Set(physicalLonghandExpansion(overrideProp));
|
|
41885
|
+
const overrideIsLogical = isLogicalDirectionalProp(overrideProp);
|
|
41886
|
+
for (const branchProp of overlappedProps) {
|
|
41887
|
+
if (!(branchProp in branch)) continue;
|
|
41888
|
+
const branchPhysical = physicalLonghandExpansion(branchProp);
|
|
41889
|
+
const remainder = branchPhysical.filter((prop) => !overridePhysical.has(prop));
|
|
41890
|
+
if (remainder.length === branchPhysical.length) continue;
|
|
41891
|
+
if (isLogicalDirectionalProp(branchProp) !== overrideIsLogical) return false;
|
|
41892
|
+
const value = branch[branchProp];
|
|
41893
|
+
delete branch[branchProp];
|
|
41894
|
+
if (!remainder.length) continue;
|
|
41895
|
+
if (!isSingleCssToken(value)) return false;
|
|
41896
|
+
for (const physical of remainder) {
|
|
41897
|
+
const name = overrideIsLogical && LOGICAL_TO_PHYSICAL[branchProp] ? logicalFormForPhysical(branchProp, physical) : physical;
|
|
41898
|
+
if (!name) return false;
|
|
41899
|
+
branch[name] = value;
|
|
41900
|
+
}
|
|
40322
41901
|
}
|
|
40323
|
-
return
|
|
41902
|
+
return true;
|
|
41903
|
+
}
|
|
41904
|
+
/**
|
|
41905
|
+
* True for a logical directional longhand whose physical side(s) depend on the
|
|
41906
|
+
* writing mode — `marginInline`, `paddingBlockEnd`, `scrollMarginInlineStart`,
|
|
41907
|
+
* etc. The physical-neutral full shorthands (`margin`, `padding`) and physical
|
|
41908
|
+
* sides (`marginTop`) are not logical.
|
|
41909
|
+
*/
|
|
41910
|
+
function isLogicalDirectionalProp(prop) {
|
|
41911
|
+
return LOGICAL_TO_PHYSICAL[prop] !== void 0;
|
|
41912
|
+
}
|
|
41913
|
+
/** Physical longhands covered by a StyleX directional/border property. */
|
|
41914
|
+
function physicalLonghandExpansion(prop) {
|
|
41915
|
+
const group = SHORTHAND_LONGHANDS[prop];
|
|
41916
|
+
if (group) return [...group.physical];
|
|
41917
|
+
const logical = LOGICAL_TO_PHYSICAL[prop];
|
|
41918
|
+
if (logical) return [...logical];
|
|
41919
|
+
const borderMatch = prop.match(/^border(Top|Right|Bottom|Left)?(Width|Style|Color)$/);
|
|
41920
|
+
if (borderMatch) {
|
|
41921
|
+
const side = borderMatch[1];
|
|
41922
|
+
const kind = borderMatch[2];
|
|
41923
|
+
return side ? [prop] : [
|
|
41924
|
+
"Top",
|
|
41925
|
+
"Right",
|
|
41926
|
+
"Bottom",
|
|
41927
|
+
"Left"
|
|
41928
|
+
].map((s) => `border${s}${kind}`);
|
|
41929
|
+
}
|
|
41930
|
+
return [prop];
|
|
41931
|
+
}
|
|
41932
|
+
/** Maps a physical longhand back to the Start/End form of a logical branch prop. */
|
|
41933
|
+
function logicalFormForPhysical(logicalProp, physical) {
|
|
41934
|
+
for (const [name, physicalProps] of Object.entries(LOGICAL_TO_PHYSICAL)) if (physicalProps.length === 1 && physicalProps[0] === physical && name.startsWith(logicalProp)) return name;
|
|
41935
|
+
return null;
|
|
41936
|
+
}
|
|
41937
|
+
function isSingleCssToken(value) {
|
|
41938
|
+
if (typeof value === "number") return true;
|
|
41939
|
+
return typeof value === "string" && value.trim() !== "" && !/\s/.test(value.trim());
|
|
40324
41940
|
}
|
|
40325
41941
|
function stylexPropsOverlap(left, right) {
|
|
40326
41942
|
const leftRelated = relatedDirectionalProps(left);
|
|
@@ -40356,21 +41972,20 @@ function addRelatedBorderLonghands(prop, related) {
|
|
|
40356
41972
|
}
|
|
40357
41973
|
function isImportedRuntimeCondition(expr, importMap) {
|
|
40358
41974
|
const info = extractRootAndPath(expr);
|
|
40359
|
-
if (info && info.path.length > 0 && importMap.has(info.rootName)
|
|
41975
|
+
if (info && info.path.length > 0 && importMap.has(info.rootName)) return true;
|
|
40360
41976
|
if (expr.type === "LogicalExpression" && expr.operator === "&&") return isImportedRuntimeCondition(expr.left, importMap) && isImportedRuntimeCondition(expr.right, importMap);
|
|
40361
41977
|
if (expr.type === "UnaryExpression" && expr.operator === "!") return isImportedRuntimeCondition(expr.argument, importMap);
|
|
40362
41978
|
return false;
|
|
40363
41979
|
}
|
|
40364
|
-
function
|
|
40365
|
-
return /^[A-Z]/.test(rootName);
|
|
40366
|
-
}
|
|
40367
|
-
function isImportedShorthandUnitValue(d, decl, importMap) {
|
|
41980
|
+
function isImportedShorthandUnitValue(d, decl, importMap, numericIdentifiers) {
|
|
40368
41981
|
if (!d.property || !isCssShorthandProperty(d.property)) return false;
|
|
40369
41982
|
const staticParts = getSingleSlotStaticParts(d, decl);
|
|
40370
41983
|
if (!staticParts || !/^[a-zA-Z%]/.test(staticParts.suffix)) return false;
|
|
40371
41984
|
const slotPart = d.value.kind === "interpolated" ? d.value.parts.find((part) => part.kind === "slot") : null;
|
|
40372
41985
|
const info = extractRootAndPath(slotPart && slotPart.kind === "slot" ? decl.templateExpressions[slotPart.slotId] : void 0);
|
|
40373
|
-
|
|
41986
|
+
if (!info || !importMap.has(info.rootName)) return false;
|
|
41987
|
+
if ((d.property === "margin" || d.property === "padding") && staticParts.prefix.trim() === "" && /^[a-zA-Z%]+$/.test(staticParts.suffix.trim()) && numericIdentifiers.has(info.rootName)) return false;
|
|
41988
|
+
return true;
|
|
40374
41989
|
}
|
|
40375
41990
|
function expressionToSource(j, expr) {
|
|
40376
41991
|
try {
|
|
@@ -40684,20 +42299,22 @@ function buildCssCalcTemplateExpression(args) {
|
|
|
40684
42299
|
const expressions = [];
|
|
40685
42300
|
const quasis = [];
|
|
40686
42301
|
let currentQuasi = "calc(";
|
|
40687
|
-
const appendOperand = (operand) => {
|
|
40688
|
-
const staticText = expressionToCalcStaticText(operand.node, args.unit);
|
|
42302
|
+
const appendOperand = (operand, options = {}) => {
|
|
42303
|
+
const staticText = expressionToCalcStaticText(operand.node, args.unit, args.staticIdentifierValues);
|
|
40689
42304
|
if (staticText !== null) {
|
|
40690
|
-
currentQuasi += staticText;
|
|
42305
|
+
currentQuasi += options.negate ? negateCalcStaticText(staticText) : staticText;
|
|
40691
42306
|
return true;
|
|
40692
42307
|
}
|
|
40693
42308
|
if (!operand.allowExpression || !isStylexCalcExpression(operand.node)) return false;
|
|
42309
|
+
if (options.negate) currentQuasi += "-1 * ";
|
|
40694
42310
|
quasis.push(currentQuasi);
|
|
40695
42311
|
currentQuasi = "";
|
|
40696
42312
|
expressions.push(operand.node);
|
|
40697
42313
|
return true;
|
|
40698
42314
|
};
|
|
40699
|
-
if (!appendOperand(args.left)) return null;
|
|
40700
|
-
|
|
42315
|
+
if (!appendOperand(args.left, { negate: args.negate })) return null;
|
|
42316
|
+
const operator = args.negate ? negateCssCalcOperator(args.operator) : args.operator;
|
|
42317
|
+
currentQuasi += ` ${operator} `;
|
|
40701
42318
|
if (!appendOperand(args.right)) return null;
|
|
40702
42319
|
currentQuasi += ")";
|
|
40703
42320
|
if (expressions.length === 0) return args.j.literal(currentQuasi);
|
|
@@ -40708,9 +42325,27 @@ function buildCssCalcTemplateExpression(args) {
|
|
|
40708
42325
|
cooked: raw
|
|
40709
42326
|
}, index === quasis.length - 1)), expressions);
|
|
40710
42327
|
}
|
|
40711
|
-
function
|
|
42328
|
+
function buildNegatedCssTokenTemplate(j, expression) {
|
|
42329
|
+
return j.templateLiteral([j.templateElement({
|
|
42330
|
+
raw: "calc(-1 * ",
|
|
42331
|
+
cooked: "calc(-1 * "
|
|
42332
|
+
}, false), j.templateElement({
|
|
42333
|
+
raw: ")",
|
|
42334
|
+
cooked: ")"
|
|
42335
|
+
}, true)], [expression]);
|
|
42336
|
+
}
|
|
42337
|
+
function negateCssCalcOperator(operator) {
|
|
42338
|
+
return operator === "+" ? "-" : operator === "-" ? "+" : operator;
|
|
42339
|
+
}
|
|
42340
|
+
function negateCalcStaticText(value) {
|
|
42341
|
+
return value.startsWith("-") ? value.slice(1) : `-${value}`;
|
|
42342
|
+
}
|
|
42343
|
+
function expressionToCalcStaticText(node, unit = "", staticIdentifierValues) {
|
|
40712
42344
|
const staticValue = literalToStaticValue(node);
|
|
40713
42345
|
if (typeof staticValue === "number") return `${staticValue}${unit}`;
|
|
42346
|
+
const identifierName = node && typeof node === "object" && node.type === "Identifier" ? node.name : void 0;
|
|
42347
|
+
const identifierValue = identifierName ? staticIdentifierValues?.get(identifierName) : void 0;
|
|
42348
|
+
if (typeof identifierValue === "number") return `${identifierValue}${unit}`;
|
|
40714
42349
|
return null;
|
|
40715
42350
|
}
|
|
40716
42351
|
function hasAdjacentTemplateUnit(quasis, expressionIndex) {
|
|
@@ -40873,7 +42508,7 @@ function tryHandleDynamicPseudoElementStyleFunction(args) {
|
|
|
40873
42508
|
* Apply a resolved theme boolean value to a style object, expanding CSS shorthands.
|
|
40874
42509
|
* Returns false if the value cannot be expanded (caller should bail).
|
|
40875
42510
|
*/
|
|
40876
|
-
function applyThemeBooleanValue(j, cssProp, value, target) {
|
|
42511
|
+
function applyThemeBooleanValue(j, cssProp, value, target, important, cssValueText) {
|
|
40877
42512
|
const node = value;
|
|
40878
42513
|
const unwrapped = node?.type === "ExpressionStatement" ? node.expression : node;
|
|
40879
42514
|
const strValue = unwrapped && (unwrapped.type === "StringLiteral" || unwrapped.type === "Literal") && typeof unwrapped.value === "string" ? unwrapped.value : null;
|
|
@@ -40883,18 +42518,85 @@ function applyThemeBooleanValue(j, cssProp, value, target) {
|
|
|
40883
42518
|
const direction = borderMatch[1] ? borderMatch[1].slice(1).charAt(0).toUpperCase() + borderMatch[1].slice(2) : "";
|
|
40884
42519
|
const parsed = parseBorderShorthandParts(strValue);
|
|
40885
42520
|
if (!parsed) return false;
|
|
40886
|
-
if (parsed.width) target[`border${direction}Width`] = j.literal(parsed.width);
|
|
40887
|
-
if (parsed.style) target[`border${direction}Style`] = j.literal(parsed.style);
|
|
40888
|
-
if (parsed.color) target[`border${direction}Color`] = j.literal(parsed.color);
|
|
42521
|
+
if (parsed.width) target[`border${direction}Width`] = appendImportantToStyleValue(j, j.literal(parsed.width), important);
|
|
42522
|
+
if (parsed.style) target[`border${direction}Style`] = appendImportantToStyleValue(j, j.literal(parsed.style), important);
|
|
42523
|
+
if (parsed.color) target[`border${direction}Color`] = appendImportantToStyleValue(j, j.literal(parsed.color), important);
|
|
40889
42524
|
return true;
|
|
40890
42525
|
}
|
|
40891
42526
|
if (cssProp === "background") {
|
|
40892
|
-
|
|
42527
|
+
const backgroundText = strValue ?? cssValueText ?? "";
|
|
42528
|
+
if (backgroundText.trim() === "none") {
|
|
42529
|
+
target.backgroundImage = appendImportantToStyleValue(j, j.literal("none"), important);
|
|
42530
|
+
target.backgroundColor = appendImportantToStyleValue(j, j.literal("transparent"), important);
|
|
42531
|
+
return true;
|
|
42532
|
+
}
|
|
42533
|
+
const backgroundProp = resolveBackgroundStylexProp(backgroundText);
|
|
42534
|
+
target[backgroundProp] = appendImportantToStyleValue(j, value, important);
|
|
42535
|
+
applyBackgroundShorthandLayerReset(j, target, backgroundProp, important);
|
|
40893
42536
|
return true;
|
|
40894
42537
|
}
|
|
40895
|
-
|
|
42538
|
+
if (isCssShorthandProperty(cssProp)) return false;
|
|
42539
|
+
target[cssPropertyToStylexProp(cssProp)] = appendImportantToStyleValue(j, value, important);
|
|
40896
42540
|
return true;
|
|
40897
42541
|
}
|
|
42542
|
+
function restoreThemeStyleKeyFromPairedSide(targetBaseKey, pairedBaseKey, pairedStyleKey) {
|
|
42543
|
+
if (pairedStyleKey?.startsWith(pairedBaseKey)) return `${targetBaseKey}${pairedStyleKey.slice(pairedBaseKey.length)}`;
|
|
42544
|
+
return targetBaseKey;
|
|
42545
|
+
}
|
|
42546
|
+
function getLatestThemeInterleavableSourceOrder(args) {
|
|
42547
|
+
const sourceOrders = Object.values(args.variantSourceOrder);
|
|
42548
|
+
appendSourceOrders(sourceOrders, args.styleFnFromProps);
|
|
42549
|
+
appendSourceOrders(sourceOrders, args.decl.needsUseThemeHook);
|
|
42550
|
+
appendSourceOrders(sourceOrders, args.decl.pseudoAliasSelectors);
|
|
42551
|
+
appendSourceOrders(sourceOrders, args.decl.variantDimensions);
|
|
42552
|
+
return sourceOrders.length > 0 ? Math.max(...sourceOrders) : -1;
|
|
42553
|
+
}
|
|
42554
|
+
function appendSourceOrders(sourceOrders, entries) {
|
|
42555
|
+
for (const entry of entries ?? []) if (entry.sourceOrder !== void 0) sourceOrders.push(entry.sourceOrder);
|
|
42556
|
+
}
|
|
42557
|
+
function applyBackgroundShorthandLayerReset(j, target, backgroundProp, important) {
|
|
42558
|
+
if (backgroundProp === "backgroundColor") {
|
|
42559
|
+
target.backgroundImage = appendImportantToStyleValue(j, j.literal("none"), important);
|
|
42560
|
+
return;
|
|
42561
|
+
}
|
|
42562
|
+
target.backgroundColor = appendImportantToStyleValue(j, j.literal("transparent"), important);
|
|
42563
|
+
}
|
|
42564
|
+
function resolveRuntimeBackgroundStylexProp(value, cssValueText) {
|
|
42565
|
+
const node = unwrapExpressionNode(value);
|
|
42566
|
+
if (node?.type !== "ConditionalExpression") {
|
|
42567
|
+
const staticText = getRuntimeBackgroundStaticText(node);
|
|
42568
|
+
if (staticText !== null) return resolveBackgroundStylexProp(staticText);
|
|
42569
|
+
return cssValueText ? resolveBackgroundStylexProp(cssValueText) : null;
|
|
42570
|
+
}
|
|
42571
|
+
const consequentProp = classifyRuntimeBackgroundBranch(node.consequent);
|
|
42572
|
+
const alternateProp = classifyRuntimeBackgroundBranch(node.alternate);
|
|
42573
|
+
if (consequentProp && alternateProp) return consequentProp === alternateProp ? consequentProp : "unsupported";
|
|
42574
|
+
const cssTextProp = cssValueText ? resolveBackgroundStylexProp(cssValueText) : null;
|
|
42575
|
+
const knownProp = consequentProp ?? alternateProp;
|
|
42576
|
+
if (knownProp) {
|
|
42577
|
+
if (knownProp === "backgroundImage") return "unsupported";
|
|
42578
|
+
if (cssTextProp && cssTextProp !== knownProp) return "unsupported";
|
|
42579
|
+
return "backgroundColor";
|
|
42580
|
+
}
|
|
42581
|
+
if (cssTextProp === "backgroundImage") return "unsupported";
|
|
42582
|
+
return "backgroundColor";
|
|
42583
|
+
}
|
|
42584
|
+
function classifyRuntimeBackgroundBranch(value) {
|
|
42585
|
+
const staticText = getRuntimeBackgroundStaticText(unwrapExpressionNode(value));
|
|
42586
|
+
return staticText === null ? null : resolveBackgroundStylexProp(staticText);
|
|
42587
|
+
}
|
|
42588
|
+
function unwrapExpressionNode(value) {
|
|
42589
|
+
if (!value || typeof value !== "object") return null;
|
|
42590
|
+
const node = value;
|
|
42591
|
+
if (node.type === "ExpressionStatement" || node.type === "TSAsExpression" || node.type === "TSSatisfiesExpression") return unwrapExpressionNode(node.expression);
|
|
42592
|
+
return node;
|
|
42593
|
+
}
|
|
42594
|
+
function getRuntimeBackgroundStaticText(value) {
|
|
42595
|
+
if (!value) return null;
|
|
42596
|
+
if ((value.type === "StringLiteral" || value.type === "Literal") && typeof value.value === "string") return value.value;
|
|
42597
|
+
if (value.type === "TemplateLiteral") return (value.quasis ?? []).map((quasi) => quasi.value?.cooked ?? quasi.value?.raw ?? "").join("") || null;
|
|
42598
|
+
return null;
|
|
42599
|
+
}
|
|
40898
42600
|
function scalarizePropsObjectDynamicValue(args) {
|
|
40899
42601
|
const propNames = uniqueScalarPropNames(args.propNames);
|
|
40900
42602
|
if (propNames.length === 0) return null;
|
|
@@ -41538,6 +43240,84 @@ function tryHandleMultiSlotTernary(ctx, d) {
|
|
|
41538
43240
|
function hasRuntimeImport(imports) {
|
|
41539
43241
|
return (imports ?? []).some((imp) => !isStylexImportSource(imp.from.value));
|
|
41540
43242
|
}
|
|
43243
|
+
function hasSourceOrderedThemeStyleOverlap(decl, extraStyleObjects, cssText) {
|
|
43244
|
+
const themeProps = /* @__PURE__ */ new Set();
|
|
43245
|
+
for (const entry of decl.needsUseThemeHook ?? []) {
|
|
43246
|
+
if (entry.sourceOrder === void 0) continue;
|
|
43247
|
+
collectStyleObjectProps(extraStyleObjects.get(entry.trueStyleKey ?? ""), themeProps);
|
|
43248
|
+
collectStyleObjectProps(extraStyleObjects.get(entry.falseStyleKey ?? ""), themeProps);
|
|
43249
|
+
}
|
|
43250
|
+
return cssTextMayOverlapStylexProps(cssText, themeProps);
|
|
43251
|
+
}
|
|
43252
|
+
function collectStyleObjectProps(style, props) {
|
|
43253
|
+
if (!style) return;
|
|
43254
|
+
for (const prop of Object.keys(style)) props.add(prop);
|
|
43255
|
+
}
|
|
43256
|
+
function cssTextMayOverlapStylexProps(cssText, props) {
|
|
43257
|
+
if (props.size === 0) return false;
|
|
43258
|
+
if (!cssText) return true;
|
|
43259
|
+
const chunks = cssText.split(";").map((chunk) => chunk.trim()).filter(Boolean);
|
|
43260
|
+
if (chunks.length === 0) return true;
|
|
43261
|
+
for (const chunk of chunks) {
|
|
43262
|
+
const match = chunk.match(/^([^:]+):([\s\S]+)$/);
|
|
43263
|
+
if (!match?.[1] || !match[2]) return true;
|
|
43264
|
+
const property = match[1].trim();
|
|
43265
|
+
const valueRaw = match[2].trim();
|
|
43266
|
+
if (laterDeclarationMayResetStylexProps(property, props)) return true;
|
|
43267
|
+
for (const out of cssDeclarationToStylexDeclarations({
|
|
43268
|
+
property,
|
|
43269
|
+
value: {
|
|
43270
|
+
kind: "static",
|
|
43271
|
+
value: valueRaw
|
|
43272
|
+
},
|
|
43273
|
+
important: false,
|
|
43274
|
+
valueRaw
|
|
43275
|
+
})) if (hasOverlappingStylexProp(props, out.prop)) return true;
|
|
43276
|
+
}
|
|
43277
|
+
return false;
|
|
43278
|
+
}
|
|
43279
|
+
function hasLaterDeclarationForStylexProps(current, rules, props) {
|
|
43280
|
+
if (props.size === 0) return false;
|
|
43281
|
+
let sawCurrent = false;
|
|
43282
|
+
for (const rule of rules) for (const candidate of rule.declarations) {
|
|
43283
|
+
if (candidate === current) {
|
|
43284
|
+
sawCurrent = true;
|
|
43285
|
+
continue;
|
|
43286
|
+
}
|
|
43287
|
+
if (!isDeclarationAfter(current, candidate, sawCurrent)) continue;
|
|
43288
|
+
if (!candidate.property) return true;
|
|
43289
|
+
if (laterDeclarationMayResetStylexProps(candidate.property, props)) return true;
|
|
43290
|
+
for (const out of cssDeclarationToStylexDeclarations(candidate)) if (hasOverlappingStylexProp(props, out.prop)) return true;
|
|
43291
|
+
}
|
|
43292
|
+
return false;
|
|
43293
|
+
}
|
|
43294
|
+
function isDeclarationAfter(current, candidate, sawCurrent) {
|
|
43295
|
+
if (current.sourceOrder !== void 0 && candidate.sourceOrder !== void 0) return candidate.sourceOrder > current.sourceOrder;
|
|
43296
|
+
return sawCurrent;
|
|
43297
|
+
}
|
|
43298
|
+
function hasOverlappingStylexProp(props, candidate) {
|
|
43299
|
+
for (const prop of props) if (stylexPropsOverlap(prop, candidate)) return true;
|
|
43300
|
+
return false;
|
|
43301
|
+
}
|
|
43302
|
+
function laterDeclarationMayResetStylexProps(cssProperty, props) {
|
|
43303
|
+
const property = cssProperty.trim();
|
|
43304
|
+
if (property === "background") return hasStylexPropWithPrefix(props, "background");
|
|
43305
|
+
if (!isBorderShorthandProperty(property)) return false;
|
|
43306
|
+
const side = property.match(/^border-(top|right|bottom|left)$/)?.[1];
|
|
43307
|
+
return hasBorderResetOverlap(props, side);
|
|
43308
|
+
}
|
|
43309
|
+
function hasStylexPropWithPrefix(props, prefix) {
|
|
43310
|
+
for (const prop of props) if (prop.startsWith(prefix)) return true;
|
|
43311
|
+
return false;
|
|
43312
|
+
}
|
|
43313
|
+
function hasBorderResetOverlap(props, side) {
|
|
43314
|
+
const sidePrefix = side ? `border${side.charAt(0).toUpperCase()}${side.slice(1)}` : "border";
|
|
43315
|
+
for (const prop of props) {
|
|
43316
|
+
if (!/^border(?:Top|Right|Bottom|Left)?(?:Width|Style|Color)$/.test(prop)) continue;
|
|
43317
|
+
if (!side || prop.startsWith(sidePrefix) || /^border(?:Width|Style|Color)$/.test(prop)) return true;
|
|
43318
|
+
}
|
|
43319
|
+
return false;
|
|
43320
|
+
}
|
|
41541
43321
|
/**
|
|
41542
43322
|
* If any variant `when` condition references the styled-components theme object,
|
|
41543
43323
|
* mark the declaration as needing the `useTheme()` hook so the emitted wrapper
|
|
@@ -42109,7 +43889,7 @@ function findFirst(collection, predicate) {
|
|
|
42109
43889
|
//#endregion
|
|
42110
43890
|
//#region src/internal/lower-rules/process-rule-declarations.ts
|
|
42111
43891
|
function processRuleDeclarations(args) {
|
|
42112
|
-
const { ctx, rule, allRules, media, pseudos, pseudoElement, attrTarget, resolvedSelectorMedia, applyResolvedPropValue } = args;
|
|
43892
|
+
const { ctx, rule, allRules, media, pseudos, pseudoElement, attrTarget, resolvedSelectorMedia, hasAncestorAttributeScope, applyResolvedPropValue } = args;
|
|
42113
43893
|
const { state } = ctx;
|
|
42114
43894
|
for (const d of rule.declarations) {
|
|
42115
43895
|
ctx.setCurrentDeclarationSourceOrder(d.sourceOrder);
|
|
@@ -42122,6 +43902,12 @@ function processRuleDeclarations(args) {
|
|
|
42122
43902
|
d.property = resolvedProperty;
|
|
42123
43903
|
}
|
|
42124
43904
|
if (d.value.kind === "interpolated") {
|
|
43905
|
+
if (d.property && isLogicalScrollAxisShorthand(d.property)) {
|
|
43906
|
+
state.bailUnsupported(ctx.decl, "Dynamic logical scroll shorthand cannot be expanded — bind a specific longhand (e.g. scroll-padding-inline-start) instead");
|
|
43907
|
+
if (state.currentDecl === ctx.decl) continue;
|
|
43908
|
+
state.bail = true;
|
|
43909
|
+
break;
|
|
43910
|
+
}
|
|
42125
43911
|
handleInterpolatedDeclaration({
|
|
42126
43912
|
ctx,
|
|
42127
43913
|
rule,
|
|
@@ -42132,6 +43918,7 @@ function processRuleDeclarations(args) {
|
|
|
42132
43918
|
pseudoElement,
|
|
42133
43919
|
attrTarget,
|
|
42134
43920
|
resolvedSelectorMedia,
|
|
43921
|
+
hasAncestorAttributeScope,
|
|
42135
43922
|
applyResolvedPropValue
|
|
42136
43923
|
});
|
|
42137
43924
|
if (state.bail) break;
|
|
@@ -42167,6 +43954,20 @@ function processRuleDeclarations(args) {
|
|
|
42167
43954
|
}
|
|
42168
43955
|
}
|
|
42169
43956
|
if (d.property === "background" && isUnsupportedBackgroundShorthandValue(d.valueRaw)) {
|
|
43957
|
+
const expanded = d.value.kind === "static" && !d.important && !hasOtherBackgroundDeclaration(allRules, d) ? expandBackgroundShorthandComponents(d.valueRaw) : null;
|
|
43958
|
+
if (expanded) {
|
|
43959
|
+
const commentSource = {
|
|
43960
|
+
leading: d.leadingComment,
|
|
43961
|
+
leadingLine: d.leadingLineComment,
|
|
43962
|
+
trailingLine: d.trailingLineComment
|
|
43963
|
+
};
|
|
43964
|
+
let isFirst = true;
|
|
43965
|
+
for (const { prop, value } of expanded) {
|
|
43966
|
+
applyResolvedPropValue(prop, value, isFirst ? commentSource : null, d.property);
|
|
43967
|
+
isFirst = false;
|
|
43968
|
+
}
|
|
43969
|
+
continue;
|
|
43970
|
+
}
|
|
42170
43971
|
state.bailUnsupported(ctx.decl, "Unsupported background shorthand: multiple components cannot be mapped to a single StyleX longhand");
|
|
42171
43972
|
if (state.currentDecl === ctx.decl) break;
|
|
42172
43973
|
state.bail = true;
|
|
@@ -42221,10 +44022,23 @@ function resolveInterpolatedPropertyName(property, ctx) {
|
|
|
42221
44022
|
if (!resolved.startsWith("--")) return null;
|
|
42222
44023
|
return resolved;
|
|
42223
44024
|
}
|
|
44025
|
+
/**
|
|
44026
|
+
* True when any declaration other than `current` (across all of the component's
|
|
44027
|
+
* rules) targets a `background`/`background-*` property. A multi-component
|
|
44028
|
+
* background expansion only reproduces reset semantics in isolation, so the
|
|
44029
|
+
* presence of a sibling background declaration makes the expansion unsafe.
|
|
44030
|
+
*/
|
|
44031
|
+
function hasOtherBackgroundDeclaration(allRules, current) {
|
|
44032
|
+
for (const rule of allRules) for (const declaration of rule.declarations) {
|
|
44033
|
+
if (declaration === current) continue;
|
|
44034
|
+
if (declaration.property && /^background(-|$)/.test(declaration.property)) return true;
|
|
44035
|
+
}
|
|
44036
|
+
return false;
|
|
44037
|
+
}
|
|
42224
44038
|
//#endregion
|
|
42225
44039
|
//#region src/internal/lower-rules/process-rules.ts
|
|
42226
44040
|
function processDeclRules(ctx) {
|
|
42227
|
-
const { state, decl, styleObj, perPropPseudo, perPropMedia, nestedSelectors, variantBuckets, styleFnDecls, attrBuckets, localVarValues, cssHelperPropValues, getComposedDefaultValue } = ctx;
|
|
44041
|
+
const { state, decl, styleObj, perPropPseudo, perPropMedia, nestedSelectors, variantBuckets, extraStyleObjects, styleFnDecls, attrBuckets, localVarValues, cssHelperPropValues, getComposedDefaultValue } = ctx;
|
|
42228
44042
|
const { j, root, warnings, resolverImports, resolveSelector, parseExpr, cssHelperNames, declByLocalName, relationOverridePseudoBuckets, relationOverrides, ancestorSelectorParents, resolveThemeValue, resolveThemeValueFromFn, resolveImportInScope } = state;
|
|
42229
44043
|
const getConditionDefaultValue = (propName) => cssHelperPropValues.has(propName) ? getComposedDefaultValue(propName) : ctx.getWrappedComponentBaseDefaultValue(propName) ?? null;
|
|
42230
44044
|
/**
|
|
@@ -42864,6 +44678,73 @@ function processDeclRules(ctx) {
|
|
|
42864
44678
|
for (const bucket of variantBuckets.values()) if (Object.hasOwn(bucket, prop)) wrapStyleConditionValue(bucket, prop, conditionKey, conditionValue);
|
|
42865
44679
|
patchStyleFnConditionValue(prop, conditionKey, conditionValue);
|
|
42866
44680
|
};
|
|
44681
|
+
/**
|
|
44682
|
+
* A base-scope declaration later in the CSS overrides any earlier conditional
|
|
44683
|
+
* assignment of the same property — within one styled template the generated
|
|
44684
|
+
* class contains both declarations, and the last one wins regardless of the
|
|
44685
|
+
* runtime condition. Drop the dead base-scope value from earlier variant
|
|
44686
|
+
* buckets so the emitted variant (applied after the base style in
|
|
44687
|
+
* stylex.props) cannot incorrectly win. Condition-scoped values (pseudo/media
|
|
44688
|
+
* maps) only lose their `default` layer.
|
|
44689
|
+
*
|
|
44690
|
+
* Exception: an earlier `!important` conditional value still wins over a later
|
|
44691
|
+
* non-important base declaration in the CSS cascade, so it must be preserved.
|
|
44692
|
+
* (When the later base is itself `!important`, source order decides and the
|
|
44693
|
+
* later one wins, so clearing is correct.)
|
|
44694
|
+
*/
|
|
44695
|
+
const clearEarlierVariantBaseValues = (prop, laterBaseValue) => {
|
|
44696
|
+
const laterBaseIsImportant = cssValueIsImportant(laterBaseValue);
|
|
44697
|
+
for (const [when, bucket] of variantBuckets) {
|
|
44698
|
+
if (!Object.hasOwn(bucket, prop)) continue;
|
|
44699
|
+
const bucketValue = bucket[prop];
|
|
44700
|
+
if (bucketValue !== null && typeof bucketValue === "object" && !isAstNode$1(bucketValue) && "default" in bucketValue) {
|
|
44701
|
+
const conditionDefault = bucketValue.default;
|
|
44702
|
+
if (!laterBaseIsImportant && cssValueIsImportant(conditionDefault)) continue;
|
|
44703
|
+
bucketValue.default = null;
|
|
44704
|
+
continue;
|
|
44705
|
+
}
|
|
44706
|
+
if (!laterBaseIsImportant && cssValueIsImportant(bucketValue)) continue;
|
|
44707
|
+
delete bucket[prop];
|
|
44708
|
+
if (Object.keys(bucket).length === 0) {
|
|
44709
|
+
variantBuckets.delete(when);
|
|
44710
|
+
delete ctx.variantStyleKeys[when];
|
|
44711
|
+
delete ctx.variantSourceOrder[when];
|
|
44712
|
+
}
|
|
44713
|
+
}
|
|
44714
|
+
};
|
|
44715
|
+
const clearEarlierThemeBaseValues = (prop, laterBaseValue, sourceCssProperty) => {
|
|
44716
|
+
const hooks = decl.needsUseThemeHook;
|
|
44717
|
+
if (!hooks?.length) return;
|
|
44718
|
+
const propsToClear = sourceCssProperty === "background" ? ["backgroundColor", "backgroundImage"] : [prop];
|
|
44719
|
+
const laterBaseIsImportant = cssValueIsImportant(laterBaseValue);
|
|
44720
|
+
const clearHookStyleKey = (hook, side) => {
|
|
44721
|
+
const styleKey = hook[side];
|
|
44722
|
+
if (!styleKey) return false;
|
|
44723
|
+
const bucket = extraStyleObjects.get(styleKey);
|
|
44724
|
+
if (!bucket) return false;
|
|
44725
|
+
let changed = false;
|
|
44726
|
+
for (const propToClear of propsToClear) {
|
|
44727
|
+
if (!Object.hasOwn(bucket, propToClear)) continue;
|
|
44728
|
+
const bucketValue = bucket[propToClear];
|
|
44729
|
+
if (!laterBaseIsImportant && cssValueIsImportant(bucketValue)) continue;
|
|
44730
|
+
delete bucket[propToClear];
|
|
44731
|
+
changed = true;
|
|
44732
|
+
}
|
|
44733
|
+
if (!changed) return false;
|
|
44734
|
+
if (Object.keys(bucket).length === 0) {
|
|
44735
|
+
extraStyleObjects.delete(styleKey);
|
|
44736
|
+
hook[side] = null;
|
|
44737
|
+
}
|
|
44738
|
+
return true;
|
|
44739
|
+
};
|
|
44740
|
+
for (let i = hooks.length - 1; i >= 0; i--) {
|
|
44741
|
+
const hook = hooks[i];
|
|
44742
|
+
const hadStyleKeys = Boolean(hook.trueStyleKey || hook.falseStyleKey);
|
|
44743
|
+
const clearedTrue = clearHookStyleKey(hook, "trueStyleKey");
|
|
44744
|
+
const clearedFalse = clearHookStyleKey(hook, "falseStyleKey");
|
|
44745
|
+
if ((clearedTrue || clearedFalse) && hadStyleKeys && !hook.trueStyleKey && !hook.falseStyleKey) hooks.splice(i, 1);
|
|
44746
|
+
}
|
|
44747
|
+
};
|
|
42867
44748
|
const applyResolvedPropValue = (prop, value, commentSource, sourceCssProperty) => {
|
|
42868
44749
|
const noteSourceCssProperty = (target) => {
|
|
42869
44750
|
if (sourceCssProperty) {
|
|
@@ -43078,6 +44959,8 @@ function processDeclRules(ctx) {
|
|
|
43078
44959
|
}
|
|
43079
44960
|
return;
|
|
43080
44961
|
}
|
|
44962
|
+
clearEarlierVariantBaseValues(prop, value);
|
|
44963
|
+
clearEarlierThemeBaseValues(prop, value, sourceCssProperty);
|
|
43081
44964
|
const target = ctx.getBaseStyleTarget();
|
|
43082
44965
|
setStyleObjectValue(target, prop, value);
|
|
43083
44966
|
noteSourceCssProperty(target);
|
|
@@ -43096,6 +44979,7 @@ function processDeclRules(ctx) {
|
|
|
43096
44979
|
pseudoElement: pseudoElement ?? (pseudoElementsList ? pseudoElementsList[0] ?? null : null),
|
|
43097
44980
|
attrTarget,
|
|
43098
44981
|
resolvedSelectorMedia,
|
|
44982
|
+
hasAncestorAttributeScope: Boolean(ancestorAttrs?.length),
|
|
43099
44983
|
applyResolvedPropValue
|
|
43100
44984
|
});
|
|
43101
44985
|
if (state.bail) break;
|
|
@@ -43608,7 +45492,9 @@ function recoverStandaloneInterpolationsInPseudoBlock(rule, decl) {
|
|
|
43608
45492
|
}
|
|
43609
45493
|
/** Negates a `when` condition string (e.g. `$active` → `!$active`, `!$x` → `$x`). */
|
|
43610
45494
|
function negateWhen(when) {
|
|
45495
|
+
if (when.startsWith("!(") && when.endsWith(")")) return when.slice(2, -1);
|
|
43611
45496
|
if (when.startsWith("!")) return when.slice(1);
|
|
45497
|
+
if (when.includes(" || ") || when.includes(" && ")) return `!(${when})`;
|
|
43612
45498
|
if (when.includes(" === ")) return when.replace(" === ", " !== ");
|
|
43613
45499
|
if (when.includes(" !== ")) return when.replace(" !== ", " === ");
|
|
43614
45500
|
return `!${when}`;
|
|
@@ -44092,6 +45978,7 @@ function createLowerRulesState(ctx) {
|
|
|
44092
45978
|
const resolveValueDirectional = ctx.resolveValueDirectionalSafe;
|
|
44093
45979
|
const resolveCall = ctx.resolveCallSafe;
|
|
44094
45980
|
const resolveValueOptional = (rvCtx) => {
|
|
45981
|
+
if (rvCtx.kind === "importedValue" && isStylexFileSource(rvCtx.source)) return resolveValue(rvCtx);
|
|
44095
45982
|
const res = ctx.adapter.resolveValue(rvCtx);
|
|
44096
45983
|
if (res && isDirectionalResult(res)) return;
|
|
44097
45984
|
return res;
|
|
@@ -44158,6 +46045,30 @@ function createLowerRulesState(ctx) {
|
|
|
44158
46045
|
}
|
|
44159
46046
|
};
|
|
44160
46047
|
const staticPropertyValues = /* @__PURE__ */ new Map();
|
|
46048
|
+
const staticIdentifierValues = /* @__PURE__ */ new Map();
|
|
46049
|
+
root.find(j.VariableDeclarator).forEach((p) => {
|
|
46050
|
+
if (!isTopLevelConstDeclarator(p)) return;
|
|
46051
|
+
const node = p.node;
|
|
46052
|
+
if (node.id?.type !== "Identifier" || !node.id.name) return;
|
|
46053
|
+
const staticValue = literalToStaticValue(node.init, { allowStaticArrowFunctions: false });
|
|
46054
|
+
if (staticValue !== null) staticIdentifierValues.set(node.id.name, staticValue);
|
|
46055
|
+
});
|
|
46056
|
+
if (staticIdentifierValues.size > 0) {
|
|
46057
|
+
const shadowingNames = /* @__PURE__ */ new Set();
|
|
46058
|
+
root.find(j.Function).forEach((fnPath) => {
|
|
46059
|
+
collectPatternBindingNames$2(fnPath.node.params, shadowingNames);
|
|
46060
|
+
const fnId = fnPath.node.id;
|
|
46061
|
+
if (fnId?.name) shadowingNames.add(fnId.name);
|
|
46062
|
+
});
|
|
46063
|
+
root.find(j.ClassDeclaration).forEach((classPath) => {
|
|
46064
|
+
const classId = classPath.node.id;
|
|
46065
|
+
if (classId?.name) shadowingNames.add(classId.name);
|
|
46066
|
+
});
|
|
46067
|
+
root.find(j.VariableDeclarator).forEach((declPath) => {
|
|
46068
|
+
if (!isTopLevelConstDeclarator(declPath)) collectPatternBindingNames$2(declPath.node.id, shadowingNames);
|
|
46069
|
+
});
|
|
46070
|
+
for (const name of shadowingNames) staticIdentifierValues.delete(name);
|
|
46071
|
+
}
|
|
44161
46072
|
root.find(j.ExpressionStatement, { expression: {
|
|
44162
46073
|
type: "AssignmentExpression",
|
|
44163
46074
|
operator: "=",
|
|
@@ -44171,7 +46082,7 @@ function createLowerRulesState(ctx) {
|
|
|
44171
46082
|
const ownerName = expr.left?.object?.name;
|
|
44172
46083
|
const propName = expr.left?.property?.name;
|
|
44173
46084
|
if (ownerName && propName) {
|
|
44174
|
-
const staticValue = literalToStaticValue(expr.right);
|
|
46085
|
+
const staticValue = literalToStaticValue(expr.right, { allowStaticArrowFunctions: false });
|
|
44175
46086
|
let ownerMap = staticPropertyValues.get(ownerName);
|
|
44176
46087
|
if (!ownerMap) {
|
|
44177
46088
|
ownerMap = /* @__PURE__ */ new Map();
|
|
@@ -44267,6 +46178,7 @@ function createLowerRulesState(ctx) {
|
|
|
44267
46178
|
cssHelperValuesByKey,
|
|
44268
46179
|
mixinValuesByKey,
|
|
44269
46180
|
staticPropertyValues,
|
|
46181
|
+
staticIdentifierValues,
|
|
44270
46182
|
usedCssHelperFunctions: /* @__PURE__ */ new Set(),
|
|
44271
46183
|
warnPropInlineStyle,
|
|
44272
46184
|
applyCssHelperMixin,
|
|
@@ -44353,6 +46265,20 @@ function clonePropUsageByComponent(source) {
|
|
|
44353
46265
|
});
|
|
44354
46266
|
return cloned;
|
|
44355
46267
|
}
|
|
46268
|
+
function isTopLevelConstDeclarator(path) {
|
|
46269
|
+
const declarationPath = path.parentPath;
|
|
46270
|
+
if (!declarationPath) return false;
|
|
46271
|
+
const declaration = declarationPath?.node;
|
|
46272
|
+
if (declaration?.type !== "VariableDeclaration" || declaration.kind !== "const") return false;
|
|
46273
|
+
let current = declarationPath.parentPath;
|
|
46274
|
+
while (current?.node) {
|
|
46275
|
+
const type = current.node.type;
|
|
46276
|
+
if (type === "Program") return true;
|
|
46277
|
+
if (type !== "VariableDeclaration" && type !== "ExportNamedDeclaration") return false;
|
|
46278
|
+
current = current.parentPath;
|
|
46279
|
+
}
|
|
46280
|
+
return false;
|
|
46281
|
+
}
|
|
44356
46282
|
function collectOpeningPropUsage(attributes) {
|
|
44357
46283
|
const props = {};
|
|
44358
46284
|
let hasSpread = false;
|
|
@@ -44382,6 +46308,10 @@ function getJsxIdentifierName(node) {
|
|
|
44382
46308
|
const record = node;
|
|
44383
46309
|
return record.type === "JSXIdentifier" && typeof record.name === "string" ? record.name : null;
|
|
44384
46310
|
}
|
|
46311
|
+
const STYLEX_FILE_RE = /\.stylex(\.\w+)?$/;
|
|
46312
|
+
function isStylexFileSource(source) {
|
|
46313
|
+
return STYLEX_FILE_RE.test(source.value);
|
|
46314
|
+
}
|
|
44385
46315
|
//#endregion
|
|
44386
46316
|
//#region src/internal/transform-steps/lower-rules.ts
|
|
44387
46317
|
/**
|
|
@@ -46095,6 +48025,10 @@ function wrappedComponentAcceptsSxProp(ctx, componentLocalName, visiting = /* @_
|
|
|
46095
48025
|
visiting.delete(componentLocalName);
|
|
46096
48026
|
return true;
|
|
46097
48027
|
}
|
|
48028
|
+
if (localStyledDecl?.needsWrapperComponent && !localStyledDecl.skipTransform && localStyledDecl.supportsExternalStyles) {
|
|
48029
|
+
visiting.delete(componentLocalName);
|
|
48030
|
+
return true;
|
|
48031
|
+
}
|
|
46098
48032
|
const componentInterface = wrappedComponentInterfaceFor(ctx, componentLocalName);
|
|
46099
48033
|
if (componentInterface !== void 0) {
|
|
46100
48034
|
visiting.delete(componentLocalName);
|
|
@@ -46342,8 +48276,9 @@ function rewriteJsxStep(ctx) {
|
|
|
46342
48276
|
const mergeArgs = matchedCombinedStyleKey ? void 0 : opening.__promotedMergeArgs;
|
|
46343
48277
|
const baseMember = j.memberExpression(j.identifier(ctx.stylesIdentifier ?? "styles"), j.identifier(baseStyleKey));
|
|
46344
48278
|
const baseExpr = mergeArgs ? j.callExpression(baseMember, mergeArgs) : baseMember;
|
|
48279
|
+
const rendersLocalWrapperBase = decl.base.kind === "component" && decl.base.ident === finalTag && (ctx.styledDecls?.some((d) => d.localName === finalTag && d.needsWrapperComponent && !d.skipTransform) ?? false);
|
|
46345
48280
|
const styleArgs = [
|
|
46346
|
-
...decl.extendsStyleKey ? [j.memberExpression(j.identifier(ctx.stylesIdentifier ?? "styles"), j.identifier(decl.extendsStyleKey))] : [],
|
|
48281
|
+
...decl.extendsStyleKey && !rendersLocalWrapperBase ? [j.memberExpression(j.identifier(ctx.stylesIdentifier ?? "styles"), j.identifier(decl.extendsStyleKey))] : [],
|
|
46347
48282
|
...extraMixinArgs,
|
|
46348
48283
|
...decl.skipBaseStyleRef ? [] : [baseExpr],
|
|
46349
48284
|
...extraAfterBaseArgs
|
|
@@ -47089,6 +49024,43 @@ function upgradePolymorphicAsPropTypesStep(ctx) {
|
|
|
47089
49024
|
return CONTINUE;
|
|
47090
49025
|
}
|
|
47091
49026
|
//#endregion
|
|
49027
|
+
//#region src/internal/transform-steps/warn-partial-migration-incomplete.ts
|
|
49028
|
+
/**
|
|
49029
|
+
* Step: warn when partial migration leaves styled-components declarations behind.
|
|
49030
|
+
* Core concepts: partial migration diagnostics and converted declaration accounting.
|
|
49031
|
+
*/
|
|
49032
|
+
function warnPartialMigrationIncompleteStep(ctx) {
|
|
49033
|
+
if (!shouldWarnForPartialMigration(ctx)) return CONTINUE;
|
|
49034
|
+
const skippedDecls = collectSkippedStyledDeclarations(ctx.styledDecls);
|
|
49035
|
+
const convertedDecls = collectConvertedStyleDeclarations(ctx.styledDecls);
|
|
49036
|
+
if (skippedDecls.length === 0 || convertedDecls.length === 0) return CONTINUE;
|
|
49037
|
+
ctx.warnings.push({
|
|
49038
|
+
severity: "warning",
|
|
49039
|
+
type: PARTIAL_MIGRATION_INCOMPLETE_WARNING,
|
|
49040
|
+
loc: skippedDecls[0]?.loc,
|
|
49041
|
+
context: {
|
|
49042
|
+
skippedDeclarationCount: skippedDecls.length,
|
|
49043
|
+
skippedDeclarations: declarationNames(skippedDecls),
|
|
49044
|
+
convertedDeclarationCount: convertedDecls.length,
|
|
49045
|
+
convertedDeclarations: declarationNames(convertedDecls)
|
|
49046
|
+
}
|
|
49047
|
+
});
|
|
49048
|
+
return CONTINUE;
|
|
49049
|
+
}
|
|
49050
|
+
const MAX_PARTIAL_MIGRATION_WARNING_NAMES = 20;
|
|
49051
|
+
function shouldWarnForPartialMigration(ctx) {
|
|
49052
|
+
return ctx.hasChanges && ctx.options.allowPartialMigration === true && ctx.options.transformMode !== "leavesOnly";
|
|
49053
|
+
}
|
|
49054
|
+
function collectSkippedStyledDeclarations(styledDecls) {
|
|
49055
|
+
return styledDecls?.filter((decl) => decl.skipTransform && !decl.isCssHelper && !decl.isDirectJsxResolution) ?? [];
|
|
49056
|
+
}
|
|
49057
|
+
function collectConvertedStyleDeclarations(styledDecls) {
|
|
49058
|
+
return styledDecls?.filter((decl) => !decl.skipTransform && !decl.isCssHelper) ?? [];
|
|
49059
|
+
}
|
|
49060
|
+
function declarationNames(decls) {
|
|
49061
|
+
return decls.slice(0, MAX_PARTIAL_MIGRATION_WARNING_NAMES).map((decl) => decl.localName);
|
|
49062
|
+
}
|
|
49063
|
+
//#endregion
|
|
47092
49064
|
//#region src/transform.ts
|
|
47093
49065
|
/**
|
|
47094
49066
|
* Transform styled-components to StyleX
|
|
@@ -47098,8 +49070,9 @@ function upgradePolymorphicAsPropTypesStep(ctx) {
|
|
|
47098
49070
|
*/
|
|
47099
49071
|
function transform(file, api, options) {
|
|
47100
49072
|
try {
|
|
47101
|
-
const
|
|
47102
|
-
|
|
49073
|
+
const transformOptions = options;
|
|
49074
|
+
const result = transformWithWarnings(file, api, transformOptions);
|
|
49075
|
+
Logger.logWarnings(result.warnings, file.path, { silent: transformOptions.silent === true });
|
|
47103
49076
|
if (result.sidecarFiles && result.sidecarFiles.length > 0) {
|
|
47104
49077
|
const sidecarFilesMap = options.sidecarFiles;
|
|
47105
49078
|
if (sidecarFilesMap) {
|
|
@@ -47147,6 +49120,7 @@ function transformWithWarnings(file, api, options) {
|
|
|
47147
49120
|
extractCssHelpersStep,
|
|
47148
49121
|
detectStringMappingFnsStep,
|
|
47149
49122
|
collectStyledDeclsStep,
|
|
49123
|
+
inlinePropConditionalCssHelpersStep,
|
|
47150
49124
|
resolveBaseComponentsStep,
|
|
47151
49125
|
applyLeavesOnlyPolicyStep,
|
|
47152
49126
|
markPartialImportedRootsStep,
|
|
@@ -47169,7 +49143,8 @@ function transformWithWarnings(file, api, options) {
|
|
|
47169
49143
|
reinsertStaticPropsStep,
|
|
47170
49144
|
postProcessStep,
|
|
47171
49145
|
cleanupCssImportStep,
|
|
47172
|
-
ensureReactImportStep
|
|
49146
|
+
ensureReactImportStep,
|
|
49147
|
+
warnPartialMigrationIncompleteStep
|
|
47173
49148
|
];
|
|
47174
49149
|
for (const step of pipeline) {
|
|
47175
49150
|
const outcome = step(ctx);
|