@yahoo/uds 3.114.0 → 3.115.0-beta.2

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.
Files changed (102) hide show
  1. package/dist/automated-config/dist/mapTextVariantFixtureToValue.cjs +12 -1
  2. package/dist/automated-config/dist/mapTextVariantFixtureToValue.js +12 -1
  3. package/dist/automated-config/dist/properties.cjs +1 -1
  4. package/dist/automated-config/dist/properties.js +1 -1
  5. package/dist/cli/commands/sync.cjs +1 -3
  6. package/dist/cli/commands/sync.d.cts +1 -1
  7. package/dist/cli/commands/sync.d.ts +1 -1
  8. package/dist/cli/commands/sync.js +1 -3
  9. package/dist/cli/commands/version.cjs +0 -2
  10. package/dist/cli/commands/version.d.cts +1 -1
  11. package/dist/cli/commands/version.d.ts +1 -1
  12. package/dist/cli/commands/version.js +0 -2
  13. package/dist/cli/dist/commands/editor-rules.cjs +1 -1
  14. package/dist/cli/dist/commands/editor-rules.js +1 -1
  15. package/dist/cli/dist/lib/logger.cjs +66 -0
  16. package/dist/cli/dist/lib/logger.js +66 -0
  17. package/dist/cli/runner.cjs +9 -0
  18. package/dist/cli/runner.js +9 -0
  19. package/dist/components/client/Menu/Menu.ItemCheckbox.d.cts +1 -1
  20. package/dist/components/client/Menu/Menu.ItemCheckbox.d.ts +1 -1
  21. package/dist/index.cjs +2 -0
  22. package/dist/index.d.cts +3 -1
  23. package/dist/index.d.ts +3 -1
  24. package/dist/index.js +2 -1
  25. package/dist/styles/styler.d.cts +29 -29
  26. package/dist/styles/styler.d.ts +29 -29
  27. package/dist/styles/variants.cjs +278 -278
  28. package/dist/styles/variants.js +278 -278
  29. package/dist/tailwind/dist/commands/css.cjs +79 -0
  30. package/dist/tailwind/dist/commands/css.helpers.cjs +32 -0
  31. package/dist/tailwind/dist/commands/css.helpers.js +28 -0
  32. package/dist/tailwind/dist/commands/css.js +79 -0
  33. package/dist/tailwind/dist/commands/generateComponentData.cjs +33 -31
  34. package/dist/tailwind/dist/commands/generateComponentData.d.ts +1 -1
  35. package/dist/tailwind/dist/commands/generateComponentData.js +33 -31
  36. package/dist/tailwind/dist/commands/purge.cjs +3 -4
  37. package/dist/tailwind/dist/commands/purge.js +3 -4
  38. package/dist/tailwind/dist/css/generate.cjs +121 -0
  39. package/dist/tailwind/dist/css/generate.d.cts +30 -0
  40. package/dist/tailwind/dist/css/generate.d.ts +31 -0
  41. package/dist/tailwind/dist/css/generate.helpers.cjs +112 -0
  42. package/dist/tailwind/dist/css/generate.helpers.js +100 -0
  43. package/dist/tailwind/dist/css/generate.js +116 -0
  44. package/dist/tailwind/dist/css/nodeUtils.cjs +156 -0
  45. package/dist/tailwind/dist/css/nodeUtils.js +149 -0
  46. package/dist/tailwind/dist/css/postcss.cjs +35 -0
  47. package/dist/tailwind/dist/css/postcss.helpers.cjs +27 -0
  48. package/dist/tailwind/dist/css/postcss.helpers.js +26 -0
  49. package/dist/tailwind/dist/css/postcss.js +35 -0
  50. package/dist/tailwind/dist/css/runner.cjs +279 -0
  51. package/dist/tailwind/dist/css/runner.helpers.cjs +26 -0
  52. package/dist/tailwind/dist/css/runner.helpers.js +23 -0
  53. package/dist/tailwind/dist/css/runner.js +276 -0
  54. package/dist/tailwind/dist/css/theme.cjs +12 -0
  55. package/dist/tailwind/dist/css/theme.d.cts +66 -0
  56. package/dist/tailwind/dist/css/theme.d.ts +66 -0
  57. package/dist/tailwind/dist/css/theme.js +11 -0
  58. package/dist/tailwind/dist/css/utils.cjs +72 -0
  59. package/dist/tailwind/dist/css/utils.js +69 -0
  60. package/dist/tailwind/dist/index.d.cts +1 -0
  61. package/dist/tailwind/dist/index.d.ts +2 -4
  62. package/dist/tailwind/dist/purger/legacy/purgeCSS.cjs +2 -1
  63. package/dist/tailwind/dist/purger/legacy/purgeCSS.js +2 -1
  64. package/dist/tailwind/dist/purger/optimized/ast/expressions.cjs +122 -125
  65. package/dist/tailwind/dist/purger/optimized/ast/expressions.js +122 -125
  66. package/dist/tailwind/dist/purger/optimized/ast/jsx.cjs +1 -8
  67. package/dist/tailwind/dist/purger/optimized/ast/jsx.js +1 -8
  68. package/dist/tailwind/dist/purger/optimized/purge.cjs +9 -8
  69. package/dist/tailwind/dist/purger/optimized/purge.js +9 -8
  70. package/dist/tailwind/dist/purger/optimized/purgeFromCode.cjs +238 -127
  71. package/dist/tailwind/dist/purger/optimized/purgeFromCode.js +238 -127
  72. package/dist/tailwind/dist/purger/optimized/utils/componentAnalyzer.cjs +352 -260
  73. package/dist/tailwind/dist/purger/optimized/utils/componentAnalyzer.js +351 -260
  74. package/dist/tailwind/dist/purger/optimized/utils/files.cjs +4 -3
  75. package/dist/tailwind/dist/purger/optimized/utils/files.js +4 -3
  76. package/dist/tailwind/dist/purger/optimized/utils/safelist.cjs +12 -20
  77. package/dist/tailwind/dist/purger/optimized/utils/safelist.js +12 -20
  78. package/dist/tailwind/dist/tailwind/components/getResponsiveTextStyles.cjs +1 -1
  79. package/dist/tailwind/dist/tailwind/components/getResponsiveTextStyles.js +1 -1
  80. package/dist/tailwind/dist/tailwind/plugins/breakpoints.cjs +1 -1
  81. package/dist/tailwind/dist/tailwind/plugins/breakpoints.js +1 -1
  82. package/dist/tailwind/dist/tailwind/plugins/typography.cjs +41 -13
  83. package/dist/tailwind/dist/tailwind/plugins/typography.js +41 -13
  84. package/dist/tailwind/dist/tailwind/utils/composeTailwindPlugins.cjs +4 -2
  85. package/dist/tailwind/dist/tailwind/utils/composeTailwindPlugins.d.cts +10 -1
  86. package/dist/tailwind/dist/tailwind/utils/composeTailwindPlugins.d.ts +10 -1
  87. package/dist/tailwind/dist/tailwind/utils/composeTailwindPlugins.js +4 -2
  88. package/dist/tailwind/dist/utils/optimizeCSS.cjs +405 -0
  89. package/dist/tailwind/dist/utils/optimizeCSS.js +403 -0
  90. package/dist/tailwind/dist/utils/postcssPreserveVars.cjs +67 -0
  91. package/dist/tailwind/dist/utils/postcssPreserveVars.js +65 -0
  92. package/dist/tailwind/dist/utils/tsMorph.cjs +1 -1
  93. package/dist/uds/generated/componentData.cjs +1218 -1182
  94. package/dist/uds/generated/componentData.js +1218 -1182
  95. package/dist/uds/package.cjs +10 -4
  96. package/dist/uds/package.js +10 -4
  97. package/generated/componentData.json +2683 -0
  98. package/generated/tailwindPurge.ts +4591 -0
  99. package/package.json +7 -4
  100. package/dist/tailwind/dist/commands/generatePurgeCSSData.d.ts +0 -3
  101. package/dist/tailwind/dist/commands/purge.d.ts +0 -4
  102. package/dist/tailwind/dist/purger/legacy/purgeCSS.d.ts +0 -2
@@ -1,8 +1,8 @@
1
1
  /*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
2
2
  const require_runtime = require('../../../../_virtual/_rolldown/runtime.cjs');
3
3
  const require_purgeFromCode = require('./purgeFromCode.cjs');
4
- const require_files = require('./utils/files.cjs');
5
4
  const require_safelist = require('./utils/safelist.cjs');
5
+ const require_files = require('./utils/files.cjs');
6
6
  let node_path = require("node:path");
7
7
  node_path = require_runtime.__toESM(node_path);
8
8
  let node_fs = require("node:fs");
@@ -14,16 +14,16 @@ const warnedLocations = /* @__PURE__ */ new Set();
14
14
  /**
15
15
  * Clear warned locations (call at start of new purge run)
16
16
  */
17
- function clearWarnings() {
17
+ const clearWarnings = () => {
18
18
  warnedLocations.clear();
19
- }
19
+ };
20
20
  /**
21
21
  * Main purge function - optimized version
22
22
  *
23
23
  * Uses purgeFromCodeOptimized internally to ensure consistent behavior
24
24
  * between CLI and playground.
25
25
  */
26
- async function purgeOptimized(options) {
26
+ const purgeOptimized = async (options) => {
27
27
  const { entry = "/src/", output = "dist/safelist.ts", colorModes = ["dark"], variants, autoVariants, componentData } = options;
28
28
  const startTime = performance.now();
29
29
  clearWarnings();
@@ -39,19 +39,20 @@ async function purgeOptimized(options) {
39
39
  spreadsTraced: 0,
40
40
  expressionsResolved: 0
41
41
  };
42
- for (const filePath of files) {
43
- const result = await require_purgeFromCode.purgeFromCodeOptimized(node_fs.default.readFileSync(filePath, "utf-8"), {
42
+ (await Promise.all(files.map(async (filePath) => {
43
+ return require_purgeFromCode.purgeFromCodeOptimized(node_fs.default.readFileSync(filePath, "utf-8"), {
44
44
  colorModes,
45
45
  variants,
46
46
  autoVariants,
47
47
  componentData
48
48
  });
49
+ }))).forEach((result) => {
49
50
  allClasses.push(...result.safelist);
50
51
  result.imports.forEach((imp) => allImports.add(imp));
51
52
  result.components.forEach((comp) => allComponents.add(comp));
52
53
  stats.spreadsTraced += result.stats.spreadsTraced;
53
54
  stats.expressionsResolved += result.stats.expressionsResolved;
54
- }
55
+ });
55
56
  allClasses.push(...require_safelist.getThemeAndScaleClasses(colorModes));
56
57
  const finalSafelist = require_safelist.deduplicateSafelist(allClasses).sort();
57
58
  await require_safelist.saveSafelistToFile(finalSafelist, node_path.default.join(workspaceDir, output));
@@ -63,7 +64,7 @@ async function purgeOptimized(options) {
63
64
  components: [...allComponents],
64
65
  stats
65
66
  };
66
- }
67
+ };
67
68
 
68
69
  //#endregion
69
70
  exports.purgeOptimized = purgeOptimized;
@@ -1,7 +1,7 @@
1
1
  /*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
2
2
  import { purgeFromCodeOptimized } from "./purgeFromCode.js";
3
- import { scanForFiles } from "./utils/files.js";
4
3
  import { deduplicateSafelist, getThemeAndScaleClasses, saveSafelistToFile } from "./utils/safelist.js";
4
+ import { scanForFiles } from "./utils/files.js";
5
5
  import path from "node:path";
6
6
  import fs from "node:fs";
7
7
 
@@ -11,16 +11,16 @@ const warnedLocations = /* @__PURE__ */ new Set();
11
11
  /**
12
12
  * Clear warned locations (call at start of new purge run)
13
13
  */
14
- function clearWarnings() {
14
+ const clearWarnings = () => {
15
15
  warnedLocations.clear();
16
- }
16
+ };
17
17
  /**
18
18
  * Main purge function - optimized version
19
19
  *
20
20
  * Uses purgeFromCodeOptimized internally to ensure consistent behavior
21
21
  * between CLI and playground.
22
22
  */
23
- async function purgeOptimized(options) {
23
+ const purgeOptimized = async (options) => {
24
24
  const { entry = "/src/", output = "dist/safelist.ts", colorModes = ["dark"], variants, autoVariants, componentData } = options;
25
25
  const startTime = performance.now();
26
26
  clearWarnings();
@@ -36,19 +36,20 @@ async function purgeOptimized(options) {
36
36
  spreadsTraced: 0,
37
37
  expressionsResolved: 0
38
38
  };
39
- for (const filePath of files) {
40
- const result = await purgeFromCodeOptimized(fs.readFileSync(filePath, "utf-8"), {
39
+ (await Promise.all(files.map(async (filePath) => {
40
+ return purgeFromCodeOptimized(fs.readFileSync(filePath, "utf-8"), {
41
41
  colorModes,
42
42
  variants,
43
43
  autoVariants,
44
44
  componentData
45
45
  });
46
+ }))).forEach((result) => {
46
47
  allClasses.push(...result.safelist);
47
48
  result.imports.forEach((imp) => allImports.add(imp));
48
49
  result.components.forEach((comp) => allComponents.add(comp));
49
50
  stats.spreadsTraced += result.stats.spreadsTraced;
50
51
  stats.expressionsResolved += result.stats.expressionsResolved;
51
- }
52
+ });
52
53
  allClasses.push(...getThemeAndScaleClasses(colorModes));
53
54
  const finalSafelist = deduplicateSafelist(allClasses).sort();
54
55
  await saveSafelistToFile(finalSafelist, path.join(workspaceDir, output));
@@ -60,7 +61,7 @@ async function purgeOptimized(options) {
60
61
  components: [...allComponents],
61
62
  stats
62
63
  };
63
- }
64
+ };
64
65
 
65
66
  //#endregion
66
67
  export { purgeOptimized };
@@ -9,20 +9,20 @@ let ts_morph = require("ts-morph");
9
9
  /**
10
10
  * Get component info with all its dependencies (using pre-generated data)
11
11
  */
12
- function getComponentWithDeps(componentName) {
12
+ const getComponentWithDeps = (componentName) => {
13
13
  const visited = /* @__PURE__ */ new Set();
14
14
  const result = [];
15
- function collect(name) {
15
+ const collect = (name) => {
16
16
  if (visited.has(name)) return;
17
17
  visited.add(name);
18
- const info = componentCache[name];
18
+ const info = resolveComponentInfo(name);
19
19
  if (!info) return;
20
20
  result.push(info);
21
- for (const depName of info.internalComponents) collect(depName);
22
- }
21
+ info.internalComponents.forEach((depName) => collect(depName));
22
+ };
23
23
  collect(componentName);
24
24
  return result;
25
- }
25
+ };
26
26
  /**
27
27
  * Auto-variants lookup (loaded at module init)
28
28
  */
@@ -31,10 +31,96 @@ let autoVariantsCache = null;
31
31
  * Pre-generated component data (loaded at module init)
32
32
  */
33
33
  let componentCache = null;
34
- async function purgeFromCodeOptimized(code, options) {
34
+ /**
35
+ * Map of normalized component name -> actual component cache key
36
+ * Useful when internal components are imported without namespace separators
37
+ * (e.g., MenuItemBase vs Menu.ItemBase).
38
+ */
39
+ let componentNameLookup = null;
40
+ const buildComponentNameLookup = (data) => {
41
+ const lookup = {};
42
+ Object.keys(data).forEach((key) => {
43
+ const normalized = normalizeComponentName(key);
44
+ if (!lookup[normalized]) lookup[normalized] = key;
45
+ });
46
+ return lookup;
47
+ };
48
+ const resolveComponentInfo = (name) => {
49
+ if (componentCache && componentCache[name]) return componentCache[name];
50
+ const normalized = normalizeComponentName(name);
51
+ const mappedName = componentNameLookup?.[normalized];
52
+ if (mappedName && componentCache) return componentCache[mappedName];
53
+ };
54
+ const getModuleSpecifierValue = (importDecl) => {
55
+ return importDecl.getModuleSpecifierValue() ?? importDecl.getModuleSpecifier().getText().replace(/^['"]|['"]$/g, "");
56
+ };
57
+ const isUdsComponentModule = (moduleSpecifier) => {
58
+ const cleaned = moduleSpecifier.replace(/^['"]|['"]$/g, "");
59
+ return cleaned === "@yahoo/uds" || cleaned.startsWith("@yahoo/uds/");
60
+ };
61
+ /**
62
+ * Normalize component name to match autoVariants keys (lower camel, no punctuation).
63
+ */
64
+ const normalizeComponentName = (name) => {
65
+ const cleaned = name.replace(/\W/g, "");
66
+ return cleaned.charAt(0).toLowerCase() + cleaned.slice(1);
67
+ };
68
+ /**
69
+ * Fallback: infer prop -> variant key mapping from autoVariants when the
70
+ * generated component data misses it (e.g., helpers like buildAvatarRootClasses).
71
+ */
72
+ const getAutoVariantKeysForProp = (componentName, propName) => {
73
+ if (!autoVariantsCache) return [];
74
+ const segments = componentName.match(/[A-Z][a-z0-9]*/g) ?? [];
75
+ const candidates = new Set([normalizeComponentName(componentName)]);
76
+ if (segments.length > 0) Array.from({ length: segments.length }, (_, index) => index + 1).forEach((i) => {
77
+ const partial = segments.slice(0, i).join("");
78
+ candidates.add(normalizeComponentName(partial));
79
+ });
80
+ const propLower = propName.toLowerCase();
81
+ return Object.keys(autoVariantsCache).filter((key) => {
82
+ const keyLower = key.toLowerCase();
83
+ return Array.from(candidates).some((candidate) => keyLower.startsWith(candidate) && keyLower.includes(propLower));
84
+ });
85
+ };
86
+ const getVariantKeysForProp = (componentInfo, propName) => {
87
+ const keys = new Set(componentInfo.propToVariantKeys?.[propName] ?? []);
88
+ getAutoVariantKeysForProp(componentInfo.name, propName).forEach((inferred) => keys.add(inferred));
89
+ return [...keys];
90
+ };
91
+ const extractClassNamePrimitives = (sourceFile) => {
92
+ const classes = [];
93
+ sourceFile.getDescendantsOfKind(ts_morph.SyntaxKind.JsxAttribute).forEach((attr) => {
94
+ if (attr.getNameNode().getText() !== "className") return;
95
+ const initializer = attr.getInitializer();
96
+ if (!initializer) return;
97
+ const values = [];
98
+ if (ts_morph.Node.isStringLiteral(initializer)) values.push(initializer.getLiteralText());
99
+ else if (ts_morph.Node.isJsxExpression(initializer)) {
100
+ const expr = initializer.getExpression();
101
+ if (expr) values.push(...require_expressions.extractStringLiterals(expr));
102
+ }
103
+ values.forEach((raw) => {
104
+ classes.push(...raw.split(/\s+/).filter(Boolean));
105
+ });
106
+ });
107
+ sourceFile.getDescendantsOfKind(ts_morph.SyntaxKind.PropertyAssignment).forEach((prop) => {
108
+ if (prop.getName() !== "className") return;
109
+ const initializer = prop.getInitializer();
110
+ if (!initializer) return;
111
+ require_expressions.extractStringLiterals(initializer).forEach((raw) => {
112
+ classes.push(...raw.split(/\s+/).filter(Boolean));
113
+ });
114
+ });
115
+ return classes;
116
+ };
117
+ const purgeFromCodeOptimized = async (code, options) => {
35
118
  const { variants, autoVariants, componentData } = options;
36
119
  if (!autoVariantsCache) autoVariantsCache = autoVariants;
37
- if (!componentCache) componentCache = componentData;
120
+ if (!componentCache) {
121
+ componentCache = componentData;
122
+ componentNameLookup = buildComponentNameLookup(componentData);
123
+ }
38
124
  const startTime = performance.now();
39
125
  const sourceFile = new ts_morph.Project({ useInMemoryFileSystem: true }).createSourceFile("input.tsx", code);
40
126
  const stats = {
@@ -45,105 +131,126 @@ async function purgeFromCodeOptimized(code, options) {
45
131
  expressionsResolved: 0
46
132
  };
47
133
  const imports = [];
48
- for (const importDecl of sourceFile.getImportDeclarations()) if (importDecl.getModuleSpecifier().getText().includes("@yahoo/uds")) for (const namedImport of importDecl.getNamedImports()) imports.push(namedImport.getName());
134
+ sourceFile.getImportDeclarations().forEach((importDecl) => {
135
+ if (isUdsComponentModule(getModuleSpecifierValue(importDecl))) importDecl.getNamedImports().forEach((namedImport) => imports.push(namedImport.getName()));
136
+ });
49
137
  const componentProps = /* @__PURE__ */ new Map();
138
+ const referencedComponents = /* @__PURE__ */ new Set();
50
139
  const getStylesProps = extractGetStylesCalls(sourceFile, stats, variants);
51
- for (const imp of imports) {
52
- const references = findComponentReferences(sourceFile, imp);
53
- const propsMap = componentProps.get(imp) ?? /* @__PURE__ */ new Map();
54
- for (const reference of references) {
55
- const props = extractPropsFromReference(reference, stats, sourceFile);
56
- for (const [propName, values] of props) if (values.length > 0) {
57
- const existing = propsMap.get(propName) ?? /* @__PURE__ */ new Set();
58
- for (const val of values) existing.add(val);
59
- propsMap.set(propName, existing);
60
- }
61
- }
62
- componentProps.set(imp, propsMap);
63
- }
140
+ imports.forEach((imp) => {
141
+ findComponentReferences(sourceFile, imp).forEach((reference) => {
142
+ const componentName = reference.getTagNameNode().getText() || imp;
143
+ referencedComponents.add(componentName);
144
+ const propsMap = componentProps.get(componentName) ?? /* @__PURE__ */ new Map();
145
+ extractPropsFromReference(reference, stats, sourceFile).forEach(([propName, values]) => {
146
+ if (values.length > 0) {
147
+ const existing = propsMap.get(propName) ?? /* @__PURE__ */ new Set();
148
+ values.forEach((val) => existing.add(val));
149
+ propsMap.set(propName, existing);
150
+ }
151
+ });
152
+ componentProps.set(componentName, propsMap);
153
+ });
154
+ if (!componentProps.has(imp)) componentProps.set(imp, /* @__PURE__ */ new Map());
155
+ });
64
156
  const allComponents = [];
65
157
  const seenComponents = /* @__PURE__ */ new Set();
66
- for (const componentName of imports) {
67
- const componentsWithDeps = getComponentWithDeps(componentName);
68
- for (const comp of componentsWithDeps) if (!seenComponents.has(comp.name)) {
69
- seenComponents.add(comp.name);
70
- allComponents.push(comp);
71
- }
72
- }
158
+ new Set([...imports, ...referencedComponents]).forEach((componentName) => {
159
+ getComponentWithDeps(componentName).forEach((comp) => {
160
+ if (!seenComponents.has(comp.name)) {
161
+ seenComponents.add(comp.name);
162
+ allComponents.push(comp);
163
+ }
164
+ });
165
+ });
73
166
  const safelist = [];
74
- for (const [propName, values] of getStylesProps) {
167
+ [...getStylesProps.entries()].forEach(([propName, values]) => {
75
168
  const variantGroup = variants[propName];
76
- if (variantGroup) for (const value of values) {
169
+ if (variantGroup) values.forEach((value) => {
77
170
  const cls = variantGroup[value];
78
171
  if (cls) safelist.push(cls.replaceAll("\\", ""));
79
- }
80
- }
81
- for (const componentInfo of allComponents) {
172
+ });
173
+ });
174
+ allComponents.forEach((componentInfo) => {
82
175
  const userProps = componentProps.get(componentInfo.name) ?? /* @__PURE__ */ new Map();
83
- for (const [propName, propValue] of Object.entries(componentInfo.defaultProps)) {
84
- if (userProps.has(propName)) continue;
176
+ Object.entries(componentInfo.defaultProps).forEach(([propName, propValue]) => {
177
+ if (userProps.has(propName)) return;
85
178
  const variantGroup = variants[propName];
86
179
  if (variantGroup) {
87
180
  const cls = variantGroup[propValue];
88
181
  if (cls) safelist.push(cls.replaceAll("\\", ""));
89
182
  }
90
- const variantKeys = componentInfo.propToVariantKeys?.[propName];
91
- if (variantKeys) for (const variantKey of variantKeys) {
92
- const mappedVariantGroup = variants[variantKey];
183
+ const variantKeys = getVariantKeysForProp(componentInfo, propName);
184
+ if (variantKeys.length > 0) variantKeys.forEach((variantKey) => {
185
+ const mappedVariantGroup = variants[variantKey] ?? autoVariantsCache[variantKey];
93
186
  if (mappedVariantGroup) {
94
187
  const cls = mappedVariantGroup[propValue];
95
188
  if (cls) safelist.push(cls.replaceAll("\\", ""));
96
189
  }
97
- }
98
- }
99
- for (const [propName, propValue] of Object.entries(componentInfo.getStylesLiterals)) {
190
+ });
191
+ });
192
+ Object.entries(componentInfo.getStylesLiterals).forEach(([propName, propValue]) => {
100
193
  const variantGroup = variants[propName.replace(/:\d+$/, "")];
101
194
  if (variantGroup) {
102
195
  const cls = variantGroup[propValue];
103
196
  if (cls) safelist.push(cls.replaceAll("\\", ""));
104
197
  }
105
- }
106
- if (componentInfo.cxLiterals) for (const cls of componentInfo.cxLiterals) safelist.push(cls);
198
+ });
199
+ if (componentInfo.cxLiterals) componentInfo.cxLiterals.forEach((cls) => safelist.push(cls));
107
200
  if (componentInfo.propToVariantKeys) {
108
201
  const componentDefaults = options.variantDefaults?.[componentInfo.name] ?? {};
109
- for (const [propName, variantKeys] of Object.entries(componentInfo.propToVariantKeys)) {
110
- if (userProps.has(propName)) continue;
202
+ Object.keys(componentInfo.propToVariantKeys).forEach((propName) => {
203
+ if (userProps.has(propName)) return;
111
204
  const defaultValue = componentDefaults[propName];
112
- for (const variantKey of variantKeys) {
205
+ getVariantKeysForProp(componentInfo, propName).forEach((variantKey) => {
113
206
  const variantGroup = autoVariantsCache[variantKey];
114
207
  if (variantGroup) {
115
208
  if (variantGroup["default"]) safelist.push(variantGroup["default"]);
116
209
  if (defaultValue && variantGroup[defaultValue]) safelist.push(variantGroup[defaultValue]);
117
210
  }
118
- }
119
- }
211
+ });
212
+ });
120
213
  }
121
- for (const [_internalCompName, propsRecord] of Object.entries(componentInfo.internalComponentProps)) for (const [propName, propValues] of Object.entries(propsRecord)) {
122
- const variantGroup = variants[propName];
123
- if (variantGroup) for (const propValue of propValues) {
124
- const cls = variantGroup[propValue];
125
- if (cls) safelist.push(cls.replaceAll("\\", ""));
214
+ Object.entries(componentInfo.internalComponentProps).forEach(([_internalCompName, propsRecord]) => {
215
+ Object.entries(propsRecord).forEach(([propName, propValues]) => {
216
+ if (propName === "className") {
217
+ propValues.forEach((propValue) => {
218
+ propValue.split(/\s+/).filter(Boolean).forEach((cls) => safelist.push(cls));
219
+ });
220
+ return;
221
+ }
222
+ const variantGroup = variants[propName];
223
+ if (variantGroup) propValues.forEach((propValue) => {
224
+ const cls = variantGroup[propValue];
225
+ if (cls) safelist.push(cls.replaceAll("\\", ""));
226
+ });
227
+ });
228
+ });
229
+ [...userProps.entries()].forEach(([propName, usedValues]) => {
230
+ if (propName === "className") {
231
+ [...usedValues].forEach((value) => {
232
+ value.split(/\s+/).filter(Boolean).forEach((cls) => safelist.push(cls));
233
+ });
234
+ return;
126
235
  }
127
- }
128
- for (const [propName, usedValues] of userProps) {
129
236
  const variantGroup = variants[propName];
130
- if (variantGroup) for (const value of usedValues) {
237
+ if (variantGroup) [...usedValues].forEach((value) => {
131
238
  const cls = variantGroup[value];
132
239
  if (cls) safelist.push(cls.replaceAll("\\", ""));
133
- }
134
- const componentsToCheck = [componentInfo, ...getComponentWithDeps(componentInfo.name).slice(1)];
135
- for (const comp of componentsToCheck) {
136
- const variantKeys = comp.propToVariantKeys?.[propName];
137
- if (variantKeys) for (const variantKey of variantKeys) {
240
+ });
241
+ [componentInfo, ...getComponentWithDeps(componentInfo.name).slice(1)].forEach((comp) => {
242
+ const variantKeys = getVariantKeysForProp(comp, propName);
243
+ if (variantKeys.length > 0) variantKeys.forEach((variantKey) => {
138
244
  const mappedVariantGroup = variants[variantKey];
139
- if (mappedVariantGroup) for (const value of usedValues) {
245
+ if (mappedVariantGroup) [...usedValues].forEach((value) => {
140
246
  const cls = mappedVariantGroup[value];
141
247
  if (cls) safelist.push(cls.replaceAll("\\", ""));
142
- }
143
- }
144
- }
145
- }
146
- }
248
+ });
249
+ });
250
+ });
251
+ });
252
+ });
253
+ if (options.includeAllClassNamePrimitives) safelist.push(...extractClassNamePrimitives(sourceFile));
147
254
  const finalSafelist = [...new Set(safelist)];
148
255
  stats.timeMs = Math.round(performance.now() - startTime);
149
256
  stats.classesGenerated = finalSafelist.length;
@@ -153,28 +260,29 @@ async function purgeFromCodeOptimized(code, options) {
153
260
  components: [...seenComponents],
154
261
  stats
155
262
  };
156
- }
263
+ };
157
264
  /**
158
265
  * Find JSX references for a component in the source file
159
266
  */
160
- function findComponentReferences(sourceFile, componentName) {
267
+ const findComponentReferences = (sourceFile, componentName) => {
161
268
  const references = [];
162
- for (const importDecl of sourceFile.getImportDeclarations()) {
163
- if (!importDecl.getModuleSpecifier().getText().includes("@yahoo/uds")) continue;
164
- for (const namedImport of importDecl.getNamedImports()) if (namedImport.getName() === componentName) {
165
- const identifier = namedImport.getFirstDescendantByKindOrThrow(ts_morph.ts.SyntaxKind.Identifier);
166
- references.push(...require_jsx.findJsxReferences(identifier));
167
- }
168
- }
269
+ sourceFile.getImportDeclarations().forEach((importDecl) => {
270
+ if (!isUdsComponentModule(getModuleSpecifierValue(importDecl))) return;
271
+ importDecl.getNamedImports().forEach((namedImport) => {
272
+ if (namedImport.getName() === componentName) {
273
+ const identifier = namedImport.getFirstDescendantByKindOrThrow(ts_morph.ts.SyntaxKind.Identifier);
274
+ references.push(...require_jsx.findJsxReferences(identifier));
275
+ }
276
+ });
277
+ });
169
278
  return references;
170
- }
279
+ };
171
280
  /**
172
281
  * Extract props from a JSX reference.
173
282
  */
174
- function extractPropsFromReference(reference, stats, sourceFile) {
283
+ const extractPropsFromReference = (reference, stats, sourceFile) => {
175
284
  const props = [];
176
- const attributes = reference.getAttributes();
177
- for (const attr of attributes) {
285
+ reference.getAttributes().forEach((attr) => {
178
286
  if (attr.asKind(ts_morph.SyntaxKind.JsxAttribute)) {
179
287
  const jsxAttr = attr.asKindOrThrow(ts_morph.SyntaxKind.JsxAttribute);
180
288
  const propName = jsxAttr.getNameNode().getText();
@@ -195,16 +303,17 @@ function extractPropsFromReference(reference, stats, sourceFile) {
195
303
  }
196
304
  if (attr.asKind(ts_morph.SyntaxKind.JsxSpreadAttribute)) {
197
305
  stats.spreadsTraced++;
198
- const resolvedSpreadProps = traceSpreadInFile(attr.asKindOrThrow(ts_morph.SyntaxKind.JsxSpreadAttribute).getExpression().getText(), sourceFile);
199
- for (const [propName, values] of resolvedSpreadProps) if (values.length > 0) props.push([propName, values]);
306
+ traceSpreadInFile(attr.asKindOrThrow(ts_morph.SyntaxKind.JsxSpreadAttribute).getExpression().getText(), sourceFile).forEach(([propName, values]) => {
307
+ if (values.length > 0) props.push([propName, values]);
308
+ });
200
309
  }
201
- }
310
+ });
202
311
  return props;
203
- }
312
+ };
204
313
  /**
205
314
  * Trace spread props to their source within the same file.
206
315
  */
207
- function traceSpreadInFile(spreadName, sourceFile) {
316
+ const traceSpreadInFile = (spreadName, sourceFile) => {
208
317
  const props = [];
209
318
  const varDecl = sourceFile.getVariableDeclaration(spreadName);
210
319
  if (!varDecl) return props;
@@ -212,62 +321,64 @@ function traceSpreadInFile(spreadName, sourceFile) {
212
321
  if (!initializer) return props;
213
322
  const objLiteral = initializer.asKind(ts_morph.SyntaxKind.ObjectLiteralExpression) ? initializer.asKindOrThrow(ts_morph.SyntaxKind.ObjectLiteralExpression) : initializer.asKind(ts_morph.SyntaxKind.AsExpression) ? initializer.asKindOrThrow(ts_morph.SyntaxKind.AsExpression).getExpression().asKind(ts_morph.SyntaxKind.ObjectLiteralExpression) ? initializer.asKindOrThrow(ts_morph.SyntaxKind.AsExpression).getExpression().asKindOrThrow(ts_morph.SyntaxKind.ObjectLiteralExpression) : null : null;
214
323
  if (!objLiteral) return props;
215
- for (const prop of objLiteral.getProperties()) if (prop.asKind(ts_morph.SyntaxKind.PropertyAssignment)) {
216
- const propAssign = prop.asKindOrThrow(ts_morph.SyntaxKind.PropertyAssignment);
217
- const propName = propAssign.getName();
218
- const propInit = propAssign.getInitializer();
219
- if (propInit) {
220
- const values = require_expressions.extractStringLiterals(propInit);
221
- if (values.length > 0) props.push([propName, values]);
324
+ objLiteral.getProperties().forEach((prop) => {
325
+ if (prop.asKind(ts_morph.SyntaxKind.PropertyAssignment)) {
326
+ const propAssign = prop.asKindOrThrow(ts_morph.SyntaxKind.PropertyAssignment);
327
+ const propName = propAssign.getName();
328
+ const propInit = propAssign.getInitializer();
329
+ if (propInit) {
330
+ const values = require_expressions.extractStringLiterals(propInit);
331
+ if (values.length > 0) props.push([propName, values]);
332
+ }
222
333
  }
223
- }
334
+ });
224
335
  return props;
225
- }
336
+ };
226
337
  /**
227
338
  * Extract props from getStyles() calls in user code.
228
339
  * This handles cases like:
229
340
  * const styles = getStyles({ backgroundColor: 'brand', spacing: '4' });
230
341
  */
231
- function extractGetStylesCalls(sourceFile, stats, variants) {
342
+ const extractGetStylesCalls = (sourceFile, stats, variants) => {
232
343
  const props = /* @__PURE__ */ new Map();
233
344
  const VALID_VARIANTS = new Set(Object.keys(variants));
234
- const callExpressions = sourceFile.getDescendantsOfKind(ts_morph.SyntaxKind.CallExpression);
235
- for (const call of callExpressions) {
236
- if (call.getExpression().getText() !== "getStyles") continue;
345
+ sourceFile.getDescendantsOfKind(ts_morph.SyntaxKind.CallExpression).forEach((call) => {
346
+ if (call.getExpression().getText() !== "getStyles") return;
237
347
  const args = call.getArguments();
238
- if (args.length === 0) continue;
348
+ if (args.length === 0) return;
239
349
  const firstArg = args[0];
240
- if (!firstArg.asKind(ts_morph.SyntaxKind.ObjectLiteralExpression)) continue;
241
- const objLiteral = firstArg.asKindOrThrow(ts_morph.SyntaxKind.ObjectLiteralExpression);
242
- for (const prop of objLiteral.getProperties()) if (prop.asKind(ts_morph.SyntaxKind.PropertyAssignment)) {
243
- const propAssign = prop.asKindOrThrow(ts_morph.SyntaxKind.PropertyAssignment);
244
- const propName = propAssign.getName();
245
- const propInit = propAssign.getInitializer();
246
- if (propInit && VALID_VARIANTS.has(propName)) {
247
- const values = require_expressions.extractStringLiterals(propInit);
248
- if (values.length > 0) {
249
- const existing = props.get(propName) ?? /* @__PURE__ */ new Set();
250
- for (const v of values) existing.add(v);
251
- props.set(propName, existing);
252
- stats.expressionsResolved++;
350
+ if (!firstArg.asKind(ts_morph.SyntaxKind.ObjectLiteralExpression)) return;
351
+ firstArg.asKindOrThrow(ts_morph.SyntaxKind.ObjectLiteralExpression).getProperties().forEach((prop) => {
352
+ if (prop.asKind(ts_morph.SyntaxKind.PropertyAssignment)) {
353
+ const propAssign = prop.asKindOrThrow(ts_morph.SyntaxKind.PropertyAssignment);
354
+ const propName = propAssign.getName();
355
+ const propInit = propAssign.getInitializer();
356
+ if (propInit && VALID_VARIANTS.has(propName)) {
357
+ const values = require_expressions.extractStringLiterals(propInit);
358
+ if (values.length > 0) {
359
+ const existing = props.get(propName) ?? /* @__PURE__ */ new Set();
360
+ values.forEach((v) => existing.add(v));
361
+ props.set(propName, existing);
362
+ stats.expressionsResolved++;
363
+ }
253
364
  }
254
- }
255
- } else if (prop.asKind(ts_morph.SyntaxKind.ShorthandPropertyAssignment)) {
256
- const shorthand = prop.asKindOrThrow(ts_morph.SyntaxKind.ShorthandPropertyAssignment);
257
- const propName = shorthand.getName();
258
- if (VALID_VARIANTS.has(propName)) {
259
- const values = require_expressions.extractStringLiterals(shorthand.getNameNode());
260
- if (values.length > 0) {
261
- const existing = props.get(propName) ?? /* @__PURE__ */ new Set();
262
- for (const v of values) existing.add(v);
263
- props.set(propName, existing);
264
- stats.expressionsResolved++;
365
+ } else if (prop.asKind(ts_morph.SyntaxKind.ShorthandPropertyAssignment)) {
366
+ const shorthand = prop.asKindOrThrow(ts_morph.SyntaxKind.ShorthandPropertyAssignment);
367
+ const propName = shorthand.getName();
368
+ if (VALID_VARIANTS.has(propName)) {
369
+ const values = require_expressions.extractStringLiterals(shorthand.getNameNode());
370
+ if (values.length > 0) {
371
+ const existing = props.get(propName) ?? /* @__PURE__ */ new Set();
372
+ values.forEach((v) => existing.add(v));
373
+ props.set(propName, existing);
374
+ stats.expressionsResolved++;
375
+ }
265
376
  }
266
377
  }
267
- }
268
- }
378
+ });
379
+ });
269
380
  return props;
270
- }
381
+ };
271
382
 
272
383
  //#endregion
273
384
  exports.purgeFromCodeOptimized = purgeFromCodeOptimized;