styled-components-to-stylex-codemod 0.0.52 → 0.0.53
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{bridge-consumer-patcher-BlOkZiEv.mjs → bridge-consumer-patcher-DDcYZM_G.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 +4 -4
- package/dist/{run-prepass-CWnoXqI6.mjs → run-prepass-BjTbmT-5.mjs} +1 -1
- package/dist/{string-utils-BYTEHwNg.mjs → string-utils-Bo3cWgss.mjs} +2 -1
- package/dist/{transform-types-BIv4-1OO.d.mts → transform-types-DVH8jgA2.d.mts} +1 -1
- package/dist/transform.d.mts +1 -1
- package/dist/transform.mjs +878 -117
- 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
|
@@ -2,7 +2,7 @@ import { t as createModuleResolver } from "./resolve-imports-DgSAddIF.mjs";
|
|
|
2
2
|
import { a as isDirectionalResult, n as mergeMarkerDeclarations, o as assertValidAdapter, r as DEFAULT_THEME_HOOK, t as transformedComponentAcceptsSx } from "./sx-surface-CEPFSTO1.mjs";
|
|
3
3
|
import { a as findImportSource, c as resolveBarrelReExportBinding, d as UNSUPPORTED_SHOULD_FORWARD_PROP_WARNING, l as CASCADE_CONFLICT_WARNING, n as createPrepassParser, o as getReExportedSourceName, r as fileExports, t as walkAst, u as Logger } from "./ast-walk-BOXS-DT7.mjs";
|
|
4
4
|
import { n as resolveExistingFilePath, r as toRealPath, t as isRelativeSpecifier } from "./path-utils-BC4U8X_q.mjs";
|
|
5
|
-
import { a as
|
|
5
|
+
import { a as hasTopLevelMatch, c as isPrettierIgnoreComment, d as isValidIdentifierName, f as kebabToCamelCase, g as sanitizeIdentifier, h as normalizeWhitespace, i as getCommentBody, l as isSingleBackgroundComponent, m as lowerFirst, n as capitalize$1, o as isBackgroundImageValue, p as looksLikeLength, r as escapeRegex, s as isJSDocBlockComment, t as camelToKebabCase, u as isStyleSectionMarkerComment } from "./string-utils-Bo3cWgss.mjs";
|
|
6
6
|
import { a as terminateStandaloneInterpolationStatements, i as parseStyledTemplateLiteral, n as isTemplatePlaceholderInSelectorContext, r as PLACEHOLDER_RE } from "./selector-context-heuristic-LVizWWOR.mjs";
|
|
7
7
|
import { _ as walkForImportsAndTemplates, a as mergeComponentPropUsage, i as getExhaustiveObservedStaticValues, n as createComponentPropUsageInfo, o as readStaticJsxLiteral, r as formatObservedVariantCondition, s as collectStylexExportNames, t as KNOWN_NON_ELEMENT_PROPS, u as buildImportMapFromNodes } from "./prop-usage-SADzZJdX.mjs";
|
|
8
8
|
import { createRequire } from "node:module";
|
|
@@ -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) {
|
|
@@ -1741,6 +1974,11 @@ function toSuffixFromProp(propName) {
|
|
|
1741
1974
|
return suffixes.join("");
|
|
1742
1975
|
}
|
|
1743
1976
|
}
|
|
1977
|
+
const defaultTruthyMatch = trimmed.match(/^(.+?) === undefined \|\| (.+)$/);
|
|
1978
|
+
if (defaultTruthyMatch) {
|
|
1979
|
+
const lhs = defaultTruthyMatch[1].replace(/^\$/, "");
|
|
1980
|
+
if (lhs === defaultTruthyMatch[2].replace(/^\$/, "")) return toSuffixFromProp(lhs);
|
|
1981
|
+
}
|
|
1744
1982
|
if (trimmed.includes(" || ")) {
|
|
1745
1983
|
const parts = trimmed.split(" || ").map((s) => s.trim()).filter(Boolean);
|
|
1746
1984
|
if (parts.length) {
|
|
@@ -3498,7 +3736,7 @@ function specifierExportedName(spec) {
|
|
|
3498
3736
|
* - Disjunction: `"a || b"` → `a || b`
|
|
3499
3737
|
* - Grouped negation: `"!(a || b)"` → `!(a || b)`
|
|
3500
3738
|
*/
|
|
3501
|
-
function parseVariantWhenToAst(j, when, booleanProps, knownProps) {
|
|
3739
|
+
function parseVariantWhenToAst(j, when, booleanProps, knownProps, nonPropRoots) {
|
|
3502
3740
|
const buildMemberExpr = (raw) => {
|
|
3503
3741
|
if (!raw.includes(".")) return null;
|
|
3504
3742
|
const parts = raw.split(".").map((part) => part.trim()).filter(Boolean);
|
|
@@ -3533,7 +3771,7 @@ function parseVariantWhenToAst(j, when, booleanProps, knownProps) {
|
|
|
3533
3771
|
}
|
|
3534
3772
|
const memberExpr = buildMemberExpr(trimmedRaw);
|
|
3535
3773
|
if (memberExpr) return {
|
|
3536
|
-
propName: root && root !== "theme" && isConditionPropIdentifier(root) ? root : null,
|
|
3774
|
+
propName: root && root !== "theme" && !nonPropRoots?.has(root) && isConditionPropIdentifier(root) ? root : null,
|
|
3537
3775
|
expr: memberExpr
|
|
3538
3776
|
};
|
|
3539
3777
|
return {
|
|
@@ -3542,7 +3780,7 @@ function parseVariantWhenToAst(j, when, booleanProps, knownProps) {
|
|
|
3542
3780
|
};
|
|
3543
3781
|
}
|
|
3544
3782
|
return {
|
|
3545
|
-
propName: trimmedRaw === "theme" || !isConditionPropIdentifier(trimmedRaw) ? null : trimmedRaw,
|
|
3783
|
+
propName: trimmedRaw === "theme" || nonPropRoots?.has(trimmedRaw) || !isConditionPropIdentifier(trimmedRaw) ? null : trimmedRaw,
|
|
3546
3784
|
expr: j.identifier(trimmedRaw)
|
|
3547
3785
|
};
|
|
3548
3786
|
};
|
|
@@ -3553,7 +3791,7 @@ function parseVariantWhenToAst(j, when, booleanProps, knownProps) {
|
|
|
3553
3791
|
isBoolean: true
|
|
3554
3792
|
};
|
|
3555
3793
|
if (trimmed.startsWith("!(") && trimmed.endsWith(")")) {
|
|
3556
|
-
const innerParsed = parseVariantWhenToAst(j, trimmed.slice(2, -1).trim(), booleanProps, knownProps);
|
|
3794
|
+
const innerParsed = parseVariantWhenToAst(j, trimmed.slice(2, -1).trim(), booleanProps, knownProps, nonPropRoots);
|
|
3557
3795
|
return {
|
|
3558
3796
|
cond: j.unaryExpression("!", innerParsed.cond),
|
|
3559
3797
|
props: innerParsed.props,
|
|
@@ -3561,7 +3799,7 @@ function parseVariantWhenToAst(j, when, booleanProps, knownProps) {
|
|
|
3561
3799
|
};
|
|
3562
3800
|
}
|
|
3563
3801
|
if (trimmed.includes("&&")) {
|
|
3564
|
-
const parsed = trimmed.split("&&").map((s) => s.trim()).filter(Boolean).map((p) => parseVariantWhenToAst(j, p, booleanProps, knownProps));
|
|
3802
|
+
const parsed = trimmed.split("&&").map((s) => s.trim()).filter(Boolean).map((p) => parseVariantWhenToAst(j, p, booleanProps, knownProps, nonPropRoots));
|
|
3565
3803
|
const firstParsed = parsed[0];
|
|
3566
3804
|
if (!firstParsed) return {
|
|
3567
3805
|
cond: j.identifier("true"),
|
|
@@ -3575,7 +3813,7 @@ function parseVariantWhenToAst(j, when, booleanProps, knownProps) {
|
|
|
3575
3813
|
};
|
|
3576
3814
|
}
|
|
3577
3815
|
if (trimmed.includes(" || ")) {
|
|
3578
|
-
const parsed = trimmed.split(" || ").map((s) => s.trim()).filter(Boolean).map((p) => parseVariantWhenToAst(j, p, booleanProps, knownProps));
|
|
3816
|
+
const parsed = trimmed.split(" || ").map((s) => s.trim()).filter(Boolean).map((p) => parseVariantWhenToAst(j, p, booleanProps, knownProps, nonPropRoots));
|
|
3579
3817
|
const firstParsedOr = parsed[0];
|
|
3580
3818
|
if (!firstParsedOr) return {
|
|
3581
3819
|
cond: j.identifier("true"),
|
|
@@ -3589,7 +3827,7 @@ function parseVariantWhenToAst(j, when, booleanProps, knownProps) {
|
|
|
3589
3827
|
};
|
|
3590
3828
|
}
|
|
3591
3829
|
if (trimmed.startsWith("!")) {
|
|
3592
|
-
const innerParsed = parseVariantWhenToAst(j, trimmed.slice(1).trim(), booleanProps, knownProps);
|
|
3830
|
+
const innerParsed = parseVariantWhenToAst(j, trimmed.slice(1).trim(), booleanProps, knownProps, nonPropRoots);
|
|
3593
3831
|
return {
|
|
3594
3832
|
cond: j.unaryExpression("!", innerParsed.cond),
|
|
3595
3833
|
props: innerParsed.props,
|
|
@@ -3718,8 +3956,8 @@ function isConditionPropIdentifier(name, knownProps) {
|
|
|
3718
3956
|
* function's parameter destructuring.
|
|
3719
3957
|
*/
|
|
3720
3958
|
function collectConditionProps(j, args) {
|
|
3721
|
-
const { when, destructureProps, booleanProps, knownProps } = args;
|
|
3722
|
-
const parsed = parseVariantWhenToAst(j, when, booleanProps, knownProps);
|
|
3959
|
+
const { when, destructureProps, booleanProps, knownProps, nonPropRoots } = args;
|
|
3960
|
+
const parsed = parseVariantWhenToAst(j, when, booleanProps, knownProps, nonPropRoots);
|
|
3723
3961
|
if (destructureProps) {
|
|
3724
3962
|
for (const p of parsed.props) if (p && !destructureProps.includes(p)) destructureProps.push(p);
|
|
3725
3963
|
}
|
|
@@ -4627,6 +4865,19 @@ function getPropertyNameFromKey(key) {
|
|
|
4627
4865
|
* Core concepts: deep merge semantics, AST node detection, and media query resolution.
|
|
4628
4866
|
*/
|
|
4629
4867
|
/**
|
|
4868
|
+
* Marks an emitted AST value node as proven to be a single CSS token (e.g. a
|
|
4869
|
+
* numeric stylex const that had a unit suffix). Shorthand properties holding
|
|
4870
|
+
* such values cannot expand to multiple tokens, so the opaque-shorthand
|
|
4871
|
+
* warning does not apply to them.
|
|
4872
|
+
*/
|
|
4873
|
+
function markProvenSingleTokenValue(node) {
|
|
4874
|
+
if (node && typeof node === "object") provenSingleTokenValues.add(node);
|
|
4875
|
+
}
|
|
4876
|
+
function isProvenSingleTokenValue(node) {
|
|
4877
|
+
return !!node && typeof node === "object" && provenSingleTokenValues.has(node);
|
|
4878
|
+
}
|
|
4879
|
+
const provenSingleTokenValues = /* @__PURE__ */ new WeakSet();
|
|
4880
|
+
/**
|
|
4630
4881
|
* Tries to resolve a CallExpression via the adapter's `resolveCall`.
|
|
4631
4882
|
* Shared by both css-helper and process-rules slot resolution.
|
|
4632
4883
|
*
|
|
@@ -5284,6 +5535,10 @@ function staticStringValue(value) {
|
|
|
5284
5535
|
function invertWhen(when) {
|
|
5285
5536
|
if (when.startsWith("!(") && when.endsWith(")")) return when.slice(2, -1);
|
|
5286
5537
|
if (when.startsWith("!")) return when.slice(1);
|
|
5538
|
+
if (when.includes(" || ") || when.includes(" && ")) {
|
|
5539
|
+
if (when.includes(" || ") && when.includes(" && ")) return null;
|
|
5540
|
+
return `!(${when})`;
|
|
5541
|
+
}
|
|
5287
5542
|
const match = when.match(/^(.+)\s+(===|!==)\s+(.+)$/);
|
|
5288
5543
|
if (match) {
|
|
5289
5544
|
const [, propName, op, rhs] = match;
|
|
@@ -5336,31 +5591,46 @@ const createPropTestHelpers = (bindings) => {
|
|
|
5336
5591
|
}
|
|
5337
5592
|
return null;
|
|
5338
5593
|
};
|
|
5594
|
+
const applyDefaultToTruthyWhen = (whenName, propName) => {
|
|
5595
|
+
if (bindings.kind !== "destructured" || !bindings.defaults?.has(propName)) return whenName;
|
|
5596
|
+
if (whenName !== propName) return null;
|
|
5597
|
+
const defaultValue = literalToStaticValue(bindings.defaults.get(propName));
|
|
5598
|
+
if (defaultValue === null) return null;
|
|
5599
|
+
return defaultValue ? `${whenName} === undefined || ${whenName}` : whenName;
|
|
5600
|
+
};
|
|
5339
5601
|
const parseTestInfo = (test) => {
|
|
5340
5602
|
if (!test || typeof test !== "object") return null;
|
|
5341
5603
|
if (test.type === "Identifier" && bindings.kind === "destructured") {
|
|
5342
5604
|
const propAccess = readPropAccess(test);
|
|
5343
|
-
|
|
5344
|
-
|
|
5605
|
+
if (!propAccess) return null;
|
|
5606
|
+
const when = applyDefaultToTruthyWhen(propAccess.whenName, propAccess.propName);
|
|
5607
|
+
return when === null ? null : {
|
|
5608
|
+
when,
|
|
5345
5609
|
propName: propAccess.propName
|
|
5346
|
-
}
|
|
5610
|
+
};
|
|
5347
5611
|
}
|
|
5348
5612
|
if (isMemberExpression(test)) {
|
|
5349
5613
|
const propAccess = readPropAccess(test);
|
|
5350
|
-
|
|
5351
|
-
|
|
5614
|
+
if (!propAccess) return null;
|
|
5615
|
+
const when = applyDefaultToTruthyWhen(propAccess.whenName, propAccess.propName);
|
|
5616
|
+
return when === null ? null : {
|
|
5617
|
+
when,
|
|
5352
5618
|
propName: propAccess.propName
|
|
5353
|
-
}
|
|
5619
|
+
};
|
|
5354
5620
|
}
|
|
5355
5621
|
if (test.type === "UnaryExpression" && test.operator === "!" && test.argument) {
|
|
5356
5622
|
const propAccess = readPropAccess(test.argument);
|
|
5357
|
-
|
|
5358
|
-
|
|
5623
|
+
if (!propAccess) return null;
|
|
5624
|
+
const truthyWhen = applyDefaultToTruthyWhen(propAccess.whenName, propAccess.propName);
|
|
5625
|
+
if (truthyWhen === null) return null;
|
|
5626
|
+
return {
|
|
5627
|
+
when: truthyWhen === propAccess.whenName ? `!${truthyWhen}` : `!(${truthyWhen})`,
|
|
5359
5628
|
propName: propAccess.propName
|
|
5360
|
-
}
|
|
5629
|
+
};
|
|
5361
5630
|
}
|
|
5362
5631
|
if (test.type === "BinaryExpression" && (test.operator === "===" || test.operator === "!==")) {
|
|
5363
5632
|
const left = test.left;
|
|
5633
|
+
const operator = test.operator;
|
|
5364
5634
|
const getRhsValue = () => {
|
|
5365
5635
|
const rhsTyped = test.right;
|
|
5366
5636
|
if (rhsTyped.type === "Identifier" && rhsTyped.name === "undefined") return "undefined";
|
|
@@ -5368,12 +5638,28 @@ const createPropTestHelpers = (bindings) => {
|
|
|
5368
5638
|
if (rhs === null) return getMemberExpressionSource(test.right);
|
|
5369
5639
|
return JSON.stringify(rhs);
|
|
5370
5640
|
};
|
|
5641
|
+
const buildBinaryWhen = (propAccess, rhsValue) => {
|
|
5642
|
+
const base = `${propAccess.whenName} ${operator} ${rhsValue}`;
|
|
5643
|
+
if (bindings.kind !== "destructured" || !bindings.defaults?.has(propAccess.propName)) return base;
|
|
5644
|
+
if (propAccess.whenName !== propAccess.propName || rhsValue === "undefined") return null;
|
|
5645
|
+
const defaultValue = literalToStaticValue(bindings.defaults.get(propAccess.propName));
|
|
5646
|
+
if (defaultValue === null) return null;
|
|
5647
|
+
let rhsStatic;
|
|
5648
|
+
try {
|
|
5649
|
+
rhsStatic = JSON.parse(rhsValue);
|
|
5650
|
+
} catch {
|
|
5651
|
+
return null;
|
|
5652
|
+
}
|
|
5653
|
+
if (defaultValue !== rhsStatic) return base;
|
|
5654
|
+
return operator === "===" ? `${propAccess.whenName} === undefined || ${base}` : `${propAccess.whenName} !== undefined && ${base}`;
|
|
5655
|
+
};
|
|
5371
5656
|
if (bindings.kind === "destructured" && left.type === "Identifier") {
|
|
5372
5657
|
const propAccess = readPropAccess(left);
|
|
5373
5658
|
const rhsValue = getRhsValue();
|
|
5374
5659
|
if (!propAccess || rhsValue === null) return null;
|
|
5375
|
-
|
|
5376
|
-
|
|
5660
|
+
const when = buildBinaryWhen(propAccess, rhsValue);
|
|
5661
|
+
return when === null ? null : {
|
|
5662
|
+
when,
|
|
5377
5663
|
propName: propAccess.propName
|
|
5378
5664
|
};
|
|
5379
5665
|
}
|
|
@@ -5381,8 +5667,9 @@ const createPropTestHelpers = (bindings) => {
|
|
|
5381
5667
|
const propAccess = readPropAccess(left);
|
|
5382
5668
|
const rhsValue = getRhsValue();
|
|
5383
5669
|
if (!propAccess || rhsValue === null) return null;
|
|
5384
|
-
|
|
5385
|
-
|
|
5670
|
+
const when = buildBinaryWhen(propAccess, rhsValue);
|
|
5671
|
+
return when === null ? null : {
|
|
5672
|
+
when,
|
|
5386
5673
|
propName: propAccess.propName
|
|
5387
5674
|
};
|
|
5388
5675
|
}
|
|
@@ -8513,10 +8800,10 @@ function collectDeclPropNames(root, j, decl, filter) {
|
|
|
8513
8800
|
const addIfMatch = (name) => {
|
|
8514
8801
|
if (filter(name)) result.add(name);
|
|
8515
8802
|
};
|
|
8516
|
-
for (const when of Object.keys(decl.variantStyleKeys ?? {})) for (const p of parseVariantWhenToAst(j, when).props) addIfMatch(p);
|
|
8803
|
+
for (const when of Object.keys(decl.variantStyleKeys ?? {})) for (const p of parseVariantWhenToAst(j, when, void 0, void 0, decl.nonPropConditionRoots).props) addIfMatch(p);
|
|
8517
8804
|
for (const sf of decl.styleFnFromProps ?? []) {
|
|
8518
8805
|
addIfMatch(sf.jsxProp);
|
|
8519
|
-
if (sf.conditionWhen) for (const p of parseVariantWhenToAst(j, sf.conditionWhen).props) addIfMatch(p);
|
|
8806
|
+
if (sf.conditionWhen) for (const p of parseVariantWhenToAst(j, sf.conditionWhen, void 0, void 0, decl.nonPropConditionRoots).props) addIfMatch(p);
|
|
8520
8807
|
}
|
|
8521
8808
|
for (const isp of decl.inlineStyleProps ?? []) addIfMatch(isp.jsxProp ?? isp.prop);
|
|
8522
8809
|
for (const cv of decl.compoundVariants ?? []) if (cv.kind === "3branch" || cv.kind === "4branch") {
|
|
@@ -14521,10 +14808,13 @@ function tryHandleAnimation(args) {
|
|
|
14521
14808
|
for (let segmentIndex = 0; segmentIndex < segments.length; segmentIndex++) {
|
|
14522
14809
|
const tokens = segments[segmentIndex];
|
|
14523
14810
|
if (!tokens.length) return false;
|
|
14524
|
-
const
|
|
14525
|
-
|
|
14811
|
+
const nameIdx = tokens.findIndex((t) => {
|
|
14812
|
+
const slotMatch = t.match(/^__SC_EXPR_(\d+)__$/);
|
|
14813
|
+
return slotMatch ? getKeyframeFromSlot(Number(slotMatch[1])) !== null : false;
|
|
14814
|
+
});
|
|
14815
|
+
if (nameIdx === -1) return false;
|
|
14816
|
+
const m = tokens.splice(nameIdx, 1)[0].match(/^__SC_EXPR_(\d+)__$/);
|
|
14526
14817
|
const kf = getKeyframeFromSlot(Number(m[1]));
|
|
14527
|
-
if (!kf) return false;
|
|
14528
14818
|
animNames.push({
|
|
14529
14819
|
kind: "ident",
|
|
14530
14820
|
name: kf
|
|
@@ -20653,7 +20943,8 @@ function buildVariantStyleExprs(opts) {
|
|
|
20653
20943
|
when: positiveWhen,
|
|
20654
20944
|
destructureProps,
|
|
20655
20945
|
booleanProps,
|
|
20656
|
-
...knownProps ? { knownProps } : {}
|
|
20946
|
+
...knownProps ? { knownProps } : {},
|
|
20947
|
+
nonPropRoots: d.nonPropConditionRoots
|
|
20657
20948
|
});
|
|
20658
20949
|
if (onNewDestructureProp && prevLengthRef && destructureProps) for (let i = prevLengthRef.value; i < destructureProps.length; i++) onNewDestructureProp(destructureProps[i]);
|
|
20659
20950
|
const isCurrentPositive = areEquivalentWhen(when, positiveWhen);
|
|
@@ -20668,7 +20959,8 @@ function buildVariantStyleExprs(opts) {
|
|
|
20668
20959
|
when,
|
|
20669
20960
|
destructureProps,
|
|
20670
20961
|
booleanProps,
|
|
20671
|
-
...knownProps ? { knownProps } : {}
|
|
20962
|
+
...knownProps ? { knownProps } : {},
|
|
20963
|
+
nonPropRoots: d.nonPropConditionRoots
|
|
20672
20964
|
});
|
|
20673
20965
|
if (onNewDestructureProp && prevLengthRef && destructureProps) for (let i = prevLengthRef.value; i < destructureProps.length; i++) onNewDestructureProp(destructureProps[i]);
|
|
20674
20966
|
const styleExpr = styleRef(j, stylesIdentifier, variantKey);
|
|
@@ -20684,7 +20976,8 @@ function buildVariantStyleExprs(opts) {
|
|
|
20684
20976
|
when,
|
|
20685
20977
|
destructureProps,
|
|
20686
20978
|
booleanProps,
|
|
20687
|
-
...knownProps ? { knownProps } : {}
|
|
20979
|
+
...knownProps ? { knownProps } : {},
|
|
20980
|
+
nonPropRoots: d.nonPropConditionRoots
|
|
20688
20981
|
});
|
|
20689
20982
|
const styleExpr = styleRef(j, stylesIdentifier, variantKey);
|
|
20690
20983
|
pushExpr(emitter.makeConditionalStyleExpr({
|
|
@@ -24569,7 +24862,8 @@ function emitShouldForwardPropWrappers(ctx) {
|
|
|
24569
24862
|
for (const when of Object.keys(d.variantStyleKeys ?? {})) {
|
|
24570
24863
|
const { props } = emitter.collectConditionProps({
|
|
24571
24864
|
when,
|
|
24572
|
-
...knownConditionProps ? { knownProps: knownConditionProps } : {}
|
|
24865
|
+
...knownConditionProps ? { knownProps: knownConditionProps } : {},
|
|
24866
|
+
nonPropRoots: d.nonPropConditionRoots
|
|
24573
24867
|
});
|
|
24574
24868
|
for (const p of props) if (p) extraProps.add(p);
|
|
24575
24869
|
}
|
|
@@ -24715,7 +25009,8 @@ function emitShouldForwardPropWrappers(ctx) {
|
|
|
24715
25009
|
if (compoundVariantKeys.has(when)) continue;
|
|
24716
25010
|
const { props } = emitter.collectConditionProps({
|
|
24717
25011
|
when,
|
|
24718
|
-
...knownProps ? { knownProps } : {}
|
|
25012
|
+
...knownProps ? { knownProps } : {},
|
|
25013
|
+
nonPropRoots: d.nonPropConditionRoots
|
|
24719
25014
|
});
|
|
24720
25015
|
for (const p of props) if (p && !dropProps.includes(p)) dropProps.push(p);
|
|
24721
25016
|
}
|
|
@@ -24726,7 +25021,8 @@ function emitShouldForwardPropWrappers(ctx) {
|
|
|
24726
25021
|
for (const extra of d.extraStylexPropsArgs) if (extra.when) {
|
|
24727
25022
|
const { props } = emitter.collectConditionProps({
|
|
24728
25023
|
when: extra.when,
|
|
24729
|
-
...knownProps ? { knownProps } : {}
|
|
25024
|
+
...knownProps ? { knownProps } : {},
|
|
25025
|
+
nonPropRoots: d.nonPropConditionRoots
|
|
24730
25026
|
});
|
|
24731
25027
|
for (const p of props) if (p && !destructureParts.includes(p)) destructureParts.push(p);
|
|
24732
25028
|
}
|
|
@@ -24760,7 +25056,8 @@ function emitShouldForwardPropWrappers(ctx) {
|
|
|
24760
25056
|
when: p.conditionWhen,
|
|
24761
25057
|
destructureProps: destructureParts,
|
|
24762
25058
|
booleanProps,
|
|
24763
|
-
...knownProps ? { knownProps } : {}
|
|
25059
|
+
...knownProps ? { knownProps } : {},
|
|
25060
|
+
nonPropRoots: d.nonPropConditionRoots
|
|
24764
25061
|
});
|
|
24765
25062
|
expr = emitter.makeConditionalStyleExpr({
|
|
24766
25063
|
cond,
|
|
@@ -25059,7 +25356,8 @@ function emitSimpleWithConfigWrappers(ctx) {
|
|
|
25059
25356
|
if (d.variantStyleKeys) for (const [when] of Object.entries(d.variantStyleKeys)) {
|
|
25060
25357
|
const { props } = emitter.collectConditionProps({
|
|
25061
25358
|
when,
|
|
25062
|
-
...knownProps ? { knownProps } : {}
|
|
25359
|
+
...knownProps ? { knownProps } : {},
|
|
25360
|
+
nonPropRoots: d.nonPropConditionRoots
|
|
25063
25361
|
});
|
|
25064
25362
|
for (const p of props) if (p) variantProps.add(p);
|
|
25065
25363
|
}
|
|
@@ -25073,7 +25371,8 @@ function emitSimpleWithConfigWrappers(ctx) {
|
|
|
25073
25371
|
if (!extra.when) continue;
|
|
25074
25372
|
const { props } = emitter.collectConditionProps({
|
|
25075
25373
|
when: extra.when,
|
|
25076
|
-
...knownProps ? { knownProps } : {}
|
|
25374
|
+
...knownProps ? { knownProps } : {},
|
|
25375
|
+
nonPropRoots: d.nonPropConditionRoots
|
|
25077
25376
|
});
|
|
25078
25377
|
for (const p of props) if (p) extraProps.add(p);
|
|
25079
25378
|
}
|
|
@@ -25668,7 +25967,7 @@ function collectPropsUsedOutsideExtraStyleConditionals(j, d, knownProps) {
|
|
|
25668
25967
|
if (name) used.add(name);
|
|
25669
25968
|
};
|
|
25670
25969
|
for (const [when] of Object.entries(d.variantStyleKeys ?? {})) {
|
|
25671
|
-
const parsed = parseVariantWhenToAst(j, when, void 0, knownProps);
|
|
25970
|
+
const parsed = parseVariantWhenToAst(j, when, void 0, knownProps, d.nonPropConditionRoots);
|
|
25672
25971
|
for (const prop of parsed.props) add(prop);
|
|
25673
25972
|
}
|
|
25674
25973
|
for (const dim of d.variantDimensions ?? []) {
|
|
@@ -27268,43 +27567,47 @@ function tryResolveConditionalValue(node, ctx) {
|
|
|
27268
27567
|
}
|
|
27269
27568
|
if (info?.kind === "themeBinding" && test.type === "Identifier" && typeof test.name === "string" && isDestructuredFromParam(expr, test.name)) {
|
|
27270
27569
|
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
|
-
|
|
27570
|
+
const whens = destructuredBooleanWhens(destructuredProp, getArrowFnParamBindings(expr));
|
|
27571
|
+
if (whens) {
|
|
27572
|
+
const cons = getBranch(consequent);
|
|
27573
|
+
const alt = getBranch(alternate);
|
|
27574
|
+
if (cons && alt) {
|
|
27575
|
+
if (new Set([cons.usage, alt.usage]).size === 1) {
|
|
27576
|
+
const usage = cons.usage;
|
|
27577
|
+
const variants = [{
|
|
27578
|
+
nameHint: "truthy",
|
|
27579
|
+
when: whens.truthy,
|
|
27580
|
+
expr: cons.expr,
|
|
27581
|
+
imports: cons.imports
|
|
27582
|
+
}, {
|
|
27583
|
+
nameHint: "falsy",
|
|
27584
|
+
when: whens.falsy,
|
|
27585
|
+
expr: alt.expr,
|
|
27586
|
+
imports: alt.imports
|
|
27587
|
+
}];
|
|
27588
|
+
return usage === "props" ? {
|
|
27589
|
+
type: "splitVariantsResolvedStyles",
|
|
27590
|
+
variants
|
|
27591
|
+
} : {
|
|
27592
|
+
type: "splitVariantsResolvedValue",
|
|
27593
|
+
variants
|
|
27594
|
+
};
|
|
27595
|
+
}
|
|
27294
27596
|
}
|
|
27597
|
+
const oneSided = buildOneSidedVariantResult({
|
|
27598
|
+
cons,
|
|
27599
|
+
alt,
|
|
27600
|
+
alternate,
|
|
27601
|
+
truthyWhen: whens.truthy
|
|
27602
|
+
});
|
|
27603
|
+
if (oneSided) return oneSided;
|
|
27604
|
+
if (!cons || !alt) return buildRuntimeCallResult();
|
|
27295
27605
|
}
|
|
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
27606
|
}
|
|
27305
27607
|
if (paramBindings?.kind === "destructured" && test.type === "Identifier" && typeof test.name === "string") {
|
|
27306
27608
|
const resolvedProp = resolveIdentifierToPropName(test, paramBindings);
|
|
27307
|
-
|
|
27609
|
+
const resolvedWhens = resolvedProp ? destructuredBooleanWhens(resolvedProp, paramBindings) : null;
|
|
27610
|
+
if (resolvedProp && resolvedWhens) {
|
|
27308
27611
|
const cons = getBranch(consequent);
|
|
27309
27612
|
const alt = getBranch(alternate);
|
|
27310
27613
|
if (cons && alt) {
|
|
@@ -27312,12 +27615,12 @@ function tryResolveConditionalValue(node, ctx) {
|
|
|
27312
27615
|
const usage = cons.usage;
|
|
27313
27616
|
const variants = [{
|
|
27314
27617
|
nameHint: "truthy",
|
|
27315
|
-
when:
|
|
27618
|
+
when: resolvedWhens.truthy,
|
|
27316
27619
|
expr: cons.expr,
|
|
27317
27620
|
imports: cons.imports
|
|
27318
27621
|
}, {
|
|
27319
27622
|
nameHint: "falsy",
|
|
27320
|
-
when:
|
|
27623
|
+
when: resolvedWhens.falsy,
|
|
27321
27624
|
expr: alt.expr,
|
|
27322
27625
|
imports: alt.imports
|
|
27323
27626
|
}];
|
|
@@ -27342,7 +27645,7 @@ function tryResolveConditionalValue(node, ctx) {
|
|
|
27342
27645
|
cons,
|
|
27343
27646
|
alt,
|
|
27344
27647
|
alternate,
|
|
27345
|
-
truthyWhen:
|
|
27648
|
+
truthyWhen: resolvedWhens.truthy
|
|
27346
27649
|
});
|
|
27347
27650
|
if (oneSided) return oneSided;
|
|
27348
27651
|
if (!cons || !alt) return buildRuntimeCallResult();
|
|
@@ -27419,6 +27722,8 @@ function tryResolveConditionalCssBlock(node, ctx) {
|
|
|
27419
27722
|
const { left, right } = body;
|
|
27420
27723
|
const testProp = paramName ? getSinglePropFromMemberExpr(left, paramName) : bindings?.kind === "destructured" ? resolveIdentifierToPropName(left, bindings) : null;
|
|
27421
27724
|
if (!testProp) return null;
|
|
27725
|
+
const whens = destructuredBooleanWhens(testProp, bindings);
|
|
27726
|
+
if (!whens) return null;
|
|
27422
27727
|
const cssText = literalToString(right);
|
|
27423
27728
|
if (cssText !== null && cssText !== void 0) {
|
|
27424
27729
|
const style = parseCssDeclarationBlock(cssText);
|
|
@@ -27427,7 +27732,7 @@ function tryResolveConditionalCssBlock(node, ctx) {
|
|
|
27427
27732
|
type: "splitVariants",
|
|
27428
27733
|
variants: [{
|
|
27429
27734
|
nameHint: "truthy",
|
|
27430
|
-
when:
|
|
27735
|
+
when: whens.truthy,
|
|
27431
27736
|
style
|
|
27432
27737
|
}]
|
|
27433
27738
|
};
|
|
@@ -27435,7 +27740,7 @@ function tryResolveConditionalCssBlock(node, ctx) {
|
|
|
27435
27740
|
if (!paramName) return null;
|
|
27436
27741
|
return resolveThemeTemplateToCssVariant(right, paramName, ctx, {
|
|
27437
27742
|
nameHint: "truthy",
|
|
27438
|
-
when:
|
|
27743
|
+
when: whens.truthy
|
|
27439
27744
|
});
|
|
27440
27745
|
}
|
|
27441
27746
|
function tryResolveConditionalCssBlockTernary(node, ctx) {
|
|
@@ -27887,6 +28192,35 @@ function replaceThemeRefsWithHookVar(expr, paramName, info) {
|
|
|
27887
28192
|
};
|
|
27888
28193
|
return replace(cloned);
|
|
27889
28194
|
}
|
|
28195
|
+
/**
|
|
28196
|
+
* Builds truthy/falsy `when` condition strings for a destructured boolean-ish prop,
|
|
28197
|
+
* accounting for destructuring defaults. A default applies only when the prop is
|
|
28198
|
+
* `undefined`, so a statically-truthy default means the truthy branch must also
|
|
28199
|
+
* apply when the prop is unset (`prop === undefined || prop`).
|
|
28200
|
+
*
|
|
28201
|
+
* Returns null when the prop has a default whose truthiness cannot be determined
|
|
28202
|
+
* statically — callers should fall back to other handlers instead of emitting a
|
|
28203
|
+
* condition that ignores the default.
|
|
28204
|
+
*/
|
|
28205
|
+
function destructuredBooleanWhens(propName, bindings) {
|
|
28206
|
+
if (bindings?.kind !== "destructured" || !bindings.defaults?.has(propName)) return {
|
|
28207
|
+
truthy: propName,
|
|
28208
|
+
falsy: `!${propName}`
|
|
28209
|
+
};
|
|
28210
|
+
const defaultValue = literalToStaticValue(bindings.defaults.get(propName));
|
|
28211
|
+
if (defaultValue === null) return null;
|
|
28212
|
+
if (defaultValue) {
|
|
28213
|
+
const truthy = `${propName} === undefined || ${propName}`;
|
|
28214
|
+
return {
|
|
28215
|
+
truthy,
|
|
28216
|
+
falsy: `!(${truthy})`
|
|
28217
|
+
};
|
|
28218
|
+
}
|
|
28219
|
+
return {
|
|
28220
|
+
truthy: propName,
|
|
28221
|
+
falsy: `!${propName}`
|
|
28222
|
+
};
|
|
28223
|
+
}
|
|
27890
28224
|
//#endregion
|
|
27891
28225
|
//#region src/internal/builtin-handlers.ts
|
|
27892
28226
|
/**
|
|
@@ -29386,7 +29720,9 @@ function tryHandleInterpolatedStringValue(args) {
|
|
|
29386
29720
|
const outputs = cssDeclarationToStylexDeclarations(d);
|
|
29387
29721
|
for (let i = 0; i < outputs.length; i++) {
|
|
29388
29722
|
const out = outputs[i];
|
|
29389
|
-
|
|
29723
|
+
const emitted = maybeOmitPxUnitFromStylexValue(j, tl, out.prop, d.important, { numericIdentifiers: args.numericIdentifiers });
|
|
29724
|
+
if (emitted !== tl && hasSingleSlotUnitSuffix(d.value)) markProvenSingleTokenValue(emitted);
|
|
29725
|
+
setValue(out.prop, emitted);
|
|
29390
29726
|
if (i === 0 && (d.leadingComment || d.leadingLineComment)) addPropComments(styleObj, out.prop, {
|
|
29391
29727
|
leading: d.leadingComment,
|
|
29392
29728
|
leadingLine: d.leadingLineComment
|
|
@@ -33494,7 +33830,12 @@ const createValuePatternHandlers = (ctx) => {
|
|
|
33494
33830
|
callArg,
|
|
33495
33831
|
condition: "always"
|
|
33496
33832
|
});
|
|
33497
|
-
} else styleFnFromProps.push({
|
|
33833
|
+
} else if (expr.body.operator === "||") styleFnFromProps.push({
|
|
33834
|
+
fnKey,
|
|
33835
|
+
jsxProp,
|
|
33836
|
+
condition: "truthy"
|
|
33837
|
+
});
|
|
33838
|
+
else styleFnFromProps.push({
|
|
33498
33839
|
fnKey,
|
|
33499
33840
|
jsxProp
|
|
33500
33841
|
});
|
|
@@ -34201,6 +34542,89 @@ function createDeclProcessingState(state, decl) {
|
|
|
34201
34542
|
};
|
|
34202
34543
|
}
|
|
34203
34544
|
//#endregion
|
|
34545
|
+
//#region src/internal/lower-rules/validate-decl-conflicts.ts
|
|
34546
|
+
/**
|
|
34547
|
+
* Returns the name of an imported runtime-condition root (recorded in
|
|
34548
|
+
* `nonPropConditionRoots`) that also appears as a genuine component prop. Such a
|
|
34549
|
+
* collision is unrepresentable: the decl-wide non-prop marking suppresses
|
|
34550
|
+
* destructuring of the prop, so a prop-based variant would silently read the
|
|
34551
|
+
* imported binding instead. Covers both typed props and props inferred from
|
|
34552
|
+
* `props.<name>` usage in styling.
|
|
34553
|
+
*
|
|
34554
|
+
* `variantWhens` must be sourced from the in-progress finalize state, since
|
|
34555
|
+
* `decl.variantStyleKeys` is not assigned until later in finalize.
|
|
34556
|
+
*/
|
|
34557
|
+
function findImportedRootPropCollision(decl, variantWhens) {
|
|
34558
|
+
const roots = decl.nonPropConditionRoots;
|
|
34559
|
+
if (!roots || roots.size === 0) return null;
|
|
34560
|
+
const directProps = collectDirectPropReferences(decl);
|
|
34561
|
+
for (const root of roots) {
|
|
34562
|
+
if (directProps.has(root)) return root;
|
|
34563
|
+
const bareRef = new RegExp(`(?:^|[^\\w.])${escapeRegex(root)}(?:$|[^\\w.])`);
|
|
34564
|
+
if (variantWhens.some((when) => bareRef.test(when))) return root;
|
|
34565
|
+
}
|
|
34566
|
+
return null;
|
|
34567
|
+
}
|
|
34568
|
+
/**
|
|
34569
|
+
* Returns true when the component declares both a logical scroll longhand
|
|
34570
|
+
* (e.g. `scroll-padding-inline-start`) and a physical scroll side
|
|
34571
|
+
* (e.g. `scroll-padding-left`) in the same scroll family. StyleX's
|
|
34572
|
+
* logical/physical conflict normalization resolves these to physical sides
|
|
34573
|
+
* assuming horizontal-tb LTR, but the logical-to-physical mapping depends on
|
|
34574
|
+
* `writing-mode`/`direction` (e.g. `inline-start` is the right side in RTL),
|
|
34575
|
+
* so any such mix may silently preserve or override the wrong side — bail.
|
|
34576
|
+
*/
|
|
34577
|
+
function hasConflictingLogicalPhysicalScrollProps(decl) {
|
|
34578
|
+
for (const family of SCROLL_FAMILIES) {
|
|
34579
|
+
let hasLogical = false;
|
|
34580
|
+
let hasPhysical = false;
|
|
34581
|
+
for (const rule of decl.rules) for (const declaration of rule.declarations) {
|
|
34582
|
+
const prop = declaration.property?.trim();
|
|
34583
|
+
if (!prop) continue;
|
|
34584
|
+
const camel = kebabToCamel(prop);
|
|
34585
|
+
if (!camel.startsWith(family)) continue;
|
|
34586
|
+
const side = camel.slice(family.length);
|
|
34587
|
+
if (/^(?:Inline|Block)/.test(side)) hasLogical = true;
|
|
34588
|
+
else if (side === "" || /^(?:Top|Right|Bottom|Left)$/.test(side)) hasPhysical = true;
|
|
34589
|
+
}
|
|
34590
|
+
if (hasLogical && hasPhysical) return true;
|
|
34591
|
+
}
|
|
34592
|
+
return false;
|
|
34593
|
+
}
|
|
34594
|
+
const SCROLL_FAMILIES = ["scrollMargin", "scrollPadding"];
|
|
34595
|
+
function collectDirectPropReferences(decl) {
|
|
34596
|
+
const props = /* @__PURE__ */ new Set();
|
|
34597
|
+
const add = (name) => {
|
|
34598
|
+
if (name && !name.startsWith("__")) props.add(name);
|
|
34599
|
+
};
|
|
34600
|
+
for (const name of decl.typeScriptExplicitPropNames ?? []) add(name);
|
|
34601
|
+
for (const entry of decl.styleFnFromProps ?? []) {
|
|
34602
|
+
add(entry.jsxProp);
|
|
34603
|
+
for (const extra of entry.extraCallArgs ?? []) add(extra.jsxProp);
|
|
34604
|
+
}
|
|
34605
|
+
for (const entry of decl.inlineStyleProps ?? []) add(entry.jsxProp);
|
|
34606
|
+
for (const dim of decl.variantDimensions ?? []) {
|
|
34607
|
+
add(dim.propName);
|
|
34608
|
+
add(dim.namespaceBooleanProp);
|
|
34609
|
+
}
|
|
34610
|
+
for (const cv of decl.compoundVariants ?? []) {
|
|
34611
|
+
add(cv.outerProp);
|
|
34612
|
+
add(cv.innerProp);
|
|
34613
|
+
}
|
|
34614
|
+
const attrs = decl.attrsInfo;
|
|
34615
|
+
if (attrs) {
|
|
34616
|
+
for (const entry of attrs.defaultAttrs ?? []) add(entry.jsxProp);
|
|
34617
|
+
for (const entry of attrs.dynamicAttrs ?? []) add(entry.jsxProp);
|
|
34618
|
+
for (const entry of attrs.conditionalAttrs ?? []) add(entry.jsxProp);
|
|
34619
|
+
for (const entry of attrs.invertedBoolAttrs ?? []) add(entry.jsxProp);
|
|
34620
|
+
for (const entry of attrs.attrsDynamicStyles ?? []) add(entry.jsxProp);
|
|
34621
|
+
}
|
|
34622
|
+
return props;
|
|
34623
|
+
}
|
|
34624
|
+
function kebabToCamel(prop) {
|
|
34625
|
+
return prop.replace(/-([a-z])/g, (_, ch) => ch.toUpperCase());
|
|
34626
|
+
}
|
|
34627
|
+
//#endregion
|
|
34204
34628
|
//#region src/internal/lower-rules/finalize-decl.ts
|
|
34205
34629
|
/**
|
|
34206
34630
|
* Finalizes per-declaration style objects after rule processing.
|
|
@@ -34209,6 +34633,14 @@ function createDeclProcessingState(state, decl) {
|
|
|
34209
34633
|
function finalizeDeclProcessing(ctx) {
|
|
34210
34634
|
const { state, decl, styleObj, perPropPseudo, perPropMedia, perPropComputedMedia, nestedSelectors, variantBuckets, variantStyleKeys, variantSourceOrder, extraStyleObjects, styleFnFromProps, styleFnDecls, attrBuckets, observedVariantFallbackFns, inlineStyleProps, localVarValues, cssHelperPropValues } = ctx;
|
|
34211
34635
|
const { rewriteCssVarsInStyleObject, rewriteCssVarsInAstNode, relationOverridePseudoBuckets, relationOverrides, ancestorSelectorParents, resolvedStyleObjects, warnings } = state;
|
|
34636
|
+
if (findImportedRootPropCollision(decl, Object.keys(variantStyleKeys ?? {}))) {
|
|
34637
|
+
state.bailUnsupported(decl, "Imported runtime condition root collides with a component prop of the same name");
|
|
34638
|
+
return;
|
|
34639
|
+
}
|
|
34640
|
+
if (hasConflictingLogicalPhysicalScrollProps(decl)) {
|
|
34641
|
+
state.bailUnsupported(decl, "Mixed logical and physical scroll properties cannot be normalized without a known writing-mode");
|
|
34642
|
+
return;
|
|
34643
|
+
}
|
|
34212
34644
|
mergeConditionBucket(styleObj, perPropPseudo);
|
|
34213
34645
|
mergeConditionBucket(styleObj, perPropMedia);
|
|
34214
34646
|
for (const [prop, entry] of perPropComputedMedia) {
|
|
@@ -36309,7 +36741,7 @@ const OPAQUE_SHORTHAND_PROPS = new Set([
|
|
|
36309
36741
|
function warnOpaqueShorthands(styleObj, decl, warnings) {
|
|
36310
36742
|
for (const prop of OPAQUE_SHORTHAND_PROPS) {
|
|
36311
36743
|
const val = styleObj[prop];
|
|
36312
|
-
if (val !== void 0 && isAstNode$1(val)) warnings.push({
|
|
36744
|
+
if (val !== void 0 && isAstNode$1(val) && !isProvenSingleTokenValue(val)) warnings.push({
|
|
36313
36745
|
severity: "warning",
|
|
36314
36746
|
type: "Shorthand property has an opaque value that StyleX will expand to longhands — use `directional` in resolveValue to return separate longhand tokens",
|
|
36315
36747
|
loc: decl.loc,
|
|
@@ -36985,6 +37417,11 @@ function tryHandleInterpolatedBorder(ctx, args) {
|
|
|
36985
37417
|
if (width) applyResolvedPropValue(widthProp, width);
|
|
36986
37418
|
if (style) applyResolvedPropValue(styleProp, style);
|
|
36987
37419
|
if (color) applyResolvedPropValue(colorProp, color);
|
|
37420
|
+
const stripConsumedStaticParts = () => {
|
|
37421
|
+
const value = d.value;
|
|
37422
|
+
if (!staticRaw || value?.kind !== "interpolated" || !Array.isArray(value.parts)) return;
|
|
37423
|
+
for (const part of value.parts) if (part?.kind === "static") part.value = "";
|
|
37424
|
+
};
|
|
36988
37425
|
const hasStaticWidthOrStyle = Boolean(width || style);
|
|
36989
37426
|
const targetProp = interpolationTarget === "color" ? colorProp : interpolationTarget === "width" ? widthProp : styleProp;
|
|
36990
37427
|
const targetCssProperty = interpolationTarget === "width" ? directionLower ? `border-${directionLower}-width` : "border-width" : interpolationTarget === "style" ? directionLower ? `border-${directionLower}-style` : "border-style" : directionLower ? `border-${directionLower}-color` : "border-color";
|
|
@@ -37046,6 +37483,7 @@ function tryHandleInterpolatedBorder(ctx, args) {
|
|
|
37046
37483
|
const alt = expr.body.alternate;
|
|
37047
37484
|
if (isMemberExpression(cons) || isMemberExpression(alt)) {
|
|
37048
37485
|
d.property = targetCssProperty;
|
|
37486
|
+
stripConsumedStaticParts();
|
|
37049
37487
|
return false;
|
|
37050
37488
|
}
|
|
37051
37489
|
}
|
|
@@ -37242,6 +37680,7 @@ function tryHandleInterpolatedBorder(ctx, args) {
|
|
|
37242
37680
|
if (expr?.type === "ArrowFunctionExpression") {
|
|
37243
37681
|
if (expr.body?.type === "MemberExpression") {
|
|
37244
37682
|
d.property = targetCssProperty;
|
|
37683
|
+
stripConsumedStaticParts();
|
|
37245
37684
|
return false;
|
|
37246
37685
|
}
|
|
37247
37686
|
}
|
|
@@ -37435,7 +37874,39 @@ function handleSplitVariantsResolvedValue(ctx) {
|
|
|
37435
37874
|
target[prop] = map;
|
|
37436
37875
|
return map;
|
|
37437
37876
|
};
|
|
37438
|
-
const
|
|
37877
|
+
const withImportant = (valueAst) => {
|
|
37878
|
+
if (!d.important || !valueAst || typeof valueAst !== "object") return valueAst;
|
|
37879
|
+
const node = valueAst;
|
|
37880
|
+
if (node.type === "StringLiteral" || node.type === "Literal" || node.type === "NumericLiteral") {
|
|
37881
|
+
if (typeof node.value === "string") return node.value.includes("!important") ? valueAst : j.literal(`${node.value} !important`);
|
|
37882
|
+
if (typeof node.value === "number") return j.literal(`${node.value} !important`);
|
|
37883
|
+
return valueAst;
|
|
37884
|
+
}
|
|
37885
|
+
if (node.type === "TemplateLiteral" && Array.isArray(node.quasis)) {
|
|
37886
|
+
const quasis = node.quasis;
|
|
37887
|
+
const lastIndex = quasis.length - 1;
|
|
37888
|
+
const last = quasis[lastIndex];
|
|
37889
|
+
const lastText = last?.value?.cooked ?? last?.value?.raw ?? "";
|
|
37890
|
+
if (lastText.includes("!important")) return valueAst;
|
|
37891
|
+
const newQuasis = quasis.map((q, i) => i === lastIndex ? j.templateElement({
|
|
37892
|
+
raw: `${lastText} !important`,
|
|
37893
|
+
cooked: `${lastText} !important`
|
|
37894
|
+
}, true) : j.templateElement({
|
|
37895
|
+
raw: q?.value?.raw ?? q?.value?.cooked ?? "",
|
|
37896
|
+
cooked: q?.value?.cooked ?? q?.value?.raw ?? ""
|
|
37897
|
+
}, false));
|
|
37898
|
+
return j.templateLiteral(newQuasis, node.expressions ?? []);
|
|
37899
|
+
}
|
|
37900
|
+
return j.templateLiteral([j.templateElement({
|
|
37901
|
+
raw: "",
|
|
37902
|
+
cooked: ""
|
|
37903
|
+
}, false), j.templateElement({
|
|
37904
|
+
raw: " !important",
|
|
37905
|
+
cooked: " !important"
|
|
37906
|
+
}, true)], [valueAst]);
|
|
37907
|
+
};
|
|
37908
|
+
const applyWithContext = (prop, valueAstRaw) => {
|
|
37909
|
+
const valueAst = withImportant(valueAstRaw);
|
|
37439
37910
|
if (media) {
|
|
37440
37911
|
const map = getOrCreateConditionMap(prop);
|
|
37441
37912
|
map[media] = valueAst;
|
|
@@ -38786,9 +39257,10 @@ function handleInterpolatedDeclaration(args) {
|
|
|
38786
39257
|
};
|
|
38787
39258
|
const resolveValueResult = resolveValue(resolveValueContext);
|
|
38788
39259
|
if (!resolveValueResult) {
|
|
39260
|
+
const isPlainOwnedConstant = info.path.length === 0 && imp.source.kind === "absolutePath" && !isStylexImportSource(imp.source.value);
|
|
38789
39261
|
warnings.push({
|
|
38790
39262
|
severity: "error",
|
|
38791
|
-
type: "Adapter resolveValue returned undefined for imported value",
|
|
39263
|
+
type: isPlainOwnedConstant ? "Imported constant cannot be referenced inside stylex.create() — move it into a `.stylex` defineConsts/defineVars group (or map it via adapter.resolveValue)" : "Adapter resolveValue returned undefined for imported value",
|
|
38792
39264
|
loc: getNodeLocStart(expr) ?? decl.loc,
|
|
38793
39265
|
context: {
|
|
38794
39266
|
localName: decl.localName,
|
|
@@ -38888,7 +39360,8 @@ function handleInterpolatedDeclaration(args) {
|
|
|
38888
39360
|
attrTarget,
|
|
38889
39361
|
resolvedSelectorMedia
|
|
38890
39362
|
})) continue;
|
|
38891
|
-
|
|
39363
|
+
const numericIdentifiers = getNumericImportedStylexIdentifiers(j, filePath, importMap, resolverImports);
|
|
39364
|
+
if (isImportedShorthandUnitValue(d, decl, importMap, numericIdentifiers)) {
|
|
38892
39365
|
bailUnsupportedLocal(decl, "Unsupported interpolation: call expression");
|
|
38893
39366
|
continue;
|
|
38894
39367
|
}
|
|
@@ -38901,7 +39374,7 @@ function handleInterpolatedDeclaration(args) {
|
|
|
38901
39374
|
addImport,
|
|
38902
39375
|
resolveImportedValueExpr,
|
|
38903
39376
|
resolveThemeValue,
|
|
38904
|
-
numericIdentifiers
|
|
39377
|
+
numericIdentifiers,
|
|
38905
39378
|
setStyleValue: (prop, value) => applyResolvedPropValue(prop, value, null)
|
|
38906
39379
|
})) continue;
|
|
38907
39380
|
if (bail) break;
|
|
@@ -38910,9 +39383,31 @@ function handleInterpolatedDeclaration(args) {
|
|
|
38910
39383
|
if (slot) {
|
|
38911
39384
|
const expr = decl.templateExpressions[slot.slotId];
|
|
38912
39385
|
if (tryEmitObservedCssBlockVariantBuckets(expr)) continue;
|
|
39386
|
+
const bailOnPropDependentCssHelper = (helperDecl) => {
|
|
39387
|
+
for (const helperExpr of helperDecl.templateExpressions ?? []) {
|
|
39388
|
+
if (!helperExpr || helperExpr.type !== "ArrowFunctionExpression" && helperExpr.type !== "FunctionExpression") continue;
|
|
39389
|
+
const propsUsed = new Set([...collectPropsFromArrowFn(helperExpr), ...collectPropsFromArrowFnDestructured(helperExpr)]);
|
|
39390
|
+
propsUsed.delete("theme");
|
|
39391
|
+
if (propsUsed.size > 0) {
|
|
39392
|
+
warnings.push({
|
|
39393
|
+
severity: "warning",
|
|
39394
|
+
type: "css helper with prop-based interpolation cannot be reused as a mixin",
|
|
39395
|
+
loc: decl.loc,
|
|
39396
|
+
context: {
|
|
39397
|
+
localName: decl.localName,
|
|
39398
|
+
mixin: helperDecl.localName
|
|
39399
|
+
}
|
|
39400
|
+
});
|
|
39401
|
+
bail = true;
|
|
39402
|
+
return true;
|
|
39403
|
+
}
|
|
39404
|
+
}
|
|
39405
|
+
return false;
|
|
39406
|
+
};
|
|
38913
39407
|
if (expr?.type === "Identifier" && cssHelperNames.has(expr.name)) {
|
|
38914
39408
|
const helperDecl = declByLocalName.get(expr.name);
|
|
38915
39409
|
if (helperDecl) {
|
|
39410
|
+
if (bailOnPropDependentCssHelper(helperDecl)) break;
|
|
38916
39411
|
applyCssHelperMixin(decl, helperDecl, cssHelperPropValues, inlineStyleProps);
|
|
38917
39412
|
continue;
|
|
38918
39413
|
}
|
|
@@ -38921,6 +39416,7 @@ function handleInterpolatedDeclaration(args) {
|
|
|
38921
39416
|
const calleeName = expr.callee.name;
|
|
38922
39417
|
const helperDecl = declByLocalName.get(calleeName);
|
|
38923
39418
|
if (helperDecl?.isCssHelper) {
|
|
39419
|
+
if (bailOnPropDependentCssHelper(helperDecl)) break;
|
|
38924
39420
|
applyCssHelperMixin(decl, helperDecl, cssHelperPropValues, inlineStyleProps);
|
|
38925
39421
|
continue;
|
|
38926
39422
|
}
|
|
@@ -39066,7 +39562,24 @@ function handleInterpolatedDeclaration(args) {
|
|
|
39066
39562
|
})) continue;
|
|
39067
39563
|
if (d.property && d.value.kind === "interpolated" && tryHandleMultiSlotTernary(ctx, d)) continue;
|
|
39068
39564
|
if (tryHandleMultiSlotRuntimeValue(resolveImportedValueExpr)) continue;
|
|
39069
|
-
const
|
|
39565
|
+
const remainingSlotParts = d.value.parts.filter((p) => p.kind === "slot");
|
|
39566
|
+
if (remainingSlotParts.filter((p) => {
|
|
39567
|
+
const slotExpr = decl.templateExpressions[p.slotId];
|
|
39568
|
+
return slotExpr?.type === "ArrowFunctionExpression" || slotExpr?.type === "FunctionExpression";
|
|
39569
|
+
}).length > 1) {
|
|
39570
|
+
warnings.push({
|
|
39571
|
+
severity: "error",
|
|
39572
|
+
type: "Unsupported interpolation: multiple dynamic slots in one declaration",
|
|
39573
|
+
loc: decl.loc,
|
|
39574
|
+
context: {
|
|
39575
|
+
localName: decl.localName,
|
|
39576
|
+
property: d.property
|
|
39577
|
+
}
|
|
39578
|
+
});
|
|
39579
|
+
bail = true;
|
|
39580
|
+
break;
|
|
39581
|
+
}
|
|
39582
|
+
const slotPart = remainingSlotParts[0];
|
|
39070
39583
|
const slotId = slotPart && slotPart.kind === "slot" ? slotPart.slotId : 0;
|
|
39071
39584
|
const expr = decl.templateExpressions[slotId];
|
|
39072
39585
|
const loc = getNodeLocStart(expr);
|
|
@@ -39592,11 +40105,11 @@ function handleInterpolatedDeclaration(args) {
|
|
|
39592
40105
|
const scalarDynamic = shouldUseScalarDynamicArgs(d.property, d.valueRaw) && dynamicProps.length > 0 ? scalarizePropsObjectDynamicValue({
|
|
39593
40106
|
j,
|
|
39594
40107
|
valueExpr: dynamicValueExpr,
|
|
39595
|
-
paramName
|
|
40108
|
+
paramName,
|
|
39596
40109
|
propNames: dynamicProps
|
|
39597
40110
|
}) : null;
|
|
39598
40111
|
const dynamicStyleValueExpr = scalarDynamic?.valueExpr ?? dynamicValueExpr;
|
|
39599
|
-
const dynamicStyleParams = scalarDynamic ? scalarDynamic.paramNames.map((propName) => j.identifier(propName)) : [j.identifier(
|
|
40112
|
+
const dynamicStyleParams = scalarDynamic ? scalarDynamic.paramNames.map((propName) => j.identifier(propName)) : [j.identifier(paramName)];
|
|
39600
40113
|
if (scalarDynamic) annotateScalarParams(dynamicStyleParams, scalarDynamic.paramNames);
|
|
39601
40114
|
const callArg = j.objectExpression(dynamicProps.map((name) => {
|
|
39602
40115
|
const prop = j.property("init", j.identifier(name), j.identifier(name));
|
|
@@ -39884,17 +40397,22 @@ function handleInterpolatedDeclaration(args) {
|
|
|
39884
40397
|
const callArg = resolvedCallArg ?? scalarCallArg;
|
|
39885
40398
|
const hasExplicitType = !!decl.propsType;
|
|
39886
40399
|
const isOptional = ctx.isJsxPropOptional(jsxProp);
|
|
40400
|
+
const foldsStaticBaseIntoPseudoDefault = !media && !!pseudos?.length && staticBaseValueWouldFold(styleObj[out.prop]);
|
|
39887
40401
|
styleFnFromProps.push({
|
|
39888
40402
|
fnKey,
|
|
39889
40403
|
jsxProp,
|
|
39890
40404
|
...callArg ? { callArg } : {},
|
|
39891
|
-
...hasExplicitType && !isOptional ? { condition: "always" } : {}
|
|
40405
|
+
...hasExplicitType && !isOptional || foldsStaticBaseIntoPseudoDefault ? { condition: "always" } : {}
|
|
39892
40406
|
});
|
|
39893
40407
|
if (!styleFnDecls.has(fnKey)) {
|
|
39894
40408
|
const param = j.identifier(outParamName);
|
|
39895
40409
|
const valueId = j.identifier(outParamName);
|
|
39896
40410
|
if (jsxProp !== "__props") annotateParamFromJsxProp(param, jsxProp);
|
|
39897
40411
|
if (resolvedCallArg && /\.(ts|tsx)$/.test(filePath)) param.typeAnnotation = j.tsTypeAnnotation(j.tsStringKeyword());
|
|
40412
|
+
if (foldsStaticBaseIntoPseudoDefault && isOptional && jsxProp !== "__props" && /\.(ts|tsx)$/.test(filePath)) {
|
|
40413
|
+
const baseTypeNode = param.typeAnnotation?.typeAnnotation ?? j.tsStringKeyword();
|
|
40414
|
+
param.typeAnnotation = j.tsTypeAnnotation(j.tsUnionType([baseTypeNode, j.tsUndefinedKeyword()]));
|
|
40415
|
+
}
|
|
39898
40416
|
if (jsxProp?.startsWith?.("$")) ensureShouldForwardPropDrop(decl, jsxProp);
|
|
39899
40417
|
const buildValueExpr = () => {
|
|
39900
40418
|
const transformed = (() => {
|
|
@@ -39959,7 +40477,28 @@ function handleInterpolatedDeclaration(args) {
|
|
|
39959
40477
|
};
|
|
39960
40478
|
const valueExpr = buildValueExpr();
|
|
39961
40479
|
const getPropValue = () => {
|
|
40480
|
+
if (!media && !pseudos?.length) return valueExpr;
|
|
40481
|
+
if (!media && pseudos?.length) {
|
|
40482
|
+
const existingStatic = styleObj[out.prop];
|
|
40483
|
+
let defaultValue = j.literal(null);
|
|
40484
|
+
if (existingStatic !== void 0 && existingStatic !== null) if (typeof existingStatic === "object") {
|
|
40485
|
+
if ("type" in existingStatic) {
|
|
40486
|
+
defaultValue = cloneAstNode(existingStatic);
|
|
40487
|
+
delete styleObj[out.prop];
|
|
40488
|
+
}
|
|
40489
|
+
} else {
|
|
40490
|
+
defaultValue = staticValueToLiteral(j, existingStatic);
|
|
40491
|
+
delete styleObj[out.prop];
|
|
40492
|
+
}
|
|
40493
|
+
return j.objectExpression([j.property("init", j.identifier("default"), defaultValue), ...pseudos.map((ps) => j.property("init", j.literal(ps), valueExpr))]);
|
|
40494
|
+
}
|
|
39962
40495
|
if (!media) return valueExpr;
|
|
40496
|
+
if (pseudos?.length) return buildPseudoMediaPropValue({
|
|
40497
|
+
j,
|
|
40498
|
+
valueExpr,
|
|
40499
|
+
pseudos,
|
|
40500
|
+
media
|
|
40501
|
+
});
|
|
39963
40502
|
const existingFn = styleFnDecls.get(fnKey);
|
|
39964
40503
|
let existingValue = null;
|
|
39965
40504
|
if (existingFn?.type === "ArrowFunctionExpression") {
|
|
@@ -40215,6 +40754,17 @@ function resolveDerivedLocalVariable(j, fnBody, fnParamName, localName, jsxProp)
|
|
|
40215
40754
|
function isPseudoElementSelector(pseudoElement) {
|
|
40216
40755
|
return pseudoElement === "::before" || pseudoElement === "::after" || pseudoElement === "::placeholder";
|
|
40217
40756
|
}
|
|
40757
|
+
/**
|
|
40758
|
+
* Whether a base style value for a property would be folded into a pseudo-gated
|
|
40759
|
+
* dynamic style function's `default` (mirrors the fold logic in getPropValue):
|
|
40760
|
+
* plain primitives and AST-node values fold; existing pseudo/media condition
|
|
40761
|
+
* buckets (plain objects without a `type` discriminator) do not.
|
|
40762
|
+
*/
|
|
40763
|
+
function staticBaseValueWouldFold(existingStatic) {
|
|
40764
|
+
if (existingStatic === void 0 || existingStatic === null) return false;
|
|
40765
|
+
if (typeof existingStatic === "object") return "type" in existingStatic;
|
|
40766
|
+
return true;
|
|
40767
|
+
}
|
|
40218
40768
|
function tryHandleLocalCustomPropertyDefinition(args) {
|
|
40219
40769
|
const { j, d, decl, expr, getOrCreateLocalStylexVar, inlineStyleProps } = args;
|
|
40220
40770
|
if (!expr || typeof expr !== "object") return false;
|
|
@@ -40269,16 +40819,45 @@ function tryHandleRuntimeConditionalStaticBranches(ctx, args) {
|
|
|
40269
40819
|
state.bailUnsupported(decl, "Unsupported interpolation: call expression");
|
|
40270
40820
|
return true;
|
|
40271
40821
|
}
|
|
40272
|
-
if (
|
|
40822
|
+
if (!subtractLaterStaticOverrides({
|
|
40823
|
+
rule,
|
|
40824
|
+
allRules,
|
|
40825
|
+
currentDecl: d,
|
|
40826
|
+
branchStyles: [consequentStyle, alternateStyle]
|
|
40827
|
+
})) {
|
|
40273
40828
|
state.bailUnsupported(decl, "Unsupported interpolation: call expression");
|
|
40274
40829
|
return true;
|
|
40275
40830
|
}
|
|
40831
|
+
if (!Object.keys(consequentStyle).length && !Object.keys(alternateStyle).length) return true;
|
|
40276
40832
|
const target = getBaseStyleTarget();
|
|
40277
40833
|
for (const [prop, value] of Object.entries(alternateStyle)) target[prop] = value;
|
|
40278
40834
|
applyVariant({ when }, consequentStyle);
|
|
40279
40835
|
decl.needsWrapperComponent = true;
|
|
40836
|
+
recordNonPropConditionRoots(decl, expr.test);
|
|
40280
40837
|
return true;
|
|
40281
40838
|
}
|
|
40839
|
+
/**
|
|
40840
|
+
* Records the root identifiers of an imported runtime condition on the decl so
|
|
40841
|
+
* wrapper emission treats them as module-scope bindings rather than component
|
|
40842
|
+
* props (which matters for lowercase roots like `browser.isTouchDevice`).
|
|
40843
|
+
*/
|
|
40844
|
+
function recordNonPropConditionRoots(decl, test) {
|
|
40845
|
+
const roots = decl.nonPropConditionRoots ??= /* @__PURE__ */ new Set();
|
|
40846
|
+
const visit = (expr) => {
|
|
40847
|
+
if (expr.type === "LogicalExpression") {
|
|
40848
|
+
visit(expr.left);
|
|
40849
|
+
visit(expr.right);
|
|
40850
|
+
return;
|
|
40851
|
+
}
|
|
40852
|
+
if (expr.type === "UnaryExpression") {
|
|
40853
|
+
visit(expr.argument);
|
|
40854
|
+
return;
|
|
40855
|
+
}
|
|
40856
|
+
const info = extractRootAndPath(expr);
|
|
40857
|
+
if (info && info.path.length > 0) roots.add(info.rootName);
|
|
40858
|
+
};
|
|
40859
|
+
visit(test);
|
|
40860
|
+
}
|
|
40282
40861
|
function buildStaticBranchStyle(d, rawValue) {
|
|
40283
40862
|
if (d.property === "background" && isUnsupportedBackgroundShorthandValue(rawValue)) return null;
|
|
40284
40863
|
const staticDecl = {
|
|
@@ -40303,24 +40882,120 @@ function sameStyleProps(left, right) {
|
|
|
40303
40882
|
const rightKeys = new Set(Object.keys(right));
|
|
40304
40883
|
return leftKeys.length === rightKeys.size && leftKeys.every((key) => rightKeys.has(key));
|
|
40305
40884
|
}
|
|
40306
|
-
|
|
40885
|
+
/**
|
|
40886
|
+
* Removes branch properties that are unconditionally overridden by later static
|
|
40887
|
+
* declarations in the same selector context, so the runtime variant cannot
|
|
40888
|
+
* invert the original CSS cascade. Partially overridden directional props are
|
|
40889
|
+
* narrowed to the longhands that survive the override (e.g. `marginBlock`
|
|
40890
|
+
* overridden by a later `margin-top` becomes `marginBlockEnd`).
|
|
40891
|
+
*
|
|
40892
|
+
* Returns false when a later overlapping declaration cannot be subtracted
|
|
40893
|
+
* safely (conditional at-rule context, dynamic value, property-less helper, or
|
|
40894
|
+
* a multi-token branch value that cannot be split per longhand) — the caller
|
|
40895
|
+
* must bail in that case.
|
|
40896
|
+
*/
|
|
40897
|
+
function subtractLaterStaticOverrides(args) {
|
|
40898
|
+
const { rule, allRules, currentDecl, branchStyles } = args;
|
|
40307
40899
|
const currentIndex = rule.declarations.indexOf(currentDecl);
|
|
40308
|
-
if (currentIndex === -1) return
|
|
40309
|
-
|
|
40900
|
+
if (currentIndex === -1) return true;
|
|
40901
|
+
const laterContexts = [{
|
|
40902
|
+
declarations: rule.declarations.slice(currentIndex + 1),
|
|
40903
|
+
unconditional: true
|
|
40904
|
+
}];
|
|
40310
40905
|
const currentRuleIndex = allRules.indexOf(rule);
|
|
40311
|
-
if (currentRuleIndex
|
|
40312
|
-
|
|
40313
|
-
|
|
40314
|
-
|
|
40906
|
+
if (currentRuleIndex !== -1) for (const laterRule of allRules.slice(currentRuleIndex + 1)) {
|
|
40907
|
+
if (laterRule.selector !== rule.selector) continue;
|
|
40908
|
+
laterContexts.push({
|
|
40909
|
+
declarations: laterRule.declarations,
|
|
40910
|
+
unconditional: sameAtRuleStack(laterRule.atRuleStack, rule.atRuleStack)
|
|
40911
|
+
});
|
|
40315
40912
|
}
|
|
40316
|
-
|
|
40913
|
+
const branchProps = () => [...new Set(branchStyles.flatMap((style) => Object.keys(style)))];
|
|
40914
|
+
for (const context of laterContexts) for (const laterDecl of context.declarations) {
|
|
40915
|
+
if (!laterDecl.property) {
|
|
40916
|
+
if (branchProps().length) return false;
|
|
40917
|
+
continue;
|
|
40918
|
+
}
|
|
40919
|
+
if (isBorderShorthandProperty(laterDecl.property)) {
|
|
40920
|
+
const borderProps = new Set(cssDeclarationToStylexDeclarations(laterDecl).map((out) => out.prop));
|
|
40921
|
+
if (branchProps().some((prop) => [...borderProps].some((borderProp) => stylexPropsOverlap(prop, borderProp)))) return false;
|
|
40922
|
+
continue;
|
|
40923
|
+
}
|
|
40924
|
+
for (const out of cssDeclarationToStylexDeclarations(laterDecl)) {
|
|
40925
|
+
const overrideProp = out.prop;
|
|
40926
|
+
const overlapped = branchProps().filter((prop) => stylexPropsOverlap(prop, overrideProp));
|
|
40927
|
+
if (!overlapped.length) continue;
|
|
40928
|
+
if (currentDecl.important && !laterDecl.important) return false;
|
|
40929
|
+
if (!context.unconditional || laterDecl.value.kind !== "static") return false;
|
|
40930
|
+
for (const branch of branchStyles) if (!subtractOverrideFromBranch(branch, overlapped, overrideProp)) return false;
|
|
40931
|
+
}
|
|
40932
|
+
}
|
|
40933
|
+
return true;
|
|
40317
40934
|
}
|
|
40318
|
-
function
|
|
40319
|
-
|
|
40320
|
-
|
|
40321
|
-
|
|
40935
|
+
function sameAtRuleStack(left, right) {
|
|
40936
|
+
return left.length === right.length && left.every((entry, i) => entry === right[i]);
|
|
40937
|
+
}
|
|
40938
|
+
/** True for the `border` / `border-<side>` shorthands (not the longhands). */
|
|
40939
|
+
function isBorderShorthandProperty(property) {
|
|
40940
|
+
return /^border(?:-(?:top|right|bottom|left))?$/.test(property.trim());
|
|
40941
|
+
}
|
|
40942
|
+
function subtractOverrideFromBranch(branch, overlappedProps, overrideProp) {
|
|
40943
|
+
const overridePhysical = new Set(physicalLonghandExpansion(overrideProp));
|
|
40944
|
+
const overrideIsLogical = isLogicalDirectionalProp(overrideProp);
|
|
40945
|
+
for (const branchProp of overlappedProps) {
|
|
40946
|
+
if (!(branchProp in branch)) continue;
|
|
40947
|
+
const branchPhysical = physicalLonghandExpansion(branchProp);
|
|
40948
|
+
const remainder = branchPhysical.filter((prop) => !overridePhysical.has(prop));
|
|
40949
|
+
if (remainder.length === branchPhysical.length) continue;
|
|
40950
|
+
if (isLogicalDirectionalProp(branchProp) !== overrideIsLogical) return false;
|
|
40951
|
+
const value = branch[branchProp];
|
|
40952
|
+
delete branch[branchProp];
|
|
40953
|
+
if (!remainder.length) continue;
|
|
40954
|
+
if (!isSingleCssToken(value)) return false;
|
|
40955
|
+
for (const physical of remainder) {
|
|
40956
|
+
const name = overrideIsLogical && LOGICAL_TO_PHYSICAL[branchProp] ? logicalFormForPhysical(branchProp, physical) : physical;
|
|
40957
|
+
if (!name) return false;
|
|
40958
|
+
branch[name] = value;
|
|
40959
|
+
}
|
|
40322
40960
|
}
|
|
40323
|
-
return
|
|
40961
|
+
return true;
|
|
40962
|
+
}
|
|
40963
|
+
/**
|
|
40964
|
+
* True for a logical directional longhand whose physical side(s) depend on the
|
|
40965
|
+
* writing mode — `marginInline`, `paddingBlockEnd`, `scrollMarginInlineStart`,
|
|
40966
|
+
* etc. The physical-neutral full shorthands (`margin`, `padding`) and physical
|
|
40967
|
+
* sides (`marginTop`) are not logical.
|
|
40968
|
+
*/
|
|
40969
|
+
function isLogicalDirectionalProp(prop) {
|
|
40970
|
+
return LOGICAL_TO_PHYSICAL[prop] !== void 0;
|
|
40971
|
+
}
|
|
40972
|
+
/** Physical longhands covered by a StyleX directional/border property. */
|
|
40973
|
+
function physicalLonghandExpansion(prop) {
|
|
40974
|
+
const group = SHORTHAND_LONGHANDS[prop];
|
|
40975
|
+
if (group) return [...group.physical];
|
|
40976
|
+
const logical = LOGICAL_TO_PHYSICAL[prop];
|
|
40977
|
+
if (logical) return [...logical];
|
|
40978
|
+
const borderMatch = prop.match(/^border(Top|Right|Bottom|Left)?(Width|Style|Color)$/);
|
|
40979
|
+
if (borderMatch) {
|
|
40980
|
+
const side = borderMatch[1];
|
|
40981
|
+
const kind = borderMatch[2];
|
|
40982
|
+
return side ? [prop] : [
|
|
40983
|
+
"Top",
|
|
40984
|
+
"Right",
|
|
40985
|
+
"Bottom",
|
|
40986
|
+
"Left"
|
|
40987
|
+
].map((s) => `border${s}${kind}`);
|
|
40988
|
+
}
|
|
40989
|
+
return [prop];
|
|
40990
|
+
}
|
|
40991
|
+
/** Maps a physical longhand back to the Start/End form of a logical branch prop. */
|
|
40992
|
+
function logicalFormForPhysical(logicalProp, physical) {
|
|
40993
|
+
for (const [name, physicalProps] of Object.entries(LOGICAL_TO_PHYSICAL)) if (physicalProps.length === 1 && physicalProps[0] === physical && name.startsWith(logicalProp)) return name;
|
|
40994
|
+
return null;
|
|
40995
|
+
}
|
|
40996
|
+
function isSingleCssToken(value) {
|
|
40997
|
+
if (typeof value === "number") return true;
|
|
40998
|
+
return typeof value === "string" && value.trim() !== "" && !/\s/.test(value.trim());
|
|
40324
40999
|
}
|
|
40325
41000
|
function stylexPropsOverlap(left, right) {
|
|
40326
41001
|
const leftRelated = relatedDirectionalProps(left);
|
|
@@ -40356,21 +41031,20 @@ function addRelatedBorderLonghands(prop, related) {
|
|
|
40356
41031
|
}
|
|
40357
41032
|
function isImportedRuntimeCondition(expr, importMap) {
|
|
40358
41033
|
const info = extractRootAndPath(expr);
|
|
40359
|
-
if (info && info.path.length > 0 && importMap.has(info.rootName)
|
|
41034
|
+
if (info && info.path.length > 0 && importMap.has(info.rootName)) return true;
|
|
40360
41035
|
if (expr.type === "LogicalExpression" && expr.operator === "&&") return isImportedRuntimeCondition(expr.left, importMap) && isImportedRuntimeCondition(expr.right, importMap);
|
|
40361
41036
|
if (expr.type === "UnaryExpression" && expr.operator === "!") return isImportedRuntimeCondition(expr.argument, importMap);
|
|
40362
41037
|
return false;
|
|
40363
41038
|
}
|
|
40364
|
-
function
|
|
40365
|
-
return /^[A-Z]/.test(rootName);
|
|
40366
|
-
}
|
|
40367
|
-
function isImportedShorthandUnitValue(d, decl, importMap) {
|
|
41039
|
+
function isImportedShorthandUnitValue(d, decl, importMap, numericIdentifiers) {
|
|
40368
41040
|
if (!d.property || !isCssShorthandProperty(d.property)) return false;
|
|
40369
41041
|
const staticParts = getSingleSlotStaticParts(d, decl);
|
|
40370
41042
|
if (!staticParts || !/^[a-zA-Z%]/.test(staticParts.suffix)) return false;
|
|
40371
41043
|
const slotPart = d.value.kind === "interpolated" ? d.value.parts.find((part) => part.kind === "slot") : null;
|
|
40372
41044
|
const info = extractRootAndPath(slotPart && slotPart.kind === "slot" ? decl.templateExpressions[slotPart.slotId] : void 0);
|
|
40373
|
-
|
|
41045
|
+
if (!info || !importMap.has(info.rootName)) return false;
|
|
41046
|
+
if ((d.property === "margin" || d.property === "padding") && staticParts.prefix.trim() === "" && /^[a-zA-Z%]+$/.test(staticParts.suffix.trim()) && numericIdentifiers.has(info.rootName)) return false;
|
|
41047
|
+
return true;
|
|
40374
41048
|
}
|
|
40375
41049
|
function expressionToSource(j, expr) {
|
|
40376
41050
|
try {
|
|
@@ -42122,6 +42796,12 @@ function processRuleDeclarations(args) {
|
|
|
42122
42796
|
d.property = resolvedProperty;
|
|
42123
42797
|
}
|
|
42124
42798
|
if (d.value.kind === "interpolated") {
|
|
42799
|
+
if (d.property && isLogicalScrollAxisShorthand(d.property)) {
|
|
42800
|
+
state.bailUnsupported(ctx.decl, "Dynamic logical scroll shorthand cannot be expanded — bind a specific longhand (e.g. scroll-padding-inline-start) instead");
|
|
42801
|
+
if (state.currentDecl === ctx.decl) continue;
|
|
42802
|
+
state.bail = true;
|
|
42803
|
+
break;
|
|
42804
|
+
}
|
|
42125
42805
|
handleInterpolatedDeclaration({
|
|
42126
42806
|
ctx,
|
|
42127
42807
|
rule,
|
|
@@ -42167,6 +42847,20 @@ function processRuleDeclarations(args) {
|
|
|
42167
42847
|
}
|
|
42168
42848
|
}
|
|
42169
42849
|
if (d.property === "background" && isUnsupportedBackgroundShorthandValue(d.valueRaw)) {
|
|
42850
|
+
const expanded = d.value.kind === "static" && !d.important && !hasOtherBackgroundDeclaration(allRules, d) ? expandBackgroundShorthandComponents(d.valueRaw) : null;
|
|
42851
|
+
if (expanded) {
|
|
42852
|
+
const commentSource = {
|
|
42853
|
+
leading: d.leadingComment,
|
|
42854
|
+
leadingLine: d.leadingLineComment,
|
|
42855
|
+
trailingLine: d.trailingLineComment
|
|
42856
|
+
};
|
|
42857
|
+
let isFirst = true;
|
|
42858
|
+
for (const { prop, value } of expanded) {
|
|
42859
|
+
applyResolvedPropValue(prop, value, isFirst ? commentSource : null, d.property);
|
|
42860
|
+
isFirst = false;
|
|
42861
|
+
}
|
|
42862
|
+
continue;
|
|
42863
|
+
}
|
|
42170
42864
|
state.bailUnsupported(ctx.decl, "Unsupported background shorthand: multiple components cannot be mapped to a single StyleX longhand");
|
|
42171
42865
|
if (state.currentDecl === ctx.decl) break;
|
|
42172
42866
|
state.bail = true;
|
|
@@ -42221,6 +42915,19 @@ function resolveInterpolatedPropertyName(property, ctx) {
|
|
|
42221
42915
|
if (!resolved.startsWith("--")) return null;
|
|
42222
42916
|
return resolved;
|
|
42223
42917
|
}
|
|
42918
|
+
/**
|
|
42919
|
+
* True when any declaration other than `current` (across all of the component's
|
|
42920
|
+
* rules) targets a `background`/`background-*` property. A multi-component
|
|
42921
|
+
* background expansion only reproduces reset semantics in isolation, so the
|
|
42922
|
+
* presence of a sibling background declaration makes the expansion unsafe.
|
|
42923
|
+
*/
|
|
42924
|
+
function hasOtherBackgroundDeclaration(allRules, current) {
|
|
42925
|
+
for (const rule of allRules) for (const declaration of rule.declarations) {
|
|
42926
|
+
if (declaration === current) continue;
|
|
42927
|
+
if (declaration.property && /^background(-|$)/.test(declaration.property)) return true;
|
|
42928
|
+
}
|
|
42929
|
+
return false;
|
|
42930
|
+
}
|
|
42224
42931
|
//#endregion
|
|
42225
42932
|
//#region src/internal/lower-rules/process-rules.ts
|
|
42226
42933
|
function processDeclRules(ctx) {
|
|
@@ -42864,6 +43571,40 @@ function processDeclRules(ctx) {
|
|
|
42864
43571
|
for (const bucket of variantBuckets.values()) if (Object.hasOwn(bucket, prop)) wrapStyleConditionValue(bucket, prop, conditionKey, conditionValue);
|
|
42865
43572
|
patchStyleFnConditionValue(prop, conditionKey, conditionValue);
|
|
42866
43573
|
};
|
|
43574
|
+
/**
|
|
43575
|
+
* A base-scope declaration later in the CSS overrides any earlier conditional
|
|
43576
|
+
* assignment of the same property — within one styled template the generated
|
|
43577
|
+
* class contains both declarations, and the last one wins regardless of the
|
|
43578
|
+
* runtime condition. Drop the dead base-scope value from earlier variant
|
|
43579
|
+
* buckets so the emitted variant (applied after the base style in
|
|
43580
|
+
* stylex.props) cannot incorrectly win. Condition-scoped values (pseudo/media
|
|
43581
|
+
* maps) only lose their `default` layer.
|
|
43582
|
+
*
|
|
43583
|
+
* Exception: an earlier `!important` conditional value still wins over a later
|
|
43584
|
+
* non-important base declaration in the CSS cascade, so it must be preserved.
|
|
43585
|
+
* (When the later base is itself `!important`, source order decides and the
|
|
43586
|
+
* later one wins, so clearing is correct.)
|
|
43587
|
+
*/
|
|
43588
|
+
const clearEarlierVariantBaseValues = (prop, laterBaseValue) => {
|
|
43589
|
+
const laterBaseIsImportant = cssValueIsImportant(laterBaseValue);
|
|
43590
|
+
for (const [when, bucket] of variantBuckets) {
|
|
43591
|
+
if (!Object.hasOwn(bucket, prop)) continue;
|
|
43592
|
+
const bucketValue = bucket[prop];
|
|
43593
|
+
if (bucketValue !== null && typeof bucketValue === "object" && !isAstNode$1(bucketValue) && "default" in bucketValue) {
|
|
43594
|
+
const conditionDefault = bucketValue.default;
|
|
43595
|
+
if (!laterBaseIsImportant && cssValueIsImportant(conditionDefault)) continue;
|
|
43596
|
+
bucketValue.default = null;
|
|
43597
|
+
continue;
|
|
43598
|
+
}
|
|
43599
|
+
if (!laterBaseIsImportant && cssValueIsImportant(bucketValue)) continue;
|
|
43600
|
+
delete bucket[prop];
|
|
43601
|
+
if (Object.keys(bucket).length === 0) {
|
|
43602
|
+
variantBuckets.delete(when);
|
|
43603
|
+
delete ctx.variantStyleKeys[when];
|
|
43604
|
+
delete ctx.variantSourceOrder[when];
|
|
43605
|
+
}
|
|
43606
|
+
}
|
|
43607
|
+
};
|
|
42867
43608
|
const applyResolvedPropValue = (prop, value, commentSource, sourceCssProperty) => {
|
|
42868
43609
|
const noteSourceCssProperty = (target) => {
|
|
42869
43610
|
if (sourceCssProperty) {
|
|
@@ -43078,6 +43819,7 @@ function processDeclRules(ctx) {
|
|
|
43078
43819
|
}
|
|
43079
43820
|
return;
|
|
43080
43821
|
}
|
|
43822
|
+
clearEarlierVariantBaseValues(prop, value);
|
|
43081
43823
|
const target = ctx.getBaseStyleTarget();
|
|
43082
43824
|
setStyleObjectValue(target, prop, value);
|
|
43083
43825
|
noteSourceCssProperty(target);
|
|
@@ -43606,9 +44348,23 @@ function recoverStandaloneInterpolationsInPseudoBlock(rule, decl) {
|
|
|
43606
44348
|
cssProps
|
|
43607
44349
|
};
|
|
43608
44350
|
}
|
|
44351
|
+
/**
|
|
44352
|
+
* Whether a lowered StyleX value carries `!important`. Values are stored either
|
|
44353
|
+
* as plain strings (e.g. `"red !important"`) or as AST string/template literals.
|
|
44354
|
+
*/
|
|
44355
|
+
function cssValueIsImportant(value) {
|
|
44356
|
+
if (typeof value === "string") return value.includes("!important");
|
|
44357
|
+
if (!value || typeof value !== "object") return false;
|
|
44358
|
+
const node = value;
|
|
44359
|
+
if ((node.type === "StringLiteral" || node.type === "Literal") && typeof node.value === "string") return node.value.includes("!important");
|
|
44360
|
+
if (node.type === "TemplateLiteral" && Array.isArray(node.quasis)) return node.quasis.some((q) => (q?.value?.cooked ?? q?.value?.raw ?? "").includes("!important"));
|
|
44361
|
+
return false;
|
|
44362
|
+
}
|
|
43609
44363
|
/** Negates a `when` condition string (e.g. `$active` → `!$active`, `!$x` → `$x`). */
|
|
43610
44364
|
function negateWhen(when) {
|
|
44365
|
+
if (when.startsWith("!(") && when.endsWith(")")) return when.slice(2, -1);
|
|
43611
44366
|
if (when.startsWith("!")) return when.slice(1);
|
|
44367
|
+
if (when.includes(" || ") || when.includes(" && ")) return `!(${when})`;
|
|
43612
44368
|
if (when.includes(" === ")) return when.replace(" === ", " !== ");
|
|
43613
44369
|
if (when.includes(" !== ")) return when.replace(" !== ", " === ");
|
|
43614
44370
|
return `!${when}`;
|
|
@@ -46095,6 +46851,10 @@ function wrappedComponentAcceptsSxProp(ctx, componentLocalName, visiting = /* @_
|
|
|
46095
46851
|
visiting.delete(componentLocalName);
|
|
46096
46852
|
return true;
|
|
46097
46853
|
}
|
|
46854
|
+
if (localStyledDecl?.needsWrapperComponent && !localStyledDecl.skipTransform && localStyledDecl.supportsExternalStyles) {
|
|
46855
|
+
visiting.delete(componentLocalName);
|
|
46856
|
+
return true;
|
|
46857
|
+
}
|
|
46098
46858
|
const componentInterface = wrappedComponentInterfaceFor(ctx, componentLocalName);
|
|
46099
46859
|
if (componentInterface !== void 0) {
|
|
46100
46860
|
visiting.delete(componentLocalName);
|
|
@@ -46342,8 +47102,9 @@ function rewriteJsxStep(ctx) {
|
|
|
46342
47102
|
const mergeArgs = matchedCombinedStyleKey ? void 0 : opening.__promotedMergeArgs;
|
|
46343
47103
|
const baseMember = j.memberExpression(j.identifier(ctx.stylesIdentifier ?? "styles"), j.identifier(baseStyleKey));
|
|
46344
47104
|
const baseExpr = mergeArgs ? j.callExpression(baseMember, mergeArgs) : baseMember;
|
|
47105
|
+
const rendersLocalWrapperBase = decl.base.kind === "component" && decl.base.ident === finalTag && (ctx.styledDecls?.some((d) => d.localName === finalTag && d.needsWrapperComponent && !d.skipTransform) ?? false);
|
|
46345
47106
|
const styleArgs = [
|
|
46346
|
-
...decl.extendsStyleKey ? [j.memberExpression(j.identifier(ctx.stylesIdentifier ?? "styles"), j.identifier(decl.extendsStyleKey))] : [],
|
|
47107
|
+
...decl.extendsStyleKey && !rendersLocalWrapperBase ? [j.memberExpression(j.identifier(ctx.stylesIdentifier ?? "styles"), j.identifier(decl.extendsStyleKey))] : [],
|
|
46347
47108
|
...extraMixinArgs,
|
|
46348
47109
|
...decl.skipBaseStyleRef ? [] : [baseExpr],
|
|
46349
47110
|
...extraAfterBaseArgs
|