@yahoo/uds 3.113.0 → 3.114.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 (104) 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/automated-config/dist/utils/getConfigVariantProperties.d.cts +2 -2
  6. package/dist/automated-config/dist/utils/getConfigVariantProperties.d.ts +2 -2
  7. package/dist/cli/commands/sync.cjs +1 -3
  8. package/dist/cli/commands/sync.d.cts +1 -1
  9. package/dist/cli/commands/sync.d.ts +1 -1
  10. package/dist/cli/commands/sync.js +1 -3
  11. package/dist/cli/commands/version.cjs +0 -2
  12. package/dist/cli/commands/version.d.cts +1 -1
  13. package/dist/cli/commands/version.d.ts +1 -1
  14. package/dist/cli/commands/version.js +0 -2
  15. package/dist/cli/dist/cli.cjs +1 -1
  16. package/dist/cli/dist/cli.js +1 -1
  17. package/dist/cli/dist/commands/editor-rules.cjs +2 -2
  18. package/dist/cli/dist/commands/editor-rules.js +2 -2
  19. package/dist/cli/dist/lib/logger.cjs +66 -0
  20. package/dist/cli/dist/lib/logger.js +66 -0
  21. package/dist/cli/dist/utils/rules/config.cjs +1 -1
  22. package/dist/cli/dist/utils/rules/config.js +1 -1
  23. package/dist/cli/runner.cjs +11 -2
  24. package/dist/cli/runner.js +11 -2
  25. package/dist/components/client/Menu/Menu.ItemCheckbox.d.cts +1 -1
  26. package/dist/components/client/Menu/Menu.ItemCheckbox.d.ts +1 -1
  27. package/dist/index.cjs +2 -0
  28. package/dist/index.d.cts +3 -1
  29. package/dist/index.d.ts +3 -1
  30. package/dist/index.js +2 -1
  31. package/dist/styles/styler.d.cts +41 -41
  32. package/dist/styles/styler.d.ts +41 -41
  33. package/dist/styles/variants.cjs +278 -278
  34. package/dist/styles/variants.js +278 -278
  35. package/dist/tailwind/dist/commands/css.cjs +79 -0
  36. package/dist/tailwind/dist/commands/css.d.ts +3 -0
  37. package/dist/tailwind/dist/commands/css.helpers.cjs +32 -0
  38. package/dist/tailwind/dist/commands/css.helpers.js +28 -0
  39. package/dist/tailwind/dist/commands/css.js +79 -0
  40. package/dist/tailwind/dist/commands/generateComponentData.cjs +33 -31
  41. package/dist/tailwind/dist/commands/generateComponentData.d.ts +1 -1
  42. package/dist/tailwind/dist/commands/generateComponentData.js +33 -31
  43. package/dist/tailwind/dist/commands/generatePurgeCSSData.d.ts +1 -1
  44. package/dist/tailwind/dist/commands/purge.cjs +3 -4
  45. package/dist/tailwind/dist/commands/purge.d.ts +1 -1
  46. package/dist/tailwind/dist/commands/purge.js +3 -4
  47. package/dist/tailwind/dist/css/generate.cjs +120 -0
  48. package/dist/tailwind/dist/css/generate.d.cts +30 -0
  49. package/dist/tailwind/dist/css/generate.d.ts +31 -0
  50. package/dist/tailwind/dist/css/generate.helpers.cjs +112 -0
  51. package/dist/tailwind/dist/css/generate.helpers.js +100 -0
  52. package/dist/tailwind/dist/css/generate.js +115 -0
  53. package/dist/tailwind/dist/css/postcss.cjs +35 -0
  54. package/dist/tailwind/dist/css/postcss.helpers.cjs +27 -0
  55. package/dist/tailwind/dist/css/postcss.helpers.js +26 -0
  56. package/dist/tailwind/dist/css/postcss.js +35 -0
  57. package/dist/tailwind/dist/css/runner.cjs +278 -0
  58. package/dist/tailwind/dist/css/runner.helpers.cjs +26 -0
  59. package/dist/tailwind/dist/css/runner.helpers.js +23 -0
  60. package/dist/tailwind/dist/css/runner.js +275 -0
  61. package/dist/tailwind/dist/css/theme.cjs +12 -0
  62. package/dist/tailwind/dist/css/theme.d.cts +66 -0
  63. package/dist/tailwind/dist/css/theme.d.ts +66 -0
  64. package/dist/tailwind/dist/css/theme.js +11 -0
  65. package/dist/tailwind/dist/css/utils.cjs +234 -0
  66. package/dist/tailwind/dist/css/utils.js +223 -0
  67. package/dist/tailwind/dist/index.d.cts +1 -0
  68. package/dist/tailwind/dist/index.d.ts +5 -3
  69. package/dist/tailwind/dist/purger/legacy/purgeCSS.cjs +4 -3
  70. package/dist/tailwind/dist/purger/legacy/purgeCSS.js +4 -3
  71. package/dist/tailwind/dist/purger/optimized/ast/expressions.cjs +122 -125
  72. package/dist/tailwind/dist/purger/optimized/ast/expressions.js +122 -125
  73. package/dist/tailwind/dist/purger/optimized/ast/jsx.cjs +1 -8
  74. package/dist/tailwind/dist/purger/optimized/ast/jsx.js +1 -8
  75. package/dist/tailwind/dist/purger/optimized/purge.cjs +11 -10
  76. package/dist/tailwind/dist/purger/optimized/purge.js +10 -9
  77. package/dist/tailwind/dist/purger/optimized/purgeFromCode.cjs +232 -127
  78. package/dist/tailwind/dist/purger/optimized/purgeFromCode.js +232 -127
  79. package/dist/tailwind/dist/purger/optimized/utils/componentAnalyzer.cjs +330 -262
  80. package/dist/tailwind/dist/purger/optimized/utils/componentAnalyzer.js +329 -262
  81. package/dist/tailwind/dist/purger/optimized/utils/files.cjs +4 -3
  82. package/dist/tailwind/dist/purger/optimized/utils/files.js +4 -3
  83. package/dist/tailwind/dist/purger/optimized/utils/safelist.cjs +13 -21
  84. package/dist/tailwind/dist/purger/optimized/utils/safelist.js +13 -21
  85. package/dist/tailwind/dist/tailwind/plugins/typography.cjs +41 -13
  86. package/dist/tailwind/dist/tailwind/plugins/typography.js +41 -13
  87. package/dist/tailwind/dist/tailwind/utils/composeTailwindPlugins.cjs +4 -2
  88. package/dist/tailwind/dist/tailwind/utils/composeTailwindPlugins.d.cts +10 -1
  89. package/dist/tailwind/dist/tailwind/utils/composeTailwindPlugins.d.ts +10 -1
  90. package/dist/tailwind/dist/tailwind/utils/composeTailwindPlugins.js +4 -2
  91. package/dist/tailwind/dist/tailwind/utils/getFontStyles.d.cts +1 -1
  92. package/dist/tailwind/dist/tailwind/utils/getFontStyles.d.ts +1 -1
  93. package/dist/tailwind/dist/utils/optimizeCSS.cjs +405 -0
  94. package/dist/tailwind/dist/utils/optimizeCSS.js +403 -0
  95. package/dist/tailwind/dist/utils/postcssPreserveVars.cjs +67 -0
  96. package/dist/tailwind/dist/utils/postcssPreserveVars.js +65 -0
  97. package/dist/tailwind/dist/utils/tsMorph.cjs +1 -1
  98. package/dist/uds/generated/componentData.cjs +943 -928
  99. package/dist/uds/generated/componentData.js +943 -928
  100. package/dist/uds/package.cjs +10 -4
  101. package/dist/uds/package.js +10 -4
  102. package/generated/componentData.json +2397 -0
  103. package/generated/tailwindPurge.ts +4560 -0
  104. package/package.json +7 -4
@@ -1,12 +1,12 @@
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');
6
- let node_path = require("node:path");
7
- node_path = require_runtime.__toESM(node_path);
5
+ const require_files = require('./utils/files.cjs');
8
6
  let node_fs = require("node:fs");
9
7
  node_fs = require_runtime.__toESM(node_fs);
8
+ let node_path = require("node:path");
9
+ node_path = require_runtime.__toESM(node_path);
10
10
 
11
11
  //#region ../tailwind/dist/purger/optimized/purge.js
12
12
  /*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
@@ -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,9 +1,9 @@
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";
5
- import path from "node:path";
4
+ import { scanForFiles } from "./utils/files.js";
6
5
  import fs from "node:fs";
6
+ import path from "node:path";
7
7
 
8
8
  //#region ../tailwind/dist/purger/optimized/purge.js
9
9
  /*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
@@ -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,120 @@ 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
+ const variantGroup = variants[propName];
217
+ if (variantGroup) propValues.forEach((propValue) => {
218
+ const cls = variantGroup[propValue];
219
+ if (cls) safelist.push(cls.replaceAll("\\", ""));
220
+ });
221
+ });
222
+ });
223
+ [...userProps.entries()].forEach(([propName, usedValues]) => {
224
+ if (propName === "className") {
225
+ [...usedValues].forEach((value) => {
226
+ value.split(/\s+/).filter(Boolean).forEach((cls) => safelist.push(cls));
227
+ });
228
+ return;
126
229
  }
127
- }
128
- for (const [propName, usedValues] of userProps) {
129
230
  const variantGroup = variants[propName];
130
- if (variantGroup) for (const value of usedValues) {
231
+ if (variantGroup) [...usedValues].forEach((value) => {
131
232
  const cls = variantGroup[value];
132
233
  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) {
234
+ });
235
+ [componentInfo, ...getComponentWithDeps(componentInfo.name).slice(1)].forEach((comp) => {
236
+ const variantKeys = getVariantKeysForProp(comp, propName);
237
+ if (variantKeys.length > 0) variantKeys.forEach((variantKey) => {
138
238
  const mappedVariantGroup = variants[variantKey];
139
- if (mappedVariantGroup) for (const value of usedValues) {
239
+ if (mappedVariantGroup) [...usedValues].forEach((value) => {
140
240
  const cls = mappedVariantGroup[value];
141
241
  if (cls) safelist.push(cls.replaceAll("\\", ""));
142
- }
143
- }
144
- }
145
- }
146
- }
242
+ });
243
+ });
244
+ });
245
+ });
246
+ });
247
+ if (options.includeAllClassNamePrimitives) safelist.push(...extractClassNamePrimitives(sourceFile));
147
248
  const finalSafelist = [...new Set(safelist)];
148
249
  stats.timeMs = Math.round(performance.now() - startTime);
149
250
  stats.classesGenerated = finalSafelist.length;
@@ -153,28 +254,29 @@ async function purgeFromCodeOptimized(code, options) {
153
254
  components: [...seenComponents],
154
255
  stats
155
256
  };
156
- }
257
+ };
157
258
  /**
158
259
  * Find JSX references for a component in the source file
159
260
  */
160
- function findComponentReferences(sourceFile, componentName) {
261
+ const findComponentReferences = (sourceFile, componentName) => {
161
262
  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
- }
263
+ sourceFile.getImportDeclarations().forEach((importDecl) => {
264
+ if (!isUdsComponentModule(getModuleSpecifierValue(importDecl))) return;
265
+ importDecl.getNamedImports().forEach((namedImport) => {
266
+ if (namedImport.getName() === componentName) {
267
+ const identifier = namedImport.getFirstDescendantByKindOrThrow(ts_morph.ts.SyntaxKind.Identifier);
268
+ references.push(...require_jsx.findJsxReferences(identifier));
269
+ }
270
+ });
271
+ });
169
272
  return references;
170
- }
273
+ };
171
274
  /**
172
275
  * Extract props from a JSX reference.
173
276
  */
174
- function extractPropsFromReference(reference, stats, sourceFile) {
277
+ const extractPropsFromReference = (reference, stats, sourceFile) => {
175
278
  const props = [];
176
- const attributes = reference.getAttributes();
177
- for (const attr of attributes) {
279
+ reference.getAttributes().forEach((attr) => {
178
280
  if (attr.asKind(ts_morph.SyntaxKind.JsxAttribute)) {
179
281
  const jsxAttr = attr.asKindOrThrow(ts_morph.SyntaxKind.JsxAttribute);
180
282
  const propName = jsxAttr.getNameNode().getText();
@@ -195,16 +297,17 @@ function extractPropsFromReference(reference, stats, sourceFile) {
195
297
  }
196
298
  if (attr.asKind(ts_morph.SyntaxKind.JsxSpreadAttribute)) {
197
299
  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]);
300
+ traceSpreadInFile(attr.asKindOrThrow(ts_morph.SyntaxKind.JsxSpreadAttribute).getExpression().getText(), sourceFile).forEach(([propName, values]) => {
301
+ if (values.length > 0) props.push([propName, values]);
302
+ });
200
303
  }
201
- }
304
+ });
202
305
  return props;
203
- }
306
+ };
204
307
  /**
205
308
  * Trace spread props to their source within the same file.
206
309
  */
207
- function traceSpreadInFile(spreadName, sourceFile) {
310
+ const traceSpreadInFile = (spreadName, sourceFile) => {
208
311
  const props = [];
209
312
  const varDecl = sourceFile.getVariableDeclaration(spreadName);
210
313
  if (!varDecl) return props;
@@ -212,62 +315,64 @@ function traceSpreadInFile(spreadName, sourceFile) {
212
315
  if (!initializer) return props;
213
316
  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
317
  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]);
318
+ objLiteral.getProperties().forEach((prop) => {
319
+ if (prop.asKind(ts_morph.SyntaxKind.PropertyAssignment)) {
320
+ const propAssign = prop.asKindOrThrow(ts_morph.SyntaxKind.PropertyAssignment);
321
+ const propName = propAssign.getName();
322
+ const propInit = propAssign.getInitializer();
323
+ if (propInit) {
324
+ const values = require_expressions.extractStringLiterals(propInit);
325
+ if (values.length > 0) props.push([propName, values]);
326
+ }
222
327
  }
223
- }
328
+ });
224
329
  return props;
225
- }
330
+ };
226
331
  /**
227
332
  * Extract props from getStyles() calls in user code.
228
333
  * This handles cases like:
229
334
  * const styles = getStyles({ backgroundColor: 'brand', spacing: '4' });
230
335
  */
231
- function extractGetStylesCalls(sourceFile, stats, variants) {
336
+ const extractGetStylesCalls = (sourceFile, stats, variants) => {
232
337
  const props = /* @__PURE__ */ new Map();
233
338
  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;
339
+ sourceFile.getDescendantsOfKind(ts_morph.SyntaxKind.CallExpression).forEach((call) => {
340
+ if (call.getExpression().getText() !== "getStyles") return;
237
341
  const args = call.getArguments();
238
- if (args.length === 0) continue;
342
+ if (args.length === 0) return;
239
343
  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++;
344
+ if (!firstArg.asKind(ts_morph.SyntaxKind.ObjectLiteralExpression)) return;
345
+ firstArg.asKindOrThrow(ts_morph.SyntaxKind.ObjectLiteralExpression).getProperties().forEach((prop) => {
346
+ if (prop.asKind(ts_morph.SyntaxKind.PropertyAssignment)) {
347
+ const propAssign = prop.asKindOrThrow(ts_morph.SyntaxKind.PropertyAssignment);
348
+ const propName = propAssign.getName();
349
+ const propInit = propAssign.getInitializer();
350
+ if (propInit && VALID_VARIANTS.has(propName)) {
351
+ const values = require_expressions.extractStringLiterals(propInit);
352
+ if (values.length > 0) {
353
+ const existing = props.get(propName) ?? /* @__PURE__ */ new Set();
354
+ values.forEach((v) => existing.add(v));
355
+ props.set(propName, existing);
356
+ stats.expressionsResolved++;
357
+ }
253
358
  }
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++;
359
+ } else if (prop.asKind(ts_morph.SyntaxKind.ShorthandPropertyAssignment)) {
360
+ const shorthand = prop.asKindOrThrow(ts_morph.SyntaxKind.ShorthandPropertyAssignment);
361
+ const propName = shorthand.getName();
362
+ if (VALID_VARIANTS.has(propName)) {
363
+ const values = require_expressions.extractStringLiterals(shorthand.getNameNode());
364
+ if (values.length > 0) {
365
+ const existing = props.get(propName) ?? /* @__PURE__ */ new Set();
366
+ values.forEach((v) => existing.add(v));
367
+ props.set(propName, existing);
368
+ stats.expressionsResolved++;
369
+ }
265
370
  }
266
371
  }
267
- }
268
- }
372
+ });
373
+ });
269
374
  return props;
270
- }
375
+ };
271
376
 
272
377
  //#endregion
273
378
  exports.purgeFromCodeOptimized = purgeFromCodeOptimized;