styled-components-to-stylex-codemod 0.0.17 → 0.0.18

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/README.md CHANGED
@@ -34,6 +34,12 @@ const adapter = defineAdapter({
34
34
  },
35
35
  // Optional: use a helper for merging StyleX styles with external className/style
36
36
  styleMerger: null,
37
+ // Optional: customize the runtime theme hook import/call used for theme conditionals
38
+ // Defaults to { functionName: "useTheme", importSource: { kind: "specifier", value: "styled-components" } }
39
+ themeHook: {
40
+ functionName: "useTheme",
41
+ importSource: { kind: "specifier", value: "styled-components" },
42
+ },
37
43
  });
38
44
 
39
45
  await runTransform({
@@ -133,6 +139,15 @@ const adapter = defineAdapter({
133
139
  functionName: "mergedSx",
134
140
  importSource: { kind: "specifier", value: "./lib/mergedSx" },
135
141
  },
142
+
143
+ /**
144
+ * Optional: customize the runtime theme hook used when wrappers need theme booleans.
145
+ * Defaults to useTheme from styled-components.
146
+ */
147
+ themeHook: {
148
+ functionName: "useDesignTheme",
149
+ importSource: { kind: "specifier", value: "@company/theme-hooks" },
150
+ },
136
151
  });
137
152
 
138
153
  await runTransform({
@@ -156,6 +171,7 @@ Adapters are the main extension point, see full example above. They let you cont
156
171
  - how helper calls are resolved (via `resolveCall({ ... })` returning `{ expr, imports }`; `null`/`undefined` bails the file)
157
172
  - which exported components should support external className/style extension and/or polymorphic `as` prop (`externalInterface`)
158
173
  - how className/style merging is handled for components accepting external styling (`styleMerger`)
174
+ - which runtime theme hook import/call to use for emitted wrapper theme conditionals (`themeHook`)
159
175
 
160
176
  #### Cross-file selectors (`consumerPaths`)
161
177
 
@@ -263,7 +279,11 @@ export const truncate = stylex.create({
263
279
 
264
280
  The adapter maps your project's `props.theme.*` access, CSS variables, and helper calls to the StyleX equivalents from step 1. See [Usage](#usage) for the full API.
265
281
 
266
- ### 3. Verify, iterate, clean up
282
+ ### 3. Convert bottom-up (leaf components first)
283
+
284
+ When a component wraps another component that internally uses styled-components (e.g. `styled(GroupHeader)` where `GroupHeader` renders a `StyledHeader`), CSS cascade conflicts can arise after migration. Convert leaf files — the ones that don't wrap other styled-components — first, then work your way up. The codemod will bail with a warning if it detects this pattern.
285
+
286
+ ### 4. Verify, iterate, clean up
267
287
 
268
288
  Build and test your project. Review warnings — they tell you which files were skipped and why. Fix adapter gaps, re-run on remaining files, and repeat until done. [Report issues](https://github.com/skovhus/styled-components-to-stylex-codemod/issues) with input/output examples if the codemod produces incorrect results.
269
289
 
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as defineAdapter, i as AdapterInput, t as CollectedWarning } from "./logger-B7SOfCti.mjs";
1
+ import { a as defineAdapter, i as AdapterInput, t as CollectedWarning } from "./logger-vL9nn4Bu.mjs";
2
2
 
3
3
  //#region src/run.d.ts
4
4
  interface RunTransformOptions {
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { i as describeValue, r as assertValidAdapterInput, t as Logger } from "./logger-D-R2KB6I.mjs";
1
+ import { a as assertValidAdapterInput, o as describeValue, r as defineAdapter, t as Logger } from "./logger-Cn8OiPdU.mjs";
2
2
  import { run } from "jscodeshift/src/Runner.js";
3
3
  import { fileURLToPath } from "node:url";
4
4
  import { dirname, join, resolve } from "node:path";
@@ -6,68 +6,6 @@ import { existsSync, readFileSync, realpathSync } from "node:fs";
6
6
  import { glob, writeFile } from "node:fs/promises";
7
7
  import { spawn } from "node:child_process";
8
8
 
9
- //#region src/adapter.ts
10
- /**
11
- * Adapter entry point for customizing the codemod.
12
- * Core concepts: value resolution hooks and adapter validation.
13
- */
14
- /**
15
- * Helper for nicer user authoring + type inference.
16
- *
17
- * `defineAdapter(...)` also performs runtime validation (helpful for JS consumers)
18
- * and will throw a descriptive error message if the adapter shape is invalid.
19
- *
20
- * Usage:
21
- * export default defineAdapter({
22
- * resolveValue(ctx) {
23
- * if (ctx.kind === "theme") {
24
- * return {
25
- * expr: `tokens.${ctx.path}`,
26
- * imports: [
27
- * { from: { kind: "specifier", value: "./tokens" }, names: [{ imported: "tokens" }] },
28
- * ],
29
- * };
30
- * }
31
- * // Return undefined to bail/skip the file
32
- * },
33
- *
34
- * resolveCall(ctx) {
35
- * // Resolve helper calls inside template interpolations.
36
- * // Use ctx.cssProperty to determine context:
37
- * // - If ctx.cssProperty exists → return a CSS value expression
38
- * // - If ctx.cssProperty is undefined → return a StyleX style object reference
39
- * // Return { expr, imports } or undefined to bail/skip the file
40
- * void ctx;
41
- * },
42
- *
43
- * resolveSelector(ctx) {
44
- * // Resolve imported values used in selector position.
45
- * // Return one of:
46
- * // - { kind: "media", expr, imports } for media queries (e.g., breakpoints.phone)
47
- * // - { kind: "pseudoAlias", values, styleSelectorExpr?, imports? } for pseudo-class expansion
48
- * // - undefined to bail/skip the file
49
- * void ctx;
50
- * },
51
- *
52
- * // Configure external interface for exported components
53
- * externalInterface(ctx) {
54
- * // Example: Enable styles and `as` for shared components folder
55
- * if (ctx.filePath.includes("/shared/components/")) {
56
- * return { styles: true, as: true };
57
- * }
58
- * return { styles: false, as: false };
59
- * },
60
- *
61
- * // Optional: provide a custom merger, or use `null` for the default verbose merge output
62
- * styleMerger: null,
63
- * });
64
- */
65
- function defineAdapter(adapter) {
66
- assertValidAdapterInput(adapter, "defineAdapter(adapter)");
67
- return adapter;
68
- }
69
-
70
- //#endregion
71
9
  //#region src/run.ts
72
10
  /**
73
11
  * Runs the codemod over input files with an adapter.
@@ -194,7 +132,7 @@ async function runTransform(options) {
194
132
  ].join("\n"));
195
133
  const { createModuleResolver } = await import("./resolve-imports-BDk6Ms09.mjs");
196
134
  const sharedResolver = createModuleResolver();
197
- const { runPrepass } = await import("./run-prepass-C4Lv1FHf.mjs");
135
+ const { runPrepass } = await import("./run-prepass-ByjC18e6.mjs");
198
136
  const absoluteFiles = filePaths.map((f) => resolve(f));
199
137
  const absoluteConsumers = consumerFilePaths.map((f) => resolve(f));
200
138
  let prepassResult;
@@ -243,6 +181,7 @@ async function runTransform(options) {
243
181
  })();
244
182
  const adapterWithLogging = {
245
183
  styleMerger: resolvedAdapter.styleMerger,
184
+ themeHook: resolvedAdapter.themeHook,
246
185
  externalInterface(ctx) {
247
186
  return resolvedAdapter.externalInterface(ctx);
248
187
  },
@@ -112,23 +112,131 @@ function assertAdapterShape(candidate, where, allowAutoExtIf) {
112
112
  " }"
113
113
  ].join("\n"));
114
114
  const { functionName, importSource } = styleMerger;
115
- if (typeof functionName !== "string" || !functionName.trim()) throw new Error([`${where}: adapter.styleMerger.functionName must be a non-empty string.`, `Received: functionName=${describeValue(functionName)}`].join("\n"));
116
- if (!importSource || typeof importSource !== "object") throw new Error([
117
- `${where}: adapter.styleMerger.importSource must be an object.`,
118
- `Received: importSource=${describeValue(importSource)}`,
115
+ assertFunctionNameAndImportSource({
116
+ where,
117
+ configPath: "adapter.styleMerger",
118
+ functionName,
119
+ importSource,
120
+ specifierExample: "@company/ui-utils",
121
+ absolutePathExample: "/path/to/module.ts"
122
+ });
123
+ }
124
+ const themeHook = obj?.themeHook;
125
+ if (themeHook !== null && themeHook !== void 0) {
126
+ if (typeof themeHook !== "object") throw new Error([
127
+ `${where}: adapter.themeHook must be an object when provided.`,
128
+ `Received: themeHook=${describeValue(themeHook)}`,
119
129
  "",
120
130
  "Expected shape:",
121
- " { kind: \"specifier\", value: \"@company/ui-utils\" }",
122
- " or",
123
- " { kind: \"absolutePath\", value: \"/path/to/module.ts\" }"
131
+ " {",
132
+ " functionName: \"useTheme\",",
133
+ " importSource: { kind: \"specifier\", value: \"@company/theme-hooks\" }",
134
+ " }"
124
135
  ].join("\n"));
125
- const { kind, value } = importSource;
126
- if (kind !== "specifier" && kind !== "absolutePath") throw new Error([`${where}: adapter.styleMerger.importSource.kind must be "specifier" or "absolutePath".`, `Received: kind=${describeValue(kind)}`].join("\n"));
127
- if (typeof value !== "string" || !value.trim()) throw new Error([`${where}: adapter.styleMerger.importSource.value must be a non-empty string.`, `Received: value=${describeValue(value)}`].join("\n"));
136
+ const { functionName, importSource } = themeHook;
137
+ assertFunctionNameAndImportSource({
138
+ where,
139
+ configPath: "adapter.themeHook",
140
+ functionName,
141
+ importSource,
142
+ specifierExample: "@company/theme-hooks",
143
+ absolutePathExample: "/path/to/theme-hooks.ts"
144
+ });
128
145
  }
129
146
  }
147
+ function assertFunctionNameAndImportSource(args) {
148
+ const { where, configPath, functionName, importSource, specifierExample, absolutePathExample } = args;
149
+ if (typeof functionName !== "string" || !functionName.trim()) throw new Error([`${where}: ${configPath}.functionName must be a non-empty string.`, `Received: functionName=${describeValue(functionName)}`].join("\n"));
150
+ if (!importSource || typeof importSource !== "object") throw new Error([
151
+ `${where}: ${configPath}.importSource must be an object.`,
152
+ `Received: importSource=${describeValue(importSource)}`,
153
+ "",
154
+ "Expected shape:",
155
+ ` { kind: "specifier", value: "${specifierExample}" }`,
156
+ " or",
157
+ ` { kind: "absolutePath", value: "${absolutePathExample}" }`
158
+ ].join("\n"));
159
+ const { kind, value } = importSource;
160
+ if (kind !== "specifier" && kind !== "absolutePath") throw new Error([`${where}: ${configPath}.importSource.kind must be "specifier" or "absolutePath".`, `Received: kind=${describeValue(kind)}`].join("\n"));
161
+ if (typeof value !== "string" || !value.trim()) throw new Error([`${where}: ${configPath}.importSource.value must be a non-empty string.`, `Received: value=${describeValue(value)}`].join("\n"));
162
+ }
130
163
  const ADAPTER_DOCS_URL = `https://github.com/skovhus/styled-components-to-stylex-codemod#adapter`;
131
164
 
165
+ //#endregion
166
+ //#region src/adapter.ts
167
+ /**
168
+ * Adapter entry point for customizing the codemod.
169
+ * Core concepts: value resolution hooks and adapter validation.
170
+ */
171
+ const DEFAULT_THEME_HOOK = {
172
+ functionName: "useTheme",
173
+ importSource: {
174
+ kind: "specifier",
175
+ value: "styled-components"
176
+ }
177
+ };
178
+ /**
179
+ * Helper for nicer user authoring + type inference.
180
+ *
181
+ * `defineAdapter(...)` also performs runtime validation (helpful for JS consumers)
182
+ * and will throw a descriptive error message if the adapter shape is invalid.
183
+ *
184
+ * Usage:
185
+ * export default defineAdapter({
186
+ * resolveValue(ctx) {
187
+ * if (ctx.kind === "theme") {
188
+ * return {
189
+ * expr: `tokens.${ctx.path}`,
190
+ * imports: [
191
+ * { from: { kind: "specifier", value: "./tokens" }, names: [{ imported: "tokens" }] },
192
+ * ],
193
+ * };
194
+ * }
195
+ * // Return undefined to bail/skip the file
196
+ * },
197
+ *
198
+ * resolveCall(ctx) {
199
+ * // Resolve helper calls inside template interpolations.
200
+ * // Use ctx.cssProperty to determine context:
201
+ * // - If ctx.cssProperty exists → return a CSS value expression
202
+ * // - If ctx.cssProperty is undefined → return a StyleX style object reference
203
+ * // Return { expr, imports } or undefined to bail/skip the file
204
+ * void ctx;
205
+ * },
206
+ *
207
+ * resolveSelector(ctx) {
208
+ * // Resolve imported values used in selector position.
209
+ * // Return one of:
210
+ * // - { kind: "media", expr, imports } for media queries (e.g., breakpoints.phone)
211
+ * // - { kind: "pseudoAlias", values, styleSelectorExpr?, imports? } for pseudo-class expansion
212
+ * // - undefined to bail/skip the file
213
+ * void ctx;
214
+ * },
215
+ *
216
+ * // Configure external interface for exported components
217
+ * externalInterface(ctx) {
218
+ * // Example: Enable styles and `as` for shared components folder
219
+ * if (ctx.filePath.includes("/shared/components/")) {
220
+ * return { styles: true, as: true };
221
+ * }
222
+ * return { styles: false, as: false };
223
+ * },
224
+ *
225
+ * // Optional: provide a custom merger, or use `null` for the default verbose merge output
226
+ * styleMerger: null,
227
+ *
228
+ * // Optional: customize runtime theme hook import/call used by emitted wrappers
229
+ * themeHook: {
230
+ * functionName: "useTheme",
231
+ * importSource: { kind: "specifier", value: "styled-components" },
232
+ * },
233
+ * });
234
+ */
235
+ function defineAdapter(adapter) {
236
+ assertValidAdapterInput(adapter, "defineAdapter(adapter)");
237
+ return adapter;
238
+ }
239
+
132
240
  //#endregion
133
241
  //#region src/internal/logger.ts
134
242
  /**
@@ -361,4 +469,4 @@ const SECTION_COLOR = "\x1B[36m";
361
469
  const RESET_COLOR = "\x1B[0m";
362
470
 
363
471
  //#endregion
364
- export { describeValue as i, assertValidAdapter as n, assertValidAdapterInput as r, Logger as t };
472
+ export { assertValidAdapterInput as a, assertValidAdapter as i, DEFAULT_THEME_HOOK as n, describeValue as o, defineAdapter as r, Logger as t };
@@ -348,6 +348,25 @@ interface StyleMergerConfig {
348
348
  */
349
349
  importSource: ImportSource;
350
350
  }
351
+ /**
352
+ * Configuration for the theme hook used when wrapper emission needs runtime theme access
353
+ * (e.g. theme boolean conditionals that cannot be fully lowered statically).
354
+ *
355
+ * Defaults to:
356
+ * - functionName: "useTheme"
357
+ * - importSource: { kind: "specifier", value: "styled-components" }
358
+ */
359
+ interface ThemeHookConfig {
360
+ /**
361
+ * Function name to call in emitted wrappers (e.g. "useTheme", "useDesignSystemTheme").
362
+ */
363
+ functionName: string;
364
+ /**
365
+ * Import source for the hook function.
366
+ * Example: `{ kind: "specifier", value: "@company/theme" }`
367
+ */
368
+ importSource: ImportSource;
369
+ }
351
370
  interface Adapter {
352
371
  /**
353
372
  * Resolver for theme paths + CSS variables + imported values.
@@ -411,6 +430,13 @@ interface Adapter {
411
430
  * ```
412
431
  */
413
432
  styleMerger: StyleMergerConfig | null;
433
+ /**
434
+ * Optional theme hook import/call customization for wrapper code that needs runtime theme access.
435
+ *
436
+ * When omitted, defaults to:
437
+ * `{ functionName: "useTheme", importSource: { kind: "specifier", value: "styled-components" } }`
438
+ */
439
+ themeHook?: ThemeHookConfig;
414
440
  }
415
441
  /**
416
442
  * User-facing adapter input type accepted by `defineAdapter()`.
@@ -433,6 +459,7 @@ interface AdapterInput {
433
459
  */
434
460
  externalInterface: "auto" | Adapter["externalInterface"];
435
461
  styleMerger: Adapter["styleMerger"];
462
+ themeHook?: Adapter["themeHook"];
436
463
  }
437
464
  /**
438
465
  * Helper for nicer user authoring + type inference.
@@ -483,13 +510,19 @@ interface AdapterInput {
483
510
  *
484
511
  * // Optional: provide a custom merger, or use `null` for the default verbose merge output
485
512
  * styleMerger: null,
513
+ *
514
+ * // Optional: customize runtime theme hook import/call used by emitted wrappers
515
+ * themeHook: {
516
+ * functionName: "useTheme",
517
+ * importSource: { kind: "specifier", value: "styled-components" },
518
+ * },
486
519
  * });
487
520
  */
488
521
  declare function defineAdapter<T extends AdapterInput>(adapter: T): T;
489
522
  //#endregion
490
523
  //#region src/internal/logger.d.ts
491
524
  type Severity = "info" | "warning" | "error";
492
- type WarningType = "`css` helper function switch must return css templates in all branches" | "`css` helper usage as a function call (css(...)) is not supported" | "`css` helper used outside of a styled component template cannot be statically transformed" | "Adapter helper call in border interpolation did not resolve to a single CSS value" | "Adapter resolveCall returned an unparseable styles expression" | "Adapter resolveCall returned an unparseable value expression" | "Adapter resolveCall returned StyleX styles for helper call where a CSS value was expected" | "Adapter resolveCall returned undefined for helper call" | "Adapter resolved StyleX styles cannot be applied under nested selectors/at-rules" | "Adapter resolved StyleX styles inside pseudo selector but did not provide cssText for property expansion — add cssText to resolveCall result to enable pseudo-wrapping" | 'Adapter resolveCall cssText could not be parsed as CSS declarations — expected semicolon-separated property: value pairs (e.g. "white-space: nowrap; overflow: hidden;")' | "Adapter resolveValue returned an unparseable value expression" | "Adapter resolveValue returned undefined for imported value" | "Arrow function: body is not a recognized pattern (expected ternary, logical, call, or member expression)" | "Arrow function: conditional branches could not be resolved to static or theme values" | "Arrow function: helper call body is not supported" | "Arrow function: indexed theme lookup pattern not matched" | "Arrow function: logical expression pattern not supported" | "Arrow function: prop access cannot be converted to style function for this CSS property" | "Arrow function: theme access path could not be resolved" | "Component selectors like `${OtherComponent}:hover &` are not directly representable in StyleX. Manual refactor is required" | "Conditional `css` block: !important is not supported in StyleX" | "Conditional `css` block: @-rules (e.g., @media, @supports) are not supported" | "Conditional `css` block: failed to parse expression" | "Conditional `css` block: missing CSS property name" | "Conditional `css` block: missing interpolation expression" | "Conditional `css` block: mixed static/dynamic values with non-theme expressions cannot be safely transformed" | "Conditional `css` block: multiple interpolation slots in a single property value" | "Conditional `css` block: ternary branch value could not be resolved (imported values require adapter support)" | "Conditional `css` block: ternary expressions inside pseudo selectors are not supported" | "Conditional `css` block: unsupported selector" | "Directional border helper styles are not supported" | "Multi-slot border interpolation could not be resolved" | "createGlobalStyle is not supported in StyleX. Global styles should be handled separately (e.g., in a CSS file or using CSS reset libraries)" | "Dynamic styles inside pseudo elements (::before/::after) are not supported by StyleX. See https://github.com/facebook/stylex/issues/1396" | "Failed to parse theme expressions" | "Heterogeneous background values (mix of gradients and colors) not currently supported" | "Higher-order styled factory wrappers (e.g. hoc(styled)) are not supported" | "Imported CSS helper mixins: cannot determine inherited properties for correct pseudo selector handling" | "Styled-components specificity hacks like `&&` / `&&&` are not representable in StyleX" | "Theme-dependent block-level conditional could not be fully resolved (branches may contain dynamic interpolations)" | "Theme-dependant call expression could not be resolved (e.g. theme helper calls like theme.highlight() are not supported)" | "Theme value with fallback (props.theme.X ?? / || default) cannot be resolved statically — use adapter.resolveValue to map theme paths to StyleX tokens" | "Theme-dependent nested prop access requires a project-specific theme source (e.g. useTheme())" | "Theme-dependent template literals require a project-specific theme source (e.g. useTheme())" | "Theme prop overrides on styled components are not supported" | "Universal selectors (`*`) are currently unsupported" | "Unsupported call expression (expected imported helper(...) or imported helper(...)(...))" | "Unsupported conditional test in shouldForwardProp" | "Unsupported shouldForwardProp pattern (only !prop.startsWith(), ![].includes(prop), and prop !== are supported)" | "Unsupported interpolation: arrow function" | "Unsupported interpolation: call expression" | "Unsupported interpolation: identifier" | "Unsupported interpolation: member expression" | "Unsupported interpolation: property" | "Unsupported interpolation: unknown" | "Unsupported nested conditional interpolation" | "Unsupported prop-based inline style expression cannot be safely inlined" | "Unsupported prop-based inline style props.theme access is not supported" | "Unsupported selector interpolation: imported value in selector position" | "Unsupported selector: class selector" | "Unsupported selector: comma-separated selectors must all be simple pseudos or pseudo-elements" | "Unsupported selector: descendant pseudo selector (space before pseudo)" | "Unsupported selector: descendant/child/sibling selector" | "Unsupported selector: interpolated pseudo selector" | "Unsupported selector: sibling combinator" | "Unsupported selector: unresolved interpolation in sibling selector" | "Unsupported selector: ambiguous element selector" | "Unsupported selector: attribute selector on unsupported element" | "Unsupported selector: element selector on exported component" | "Unsupported selector: element selector with combined ancestor and child pseudos" | "Unsupported selector: element selector with dynamic children" | "Unsupported selector: element selector with plain intrinsic children" | "Unsupported selector: element selector pseudo collision" | "Unsupported selector: unresolved interpolation in cross-file component selector" | "Unsupported selector: unresolved interpolation in descendant component selector" | "Unsupported selector: unresolved interpolation in element selector" | "Unsupported selector: unresolved interpolation in reverse component selector" | "Unsupported selector: grouped reverse selector references different components" | "Unsupported selector: unknown component selector" | "Unsupported css`` mixin: after-base mixin style is not a plain object" | "Unsupported css`` mixin: nested contextual conditions in after-base mixin" | "Unsupported css`` mixin: cannot infer base default for after-base contextual override (base value is non-literal)" | "css`` helper function interpolation references closure variable that cannot be hoisted" | "Sibling selector broadened: & + & (adjacent) becomes general sibling (~) in StyleX — interleaved non-matching elements will no longer block the match" | "Using styled-components components as mixins is not supported; use css`` mixins or strings instead";
525
+ type WarningType = "`css` helper function switch must return css templates in all branches" | "`css` helper usage as a function call (css(...)) is not supported" | "`css` helper used outside of a styled component template cannot be statically transformed" | "Adapter helper call in border interpolation did not resolve to a single CSS value" | "Adapter resolveCall returned an unparseable styles expression" | "Adapter resolveCall returned an unparseable value expression" | "Adapter resolveCall returned StyleX styles for helper call where a CSS value was expected" | "Adapter resolveCall returned undefined for helper call" | "Adapter resolved StyleX styles cannot be applied under nested selectors/at-rules" | "Adapter resolved StyleX styles inside pseudo selector but did not provide cssText for property expansion — add cssText to resolveCall result to enable pseudo-wrapping" | 'Adapter resolveCall cssText could not be parsed as CSS declarations — expected semicolon-separated property: value pairs (e.g. "white-space: nowrap; overflow: hidden;")' | "Adapter resolveValue returned an unparseable value expression" | "Adapter resolveValue returned undefined for imported value" | "Arrow function: body is not a recognized pattern (expected ternary, logical, call, or member expression)" | "Arrow function: conditional branches could not be resolved to static or theme values" | "Arrow function: helper call body is not supported" | "Arrow function: indexed theme lookup pattern not matched" | "Arrow function: logical expression pattern not supported" | "Arrow function: prop access cannot be converted to style function for this CSS property" | "Arrow function: theme access path could not be resolved" | "Component selectors like `${OtherComponent}:hover &` are not directly representable in StyleX. Manual refactor is required" | "Conditional `css` block: !important is not supported in StyleX" | "Conditional `css` block: @-rules (e.g., @media, @supports) are not supported" | "CSS block contains unsupported at-rule (only @media is supported; @supports, @container, etc. require manual handling)" | "Conditional `css` block: dynamic interpolation could not be resolved to a single component prop" | "Conditional `css` block: failed to parse expression" | "Conditional `css` block: missing CSS property name" | "Conditional `css` block: missing interpolation expression" | "Conditional `css` block: mixed static/dynamic values with non-theme expressions cannot be safely transformed" | "Conditional `css` block: multiple interpolation slots in a single property value" | "Conditional `css` block: ternary branch value could not be resolved (imported values require adapter support)" | "Conditional `css` block: ternary expressions inside pseudo selectors are not supported" | "Conditional `css` block: unsupported selector" | "Directional border helper styles are not supported" | "Multi-slot border interpolation could not be resolved" | "createGlobalStyle is not supported in StyleX. Global styles should be handled separately (e.g., in a CSS file or using CSS reset libraries)" | "Dynamic styles inside pseudo elements (::before/::after) are not supported by StyleX. See https://github.com/facebook/stylex/issues/1396" | "Failed to parse theme expressions" | "Heterogeneous background values (mix of gradients and colors) not currently supported" | "Higher-order styled factory wrappers (e.g. hoc(styled)) are not supported" | "Imported CSS helper mixins: cannot determine inherited properties for correct pseudo selector handling" | "Styled-components specificity hacks like `&&` / `&&&` are not representable in StyleX" | "Theme-dependent block-level conditional could not be fully resolved (branches may contain dynamic interpolations)" | "Theme-dependant call expression could not be resolved (e.g. theme helper calls like theme.highlight() are not supported)" | "Theme value with fallback (props.theme.X ?? / || default) cannot be resolved statically — use adapter.resolveValue to map theme paths to StyleX tokens" | "Theme-dependent nested prop access requires a project-specific theme source (e.g. useTheme())" | "Theme-dependent template literals require a project-specific theme source (e.g. useTheme())" | "Theme prop overrides on styled components are not supported" | "Universal selectors (`*`) are currently unsupported" | "Unsupported call expression (expected imported helper(...) or imported helper(...)(...))" | "Unsupported conditional test in shouldForwardProp" | "Unsupported shouldForwardProp pattern (only !prop.startsWith(), ![].includes(prop), and prop !== are supported)" | "Unsupported interpolation: arrow function" | "Unsupported interpolation: call expression" | "Unsupported interpolation: identifier" | "Unsupported interpolation: member expression" | "Unsupported interpolation: property" | "Unsupported interpolation: unknown" | "Unsupported nested conditional interpolation" | "Unsupported prop-based inline style expression cannot be safely inlined" | "Unsupported prop-based inline style props.theme access is not supported" | "Unsupported selector interpolation: imported value in selector position" | "Unsupported selector: class selector" | "Unsupported selector: comma-separated selectors must all be simple pseudos or pseudo-elements" | "Unsupported selector: descendant pseudo selector (space before pseudo)" | "Unsupported selector: descendant/child/sibling selector" | "Unsupported selector: interpolated pseudo selector" | "Unsupported selector: sibling combinator" | "Unsupported selector: unresolved interpolation in sibling selector" | "Unsupported selector: ambiguous element selector" | "Unsupported selector: attribute selector on unsupported element" | "Unsupported selector: element selector on exported component" | "Unsupported selector: element selector with combined ancestor and child pseudos" | "Unsupported selector: element selector with dynamic children" | "Unsupported selector: element selector with plain intrinsic children" | "Unsupported selector: element selector pseudo collision" | "Unsupported selector: unresolved interpolation in cross-file component selector" | "Unsupported selector: unresolved interpolation in descendant component selector" | "Unsupported selector: unresolved interpolation in element selector" | "Unsupported selector: unresolved interpolation in reverse component selector" | "Unsupported selector: grouped reverse selector references different components" | "Unsupported selector: unknown component selector" | "Unsupported css`` mixin: after-base mixin style is not a plain object" | "Unsupported css`` mixin: nested contextual conditions in after-base mixin" | "Unsupported css`` mixin: cannot infer base default for after-base contextual override (base value is non-literal)" | "css`` helper function interpolation references closure variable that cannot be hoisted" | "Sibling selector broadened: & + & (adjacent) becomes general sibling (~) in StyleX — interleaved non-matching elements will no longer block the match" | "Using styled-components components as mixins is not supported; use css`` mixins or strings instead" | "styled(ImportedComponent) wraps a component whose file contains internal styled-components — convert the base component's file first to avoid CSS cascade conflicts";
493
526
  interface WarningLog {
494
527
  severity: Severity;
495
528
  type: WarningType;
@@ -652,7 +652,8 @@ async function runPrepass(options) {
652
652
  const crossFileInfo = {
653
653
  selectorUsages,
654
654
  componentsNeedingMarkerSidecar,
655
- componentsNeedingGlobalSelectorBridge
655
+ componentsNeedingGlobalSelectorBridge,
656
+ styledDefFiles: createExternalInterface ? styledDefFiles : void 0
656
657
  };
657
658
  {
658
659
  const elapsed = ((performance.now() - t0) / 1e3).toFixed(1);
@@ -1,4 +1,4 @@
1
- import { n as WarningLog, r as Adapter } from "./logger-B7SOfCti.mjs";
1
+ import { n as WarningLog, r as Adapter } from "./logger-vL9nn4Bu.mjs";
2
2
  import "stylis";
3
3
  import { API, FileInfo, Options } from "jscodeshift";
4
4
 
@@ -46,6 +46,8 @@ interface CrossFileInfo {
46
46
  selectorUsages: CrossFileSelectorUsage[];
47
47
  /** Component names in this file that need a global selector bridge className (consumer not transformed) */
48
48
  bridgeComponentNames?: Set<string>;
49
+ /** Global map: files that define styled-components → set of local names. Used for cascade conflict detection. */
50
+ styledDefFiles?: Map<string, Set<string>>;
49
51
  }
50
52
  interface CrossFileSelectorUsage {
51
53
  /** Local name in the consumer file (e.g. "CollapseArrowIcon") */