styled-components-to-stylex-codemod 0.0.29 → 0.0.30
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/index.d.mts +6 -1
- package/dist/index.mjs +1 -1
- package/dist/{logger-Dx-dRi_p.d.mts → logger-BQnWs1On.d.mts} +29 -1
- package/dist/transform.d.mts +1 -1
- package/dist/transform.mjs +210 -58
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as defineAdapter, i as AdapterInput, t as CollectedWarning } from "./logger-
|
|
1
|
+
import { a as defineAdapter, i as AdapterInput, t as CollectedWarning } from "./logger-BQnWs1On.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/run.d.ts
|
|
4
4
|
interface RunTransformOptions {
|
|
@@ -59,6 +59,11 @@ interface RunTransformOptions {
|
|
|
59
59
|
* @default 3
|
|
60
60
|
*/
|
|
61
61
|
maxExamples?: number;
|
|
62
|
+
/**
|
|
63
|
+
* Suppress jscodeshift runner output.
|
|
64
|
+
* @default false
|
|
65
|
+
*/
|
|
66
|
+
silent?: boolean;
|
|
62
67
|
}
|
|
63
68
|
interface RunTransformResult {
|
|
64
69
|
/** Number of files that had errors */
|
package/dist/index.mjs
CHANGED
|
@@ -231,7 +231,7 @@ async function runTransform(options) {
|
|
|
231
231
|
transformedFiles,
|
|
232
232
|
transientPropRenames,
|
|
233
233
|
runInBand: true,
|
|
234
|
-
silent:
|
|
234
|
+
silent: options.silent ?? false
|
|
235
235
|
});
|
|
236
236
|
if (sidecarFiles.size > 0 && !dryRun) for (const [sidecarPath, content] of sidecarFiles) await writeFile(sidecarPath, mergeSidecarContent(sidecarPath, content), "utf-8");
|
|
237
237
|
if (bridgeResults.size > 0 && !dryRun) {
|
|
@@ -260,6 +260,19 @@ type CallResolveResultWithExpr = {
|
|
|
260
260
|
* - Theme access in the original call is rewritten to use the wrapper `useTheme()` value.
|
|
261
261
|
*/
|
|
262
262
|
preserveRuntimeCall?: boolean;
|
|
263
|
+
/**
|
|
264
|
+
* Additional className expressions to merge into the component's className attribute.
|
|
265
|
+
*
|
|
266
|
+
* Used for CSS modules or other class-based styles that StyleX cannot express
|
|
267
|
+
* (child selectors like `& > *`, ancestor selectors like `html:not(.class) &`, etc.).
|
|
268
|
+
*
|
|
269
|
+
* Each entry provides an expression string (e.g., `cssModuleStyles.myClass`)
|
|
270
|
+
* and its required imports.
|
|
271
|
+
*
|
|
272
|
+
* When present, the codemod merges these expressions into the rendered element's
|
|
273
|
+
* className alongside any existing static className from `.attrs()` or bridge classes.
|
|
274
|
+
*/
|
|
275
|
+
extraClassNames?: ExprWithImports[];
|
|
263
276
|
};
|
|
264
277
|
type CallResolveRuntimeOnlyResult = {
|
|
265
278
|
/**
|
|
@@ -275,7 +288,17 @@ type CallResolveRuntimeOnlyResult = {
|
|
|
275
288
|
*/
|
|
276
289
|
usage?: "create";
|
|
277
290
|
};
|
|
278
|
-
|
|
291
|
+
/**
|
|
292
|
+
* Resolved result containing only className expressions (no StyleX style object).
|
|
293
|
+
* Used for CSS modules or other class-based styles that StyleX cannot express.
|
|
294
|
+
*/
|
|
295
|
+
type CallResolveClassNamesResult = {
|
|
296
|
+
/**
|
|
297
|
+
* className expressions to merge into the component's className attribute.
|
|
298
|
+
*/
|
|
299
|
+
extraClassNames: ExprWithImports[];
|
|
300
|
+
};
|
|
301
|
+
type CallResolveResult = CallResolveResultWithExpr | CallResolveRuntimeOnlyResult | CallResolveClassNamesResult;
|
|
279
302
|
type ImportSource = {
|
|
280
303
|
kind: "absolutePath";
|
|
281
304
|
value: string;
|
|
@@ -290,6 +313,11 @@ type ImportSpec = {
|
|
|
290
313
|
local?: string;
|
|
291
314
|
}>;
|
|
292
315
|
};
|
|
316
|
+
/** An expression string with its required imports, used for className emission. */
|
|
317
|
+
type ExprWithImports = {
|
|
318
|
+
expr: string;
|
|
319
|
+
imports: ImportSpec[];
|
|
320
|
+
};
|
|
293
321
|
type ResolveBaseComponentStaticValue = string | number | boolean;
|
|
294
322
|
interface ResolveBaseComponentContext {
|
|
295
323
|
/**
|
package/dist/transform.d.mts
CHANGED
package/dist/transform.mjs
CHANGED
|
@@ -2229,7 +2229,7 @@ function analyzeBeforeEmitStep(ctx) {
|
|
|
2229
2229
|
if (!hadWrapperBeforePrepass && decl.needsWrapperComponent) wrapperForcedByPrepass.add(decl.localName);
|
|
2230
2230
|
if (ctx.bridgeComponentNames?.has(decl.localName) || ctx.bridgeComponentNames?.has("default") && exportedComponents.get(decl.localName)?.isDefault) decl.bridgeClassName = generateBridgeClassName(resolve(file.path), decl.localName);
|
|
2231
2231
|
}
|
|
2232
|
-
for (const decl of styledDecls) if (decl.needsWrapperComponent && !wrapperForcedByPrepass.has(decl.localName) && !decl.isCssHelper && !decl.isDirectJsxResolution && decl.base.kind === "intrinsic" && !decl.bridgeClassName && !decl.attrWrapper && (decl.styleFnFromProps ?? []).length === 0 && !decl.needsUseThemeHook?.length && Object.keys(decl.variantStyleKeys ?? {}).length === 0 && !decl.enumVariant && !decl.inlineStyleProps?.length && (decl.attrsInfo?.conditionalAttrs?.length ?? 0) === 0 && (decl.attrsInfo?.defaultAttrs?.length ?? 0) === 0 && (decl.attrsInfo?.invertedBoolAttrs?.length ?? 0) === 0 && !(decl.extraStylexPropsArgs ?? []).some((arg) => arg.when) && ((decl.extraStylexPropsArgs ?? []).length > 0 || (decl.extraStyleKeys ?? []).length > 0)) decl.needsWrapperComponent = false;
|
|
2232
|
+
for (const decl of styledDecls) if (decl.needsWrapperComponent && !wrapperForcedByPrepass.has(decl.localName) && !decl.isCssHelper && !decl.isDirectJsxResolution && decl.base.kind === "intrinsic" && !decl.bridgeClassName && !decl.attrWrapper && (decl.styleFnFromProps ?? []).length === 0 && !decl.needsUseThemeHook?.length && Object.keys(decl.variantStyleKeys ?? {}).length === 0 && !decl.enumVariant && !decl.inlineStyleProps?.length && (decl.attrsInfo?.conditionalAttrs?.length ?? 0) === 0 && (decl.attrsInfo?.defaultAttrs?.length ?? 0) === 0 && (decl.attrsInfo?.invertedBoolAttrs?.length ?? 0) === 0 && !(decl.extraStylexPropsArgs ?? []).some((arg) => arg.when) && ((decl.extraStylexPropsArgs ?? []).length > 0 || (decl.extraStyleKeys ?? []).length > 0 || (decl.extraClassNames ?? []).length > 0)) decl.needsWrapperComponent = false;
|
|
2233
2233
|
const jsxUsageCountCache = /* @__PURE__ */ new Map();
|
|
2234
2234
|
const relationChildStyleKeys = new Set((ctx.relationOverrides ?? []).map((o) => o.childStyleKey));
|
|
2235
2235
|
const getJsxUsageCount = (name) => {
|
|
@@ -9048,6 +9048,7 @@ function emitStylesAndImports(ctx) {
|
|
|
9048
9048
|
const moduleSpecifier = toModuleSpecifier(spec.from);
|
|
9049
9049
|
const existing = root.find(j.ImportDeclaration, { source: { value: moduleSpecifier } });
|
|
9050
9050
|
const toImportSpecifier = (imported, local) => {
|
|
9051
|
+
if (imported === "default") return j.importDefaultSpecifier(j.identifier(local ?? "default"));
|
|
9051
9052
|
const impId = j.identifier(imported);
|
|
9052
9053
|
if (local && local !== imported) return j.importSpecifier(impId, j.identifier(local));
|
|
9053
9054
|
return j.importSpecifier(impId);
|
|
@@ -10239,19 +10240,60 @@ function buildInterleavedExtraStyleArgs(j, stylesIdentifier, d, propsArgExprs) {
|
|
|
10239
10240
|
*
|
|
10240
10241
|
* Returns `undefined` when neither is provided.
|
|
10241
10242
|
*/
|
|
10242
|
-
|
|
10243
|
-
|
|
10244
|
-
|
|
10245
|
-
|
|
10246
|
-
|
|
10247
|
-
|
|
10248
|
-
|
|
10243
|
+
/** Escape characters that are special inside template literal quasi strings. */
|
|
10244
|
+
function escapeTemplateRaw(s) {
|
|
10245
|
+
return s.replace(/\\|`|\$\{/g, "\\$&");
|
|
10246
|
+
}
|
|
10247
|
+
function buildStaticClassNameExpr(j, staticClassName, bridgeClassVar, extraClassNames) {
|
|
10248
|
+
if (!(extraClassNames && extraClassNames.length > 0)) {
|
|
10249
|
+
if (staticClassName && bridgeClassVar) {
|
|
10250
|
+
const raw = escapeTemplateRaw(`${staticClassName} `);
|
|
10251
|
+
return j.templateLiteral([j.templateElement({
|
|
10252
|
+
raw,
|
|
10253
|
+
cooked: `${staticClassName} `
|
|
10254
|
+
}, false), j.templateElement({
|
|
10255
|
+
raw: "",
|
|
10256
|
+
cooked: ""
|
|
10257
|
+
}, true)], [j.identifier(bridgeClassVar)]);
|
|
10258
|
+
}
|
|
10259
|
+
if (bridgeClassVar) return j.identifier(bridgeClassVar);
|
|
10260
|
+
if (staticClassName) return j.literal(staticClassName);
|
|
10261
|
+
return;
|
|
10262
|
+
}
|
|
10263
|
+
const expressions = [];
|
|
10264
|
+
const quasis = [];
|
|
10265
|
+
const leadingText = staticClassName ? `${escapeTemplateRaw(staticClassName)} ` : "";
|
|
10266
|
+
quasis.push(j.templateElement({
|
|
10267
|
+
raw: leadingText,
|
|
10268
|
+
cooked: staticClassName ? `${staticClassName} ` : ""
|
|
10269
|
+
}, false));
|
|
10270
|
+
if (bridgeClassVar) {
|
|
10271
|
+
expressions.push(j.identifier(bridgeClassVar));
|
|
10272
|
+
quasis.push(j.templateElement({
|
|
10273
|
+
raw: " ",
|
|
10274
|
+
cooked: " "
|
|
10275
|
+
}, false));
|
|
10276
|
+
}
|
|
10277
|
+
for (let i = 0; i < extraClassNames.length; i++) {
|
|
10278
|
+
expressions.push(extraClassNames[i].expr);
|
|
10279
|
+
if (i === extraClassNames.length - 1) quasis.push(j.templateElement({
|
|
10249
10280
|
raw: "",
|
|
10250
10281
|
cooked: ""
|
|
10251
|
-
}, true)
|
|
10282
|
+
}, true));
|
|
10283
|
+
else quasis.push(j.templateElement({
|
|
10284
|
+
raw: " ",
|
|
10285
|
+
cooked: " "
|
|
10286
|
+
}, false));
|
|
10252
10287
|
}
|
|
10253
|
-
if (
|
|
10254
|
-
|
|
10288
|
+
if (expressions.length === 0) {
|
|
10289
|
+
if (staticClassName) return j.literal(staticClassName);
|
|
10290
|
+
return;
|
|
10291
|
+
}
|
|
10292
|
+
if (!staticClassName && !bridgeClassVar) quasis[0] = j.templateElement({
|
|
10293
|
+
raw: "",
|
|
10294
|
+
cooked: ""
|
|
10295
|
+
}, false);
|
|
10296
|
+
return j.templateLiteral(quasis, expressions);
|
|
10255
10297
|
}
|
|
10256
10298
|
/**
|
|
10257
10299
|
* Extracts a static className value (if present) from attrsInfo.staticAttrs
|
|
@@ -10261,12 +10303,15 @@ function buildStaticClassNameExpr(j, staticClassName, bridgeClassVar) {
|
|
|
10261
10303
|
* When `bridgeClassVar` is provided, it is used as an identifier expression
|
|
10262
10304
|
* for the bridge class name. If a static className also exists, a template
|
|
10263
10305
|
* literal combining both is produced.
|
|
10306
|
+
*
|
|
10307
|
+
* When `extraClassNames` is provided, the expressions are merged into the
|
|
10308
|
+
* static className expression.
|
|
10264
10309
|
*/
|
|
10265
|
-
function splitAttrsInfo(j, attrsInfo, bridgeClassVar) {
|
|
10310
|
+
function splitAttrsInfo(j, attrsInfo, bridgeClassVar, extraClassNames) {
|
|
10266
10311
|
const className = attrsInfo?.staticAttrs?.className;
|
|
10267
10312
|
if (!attrsInfo) return {
|
|
10268
10313
|
attrsInfo,
|
|
10269
|
-
staticClassNameExpr: buildStaticClassNameExpr(j, void 0, bridgeClassVar)
|
|
10314
|
+
staticClassNameExpr: buildStaticClassNameExpr(j, void 0, bridgeClassVar, extraClassNames)
|
|
10270
10315
|
};
|
|
10271
10316
|
const normalized = {
|
|
10272
10317
|
...attrsInfo,
|
|
@@ -10274,7 +10319,8 @@ function splitAttrsInfo(j, attrsInfo, bridgeClassVar) {
|
|
|
10274
10319
|
conditionalAttrs: attrsInfo.conditionalAttrs ?? []
|
|
10275
10320
|
};
|
|
10276
10321
|
const hasStaticClassName = typeof className === "string";
|
|
10277
|
-
|
|
10322
|
+
const hasExtraClassNames = extraClassNames && extraClassNames.length > 0;
|
|
10323
|
+
if (!hasStaticClassName && !bridgeClassVar && !hasExtraClassNames) return {
|
|
10278
10324
|
attrsInfo: normalized,
|
|
10279
10325
|
staticClassNameExpr: void 0
|
|
10280
10326
|
};
|
|
@@ -10286,7 +10332,7 @@ function splitAttrsInfo(j, attrsInfo, bridgeClassVar) {
|
|
|
10286
10332
|
staticAttrs: rest
|
|
10287
10333
|
};
|
|
10288
10334
|
})() : normalized,
|
|
10289
|
-
staticClassNameExpr: buildStaticClassNameExpr(j, hasStaticClassName ? className : void 0, bridgeClassVar)
|
|
10335
|
+
staticClassNameExpr: buildStaticClassNameExpr(j, hasStaticClassName ? className : void 0, bridgeClassVar, extraClassNames)
|
|
10290
10336
|
};
|
|
10291
10337
|
}
|
|
10292
10338
|
/**
|
|
@@ -10590,10 +10636,6 @@ function buildVariantStyleExprs(opts) {
|
|
|
10590
10636
|
}), when);
|
|
10591
10637
|
}
|
|
10592
10638
|
}
|
|
10593
|
-
/** Escape characters that are special inside template literal quasi strings. */
|
|
10594
|
-
function escapeTemplateRaw(s) {
|
|
10595
|
-
return s.replace(/\\|`|\$\{/g, "\\$&");
|
|
10596
|
-
}
|
|
10597
10639
|
/**
|
|
10598
10640
|
* Appends conditional style args driven by theme boolean props (e.g., `theme.isDark`).
|
|
10599
10641
|
* Returns `true` if the hook is needed (and calls `markNeedsUseThemeImport`).
|
|
@@ -11611,8 +11653,8 @@ var WrapperEmitter = class {
|
|
|
11611
11653
|
buildInterleavedExtraStyleArgs(d, propsArgExprs) {
|
|
11612
11654
|
return buildInterleavedExtraStyleArgs(this.j, this.stylesIdentifier, d, propsArgExprs);
|
|
11613
11655
|
}
|
|
11614
|
-
splitAttrsInfo(attrsInfo, bridgeClassVar) {
|
|
11615
|
-
return splitAttrsInfo(this.j, attrsInfo, bridgeClassVar);
|
|
11656
|
+
splitAttrsInfo(attrsInfo, bridgeClassVar, extraClassNames) {
|
|
11657
|
+
return splitAttrsInfo(this.j, attrsInfo, bridgeClassVar, extraClassNames);
|
|
11616
11658
|
}
|
|
11617
11659
|
buildVariantDimensionLookups(args) {
|
|
11618
11660
|
buildVariantDimensionLookups(this.j, args);
|
|
@@ -12002,7 +12044,7 @@ function emitComponentWrappers(emitter) {
|
|
|
12002
12044
|
if (!firstPart) jsxTagName = j.jsxIdentifier(renderedComponent);
|
|
12003
12045
|
else jsxTagName = j.jsxMemberExpression(j.jsxIdentifier(firstPart), j.jsxIdentifier(parts.slice(1).join(".")));
|
|
12004
12046
|
} else jsxTagName = j.jsxIdentifier(renderedComponent);
|
|
12005
|
-
const { attrsInfo, staticClassNameExpr } = emitter.splitAttrsInfo(d.attrsInfo, getBridgeClassVar(d));
|
|
12047
|
+
const { attrsInfo, staticClassNameExpr } = emitter.splitAttrsInfo(d.attrsInfo, getBridgeClassVar(d), d.extraClassNames);
|
|
12006
12048
|
const defaultAttrs = attrsInfo?.defaultAttrs ?? [];
|
|
12007
12049
|
const staticAttrs = attrsInfo?.staticAttrs ?? {};
|
|
12008
12050
|
const needsSxVar = allowClassNameProp || allowStyleProp || !!d.inlineStyleProps?.length || !!staticClassNameExpr;
|
|
@@ -12777,7 +12819,7 @@ function emitIntrinsicPolymorphicWrappers(ctx) {
|
|
|
12777
12819
|
restId
|
|
12778
12820
|
});
|
|
12779
12821
|
const declStmt = j.variableDeclaration("const", [j.variableDeclarator(j.objectPattern(patternProps), propsId)]);
|
|
12780
|
-
const { attrsInfo, staticClassNameExpr } = emitter.splitAttrsInfo(d.attrsInfo, getBridgeClassVar(d));
|
|
12822
|
+
const { attrsInfo, staticClassNameExpr } = emitter.splitAttrsInfo(d.attrsInfo, getBridgeClassVar(d), d.extraClassNames);
|
|
12781
12823
|
const { attrsInfo: attrsInfoWithoutForwardedAsStatic, forwardedAsStaticFallback } = splitForwardedAsStaticAttrs({
|
|
12782
12824
|
attrsInfo,
|
|
12783
12825
|
includeForwardedAs: includesForwardedAs
|
|
@@ -13132,7 +13174,7 @@ function emitShouldForwardPropWrappers(ctx) {
|
|
|
13132
13174
|
});
|
|
13133
13175
|
const declStmt = j.variableDeclaration("const", [j.variableDeclarator(j.objectPattern(patternProps), propsId)]);
|
|
13134
13176
|
const cleanupPrefixStmt = dropPrefix && (isExportedComponent || (d.supportsExternalStyles ?? false) || shouldAllowAnyPrefixProps) && includeRest ? buildPrefixCleanupStatements(j, restId, dropPrefix) : null;
|
|
13135
|
-
const { attrsInfo, staticClassNameExpr } = emitter.splitAttrsInfo(d.attrsInfo, getBridgeClassVar(d));
|
|
13177
|
+
const { attrsInfo, staticClassNameExpr } = emitter.splitAttrsInfo(d.attrsInfo, getBridgeClassVar(d), d.extraClassNames);
|
|
13136
13178
|
let attrsInfoForJsx;
|
|
13137
13179
|
let forwardedAsStaticFallback;
|
|
13138
13180
|
if (!allowClassNameProp && !allowStyleProp) {
|
|
@@ -13365,7 +13407,7 @@ function emitSimpleWithConfigWrappers(ctx) {
|
|
|
13365
13407
|
restId
|
|
13366
13408
|
});
|
|
13367
13409
|
const declStmt = j.variableDeclaration("const", [j.variableDeclarator(j.objectPattern(patternProps), propsId)]);
|
|
13368
|
-
const { attrsInfo, staticClassNameExpr } = emitter.splitAttrsInfo(d.attrsInfo, getBridgeClassVar(d));
|
|
13410
|
+
const { attrsInfo, staticClassNameExpr } = emitter.splitAttrsInfo(d.attrsInfo, getBridgeClassVar(d), d.extraClassNames);
|
|
13369
13411
|
const merging = emitStyleMerging({
|
|
13370
13412
|
j,
|
|
13371
13413
|
emitter,
|
|
@@ -13696,7 +13738,7 @@ function emitSimpleExportedIntrinsicWrappers(ctx) {
|
|
|
13696
13738
|
});
|
|
13697
13739
|
const usePropsChildrenDirectly = emitter.isChildrenOnlyDestructurePattern(patternProps);
|
|
13698
13740
|
const declStmt = usePropsChildrenDirectly ? null : j.variableDeclaration("const", [j.variableDeclarator(j.objectPattern(patternProps), propsId)]);
|
|
13699
|
-
const { attrsInfo, staticClassNameExpr } = emitter.splitAttrsInfo(d.attrsInfo, getBridgeClassVar(d));
|
|
13741
|
+
const { attrsInfo, staticClassNameExpr } = emitter.splitAttrsInfo(d.attrsInfo, getBridgeClassVar(d), d.extraClassNames);
|
|
13700
13742
|
const { attrsInfo: attrsInfoWithoutForwardedAsStatic, forwardedAsStaticFallback } = splitForwardedAsStaticAttrs({
|
|
13701
13743
|
attrsInfo,
|
|
13702
13744
|
includeForwardedAs: includesForwardedAs
|
|
@@ -15739,12 +15781,21 @@ const createImportResolver = (args) => {
|
|
|
15739
15781
|
};
|
|
15740
15782
|
//#endregion
|
|
15741
15783
|
//#region src/internal/lower-rules/state.ts
|
|
15784
|
+
/**
|
|
15785
|
+
* Builds shared state for the lower-rules pipeline.
|
|
15786
|
+
* Core concepts: resolver wiring, precomputed mixin values, and shared tracking maps.
|
|
15787
|
+
*/
|
|
15742
15788
|
function createLowerRulesState(ctx) {
|
|
15743
15789
|
const { api, j, root, file, warnings, resolverImports, keyframesNames, parseExpr, rewriteCssVarsInStyleObject } = ctx;
|
|
15744
15790
|
const filePath = file.path;
|
|
15745
15791
|
const resolveValue = ctx.resolveValueSafe;
|
|
15746
15792
|
const resolveValueDirectional = ctx.resolveValueDirectionalSafe;
|
|
15747
15793
|
const resolveCall = ctx.resolveCallSafe;
|
|
15794
|
+
const resolveValueOptional = (rvCtx) => {
|
|
15795
|
+
const res = ctx.adapter.resolveValue(rvCtx);
|
|
15796
|
+
if (res && isDirectionalResult(res)) return;
|
|
15797
|
+
return res;
|
|
15798
|
+
};
|
|
15748
15799
|
const resolveCallOptional = ctx.adapter.resolveCall.bind(ctx.adapter);
|
|
15749
15800
|
const resolveSelector = ctx.resolveSelectorSafe;
|
|
15750
15801
|
const importMap = ctx.importMap ?? /* @__PURE__ */ new Map();
|
|
@@ -15875,6 +15926,7 @@ function createLowerRulesState(ctx) {
|
|
|
15875
15926
|
parseExpr,
|
|
15876
15927
|
rewriteCssVarsInStyleObject,
|
|
15877
15928
|
resolveValue,
|
|
15929
|
+
resolveValueOptional,
|
|
15878
15930
|
resolveValueDirectional,
|
|
15879
15931
|
resolveCall,
|
|
15880
15932
|
resolveCallOptional,
|
|
@@ -16523,6 +16575,11 @@ function isAdapterResultCssValue(result, cssProperty) {
|
|
|
16523
16575
|
* or "resolvedStyles" for StyleX references (to be used in stylex.props arguments).
|
|
16524
16576
|
*/
|
|
16525
16577
|
function buildResolvedHandlerResult(result, cssProperty, payload) {
|
|
16578
|
+
if ("extraClassNames" in result && !("expr" in result)) return {
|
|
16579
|
+
type: "resolvedClassNames",
|
|
16580
|
+
extraClassNames: result.extraClassNames,
|
|
16581
|
+
...payload
|
|
16582
|
+
};
|
|
16526
16583
|
if (!("expr" in result)) return {
|
|
16527
16584
|
type: "runtimeCallOnly",
|
|
16528
16585
|
...payload
|
|
@@ -16537,6 +16594,7 @@ function buildResolvedHandlerResult(result, cssProperty, payload) {
|
|
|
16537
16594
|
expr: result.expr,
|
|
16538
16595
|
imports: result.imports,
|
|
16539
16596
|
...result.cssText ? { cssText: result.cssText } : {},
|
|
16597
|
+
...result.extraClassNames ? { extraClassNames: result.extraClassNames } : {},
|
|
16540
16598
|
...payload
|
|
16541
16599
|
};
|
|
16542
16600
|
}
|
|
@@ -16560,20 +16618,22 @@ function getArrowFnThemeParamInfo(fn) {
|
|
|
16560
16618
|
propsName: p.name
|
|
16561
16619
|
};
|
|
16562
16620
|
if (p?.type !== "ObjectPattern" || !Array.isArray(p.properties)) return null;
|
|
16621
|
+
let themeName = null;
|
|
16622
|
+
const siblingBindings = [];
|
|
16563
16623
|
for (const prop of p.properties) {
|
|
16564
16624
|
if (!prop || prop.type !== "Property" && prop.type !== "ObjectProperty") continue;
|
|
16565
16625
|
const key = prop.key;
|
|
16566
|
-
if (!key || key.type !== "Identifier"
|
|
16626
|
+
if (!key || key.type !== "Identifier") continue;
|
|
16567
16627
|
const value = prop.value;
|
|
16568
|
-
|
|
16569
|
-
|
|
16570
|
-
|
|
16571
|
-
};
|
|
16572
|
-
if (value?.type === "AssignmentPattern" && value.left?.type === "Identifier" && typeof value.left.name === "string") return {
|
|
16573
|
-
kind: "themeBinding",
|
|
16574
|
-
themeName: value.left.name
|
|
16575
|
-
};
|
|
16628
|
+
const binding = extractBindingName(value) ?? key.name;
|
|
16629
|
+
if (key.name === "theme") themeName = binding;
|
|
16630
|
+
else siblingBindings.push(binding);
|
|
16576
16631
|
}
|
|
16632
|
+
if (themeName) return {
|
|
16633
|
+
kind: "themeBinding",
|
|
16634
|
+
themeName,
|
|
16635
|
+
siblingBindings
|
|
16636
|
+
};
|
|
16577
16637
|
return null;
|
|
16578
16638
|
}
|
|
16579
16639
|
/**
|
|
@@ -16782,6 +16842,17 @@ function callArgFromNode(node, propsParamName, themeBindingName) {
|
|
|
16782
16842
|
}
|
|
16783
16843
|
return { kind: "unknown" };
|
|
16784
16844
|
}
|
|
16845
|
+
/**
|
|
16846
|
+
* Extracts the actual binding name from a destructured property value.
|
|
16847
|
+
* Handles: `{ x }` → "x", `{ x: alias }` → "alias", `{ x: alias = def }` → "alias"
|
|
16848
|
+
*/
|
|
16849
|
+
function extractBindingName(value) {
|
|
16850
|
+
if (!value || typeof value !== "object") return null;
|
|
16851
|
+
const v = value;
|
|
16852
|
+
if (v.type === "Identifier" && typeof v.name === "string") return v.name;
|
|
16853
|
+
if (v.type === "AssignmentPattern" && v.left?.type === "Identifier" && typeof v.left.name === "string") return v.left.name;
|
|
16854
|
+
return null;
|
|
16855
|
+
}
|
|
16785
16856
|
function callArgsFromNode(args, propsParamName, themeBindingName) {
|
|
16786
16857
|
if (!Array.isArray(args)) return [];
|
|
16787
16858
|
return args.map((arg) => callArgFromNode(arg, propsParamName, themeBindingName));
|
|
@@ -16807,7 +16878,7 @@ function tryResolveConditionalValue(node, ctx) {
|
|
|
16807
16878
|
if (!body || body.type !== "ConditionalExpression") return null;
|
|
16808
16879
|
const checkThemeBooleanTest = (test) => {
|
|
16809
16880
|
const check = (node) => {
|
|
16810
|
-
if (!node || typeof node !== "object" || node
|
|
16881
|
+
if (!node || typeof node !== "object" || !isMemberExpression(node)) return null;
|
|
16811
16882
|
if (info?.kind === "propsParam" && paramName) {
|
|
16812
16883
|
const parts = getMemberPathFromIdentifier(node, paramName);
|
|
16813
16884
|
const themeProp = parts?.[1];
|
|
@@ -16836,7 +16907,7 @@ function tryResolveConditionalValue(node, ctx) {
|
|
|
16836
16907
|
return null;
|
|
16837
16908
|
};
|
|
16838
16909
|
const resolveThemeFromMemberExpr = (node) => {
|
|
16839
|
-
if (!node || typeof node !== "object" || node
|
|
16910
|
+
if (!node || typeof node !== "object" || !isMemberExpression(node)) return null;
|
|
16840
16911
|
if (info?.kind === "propsParam" && paramName) {
|
|
16841
16912
|
const parts = getMemberPathFromIdentifier(node, paramName);
|
|
16842
16913
|
if (!parts || parts[0] !== "theme") return null;
|
|
@@ -16852,7 +16923,7 @@ function tryResolveConditionalValue(node, ctx) {
|
|
|
16852
16923
|
const resolveThemeBranchValue = (branch) => {
|
|
16853
16924
|
const themeInfo = resolveThemeFromMemberExpr(branch);
|
|
16854
16925
|
if (!themeInfo) return null;
|
|
16855
|
-
const res = ctx.resolveValue({
|
|
16926
|
+
const res = (ctx.resolveValueOptional ?? ctx.resolveValue)({
|
|
16856
16927
|
kind: "theme",
|
|
16857
16928
|
path: themeInfo.path,
|
|
16858
16929
|
filePath: ctx.filePath,
|
|
@@ -16960,7 +17031,7 @@ function tryResolveConditionalValue(node, ctx) {
|
|
|
16960
17031
|
const res = resolveImportedHelperCall(call, ctx, propsParamName, cssProperty, themeBindingName);
|
|
16961
17032
|
if (res.kind === "resolved") {
|
|
16962
17033
|
if ("expr" in res.result) return res.result;
|
|
16963
|
-
if (res.result.preserveRuntimeCall) {
|
|
17034
|
+
if ("preserveRuntimeCall" in res.result && res.result.preserveRuntimeCall) {
|
|
16964
17035
|
runtimeCallState.info = {
|
|
16965
17036
|
resolveCallContext: res.resolveCallContext,
|
|
16966
17037
|
resolveCallResult: res.resolveCallResult
|
|
@@ -16975,7 +17046,7 @@ function tryResolveConditionalValue(node, ctx) {
|
|
|
16975
17046
|
const innerRes = resolveImportedHelperCall(inner, ctx, propsParamName, cssProperty, themeBindingName);
|
|
16976
17047
|
if (innerRes.kind === "resolved") {
|
|
16977
17048
|
if ("expr" in innerRes.result) return innerRes.result;
|
|
16978
|
-
if (innerRes.result.preserveRuntimeCall) {
|
|
17049
|
+
if ("preserveRuntimeCall" in innerRes.result && innerRes.result.preserveRuntimeCall) {
|
|
16979
17050
|
runtimeCallState.info = {
|
|
16980
17051
|
resolveCallContext: innerRes.resolveCallContext,
|
|
16981
17052
|
resolveCallResult: innerRes.resolveCallResult
|
|
@@ -17736,10 +17807,9 @@ function tryBuildThemeBooleanInlineStyleFallback(args) {
|
|
|
17736
17807
|
const { trueValue, falseValue, trueImports, falseImports, trueBranch, falseBranch, themeBoolInfo, cssProp, paramName, info } = args;
|
|
17737
17808
|
if (trueValue === null === (falseValue === null)) return null;
|
|
17738
17809
|
const resolvedBranchIsTrue = trueValue !== null;
|
|
17739
|
-
const
|
|
17740
|
-
if (!hasCallExpression(unresolvableBranch)) return null;
|
|
17741
|
-
const transformed = replaceThemeRefsWithHookVar(unresolvableBranch, paramName, info);
|
|
17810
|
+
const transformed = replaceThemeRefsWithHookVar(resolvedBranchIsTrue ? falseBranch : trueBranch, paramName, info);
|
|
17742
17811
|
if (!transformed) return null;
|
|
17812
|
+
if (!isFullyTransformedThemeExpr(transformed, paramName, info)) return null;
|
|
17743
17813
|
return {
|
|
17744
17814
|
type: "splitThemeBooleanWithInlineStyleFallback",
|
|
17745
17815
|
cssProp,
|
|
@@ -17751,17 +17821,49 @@ function tryBuildThemeBooleanInlineStyleFallback(args) {
|
|
|
17751
17821
|
inlineExpr: transformed
|
|
17752
17822
|
};
|
|
17753
17823
|
}
|
|
17754
|
-
/**
|
|
17755
|
-
|
|
17756
|
-
|
|
17757
|
-
|
|
17758
|
-
|
|
17759
|
-
|
|
17760
|
-
|
|
17761
|
-
|
|
17762
|
-
|
|
17824
|
+
/**
|
|
17825
|
+
* Validates that a transformed expression has no dangling references to
|
|
17826
|
+
* the original arrow function parameter or theme binding name.
|
|
17827
|
+
* After `replaceThemeRefsWithHookVar`, all `<paramName>.theme.*` should
|
|
17828
|
+
* have been rewritten to `theme.*`. If the param name still appears,
|
|
17829
|
+
* the expression accesses non-theme props and can't be safely used
|
|
17830
|
+
* with `useTheme()` alone.
|
|
17831
|
+
*/
|
|
17832
|
+
function isFullyTransformedThemeExpr(transformed, paramName, info) {
|
|
17833
|
+
const ids = /* @__PURE__ */ new Set();
|
|
17834
|
+
collectFreeIdentifiers(transformed, ids);
|
|
17835
|
+
if (paramName && ids.has(paramName)) return false;
|
|
17836
|
+
if (info?.kind === "themeBinding") {
|
|
17837
|
+
if (info.themeName !== "theme" && ids.has(info.themeName)) return false;
|
|
17838
|
+
if (info.siblingBindings.some((b) => ids.has(b))) return false;
|
|
17839
|
+
}
|
|
17840
|
+
return true;
|
|
17841
|
+
}
|
|
17842
|
+
/**
|
|
17843
|
+
* Collects free variable identifiers from an AST node, excluding
|
|
17844
|
+
* non-computed property names in member expressions (e.g., in
|
|
17845
|
+
* `theme.color.bgSub`, only `theme` is a free variable; `color`
|
|
17846
|
+
* and `bgSub` are property accesses, not variable references).
|
|
17847
|
+
*/
|
|
17848
|
+
function collectFreeIdentifiers(node, out) {
|
|
17849
|
+
if (!node || typeof node !== "object") return;
|
|
17850
|
+
if (Array.isArray(node)) {
|
|
17851
|
+
for (const child of node) collectFreeIdentifiers(child, out);
|
|
17852
|
+
return;
|
|
17853
|
+
}
|
|
17854
|
+
const typed = node;
|
|
17855
|
+
const nodeType = typed.type;
|
|
17856
|
+
if (nodeType === "MemberExpression" || nodeType === "OptionalMemberExpression") {
|
|
17857
|
+
collectFreeIdentifiers(typed.object, out);
|
|
17858
|
+
if (typed.computed) collectFreeIdentifiers(typed.property, out);
|
|
17859
|
+
return;
|
|
17860
|
+
}
|
|
17861
|
+
if (nodeType === "Identifier" && typeof typed.name === "string") out.add(typed.name);
|
|
17862
|
+
for (const key of Object.keys(typed)) {
|
|
17863
|
+
if (key === "loc" || key === "comments" || key === "type") continue;
|
|
17864
|
+
const child = typed[key];
|
|
17865
|
+
if (child && typeof child === "object") collectFreeIdentifiers(child, out);
|
|
17763
17866
|
}
|
|
17764
|
-
return false;
|
|
17765
17867
|
}
|
|
17766
17868
|
/**
|
|
17767
17869
|
* Deep-clones an expression and replaces `<paramName>.theme.*` or `theme.*`
|
|
@@ -20725,7 +20827,7 @@ const createValuePatternHandlers = (ctx) => {
|
|
|
20725
20827
|
* Core concepts: per-component style buckets, helper factories, and resolver wiring.
|
|
20726
20828
|
*/
|
|
20727
20829
|
function createDeclProcessingState(state, decl) {
|
|
20728
|
-
const { api, j, root, filePath, warnings, resolverImports, parseExpr, resolveValue, resolveValueDirectional, resolveCall, resolveCallOptional, resolveSelector, importMap, cssHelperFunctions, stringMappingFns, hasLocalThemeBinding, isCssHelperTaggedTemplate, resolveCssHelperTemplate, resolveImportInScope, usedCssHelperFunctions, enumValueMap, markBail } = state;
|
|
20830
|
+
const { api, j, root, filePath, warnings, resolverImports, parseExpr, resolveValue, resolveValueOptional, resolveValueDirectional, resolveCall, resolveCallOptional, resolveSelector, importMap, cssHelperFunctions, stringMappingFns, hasLocalThemeBinding, isCssHelperTaggedTemplate, resolveCssHelperTemplate, resolveImportInScope, usedCssHelperFunctions, enumValueMap, markBail } = state;
|
|
20729
20831
|
const styleObj = {};
|
|
20730
20832
|
const perPropPseudo = {};
|
|
20731
20833
|
const perPropMedia = {};
|
|
@@ -20839,6 +20941,7 @@ function createDeclProcessingState(state, decl) {
|
|
|
20839
20941
|
api,
|
|
20840
20942
|
filePath,
|
|
20841
20943
|
resolveValue,
|
|
20944
|
+
resolveValueOptional,
|
|
20842
20945
|
resolveValueDirectional,
|
|
20843
20946
|
resolveCall,
|
|
20844
20947
|
resolveCallOptional,
|
|
@@ -22350,6 +22453,15 @@ function handleInterpolatedDeclaration(args) {
|
|
|
22350
22453
|
if (!imports) return;
|
|
22351
22454
|
for (const imp of imports) resolverImports.set(JSON.stringify(imp), imp);
|
|
22352
22455
|
};
|
|
22456
|
+
/** Parse and store extra className expressions (from CSS modules) on the decl. */
|
|
22457
|
+
const collectExtraClassNames = (entries) => {
|
|
22458
|
+
decl.extraClassNames ??= [];
|
|
22459
|
+
for (const cn of entries) {
|
|
22460
|
+
addResolverImports(cn.imports);
|
|
22461
|
+
const cnExpr = parseExpr(cn.expr);
|
|
22462
|
+
if (cnExpr) decl.extraClassNames.push({ expr: cnExpr });
|
|
22463
|
+
}
|
|
22464
|
+
};
|
|
22353
22465
|
/**
|
|
22354
22466
|
* Try to convert an identity prop with a finite string union type into static variant
|
|
22355
22467
|
* buckets. Returns true if the optimization applied and the caller should `continue`.
|
|
@@ -22371,7 +22483,7 @@ function handleInterpolatedDeclaration(args) {
|
|
|
22371
22483
|
};
|
|
22372
22484
|
const maybeEmitPreservedRuntimeCallOverride = (args) => {
|
|
22373
22485
|
const { resolveCallResult, originalExpr, loc } = args;
|
|
22374
|
-
if (!resolveCallResult
|
|
22486
|
+
if (!resolveCallResult || !("preserveRuntimeCall" in resolveCallResult) || !resolveCallResult.preserveRuntimeCall) return "not-requested";
|
|
22375
22487
|
if (!d.property) {
|
|
22376
22488
|
warnings.push({
|
|
22377
22489
|
severity: "error",
|
|
@@ -22861,10 +22973,16 @@ function handleInterpolatedDeclaration(args) {
|
|
|
22861
22973
|
expr: exprAst,
|
|
22862
22974
|
afterBase: hasStaticPropsBefore
|
|
22863
22975
|
});
|
|
22976
|
+
if (res.extraClassNames) collectExtraClassNames(res.extraClassNames);
|
|
22864
22977
|
notifyResolvedStylesArg();
|
|
22865
22978
|
decl.needsWrapperComponent = true;
|
|
22866
22979
|
continue;
|
|
22867
22980
|
}
|
|
22981
|
+
if (res && res.type === "resolvedClassNames") {
|
|
22982
|
+
collectExtraClassNames(res.extraClassNames);
|
|
22983
|
+
decl.needsWrapperComponent = true;
|
|
22984
|
+
continue;
|
|
22985
|
+
}
|
|
22868
22986
|
if (res && res.type === "resolvedDirectional") {
|
|
22869
22987
|
let directionalFailed = false;
|
|
22870
22988
|
for (const entry of res.directional) {
|
|
@@ -22973,6 +23091,14 @@ function handleInterpolatedDeclaration(args) {
|
|
|
22973
23091
|
continue;
|
|
22974
23092
|
}
|
|
22975
23093
|
if (res && res.type === "splitThemeBooleanWithInlineStyleFallback") {
|
|
23094
|
+
if (pseudos?.length || media || pseudoElement) {
|
|
23095
|
+
bail = true;
|
|
23096
|
+
continue;
|
|
23097
|
+
}
|
|
23098
|
+
if (isCssShorthandProperty(res.cssProp)) {
|
|
23099
|
+
bail = true;
|
|
23100
|
+
continue;
|
|
23101
|
+
}
|
|
22976
23102
|
addResolverImports(res.resolvedImports);
|
|
22977
23103
|
if (!decl.needsUseThemeHook) decl.needsUseThemeHook = [];
|
|
22978
23104
|
if (!decl.needsUseThemeHook.some((e) => e.themeProp === res.themeProp)) decl.needsUseThemeHook.push({
|
|
@@ -27514,15 +27640,22 @@ function rewriteJsxStep(ctx) {
|
|
|
27514
27640
|
styleAttr = null;
|
|
27515
27641
|
}
|
|
27516
27642
|
if (promotedMerge) styleAttr = null;
|
|
27517
|
-
const
|
|
27643
|
+
const extraClassNameExpr = decl.extraClassNames && decl.extraClassNames.length > 0 ? buildExtraClassNameExpr(j, decl.extraClassNames) : void 0;
|
|
27518
27644
|
const isIntrinsicTag = /^[a-z]/.test(finalTag) && !finalTag.includes(".");
|
|
27519
|
-
|
|
27645
|
+
let effectiveClassNameAttr = classNameAttr;
|
|
27646
|
+
if (extraClassNameExpr && !ctx.adapter.useSxProp) effectiveClassNameAttr = j.jsxAttribute(j.jsxIdentifier("className"), j.jsxExpressionContainer(extraClassNameExpr));
|
|
27647
|
+
const needsMerge = effectiveClassNameAttr !== null || styleAttr !== null;
|
|
27648
|
+
const useSxProp = ctx.adapter.useSxProp && !needsMerge && isIntrinsicTag;
|
|
27649
|
+
const stylexAttr = useSxProp ? (() => {
|
|
27520
27650
|
const sxExpr = styleArgs.length === 1 && styleArgs[0] ? styleArgs[0] : j.arrayExpression([...styleArgs]);
|
|
27521
27651
|
return j.jsxAttribute(j.jsxIdentifier("sx"), j.jsxExpressionContainer(sxExpr));
|
|
27522
|
-
})() : j.jsxSpreadAttribute(needsMerge ? buildInlineMergeCall(j, styleArgs,
|
|
27652
|
+
})() : j.jsxSpreadAttribute(needsMerge ? buildInlineMergeCall(j, styleArgs, effectiveClassNameAttr, styleAttr, ctx.adapter.styleMerger?.functionName) : j.callExpression(j.memberExpression(j.identifier("stylex"), j.identifier("props")), [...styleArgs]));
|
|
27653
|
+
const extraClassNameAttrs = [];
|
|
27654
|
+
if (extraClassNameExpr && useSxProp) extraClassNameAttrs.push(j.jsxAttribute(j.jsxIdentifier("className"), j.jsxExpressionContainer(extraClassNameExpr)));
|
|
27523
27655
|
const finalRest = [
|
|
27524
27656
|
...keptRestAfterVariants.slice(0, finalInsertIndex),
|
|
27525
27657
|
stylexAttr,
|
|
27658
|
+
...extraClassNameAttrs,
|
|
27526
27659
|
...keptRestAfterVariants.slice(finalInsertIndex)
|
|
27527
27660
|
];
|
|
27528
27661
|
opening.attributes = [
|
|
@@ -27575,6 +27708,25 @@ function extractJsxAttrValueExpr(j, attr) {
|
|
|
27575
27708
|
if (a.value.type === "JSXExpressionContainer") return a.value.expression;
|
|
27576
27709
|
}
|
|
27577
27710
|
/**
|
|
27711
|
+
* Builds a single expression from extra className entries (CSS module classes).
|
|
27712
|
+
* Single entry: returns the expression directly.
|
|
27713
|
+
* Multiple entries: joins with a template literal `${a} ${b}`.
|
|
27714
|
+
*/
|
|
27715
|
+
function buildExtraClassNameExpr(j, extraClassNames) {
|
|
27716
|
+
const exprs = extraClassNames.map((cn) => cn.expr);
|
|
27717
|
+
if (exprs.length === 1 && exprs[0]) return exprs[0];
|
|
27718
|
+
const qs = [];
|
|
27719
|
+
for (let i = 0; i <= exprs.length; i++) {
|
|
27720
|
+
const isLast = i === exprs.length;
|
|
27721
|
+
const raw = i === 0 || isLast ? "" : " ";
|
|
27722
|
+
qs.push(j.templateElement({
|
|
27723
|
+
raw,
|
|
27724
|
+
cooked: raw
|
|
27725
|
+
}, isLast));
|
|
27726
|
+
}
|
|
27727
|
+
return j.templateLiteral(qs, exprs);
|
|
27728
|
+
}
|
|
27729
|
+
/**
|
|
27578
27730
|
* Finds the combined style key matching the consumed props at a JSX call site.
|
|
27579
27731
|
* Returns the style key if a matching combination exists, or undefined otherwise.
|
|
27580
27732
|
*/
|