styled-components-to-stylex-codemod 0.0.49 → 0.0.51

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.
@@ -1,290 +1,12 @@
1
- import { c as Logger, i as findImportSource, n as fileExports, o as resolveBarrelReExport, r as fileImportsFrom, s as resolveBarrelReExportBinding, t as walkAst } from "./ast-walk-DigTJqU7.mjs";
2
- import { i as extractStyledDefBasesFromSource, n as computeGlobalLeafKeys, r as extractStyledDefBasesFromAstProgram, t as createPrepassParser } from "./prepass-parser-CwdDzSgx.mjs";
3
- import { r as escapeRegex } from "./string-utils-DD9wdRHW.mjs";
4
- import { n as isTemplatePlaceholderInSelectorContext, r as PLACEHOLDER_RE, t as isSelectorContext } from "./selector-context-heuristic-LVizWWOR.mjs";
5
- import { a as mergeComponentPropUsage, n as createComponentPropUsageInfo, o as readStaticJsxLiteral, t as KNOWN_NON_ELEMENT_PROPS } from "./prop-usage-QtOSsKTr.mjs";
1
+ import { a as findImportSource, c as resolveBarrelReExportBinding, i as fileImportsFrom, n as createPrepassParser, r as fileExports, s as resolveBarrelReExport, t as walkAst, u as Logger } from "./ast-walk-BOXS-DT7.mjs";
2
+ import { n as extractStyledDefBasesFromAstProgram, r as extractStyledDefBasesFromSource, t as computeGlobalLeafKeys } from "./compute-leaf-set-ghdXvfbp.mjs";
3
+ import { r as escapeRegex } from "./string-utils-BYTEHwNg.mjs";
4
+ import { t as isSelectorContext } from "./selector-context-heuristic-LVizWWOR.mjs";
5
+ import { _ as walkForImportsAndTemplates, a as mergeComponentPropUsage, c as BARE_TEMPLATE_IDENTIFIER_RE, d as categorizeSelectorUsages, f as collectStyledLocalBindingNames, g as findStyledImportNameFromNodes, h as findCssImportNamesFromNodes, l as applyBridgeFields, m as findComponentSelectorLocalsFromNodes, n as createComponentPropUsageInfo, o as readStaticJsxLiteral, p as deduplicateAndResolve, s as collectStylexExportNames, t as KNOWN_NON_ELEMENT_PROPS, u as buildImportMapFromNodes, v as addToSetMap } from "./prop-usage-SADzZJdX.mjs";
6
6
  import { relative, resolve } from "node:path";
7
7
  import { readFileSync, realpathSync } from "node:fs";
8
8
  import { execSync } from "node:child_process";
9
9
  import { createHash } from "node:crypto";
10
- //#region src/internal/utilities/collection-utils.ts
11
- /** Add a value to a Set stored in a Map, creating the Set if it doesn't exist. */
12
- function addToSetMap(map, key, value) {
13
- let set = map.get(key);
14
- if (!set) {
15
- set = /* @__PURE__ */ new Set();
16
- map.set(key, set);
17
- }
18
- set.add(value);
19
- }
20
- //#endregion
21
- //#region src/internal/prepass/scan-cross-file-selectors.ts
22
- /**
23
- * Pre-filter: matches any bare `${Identifier}` template expression.
24
- * Used to skip files that only contain arrow functions or member expressions
25
- * in template literals (e.g. `${props => ...}`, `${theme.color}`).
26
- */
27
- const BARE_TEMPLATE_IDENTIFIER_RE = /\$\{\s*[a-zA-Z_$][\w$]*\s*\}/;
28
- /**
29
- * Categorize cross-file selector usages into marker sidecar and global selector bridge maps.
30
- *
31
- * Bridge usages (from already-converted files) are skipped — the consumer handles marker
32
- * generation via the forward selector handler, so no sidecar/bridge is needed on the target.
33
- */
34
- function categorizeSelectorUsages(usages, componentsNeedingMarkerSidecar, componentsNeedingGlobalSelectorBridge) {
35
- for (const usage of usages) {
36
- if (usage.bridgeComponentName) continue;
37
- if (usage.consumerIsTransformed) addToSetMap(componentsNeedingMarkerSidecar, usage.resolvedPath, usage.importedName);
38
- addToSetMap(componentsNeedingGlobalSelectorBridge, usage.resolvedPath, usage.importedName);
39
- }
40
- }
41
- /**
42
- * Regex matching bridge GlobalSelector export patterns (global for matchAll).
43
- * Matches both:
44
- * - Old format: `export const XGlobalSelector = ".sc2sx-..."`
45
- * - New format: `` export const XGlobalSelector = `.${xBridgeClass}` ``
46
- */
47
- const BRIDGE_EXPORT_RE = /export\s+const\s+(\w+GlobalSelector)\s*=\s*(?:["']\.sc2sx-|`\.\$\{)/g;
48
- /**
49
- * Detect whether an imported name is a bridge GlobalSelector from an
50
- * already-converted StyleX file.
51
- *
52
- * Detection criteria (hybrid fast + safe):
53
- * 1. Variable name ends with "GlobalSelector" AND the stripped name starts uppercase
54
- * 2. Target file contains "@stylexjs/stylex" (string check, no parse)
55
- * 3. Target file has a matching `export const XGlobalSelector = ".sc2sx-"` pattern
56
- *
57
- * @returns The stripped component name (e.g., "CollapseArrowIcon" for
58
- * "CollapseArrowIconGlobalSelector"), or null if not a bridge.
59
- */
60
- function detectBridgeGlobalSelector(importedName, resolvedPath, readFile) {
61
- if (!importedName.endsWith("GlobalSelector")) return null;
62
- const stripped = importedName.slice(0, -14);
63
- if (!stripped || !/^[A-Z]/.test(stripped)) return null;
64
- const content = readFile(resolvedPath);
65
- if (!content || !content.includes("@stylexjs/stylex")) return null;
66
- let found = false;
67
- for (const m of content.matchAll(BRIDGE_EXPORT_RE)) if (m[1] === importedName) {
68
- found = true;
69
- break;
70
- }
71
- if (!found) return null;
72
- return stripped;
73
- }
74
- /**
75
- * If `importedName` is a bridge GlobalSelector, populate bridge fields on `usage`
76
- * and find the corresponding component import from the same source.
77
- */
78
- function applyBridgeFields(usage, importedName, localName, resolvedPath, importMap, readFile) {
79
- const bridgeName = detectBridgeGlobalSelector(importedName, resolvedPath, readFile);
80
- if (!bridgeName) return;
81
- usage.bridgeComponentName = bridgeName;
82
- const imp = importMap.get(localName);
83
- if (!imp) return;
84
- let defaultImportLocal;
85
- for (const [otherLocal, otherImp] of importMap) {
86
- if (otherImp.source !== imp.source || otherLocal === localName) continue;
87
- if (otherImp.importedName === bridgeName) {
88
- usage.bridgeComponentLocalName = otherLocal;
89
- defaultImportLocal = void 0;
90
- break;
91
- }
92
- if (otherImp.importedName === "default" && defaultImportLocal === void 0) defaultImportLocal = otherLocal;
93
- }
94
- if (defaultImportLocal !== void 0) usage.bridgeComponentLocalName = defaultImportLocal;
95
- }
96
- /** Global version for matchAll/replace operations */
97
- const PLACEHOLDER_RE_G = new RegExp(PLACEHOLDER_RE.source, "g");
98
- /**
99
- * Walk the AST collecting ImportDeclaration and TaggedTemplateExpression nodes.
100
- *
101
- * Uses a targeted recursive walk — only descends into node types that can
102
- * contain these targets (skips type annotations, comments, etc.).
103
- */
104
- function walkForImportsAndTemplates(node, imports, templates) {
105
- if (!node || typeof node !== "object") return;
106
- const n = node;
107
- if (n.type === "ImportDeclaration") {
108
- imports.push(n);
109
- return;
110
- }
111
- if (n.type === "TaggedTemplateExpression") templates.push(n);
112
- for (const key of Object.keys(n)) {
113
- if (key === "type" || key === "start" || key === "end" || key === "loc") continue;
114
- const val = n[key];
115
- if (Array.isArray(val)) for (const child of val) walkForImportsAndTemplates(child, imports, templates);
116
- else if (val && typeof val === "object" && val.type) walkForImportsAndTemplates(val, imports, templates);
117
- }
118
- }
119
- /** Build a map of localName → import info from raw ImportDeclaration nodes. */
120
- function buildImportMapFromNodes(importNodes) {
121
- const map = /* @__PURE__ */ new Map();
122
- for (const node of importNodes) {
123
- const sourceValue = node.source?.value;
124
- if (typeof sourceValue !== "string") continue;
125
- const specifiers = node.specifiers;
126
- if (!specifiers) continue;
127
- for (const spec of specifiers) {
128
- const localName = getNodeName(spec.local);
129
- if (!localName) continue;
130
- if (spec.type === "ImportDefaultSpecifier") map.set(localName, {
131
- source: sourceValue,
132
- importedName: "default"
133
- });
134
- else if (spec.type === "ImportNamespaceSpecifier") map.set(localName, {
135
- source: sourceValue,
136
- importedName: "*"
137
- });
138
- else if (spec.type === "ImportSpecifier") {
139
- const importedName = getNodeName(spec.imported) ?? localName;
140
- map.set(localName, {
141
- source: sourceValue,
142
- importedName
143
- });
144
- }
145
- }
146
- }
147
- return map;
148
- }
149
- /**
150
- * Local identifiers that refer to `styled` from `"styled-components"` (default and/or
151
- * `import { styled }` / `import { styled as sc }`).
152
- */
153
- function collectStyledLocalBindingNames(importNodes) {
154
- const names = /* @__PURE__ */ new Set();
155
- for (const node of importNodes) {
156
- if (node.source?.value !== "styled-components") continue;
157
- const specifiers = node.specifiers;
158
- if (!specifiers) continue;
159
- for (const spec of specifiers) if (spec.type === "ImportDefaultSpecifier") {
160
- const name = getNodeName(spec.local);
161
- if (name) names.add(name);
162
- } else if (spec.type === "ImportSpecifier") {
163
- if (getNodeName(spec.imported) === "styled") {
164
- const localName = getNodeName(spec.local);
165
- if (localName) names.add(localName);
166
- }
167
- }
168
- }
169
- return names;
170
- }
171
- /** Find the local name for the styled-components default import. */
172
- function findStyledImportNameFromNodes(importNodes) {
173
- let namedStyledLocal;
174
- for (const node of importNodes) {
175
- if (node.source?.value !== "styled-components") continue;
176
- const specifiers = node.specifiers;
177
- if (!specifiers) continue;
178
- for (const spec of specifiers) if (spec.type === "ImportDefaultSpecifier") {
179
- const name = getNodeName(spec.local);
180
- if (name) return name;
181
- } else if (spec.type === "ImportSpecifier") {
182
- if (getNodeName(spec.imported) === "styled") {
183
- const localName = getNodeName(spec.local);
184
- if (localName) namedStyledLocal = localName;
185
- }
186
- }
187
- }
188
- return namedStyledLocal;
189
- }
190
- /**
191
- * Find local names of `css` imported from styled-components.
192
- * Handles aliased imports like `import { css as sc } from "styled-components"`.
193
- */
194
- function findCssImportNamesFromNodes(importNodes) {
195
- const names = /* @__PURE__ */ new Set();
196
- for (const node of importNodes) {
197
- if (node.source?.value !== "styled-components") continue;
198
- const specifiers = node.specifiers;
199
- if (!specifiers) continue;
200
- for (const spec of specifiers) if (spec.type === "ImportSpecifier") {
201
- if (getNodeName(spec.imported) === "css") {
202
- const localName = getNodeName(spec.local);
203
- if (localName) names.add(localName);
204
- }
205
- }
206
- }
207
- return names;
208
- }
209
- /**
210
- * Find local names of imported components used as selectors inside
211
- * styled-components template literals (both `styled` and `css` tagged templates).
212
- */
213
- function findComponentSelectorLocalsFromNodes(templateNodes, styledImportName, cssImportNames) {
214
- const selectorLocals = /* @__PURE__ */ new Set();
215
- for (const node of templateNodes) {
216
- if (!isStyledTag(node.tag, styledImportName) && !isCssTag(node.tag, cssImportNames)) continue;
217
- const quasi = node.quasi;
218
- if (!quasi) continue;
219
- const quasis = quasi.quasis;
220
- const expressions = quasi.expressions;
221
- if (!quasis || !expressions) continue;
222
- const rawParts = [];
223
- for (let i = 0; i < quasis.length; i++) {
224
- const value = quasis[i]?.value;
225
- rawParts.push(value?.raw ?? "");
226
- if (i < expressions.length) rawParts.push(`__SC_EXPR_${i}__`);
227
- }
228
- const rawCss = rawParts.join("");
229
- for (const match of rawCss.matchAll(PLACEHOLDER_RE_G)) {
230
- const exprIndex = Number(match[1]);
231
- const pos = match.index;
232
- if (isTemplatePlaceholderInSelectorContext(rawCss, pos, match[0].length)) {
233
- const expr = expressions[exprIndex];
234
- if (expr?.type === "Identifier" && typeof expr.name === "string") selectorLocals.add(expr.name);
235
- }
236
- }
237
- }
238
- return selectorLocals;
239
- }
240
- /**
241
- * Check whether a styled-components tag expression is a styled call.
242
- * Matches: styled.div, styled(X), styled.div.attrs(...), styled(X).withConfig(...), etc.
243
- */
244
- function isStyledTag(tag, styledName) {
245
- if (!tag || typeof tag !== "object") return false;
246
- if (tag.type === "MemberExpression") {
247
- const obj = tag.object;
248
- if (obj?.type === "Identifier" && obj.name === styledName) return true;
249
- }
250
- if (tag.type === "CallExpression") {
251
- const callee = tag.callee;
252
- if (callee?.type === "Identifier" && callee.name === styledName) return true;
253
- if (callee?.type === "MemberExpression" && callee.object) return isStyledTag(callee.object, styledName);
254
- }
255
- return false;
256
- }
257
- /** Check if a template tag is the `css` helper from styled-components. */
258
- function isCssTag(tag, cssImportNames) {
259
- if (!tag || !cssImportNames || cssImportNames.size === 0) return false;
260
- return tag.type === "Identifier" && typeof tag.name === "string" && cssImportNames.has(tag.name);
261
- }
262
- /** Safely extract the name string from an AST identifier-like node. */
263
- function getNodeName(node) {
264
- if (!node || typeof node !== "object") return;
265
- if (node.type === "Identifier" && typeof node.name === "string") return node.name;
266
- }
267
- /** Deduplicate and resolve two file lists into a single array of absolute paths. */
268
- function deduplicateAndResolve(filesToTransform, consumerPaths) {
269
- const seen = /* @__PURE__ */ new Set();
270
- const result = [];
271
- for (const f of filesToTransform) {
272
- const abs = resolve(f);
273
- if (!seen.has(abs)) {
274
- seen.add(abs);
275
- result.push(abs);
276
- }
277
- }
278
- for (const f of consumerPaths) {
279
- const abs = resolve(f);
280
- if (!seen.has(abs)) {
281
- seen.add(abs);
282
- result.push(abs);
283
- }
284
- }
285
- return result;
286
- }
287
- //#endregion
288
10
  //#region src/internal/prepass/run-prepass.ts
289
11
  /**
290
12
  * Unified prepass: single pass for both cross-file selector scanning
@@ -354,6 +76,7 @@ async function runPrepass(options) {
354
76
  const refUsages = /* @__PURE__ */ new Map();
355
77
  const styledCallUsages = [];
356
78
  const styledDefFiles = /* @__PURE__ */ new Map();
79
+ const stylexComponentFiles = /* @__PURE__ */ new Map();
357
80
  const classNameStyleUsages = /* @__PURE__ */ new Map();
358
81
  const classNameUsages = /* @__PURE__ */ new Map();
359
82
  const styleUsages = /* @__PURE__ */ new Map();
@@ -385,7 +108,8 @@ async function runPrepass(options) {
385
108
  const hasStyled = source.includes("styled-components");
386
109
  const hasAsProp = createExternalInterface && AS_PROP_RE.test(source);
387
110
  const hasRefProp = createExternalInterface && REF_PROP_RE.test(source);
388
- if (!hasStyled && !hasAsProp && !hasRefProp) continue;
111
+ const hasStylex = source.includes("@stylexjs/stylex") || /\.stylex["']/.test(source);
112
+ if (!hasStyled && !hasAsProp && !hasRefProp && !hasStylex) continue;
389
113
  fileContents.set(filePath, source);
390
114
  if (hasStyled && BARE_TEMPLATE_IDENTIFIER_RE.test(source) && hasRegexSelectorCandidate(source)) {
391
115
  const usages = scanFileForSelectorsAst(filePath, source, transformSet, resolver, parser, toRealPath, cachedRead, astCache, createExternalInterface);
@@ -398,6 +122,10 @@ async function runPrepass(options) {
398
122
  STYLED_DEF_RE.lastIndex = 0;
399
123
  for (const m of source.matchAll(STYLED_DEF_RE)) if (m[1]) addToSetMap(styledDefFiles, filePath, m[1]);
400
124
  }
125
+ if (hasStylex) {
126
+ const stylexExportNames = collectStylexExportNames(source);
127
+ if (stylexExportNames.size > 0) stylexComponentFiles.set(filePath, stylexExportNames);
128
+ }
401
129
  if ((createExternalInterface || enableTypeScriptAnalysis) && hasStyled) {
402
130
  STYLED_CALL_RE.lastIndex = 0;
403
131
  for (const m of source.matchAll(STYLED_CALL_RE)) if (m[1]) styledCallUsages.push({
@@ -612,6 +340,7 @@ async function runPrepass(options) {
612
340
  componentsNeedingGlobalSelectorBridge,
613
341
  propUsageByFile,
614
342
  styledDefFiles: createExternalInterface ? styledDefFiles : void 0,
343
+ stylexComponentFiles,
615
344
  globalLeafKeys
616
345
  };
617
346
  {
@@ -1221,14 +950,14 @@ function scanFileForSelectorsAst(filePath, source, transformSet, resolver, parse
1221
950
  return usages;
1222
951
  }
1223
952
  /**
1224
- * Use ripgrep to quickly find files containing "styled-components" or `as[={]`.
953
+ * Use ripgrep to quickly find files containing styled-components, StyleX, or relevant JSX props.
1225
954
  * Returns a Set of absolute file paths, or undefined if rg is not available.
1226
955
  */
1227
956
  function rgPreFilter(files) {
1228
957
  const dirs = deduplicateParentDirs(files);
1229
958
  if (dirs.length === 0) return;
1230
959
  try {
1231
- const pattern = String.raw`(styled-components|\bas[={]|\bref[={])`;
960
+ const pattern = String.raw`(styled-components|@stylexjs/stylex|\.stylex["']|\bas[={]|\bref[={])`;
1232
961
  const globArgs = [
1233
962
  "*.tsx",
1234
963
  "*.ts",
@@ -67,13 +67,13 @@ function looksLikeLength(token) {
67
67
  return /^-?\d*\.?\d+(px|rem|em|vh|vw|vmin|vmax|ch|ex|lh|svh|svw|dvh|dvw|cqw|cqh|%)?$/.test(token);
68
68
  }
69
69
  /**
70
- * Checks if a CSS value appears to be a background image (gradient or url).
70
+ * Checks if a CSS value appears to be a background image.
71
71
  * @example isBackgroundImageValue("linear-gradient(red, blue)") => true
72
72
  * @example isBackgroundImageValue("url(image.png)") => true
73
73
  * @example isBackgroundImageValue("#fff") => false
74
74
  */
75
75
  function isBackgroundImageValue(value) {
76
- return /\b(linear|radial|conic|repeating-linear|repeating-radial|repeating-conic)-gradient\b/.test(value) || /\burl\s*\(/.test(value);
76
+ return /\b(linear|radial|conic|repeating-linear|repeating-radial|repeating-conic)-gradient\b/.test(value) || /\burl\s*\(/.test(value) || /\b(-webkit-)?(image|image-set|cross-fade|element|paint)\s*\(/.test(value);
77
77
  }
78
78
  /**
79
79
  * Returns true when a `background` shorthand value is structurally simple
@@ -37,6 +37,7 @@ function assertAdapterShape(candidate, where, allowAutoExtIf) {
37
37
  const resolveSelector = obj?.resolveSelector;
38
38
  const resolveBaseComponent = obj?.resolveBaseComponent;
39
39
  const externalInterface = obj?.externalInterface;
40
+ const usePhysicalProperties = obj?.usePhysicalProperties;
40
41
  if (!candidate || typeof candidate !== "object") throw new Error([
41
42
  `${where}: expected an adapter object.`,
42
43
  `Received: ${describeValue(candidate)}`,
@@ -111,6 +112,13 @@ function assertAdapterShape(candidate, where, allowAutoExtIf) {
111
112
  `Docs/examples: ${ADAPTER_DOCS_URL}`
112
113
  ].join("\n"));
113
114
  if (!(typeof externalInterface === "function" || allowAutoExtIf && externalInterface === "auto")) throw new Error([`${where}: ${allowAutoExtIf ? "adapter.externalInterface must be a function or \"auto\"." : "adapter.externalInterface must be a function."}`, `Received: externalInterface=${describeValue(externalInterface)}`].join("\n"));
115
+ if (typeof usePhysicalProperties !== "boolean") throw new Error([
116
+ `${where}: adapter.usePhysicalProperties must be explicitly set to true or false.`,
117
+ `Received: usePhysicalProperties=${describeValue(usePhysicalProperties)}`,
118
+ "",
119
+ "Set `usePhysicalProperties: true` to emit physical padding/margin longhands,",
120
+ "or `usePhysicalProperties: false` to emit logical block/inline properties."
121
+ ].join("\n"));
114
122
  const styleMerger = obj?.styleMerger;
115
123
  if (styleMerger !== null && styleMerger !== void 0) {
116
124
  if (typeof styleMerger !== "object") throw new Error([
@@ -273,8 +281,8 @@ const DEFAULT_THEME_HOOK = {
273
281
  * // Emit sx={} JSX attributes instead of {...stylex.props()} spreads (requires StyleX ≥0.18)
274
282
  * useSxProp: false,
275
283
  *
276
- * // Opt out of logical properties — use paddingTop/Right/Bottom/Left instead of Block/Inline
277
- * // usePhysicalProperties: true,
284
+ * // Choose how 2-value padding/margin shorthands are expanded.
285
+ * usePhysicalProperties: true,
278
286
  *
279
287
  * // Optional: customize runtime theme hook import/call used by emitted wrappers
280
288
  * themeHook: {
@@ -799,16 +799,14 @@ interface Adapter {
799
799
  useSxProp: boolean;
800
800
  /**
801
801
  * Use physical CSS properties (`paddingTop`/`paddingRight`/`paddingBottom`/`paddingLeft`)
802
- * instead of logical properties (`paddingBlock`/`paddingInline`) when expanding
803
- * 2-value CSS shorthands like `padding: 4px 8px`.
802
+ * when expanding 2-value CSS shorthands like `padding: 4px 8px`.
804
803
  *
805
- * By default, the codemod uses logical properties which adapt to the writing direction
806
- * (RTL/LTR), matching StyleX's ESLint plugin recommendations. Enable this if your
807
- * codebase needs RTL support or prefer physical properties.
808
- *
809
- * @default false
804
+ * Set this explicitly. Use `true` to preserve CSS shorthand semantics and avoid
805
+ * StyleX property-specificity conflicts during migration. Use `false` only if
806
+ * your codebase intentionally wants logical properties (`paddingBlock`/`paddingInline`)
807
+ * for 2-value shorthand output.
810
808
  */
811
- usePhysicalProperties?: boolean;
809
+ usePhysicalProperties: boolean;
812
810
  /**
813
811
  * Optional override for sx-aware wrapped component detection.
814
812
  *
@@ -879,7 +877,7 @@ interface AdapterInput {
879
877
  styleMerger: Adapter["styleMerger"];
880
878
  themeHook?: Adapter["themeHook"];
881
879
  useSxProp: Adapter["useSxProp"];
882
- usePhysicalProperties?: Adapter["usePhysicalProperties"];
880
+ usePhysicalProperties: Adapter["usePhysicalProperties"];
883
881
  wrappedComponentInterface?: Adapter["wrappedComponentInterface"];
884
882
  markerFile?: Adapter["markerFile"];
885
883
  }
@@ -947,8 +945,8 @@ interface AdapterInput {
947
945
  * // Emit sx={} JSX attributes instead of {...stylex.props()} spreads (requires StyleX ≥0.18)
948
946
  * useSxProp: false,
949
947
  *
950
- * // Opt out of logical properties — use paddingTop/Right/Bottom/Left instead of Block/Inline
951
- * // usePhysicalProperties: true,
948
+ * // Choose how 2-value padding/margin shorthands are expanded.
949
+ * usePhysicalProperties: true,
952
950
  *
953
951
  * // Optional: customize runtime theme hook import/call used by emitted wrappers
954
952
  * themeHook: {
@@ -961,7 +959,7 @@ declare function defineAdapter<T extends AdapterInput>(adapter: T): T;
961
959
  //#endregion
962
960
  //#region src/internal/logger.d.ts
963
961
  type Severity = "info" | "warning" | "error";
964
- 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 resolved an imported helper call as StyleX styles without replacing the RuleSet helper" | "Adapter resolveCall returned undefined for helper call" | "Adapter resolveBaseComponent threw an error" | "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: unsupported or mixed @-rules require manual handling" | "CSS block contains unsupported at-rule (only @media, @container, and @supports are supported; mixed nested at-rules 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: runtime pseudo-alias styles are not supported" | "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: media query interpolation must be a simple imported reference (expressions like `value + 1` are not supported)" | "Conditional `css` block: unsupported selector" | "Directional border helper styles are not supported" | "Multi-slot border interpolation could not be resolved" | "Resolved border helper value could not be expanded to longhand properties" | "Resolved conditional border variant could not be expanded to longhand properties" | "createGlobalStyle is not supported in StyleX. Global styles should be handled separately (e.g., in a CSS file or using CSS reset libraries)" | "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" | "Local helper function returns CSS that cannot be decomposed into individual properties" | "Local helper function computes CSS values that cannot be statically traced to the component prop" | "Unsupported background shorthand: multiple components cannot be mapped to a single StyleX longhand" | "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 .attrs() callback pattern" | "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 CSS property "${string}" cannot be emitted in StyleX` | "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: media query interpolation must be a simple imported reference (expressions like `value + 1` are not supported)" | "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: adjacent sibling combinator" | "Unsupported selector: descendant/child/sibling selector" | "Unsupported selector: conditional css block inside pseudo-element selector" | "Unsupported selector: interpolated pseudo selector" | "Unsupported selector: pseudo-class on pseudo-element selector" | "Unsupported selector: unsupported pseudo-element" | "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: cross-file component selector target has no JSX usage in this file" | "Unsupported selector: unresolved interpolation in cross-file component selector" | "Unsupported selector: unresolved interpolation in descendant component selector" | "Unsupported selector: unresolved interpolation in attribute selector" | "Unsupported selector: unresolved interpolation in element selector" | "Unsupported selector: unresolved interpolation in reverse component selector" | "Unsupported selector: unresolved interpolation in cross-component sibling selector" | "Unsupported selector: grouped reverse selector references different components" | "Unsupported selector: computed media query inside ancestor attribute selector" | "Unsupported selector: computed media query inside cross-component sibling selector" | "Unsupported selector: computed media query inside sibling selector" | "Unsupported selector: computed media query inside :has() component selector" | "Unsupported selector: cross-file :has() component selector not yet supported" | "Unsupported selector: unresolved interpolation in :has() component selector" | "Unsupported selector: unknown component selector" | "Unsupported selector: component selector with child pseudo" | "Unsupported selector: component selector target has no patchable JSX usage under selector parent" | "Unsupported selector: compound pseudo 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" | "Using styled-components components as mixins is not supported; use css`` mixins or strings instead" | "styled(ImportedComponent) wraps a component whose file uses styled-components — convert the base component's file first to avoid CSS cascade conflicts" | "Partial transform would have a StyleX leaf wrap a styled-components base — the extending component was transformed but its base was not, so the leaf's StyleX overrides cannot reliably beat the base's styled-components styles" | "Conditional StyleX default would override an unproven earlier style for the same property" | "Forwarded sx conditional default would override an unproven wrapped component base style" | "Wrapped component does not accept className or sx for generated StyleX styles" | "Wrapped component sx prop targets an inner element for a root style property" | "Wrapped component sx prop rejects logical CSS properties that cannot be preserved losslessly" | "Wrapped component sx prop does not accept generated StyleX property" | "Transient $-prefixed props renamed on exported component — update consumer call sites to use the new prop names" | "Shorthand property has an opaque value that StyleX will expand to longhands — use `directional` in resolveValue to return separate longhand tokens" | "animation shorthand contains a var() with no classifiable fallback — its longhand position cannot be determined statically; bind the variable to a specific longhand (e.g. animation-duration: var(--x)) instead";
962
+ 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 resolved an imported helper call as StyleX styles without replacing the RuleSet helper" | "Adapter resolveCall returned undefined for helper call" | "Adapter resolveBaseComponent threw an error" | "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 resolved imported StyleX value under nested selectors/at-rules but did not provide cssText for property expansion — add cssText to resolveValue 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 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: unsupported or mixed @-rules require manual handling" | "CSS block contains unsupported at-rule (only @media, @container, and @supports are supported; mixed nested at-rules 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: finite ternary before a later overlapping declaration requires manual source-order handling" | "Conditional `css` block: runtime pseudo-alias styles are not supported" | "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: media query interpolation must be a simple imported reference (expressions like `value + 1` are not supported)" | "Conditional `css` block: unsupported selector" | "Directional border helper styles are not supported" | "Multi-slot border interpolation could not be resolved" | "Resolved border helper value could not be expanded to longhand properties" | "Resolved conditional border variant could not be expanded to longhand properties" | "createGlobalStyle is not supported in StyleX. Global styles should be handled separately (e.g., in a CSS file or using CSS reset libraries)" | "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" | "Local helper function returns CSS that cannot be decomposed into individual properties" | "Local helper function computes CSS values that cannot be statically traced to the component prop" | "Unsupported background shorthand: multiple components cannot be mapped to a single StyleX longhand" | "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 .attrs() callback pattern" | "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 CSS property "${string}" cannot be emitted in StyleX` | "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: media query interpolation must be a simple imported reference (expressions like `value + 1` are not supported)" | "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: adjacent sibling combinator" | "Unsupported selector: descendant/child/sibling selector" | "Unsupported selector: conditional css block inside pseudo-element selector" | "Unsupported selector: interpolated pseudo selector" | "Unsupported selector: pseudo-class on pseudo-element selector" | "Unsupported selector: unsupported pseudo-element" | "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: cross-file component selector target has no JSX usage in this file" | "Unsupported selector: unresolved interpolation in cross-file component selector" | "Unsupported selector: unresolved interpolation in descendant component selector" | "Unsupported selector: unresolved interpolation in attribute selector" | "Unsupported selector: unresolved interpolation in element selector" | "Unsupported selector: unresolved interpolation in reverse component selector" | "Unsupported selector: unresolved interpolation in cross-component sibling selector" | "Unsupported selector: grouped reverse selector references different components" | "Unsupported selector: computed media query inside ancestor attribute selector" | "Unsupported selector: computed media query inside cross-component sibling selector" | "Unsupported selector: computed media query inside sibling selector" | "Unsupported selector: computed media query inside :has() component selector" | "Unsupported selector: cross-file :has() component selector not yet supported" | "Unsupported selector: unresolved interpolation in :has() component selector" | "Unsupported selector: unknown component selector" | "Unsupported selector: component selector with child pseudo" | "Unsupported selector: component selector target has no patchable JSX usage under selector parent" | "Unsupported selector: compound pseudo 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" | "Using styled-components components as mixins is not supported; use css`` mixins or strings instead" | "styled(ImportedComponent) wraps a component whose file uses styled-components — convert the base component's file first to avoid CSS cascade conflicts" | "Partial transform would have a StyleX leaf wrap a styled-components base — the extending component was transformed but its base was not, so the leaf's StyleX overrides cannot reliably beat the base's styled-components styles" | "Conditional StyleX default would override an unproven earlier style for the same property" | "Flat StyleX value would erase earlier conditional property states" | "Forwarded sx conditional default would override an unproven wrapped component base style" | "Wrapped component does not accept className or sx for generated StyleX styles" | "Wrapped component sx prop targets an inner element for a root style property" | "Wrapped component sx prop rejects logical CSS properties that cannot be preserved losslessly" | "Wrapped component sx prop does not accept generated StyleX property" | "Transient $-prefixed props renamed on exported component — update consumer call sites to use the new prop names" | "Shorthand property has an opaque value that StyleX will expand to longhands — use `directional` in resolveValue to return separate longhand tokens" | "animation shorthand contains a var() with no classifiable fallback — its longhand position cannot be determined statically; bind the variable to a specific longhand (e.g. animation-duration: var(--x)) instead";
965
963
  interface WarningLog {
966
964
  severity: Severity;
967
965
  type: WarningType;
@@ -1056,6 +1054,8 @@ interface TransformResult {
1056
1054
  bridgeResults?: BridgeComponentResult[];
1057
1055
  /** Transient prop renames for exported components, keyed by export name. */
1058
1056
  transientPropRenames?: TransientPropRenameResult[];
1057
+ /** Local styled component names that were actually converted in this file. */
1058
+ transformedComponentNames?: string[];
1059
1059
  localStylexVarsSidecarFile?: LocalStylexVarsSidecarFile;
1060
1060
  }
1061
1061
  /** Describes a transient prop rename on an exported component for consumer patching. */
@@ -1130,10 +1130,14 @@ interface CrossFileInfo {
1130
1130
  propUsageByComponent?: Map<string, ComponentPropUsageInfo>;
1131
1131
  /** Global map: files that define styled-components → set of local names. Used for cascade conflict detection. */
1132
1132
  styledDefFiles?: Map<string, Set<string>>;
1133
+ /** Global map: files that export components already using StyleX → set of export names. */
1134
+ stylexComponentFiles?: Map<string, Set<string>>;
1133
1135
  /** Global leaf keys from prepass when leaves-only mode is enabled. */
1134
1136
  globalLeafKeys?: Set<string>;
1135
1137
  /** Files successfully converted in the current transform run. Used to avoid bailing on same-run bases. */
1136
1138
  transformedFiles?: Set<string>;
1139
+ /** File → local styled component names successfully converted in the current transform run. */
1140
+ transformedComponents?: Map<string, Set<string>>;
1137
1141
  /** Opt-in TypeScript compiler metadata from the prepass. */
1138
1142
  typeScriptMetadata?: TypeScriptPrepassMetadata;
1139
1143
  }
@@ -1,4 +1,4 @@
1
- import { i as TransformResult, r as TransformOptions, t as BridgeComponentResult } from "./transform-types-CHRHLCj_.mjs";
1
+ import { i as TransformResult, r as TransformOptions, t as BridgeComponentResult } from "./transform-types-BIv4-1OO.mjs";
2
2
  import { API, FileInfo, Options } from "jscodeshift";
3
3
 
4
4
  //#region src/transform.d.ts