@yahoo/uds 3.104.0 → 3.105.0

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 (78) hide show
  1. package/dist/automated-config/dist/generated/autoVariants.cjs +57 -0
  2. package/dist/automated-config/dist/generated/autoVariants.d.cts +57 -57
  3. package/dist/automated-config/dist/generated/autoVariants.d.ts +57 -57
  4. package/dist/automated-config/dist/generated/autoVariants.js +57 -0
  5. package/dist/automated-config/dist/utils/generateDefaultClassName.cjs +18 -0
  6. package/dist/automated-config/dist/utils/generateDefaultClassName.d.cts +14 -0
  7. package/dist/automated-config/dist/utils/generateDefaultClassName.d.ts +14 -0
  8. package/dist/automated-config/dist/utils/generateDefaultClassName.js +17 -0
  9. package/dist/automated-config/dist/utils/index.cjs +3 -6
  10. package/dist/automated-config/dist/utils/index.d.cts +2 -2
  11. package/dist/automated-config/dist/utils/index.d.ts +2 -2
  12. package/dist/automated-config/dist/utils/index.js +3 -5
  13. package/dist/cli/runner.cjs +21 -5
  14. package/dist/cli/runner.js +21 -5
  15. package/dist/components/client/Button.cjs +9 -9
  16. package/dist/components/client/Button.js +2 -2
  17. package/dist/components/client/IconButton.cjs +8 -8
  18. package/dist/components/client/IconButton.js +2 -2
  19. package/dist/components/client/SpringMotionConfig.cjs +4 -4
  20. package/dist/components/client/SpringMotionConfig.js +5 -5
  21. package/dist/components/client/buttonConstants.cjs +10 -0
  22. package/dist/components/client/buttonConstants.d.cts +9 -0
  23. package/dist/components/client/buttonConstants.d.ts +9 -0
  24. package/dist/components/client/buttonConstants.js +8 -0
  25. package/dist/index.cjs +2 -1
  26. package/dist/index.d.cts +2 -1
  27. package/dist/index.d.ts +2 -1
  28. package/dist/index.js +2 -1
  29. package/dist/motion-tokens/dist/index.cjs +11 -0
  30. package/dist/motion-tokens/dist/index.d.cts +5 -1
  31. package/dist/motion-tokens/dist/index.d.ts +5 -1
  32. package/dist/motion-tokens/dist/index.js +11 -1
  33. package/dist/styles/styler.d.cts +67 -67
  34. package/dist/styles/styler.d.ts +67 -67
  35. package/dist/styles/variants.d.cts +57 -0
  36. package/dist/styles/variants.d.ts +57 -0
  37. package/dist/tailwind/dist/commands/generateComponentData.cjs +65 -0
  38. package/dist/tailwind/dist/commands/generateComponentData.d.ts +3 -0
  39. package/dist/tailwind/dist/commands/generateComponentData.js +64 -0
  40. package/dist/tailwind/dist/commands/generatePurgeCSSData.cjs +1 -1
  41. package/dist/tailwind/dist/commands/generatePurgeCSSData.js +1 -1
  42. package/dist/tailwind/dist/commands/purge.cjs +41 -11
  43. package/dist/tailwind/dist/commands/purge.d.ts +2 -1
  44. package/dist/tailwind/dist/commands/purge.js +41 -11
  45. package/dist/tailwind/dist/index.d.ts +1 -0
  46. package/dist/tailwind/dist/{utils → purger/legacy}/purgeCSS.cjs +7 -7
  47. package/dist/tailwind/dist/{utils → purger/legacy}/purgeCSS.js +6 -6
  48. package/dist/tailwind/dist/purger/optimized/ast/expressions.cjs +193 -0
  49. package/dist/tailwind/dist/purger/optimized/ast/expressions.js +192 -0
  50. package/dist/tailwind/dist/purger/optimized/ast/jsx.cjs +20 -0
  51. package/dist/tailwind/dist/purger/optimized/ast/jsx.js +19 -0
  52. package/dist/tailwind/dist/purger/optimized/purge.cjs +69 -0
  53. package/dist/tailwind/dist/purger/optimized/purge.js +66 -0
  54. package/dist/tailwind/dist/purger/optimized/purgeFromCode.cjs +273 -0
  55. package/dist/tailwind/dist/purger/optimized/purgeFromCode.js +272 -0
  56. package/dist/tailwind/dist/purger/optimized/utils/componentAnalyzer.cjs +408 -0
  57. package/dist/tailwind/dist/purger/optimized/utils/componentAnalyzer.js +405 -0
  58. package/dist/tailwind/dist/purger/optimized/utils/files.cjs +27 -0
  59. package/dist/tailwind/dist/purger/optimized/utils/files.js +24 -0
  60. package/dist/tailwind/dist/purger/optimized/utils/safelist.cjs +64 -0
  61. package/dist/tailwind/dist/purger/optimized/utils/safelist.js +60 -0
  62. package/dist/tailwind/dist/tailwind/utils/getColorModeStyles.cjs +1 -0
  63. package/dist/tailwind/dist/tailwind/utils/getColorModeStyles.js +1 -0
  64. package/dist/tailwind/dist/utils/tsMorph.cjs +1 -1
  65. package/dist/tokens/automation/index.cjs +2 -1
  66. package/dist/tokens/automation/index.d.cts +2 -1
  67. package/dist/tokens/automation/index.d.ts +2 -1
  68. package/dist/tokens/automation/index.js +2 -1
  69. package/dist/tokens/index.cjs +2 -1
  70. package/dist/tokens/index.d.cts +2 -1
  71. package/dist/tokens/index.d.ts +2 -1
  72. package/dist/tokens/index.js +2 -1
  73. package/dist/uds/generated/componentData.cjs +2110 -0
  74. package/dist/uds/generated/componentData.js +1720 -0
  75. package/dist/uds/generated/tailwindPurge.cjs +24 -24
  76. package/dist/uds/generated/tailwindPurge.js +24 -24
  77. package/package.json +1 -1
  78. /package/dist/tailwind/dist/{utils → purger/legacy}/purgeCSS.d.ts +0 -0
@@ -0,0 +1,405 @@
1
+ /*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
2
+ import { SPRING_MOTION_DEFAULTS } from "../../../../../motion-tokens/dist/index.js";
3
+ import path from "node:path";
4
+ import { Node, SyntaxKind } from "ts-morph";
5
+
6
+ //#region ../tailwind/dist/purger/optimized/utils/componentAnalyzer.js
7
+ /*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
8
+ /**
9
+ * Known UDS component names (populated by scanning)
10
+ */
11
+ let knownComponents = null;
12
+ /**
13
+ * Map of component name -> file path
14
+ */
15
+ let componentPaths = null;
16
+ /**
17
+ * Scan src/components to build a map of all component files
18
+ */
19
+ async function scanComponentFiles(componentsDir) {
20
+ if (componentPaths) return componentPaths;
21
+ componentPaths = /* @__PURE__ */ new Map();
22
+ knownComponents = /* @__PURE__ */ new Set();
23
+ const glob = new Bun.Glob("**/*.tsx");
24
+ for await (const file of glob.scan({
25
+ cwd: componentsDir,
26
+ absolute: true
27
+ })) {
28
+ if (file.includes(".test.") || file.endsWith("index.tsx")) continue;
29
+ const fileName = path.basename(file, ".tsx");
30
+ if (/^[A-Z]/.test(fileName)) {
31
+ componentPaths.set(fileName, file);
32
+ knownComponents.add(fileName);
33
+ }
34
+ }
35
+ return componentPaths;
36
+ }
37
+ /**
38
+ * Analyze an object literal for variant key mappings.
39
+ * Handles:
40
+ * - Direct property assignments: { fontSize: variant } -> variant maps to fontSize
41
+ * - Nullish coalescing: { fontSize: fontSize ?? variant } -> variant maps to fontSize
42
+ * - Conditional spreads: ...(condition ? { props } : {}) -> recursively analyze props
43
+ */
44
+ function analyzeObjectForVariantMappings(objLiteral, styleProps, getStylesLiterals, propToVariantKeys, sourceFile) {
45
+ for (const prop of objLiteral.getProperties()) if (Node.isPropertyAssignment(prop)) {
46
+ const variantKey = prop.getName();
47
+ if (variantKey && !styleProps.includes(variantKey)) styleProps.push(variantKey);
48
+ const initializer = prop.getInitializer();
49
+ if (initializer && Node.isStringLiteral(initializer)) getStylesLiterals.set(variantKey, initializer.getLiteralValue());
50
+ if (initializer && Node.isIdentifier(initializer)) {
51
+ const propName = initializer.getText();
52
+ const existing = propToVariantKeys.get(propName) ?? [];
53
+ if (!existing.includes(variantKey)) {
54
+ existing.push(variantKey);
55
+ propToVariantKeys.set(propName, existing);
56
+ }
57
+ }
58
+ if (initializer && Node.isBinaryExpression(initializer)) {
59
+ const operatorToken = initializer.getOperatorToken();
60
+ if (operatorToken.getKind() === SyntaxKind.QuestionQuestionToken || operatorToken.getKind() === SyntaxKind.BarBarToken) {
61
+ const rightSide = initializer.getRight();
62
+ if (Node.isIdentifier(rightSide)) {
63
+ const fallbackPropName = rightSide.getText();
64
+ const existing = propToVariantKeys.get(fallbackPropName) ?? [];
65
+ if (!existing.includes(variantKey)) {
66
+ existing.push(variantKey);
67
+ propToVariantKeys.set(fallbackPropName, existing);
68
+ }
69
+ }
70
+ }
71
+ }
72
+ } else if (Node.isSpreadAssignment(prop)) {
73
+ const spreadExpr = prop.getExpression();
74
+ if (Node.isParenthesizedExpression(spreadExpr)) {
75
+ const inner = spreadExpr.getExpression();
76
+ if (Node.isConditionalExpression(inner)) {
77
+ const whenTrue = inner.getWhenTrue();
78
+ if (Node.isObjectLiteralExpression(whenTrue)) analyzeObjectForVariantMappings(whenTrue, styleProps, getStylesLiterals, propToVariantKeys, sourceFile);
79
+ }
80
+ }
81
+ if (Node.isIdentifier(spreadExpr)) {
82
+ const varName = spreadExpr.getText();
83
+ const varDecl = sourceFile.getDescendantsOfKind(SyntaxKind.VariableDeclaration).find((v) => v.getName() === varName);
84
+ if (varDecl) {
85
+ const varInit = varDecl.getInitializer();
86
+ if (varInit && Node.isObjectLiteralExpression(varInit)) analyzeObjectForVariantMappings(varInit, styleProps, getStylesLiterals, propToVariantKeys, sourceFile);
87
+ }
88
+ }
89
+ }
90
+ }
91
+ /**
92
+ * Analyzes a UDS component file to extract:
93
+ * 1. Default prop values (e.g., display = 'flex')
94
+ * 2. Props passed to getStyles()
95
+ * 3. Internal UDS component usage
96
+ */
97
+ function analyzeComponent(project, componentPath) {
98
+ const sourceFile = project.getSourceFile(componentPath);
99
+ if (!sourceFile) return null;
100
+ const componentName = path.basename(componentPath, ".tsx");
101
+ const defaultProps = /* @__PURE__ */ new Map();
102
+ const componentPropNames = /* @__PURE__ */ new Set();
103
+ const styleProps = [];
104
+ const getStylesLiterals = /* @__PURE__ */ new Map();
105
+ const cxLiterals = [];
106
+ const internalComponents = [];
107
+ const internalComponentProps = /* @__PURE__ */ new Map();
108
+ const propToVariantKeys = /* @__PURE__ */ new Map();
109
+ const functions = [...sourceFile.getFunctions(), ...sourceFile.getVariableDeclarations().filter((v) => {
110
+ const init = v.getInitializer();
111
+ return init && (Node.isArrowFunction(init) || Node.isCallExpression(init));
112
+ })];
113
+ for (const fn of functions) {
114
+ if (Node.isVariableDeclaration(fn)) {
115
+ const init = fn.getInitializer();
116
+ if (!init) continue;
117
+ if (Node.isCallExpression(init)) {
118
+ const args = init.getArguments();
119
+ for (const arg of args) if (Node.isFunctionExpression(arg) || Node.isArrowFunction(arg)) {
120
+ extractDefaultsFromFunction(arg, defaultProps);
121
+ extractAllPropNames(arg, componentPropNames);
122
+ }
123
+ }
124
+ if (Node.isArrowFunction(init)) {
125
+ extractDefaultsFromFunction(init, defaultProps);
126
+ extractAllPropNames(init, componentPropNames);
127
+ }
128
+ }
129
+ if (Node.isFunctionDeclaration(fn)) {
130
+ extractDefaultsFromFunction(fn, defaultProps);
131
+ extractAllPropNames(fn, componentPropNames);
132
+ }
133
+ }
134
+ const getStylesCalls = sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression).filter((call) => call.getExpression().getText() === "getStyles");
135
+ for (const call of getStylesCalls) {
136
+ const args = call.getArguments();
137
+ if (args.length > 0 && Node.isObjectLiteralExpression(args[0])) {
138
+ const objLiteral = args[0];
139
+ for (const prop of objLiteral.getProperties()) if (Node.isPropertyAssignment(prop)) {
140
+ const variantKey = prop.getName();
141
+ if (variantKey && !styleProps.includes(variantKey)) styleProps.push(variantKey);
142
+ const initializer = prop.getInitializer();
143
+ if (initializer && Node.isStringLiteral(initializer)) getStylesLiterals.set(variantKey, initializer.getLiteralValue());
144
+ if (initializer && Node.isIdentifier(initializer)) {
145
+ const propName = initializer.getText();
146
+ const existing = propToVariantKeys.get(propName) ?? [];
147
+ if (!existing.includes(variantKey)) {
148
+ existing.push(variantKey);
149
+ propToVariantKeys.set(propName, existing);
150
+ }
151
+ }
152
+ if (initializer && Node.isBinaryExpression(initializer)) {
153
+ const operatorToken = initializer.getOperatorToken();
154
+ if (operatorToken.getKind() === SyntaxKind.QuestionQuestionToken || operatorToken.getKind() === SyntaxKind.BarBarToken) {
155
+ const rightSide = initializer.getRight();
156
+ if (Node.isIdentifier(rightSide)) {
157
+ const fallbackPropName = rightSide.getText();
158
+ const existing = propToVariantKeys.get(fallbackPropName) ?? [];
159
+ if (!existing.includes(variantKey)) {
160
+ existing.push(variantKey);
161
+ propToVariantKeys.set(fallbackPropName, existing);
162
+ }
163
+ }
164
+ }
165
+ }
166
+ if (initializer && Node.isConditionalExpression(initializer)) {
167
+ const whenTrue = initializer.getWhenTrue();
168
+ const whenFalse = initializer.getWhenFalse();
169
+ const extractLiterals = (node) => {
170
+ const literals = [];
171
+ if (Node.isStringLiteral(node)) literals.push(node.getLiteralValue());
172
+ else if (Node.isConditionalExpression(node)) {
173
+ literals.push(...extractLiterals(node.getWhenTrue()));
174
+ literals.push(...extractLiterals(node.getWhenFalse()));
175
+ }
176
+ return literals;
177
+ };
178
+ [...extractLiterals(whenTrue), ...extractLiterals(whenFalse)].forEach((value, index) => {
179
+ const literalKey = index === 0 ? variantKey : `${variantKey}:${index}`;
180
+ getStylesLiterals.set(literalKey, value);
181
+ });
182
+ }
183
+ } else if (Node.isShorthandPropertyAssignment(prop)) {
184
+ const propName = prop.getName();
185
+ if (propName && !styleProps.includes(propName)) styleProps.push(propName);
186
+ } else if (Node.isSpreadAssignment(prop)) {
187
+ const spreadExpr = prop.getExpression();
188
+ if (Node.isIdentifier(spreadExpr)) {
189
+ const varName = spreadExpr.getText();
190
+ const varDecl = sourceFile.getDescendantsOfKind(SyntaxKind.VariableDeclaration).find((v) => v.getName() === varName);
191
+ if (varDecl) {
192
+ const varInit = varDecl.getInitializer();
193
+ if (varInit && Node.isObjectLiteralExpression(varInit)) analyzeObjectForVariantMappings(varInit, styleProps, getStylesLiterals, propToVariantKeys, sourceFile);
194
+ }
195
+ }
196
+ }
197
+ }
198
+ }
199
+ const cxCalls = sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression).filter((call) => call.getExpression().getText() === "cx");
200
+ for (const call of cxCalls) for (const arg of call.getArguments()) extractCxStringLiterals(arg, cxLiterals);
201
+ extractInternalComponents(sourceFile, internalComponents, internalComponentProps, propToVariantKeys, componentPropNames);
202
+ return {
203
+ name: componentName,
204
+ filePath: componentPath,
205
+ defaultProps,
206
+ styleProps,
207
+ getStylesLiterals,
208
+ cxLiterals,
209
+ internalComponents,
210
+ internalComponentProps,
211
+ propToVariantKeys,
212
+ motionVarPrefixes: extractMotionVarPrefixes(sourceFile)
213
+ };
214
+ }
215
+ /**
216
+ * Extract UDS components used internally in the file and their prop values.
217
+ * Also detects prop aliasing (e.g., columnGap={gap} means gap -> columnGap).
218
+ */
219
+ function extractInternalComponents(sourceFile, internalComponents, internalComponentProps, propToVariantKeys, componentProps) {
220
+ for (const importDecl of sourceFile.getImportDeclarations()) {
221
+ const moduleSpec = importDecl.getModuleSpecifierValue();
222
+ if (moduleSpec.startsWith("@yahoo/uds") || moduleSpec.startsWith("../") || moduleSpec.startsWith("./")) {
223
+ if (moduleSpec.includes("/components/") || moduleSpec === "@yahoo/uds") for (const namedImport of importDecl.getNamedImports()) {
224
+ const name = namedImport.getName();
225
+ if (/^[A-Z]/.test(name) && !internalComponents.includes(name)) internalComponents.push(name);
226
+ }
227
+ }
228
+ }
229
+ const jsxElements = [...sourceFile.getDescendantsOfKind(SyntaxKind.JsxSelfClosingElement), ...sourceFile.getDescendantsOfKind(SyntaxKind.JsxOpeningElement)];
230
+ for (const element of jsxElements) {
231
+ const tagName = element.getTagNameNode().getText();
232
+ if (!/^[A-Z]/.test(tagName)) continue;
233
+ if (!internalComponents.includes(tagName)) internalComponents.push(tagName);
234
+ const attrs = element.getAttributes();
235
+ for (const attr of attrs) if (Node.isJsxAttribute(attr)) {
236
+ const propName = attr.getNameNode().getText();
237
+ const initializer = attr.getInitializer();
238
+ let values = [];
239
+ if (initializer) {
240
+ if (Node.isStringLiteral(initializer)) values = [initializer.getLiteralValue()];
241
+ else if (Node.isJsxExpression(initializer)) {
242
+ const expr = initializer.getExpression();
243
+ if (expr && Node.isStringLiteral(expr)) values = [expr.getLiteralValue()];
244
+ else if (expr && Node.isIdentifier(expr)) {
245
+ const identifierName = expr.getText();
246
+ if (componentProps.has(identifierName) && identifierName !== propName) {
247
+ const existing = propToVariantKeys.get(identifierName) ?? [];
248
+ if (!existing.includes(propName)) {
249
+ existing.push(propName);
250
+ propToVariantKeys.set(identifierName, existing);
251
+ }
252
+ }
253
+ }
254
+ }
255
+ }
256
+ if (values.length > 0) {
257
+ let componentPropsMap = internalComponentProps.get(tagName);
258
+ if (!componentPropsMap) {
259
+ componentPropsMap = /* @__PURE__ */ new Map();
260
+ internalComponentProps.set(tagName, componentPropsMap);
261
+ }
262
+ const existingValues = componentPropsMap.get(propName) ?? [];
263
+ for (const v of values) if (!existingValues.includes(v)) existingValues.push(v);
264
+ componentPropsMap.set(propName, existingValues);
265
+ }
266
+ }
267
+ }
268
+ }
269
+ /**
270
+ * Extract default prop values from a function's parameter destructuring
271
+ */
272
+ function extractDefaultsFromFunction(fn, defaults) {
273
+ let params = [];
274
+ if (Node.isFunctionDeclaration(fn) || Node.isFunctionExpression(fn)) params = fn.getParameters();
275
+ else if (Node.isArrowFunction(fn)) params = fn.getParameters();
276
+ for (const param of params) {
277
+ if (!Node.isParameterDeclaration(param)) continue;
278
+ const nameNode = param.getNameNode();
279
+ if (!nameNode || !Node.isObjectBindingPattern(nameNode)) continue;
280
+ for (const element of nameNode.getElements()) {
281
+ const propName = element.getPropertyNameNode()?.getText() || element.getName();
282
+ const initializer = element.getInitializer();
283
+ if (initializer && Node.isStringLiteral(initializer)) defaults.set(propName, initializer.getLiteralValue());
284
+ }
285
+ }
286
+ }
287
+ /**
288
+ * Extract ALL prop names from a function's parameter destructuring (not just defaults)
289
+ */
290
+ function extractAllPropNames(fn, propNames) {
291
+ let params = [];
292
+ if (Node.isFunctionDeclaration(fn) || Node.isFunctionExpression(fn)) params = fn.getParameters();
293
+ else if (Node.isArrowFunction(fn)) params = fn.getParameters();
294
+ for (const param of params) {
295
+ if (!Node.isParameterDeclaration(param)) continue;
296
+ const nameNode = param.getNameNode();
297
+ if (!nameNode || !Node.isObjectBindingPattern(nameNode)) continue;
298
+ for (const element of nameNode.getElements()) {
299
+ const propName = element.getPropertyNameNode()?.getText() || element.getName();
300
+ propNames.add(propName);
301
+ }
302
+ }
303
+ }
304
+ /**
305
+ * Extract string literals from cx() call arguments.
306
+ * Handles:
307
+ * - Direct string literals: cx('class1', 'class2')
308
+ * - Object keys: cx({ 'class1': condition, 'class2': true })
309
+ * - Nested calls and arrays
310
+ */
311
+ function extractCxStringLiterals(node, literals) {
312
+ if (Node.isStringLiteral(node)) {
313
+ const classes = node.getLiteralValue().split(/\s+/).filter(Boolean);
314
+ for (const cls of classes) if (!literals.includes(cls)) literals.push(cls);
315
+ } else if (Node.isObjectLiteralExpression(node)) {
316
+ for (const prop of node.getProperties()) if (Node.isPropertyAssignment(prop)) {
317
+ const nameNode = prop.getNameNode();
318
+ if (Node.isStringLiteral(nameNode)) {
319
+ const classes = nameNode.getLiteralValue().split(/\s+/).filter(Boolean);
320
+ for (const cls of classes) if (!literals.includes(cls)) literals.push(cls);
321
+ } else if (Node.isIdentifier(nameNode)) {
322
+ const cls = nameNode.getText();
323
+ if (!literals.includes(cls)) literals.push(cls);
324
+ }
325
+ }
326
+ } else if (Node.isArrayLiteralExpression(node)) for (const element of node.getElements()) extractCxStringLiterals(element, literals);
327
+ else if (Node.isConditionalExpression(node)) {
328
+ extractCxStringLiterals(node.getWhenTrue(), literals);
329
+ extractCxStringLiterals(node.getWhenFalse(), literals);
330
+ } else if (Node.isBinaryExpression(node)) {
331
+ extractCxStringLiterals(node.getLeft(), literals);
332
+ extractCxStringLiterals(node.getRight(), literals);
333
+ }
334
+ }
335
+ /**
336
+ * Try to resolve an identifier to its initializer value (for const declarations)
337
+ */
338
+ function resolveIdentifierToObject(sourceFile, identifier) {
339
+ const varDecls = sourceFile.getDescendantsOfKind(SyntaxKind.VariableDeclaration);
340
+ for (const decl of varDecls) {
341
+ if (decl.getName() !== identifier) continue;
342
+ let initializer = decl.getInitializer();
343
+ if (!initializer) continue;
344
+ if (Node.isAsExpression(initializer)) initializer = initializer.getExpression();
345
+ if (!Node.isObjectLiteralExpression(initializer)) continue;
346
+ const result = {};
347
+ for (const prop of initializer.getProperties()) {
348
+ if (!Node.isPropertyAssignment(prop)) continue;
349
+ const propName = prop.getName();
350
+ const propInit = prop.getInitializer();
351
+ if (propInit && Node.isStringLiteral(propInit)) result[propName] = propInit.getLiteralValue();
352
+ }
353
+ return result;
354
+ }
355
+ return null;
356
+ }
357
+ /**
358
+ * Extract motion CSS variable prefixes from SpringMotionConfig usage.
359
+ * Returns prefixes like ['--uds-motion-bouncy-4-', '--uds-motion-smooth-3-']
360
+ */
361
+ function extractMotionVarPrefixes(sourceFile) {
362
+ const prefixes = [];
363
+ const jsxElements = [...sourceFile.getDescendantsOfKind(SyntaxKind.JsxSelfClosingElement), ...sourceFile.getDescendantsOfKind(SyntaxKind.JsxOpeningElement)];
364
+ for (const element of jsxElements) {
365
+ if (element.getTagNameNode().getText() !== "SpringMotionConfig") continue;
366
+ const props = {
367
+ layoutVariant: null,
368
+ layoutSpeed: null,
369
+ colorVariant: null,
370
+ colorSpeed: null
371
+ };
372
+ const attrs = element.getAttributes();
373
+ for (const attr of attrs) {
374
+ if (Node.isJsxSpreadAttribute(attr)) {
375
+ const expr = attr.getExpression();
376
+ if (Node.isIdentifier(expr)) {
377
+ const spreadObj = resolveIdentifierToObject(sourceFile, expr.getText());
378
+ if (spreadObj) {
379
+ for (const key of Object.keys(props)) if (key in spreadObj) props[key] = spreadObj[key];
380
+ }
381
+ }
382
+ continue;
383
+ }
384
+ if (!Node.isJsxAttribute(attr)) continue;
385
+ const propName = attr.getNameNode().getText();
386
+ if (!(propName in props)) continue;
387
+ const initializer = attr.getInitializer();
388
+ if (initializer) {
389
+ if (Node.isStringLiteral(initializer)) props[propName] = initializer.getLiteralValue();
390
+ else if (Node.isJsxExpression(initializer)) {
391
+ const expr = initializer.getExpression();
392
+ if (expr && Node.isStringLiteral(expr)) props[propName] = expr.getLiteralValue();
393
+ }
394
+ }
395
+ }
396
+ const layoutPrefix = `--uds-motion-${props.layoutVariant ?? SPRING_MOTION_DEFAULTS.layoutVariant}-${props.layoutSpeed ?? SPRING_MOTION_DEFAULTS.layoutSpeed}-`;
397
+ if (!prefixes.includes(layoutPrefix)) prefixes.push(layoutPrefix);
398
+ const colorPrefix = `--uds-motion-${props.colorVariant ?? SPRING_MOTION_DEFAULTS.colorVariant}-${props.colorSpeed ?? SPRING_MOTION_DEFAULTS.colorSpeed}-`;
399
+ if (!prefixes.includes(colorPrefix)) prefixes.push(colorPrefix);
400
+ }
401
+ return prefixes;
402
+ }
403
+
404
+ //#endregion
405
+ export { analyzeComponent, scanComponentFiles };
@@ -0,0 +1,27 @@
1
+ /*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
2
+ const require_runtime = require('../../../../../_virtual/_rolldown/runtime.cjs');
3
+ let node_path = require("node:path");
4
+ node_path = require_runtime.__toESM(node_path);
5
+ let fast_glob = require("fast-glob");
6
+ fast_glob = require_runtime.__toESM(fast_glob);
7
+
8
+ //#region ../tailwind/dist/purger/optimized/utils/files.js
9
+ /*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
10
+ /**
11
+ * Scan a directory for JSX/TSX files
12
+ */
13
+ async function scanForFiles(entry) {
14
+ const workspaceDir = process.env.PWD ?? process.cwd();
15
+ const srcDir = node_path.default.join(workspaceDir, entry);
16
+ try {
17
+ return await (0, fast_glob.default)("**/*.{jsx,tsx}", {
18
+ cwd: srcDir,
19
+ absolute: true
20
+ });
21
+ } catch {
22
+ throw new Error(`Couldn't find the entry directory: ${entry}. Please make sure it exists.`);
23
+ }
24
+ }
25
+
26
+ //#endregion
27
+ exports.scanForFiles = scanForFiles;
@@ -0,0 +1,24 @@
1
+ /*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
2
+ import path from "node:path";
3
+ import fg from "fast-glob";
4
+
5
+ //#region ../tailwind/dist/purger/optimized/utils/files.js
6
+ /*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
7
+ /**
8
+ * Scan a directory for JSX/TSX files
9
+ */
10
+ async function scanForFiles(entry) {
11
+ const workspaceDir = process.env.PWD ?? process.cwd();
12
+ const srcDir = path.join(workspaceDir, entry);
13
+ try {
14
+ return await fg("**/*.{jsx,tsx}", {
15
+ cwd: srcDir,
16
+ absolute: true
17
+ });
18
+ } catch {
19
+ throw new Error(`Couldn't find the entry directory: ${entry}. Please make sure it exists.`);
20
+ }
21
+ }
22
+
23
+ //#endregion
24
+ export { scanForFiles };
@@ -0,0 +1,64 @@
1
+ /*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
2
+ const require_runtime = require('../../../../../_virtual/_rolldown/runtime.cjs');
3
+ const require_index = require('../../../../../css-tokens/dist/index.cjs');
4
+ let node_path = require("node:path");
5
+ node_path = require_runtime.__toESM(node_path);
6
+ let node_fs = require("node:fs");
7
+
8
+ //#region ../tailwind/dist/purger/optimized/utils/safelist.js
9
+ /*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
10
+ const colorModeToClass = {
11
+ dark: require_index.DARK_COLOR_MODE_CLASSNAME,
12
+ light: require_index.LIGHT_COLOR_MODE_CLASSNAME
13
+ };
14
+ /**
15
+ * Deduplicate and clean a safelist
16
+ */
17
+ function deduplicateSafelist(safelist) {
18
+ const set = /* @__PURE__ */ new Set();
19
+ for (const cls of safelist) {
20
+ const cleaned = cls.replaceAll("\\", "").trim();
21
+ if (cleaned && isValidClassName(cleaned)) set.add(cleaned);
22
+ }
23
+ return Array.from(set);
24
+ }
25
+ /**
26
+ * Check if a class name is valid (not malformed from CSS escape sequences)
27
+ */
28
+ function isValidClassName(cls) {
29
+ if (cls.match(/^[0-9]/)) return false;
30
+ if (cls.match(/[0-9][a-z]$/)) return false;
31
+ if (cls.includes("2c")) return false;
32
+ if (cls.includes("0.")) return false;
33
+ return true;
34
+ }
35
+ /**
36
+ * Get classes for enabled color modes.
37
+ * Note: Light mode is not included by default since :root already defines light mode styles.
38
+ * Only dark mode class is needed to enable dark mode switching.
39
+ */
40
+ function getThemeAndScaleClasses(colorModes) {
41
+ const classes = [];
42
+ if (colorModes && colorModes.length > 0) {
43
+ for (const mode of colorModes) if (colorModeToClass[mode]) classes.push(colorModeToClass[mode]);
44
+ } else classes.push(colorModeToClass.dark);
45
+ return classes;
46
+ }
47
+ /**
48
+ * Save safelist to a file
49
+ */
50
+ async function saveSafelistToFile(safelist, outputPath) {
51
+ const content = `
52
+ //! This file is generated by the optimized purger from @yahoo/uds
53
+ //! Do not edit directly
54
+ //! If there is issue with this file please report to #ask-uds
55
+ export const safelist = ${JSON.stringify(safelist)};
56
+ `;
57
+ (0, node_fs.mkdirSync)(node_path.default.dirname(outputPath), { recursive: true });
58
+ (0, node_fs.writeFileSync)(outputPath, content);
59
+ }
60
+
61
+ //#endregion
62
+ exports.deduplicateSafelist = deduplicateSafelist;
63
+ exports.getThemeAndScaleClasses = getThemeAndScaleClasses;
64
+ exports.saveSafelistToFile = saveSafelistToFile;
@@ -0,0 +1,60 @@
1
+ /*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
2
+ import { DARK_COLOR_MODE_CLASSNAME, LIGHT_COLOR_MODE_CLASSNAME } from "../../../../../css-tokens/dist/index.js";
3
+ import path from "node:path";
4
+ import { mkdirSync, writeFileSync } from "node:fs";
5
+
6
+ //#region ../tailwind/dist/purger/optimized/utils/safelist.js
7
+ /*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
8
+ const colorModeToClass = {
9
+ dark: DARK_COLOR_MODE_CLASSNAME,
10
+ light: LIGHT_COLOR_MODE_CLASSNAME
11
+ };
12
+ /**
13
+ * Deduplicate and clean a safelist
14
+ */
15
+ function deduplicateSafelist(safelist) {
16
+ const set = /* @__PURE__ */ new Set();
17
+ for (const cls of safelist) {
18
+ const cleaned = cls.replaceAll("\\", "").trim();
19
+ if (cleaned && isValidClassName(cleaned)) set.add(cleaned);
20
+ }
21
+ return Array.from(set);
22
+ }
23
+ /**
24
+ * Check if a class name is valid (not malformed from CSS escape sequences)
25
+ */
26
+ function isValidClassName(cls) {
27
+ if (cls.match(/^[0-9]/)) return false;
28
+ if (cls.match(/[0-9][a-z]$/)) return false;
29
+ if (cls.includes("2c")) return false;
30
+ if (cls.includes("0.")) return false;
31
+ return true;
32
+ }
33
+ /**
34
+ * Get classes for enabled color modes.
35
+ * Note: Light mode is not included by default since :root already defines light mode styles.
36
+ * Only dark mode class is needed to enable dark mode switching.
37
+ */
38
+ function getThemeAndScaleClasses(colorModes) {
39
+ const classes = [];
40
+ if (colorModes && colorModes.length > 0) {
41
+ for (const mode of colorModes) if (colorModeToClass[mode]) classes.push(colorModeToClass[mode]);
42
+ } else classes.push(colorModeToClass.dark);
43
+ return classes;
44
+ }
45
+ /**
46
+ * Save safelist to a file
47
+ */
48
+ async function saveSafelistToFile(safelist, outputPath) {
49
+ const content = `
50
+ //! This file is generated by the optimized purger from @yahoo/uds
51
+ //! Do not edit directly
52
+ //! If there is issue with this file please report to #ask-uds
53
+ export const safelist = ${JSON.stringify(safelist)};
54
+ `;
55
+ mkdirSync(path.dirname(outputPath), { recursive: true });
56
+ writeFileSync(outputPath, content);
57
+ }
58
+
59
+ //#endregion
60
+ export { deduplicateSafelist, getThemeAndScaleClasses, saveSafelistToFile };
@@ -3,6 +3,7 @@
3
3
  //#region ../tailwind/dist/tailwind/utils/getColorModeStyles.js
4
4
  /*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
5
5
  function getColorModeStyles(tokens) {
6
+ if (!tokens.colorMode?.light?._vars || !tokens.colorMode?.dark?._vars) throw new Error("Invalid tokens configuration: missing colorMode.light._vars or colorMode.dark._vars. Ensure your uds.config.ts exports a valid UniversalTokensConfig.");
6
7
  return {
7
8
  light: {
8
9
  colorScheme: "light",
@@ -2,6 +2,7 @@
2
2
  //#region ../tailwind/dist/tailwind/utils/getColorModeStyles.js
3
3
  /*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
4
4
  function getColorModeStyles(tokens) {
5
+ if (!tokens.colorMode?.light?._vars || !tokens.colorMode?.dark?._vars) throw new Error("Invalid tokens configuration: missing colorMode.light._vars or colorMode.dark._vars. Ensure your uds.config.ts exports a valid UniversalTokensConfig.");
5
6
  return {
6
7
  light: {
7
8
  colorScheme: "light",
@@ -1,7 +1,7 @@
1
1
  /*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
2
2
  const require_runtime = require('../../../_virtual/_rolldown/runtime.cjs');
3
- let lodash_es = require("lodash-es");
4
3
  let ts_morph = require("ts-morph");
4
+ let lodash_es = require("lodash-es");
5
5
 
6
6
  //#region ../tailwind/dist/utils/tsMorph.js
7
7
  /*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
@@ -1,5 +1,6 @@
1
1
  /*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
3
+ const require_generateDefaultClassName = require('../../automated-config/dist/utils/generateDefaultClassName.cjs');
3
4
  const require_generateSchemaKey = require('../../automated-config/dist/utils/generateSchemaKey.cjs');
4
5
  const require_buildConfigSchema = require('../../automated-config/dist/utils/buildConfigSchema.cjs');
5
6
  const require_cartesianProduct = require('../../automated-config/dist/utils/cartesianProduct.cjs');
@@ -43,7 +44,7 @@ exports.findFixtureType = require_buildConfigSchema.findFixtureType;
43
44
  exports.generateClassName = require_index.generateClassName;
44
45
  exports.generateConfigStyles = require_index.generateConfigStyles;
45
46
  exports.generateDeclaration = require_index.generateDeclaration;
46
- exports.generateDefaultClassName = require_index.generateDefaultClassName;
47
+ exports.generateDefaultClassName = require_generateDefaultClassName.generateDefaultClassName;
47
48
  exports.generateKeyFromFlatConfigPath = require_generateKeyFromFlatConfigPath.generateKeyFromFlatConfigPath;
48
49
  exports.generateSchemaKey = require_generateSchemaKey.generateSchemaKey;
49
50
  exports.generateStyles = require_index.generateStyles;
@@ -4,6 +4,7 @@ import { ComponentSchema, buildConfigSchema, findFixtureType } from "../../autom
4
4
  import { cartesianProduct } from "../../automated-config/dist/utils/cartesianProduct.cjs";
5
5
  import { coalesceConfigVariant } from "../../automated-config/dist/utils/coalesceConfigVariant.cjs";
6
6
  import { getConfigDefaultValue, isConfigDefaultValue } from "../../automated-config/dist/utils/defaults.cjs";
7
+ import { generateDefaultClassName } from "../../automated-config/dist/utils/generateDefaultClassName.cjs";
7
8
  import { generateKeyFromFlatConfigPath } from "../../automated-config/dist/utils/generateKeyFromFlatConfigPath.cjs";
8
9
  import { generateSchemaKey } from "../../automated-config/dist/utils/generateSchemaKey.cjs";
9
10
  import { getConfigVariantComponentStates, getConfigVariantComponentStatesMatrix } from "../../automated-config/dist/utils/getConfigVariantComponentStatesMatrix.cjs";
@@ -11,5 +12,5 @@ import { getConfigVariantProperties } from "../../automated-config/dist/utils/ge
11
12
  import { getConfigVariantPseudoStates } from "../../automated-config/dist/utils/getConfigVariantPseudoStates.cjs";
12
13
  import { getConfigVariants } from "../../automated-config/dist/utils/getConfigVariants.cjs";
13
14
  import { getConfigSubcomponents } from "../../automated-config/dist/utils/subcomponents.cjs";
14
- import { createComponentStates, createConfigurableProperty, createLayerConfig, createSubComponentConfig, createVariantConfig, createVariantConfigWithComponentStates, createVariantConfigWithProperties, generateClassName, generateConfigStyles, generateDeclaration, generateDefaultClassName, generateStyles, statePseudoMapDocsMode } from "../../automated-config/dist/utils/index.cjs";
15
+ import { createComponentStates, createConfigurableProperty, createLayerConfig, createSubComponentConfig, createVariantConfig, createVariantConfigWithComponentStates, createVariantConfigWithProperties, generateClassName, generateConfigStyles, generateDeclaration, generateStyles, statePseudoMapDocsMode } from "../../automated-config/dist/utils/index.cjs";
15
16
  export { AvatarConfig, BadgeConfig, ButtonConfig, CheckboxConfig, ChipConfig, ComponentSchema, DividerConfig, IconButtonConfig, InputConfig, LinkConfig, MenuContentConfig, MenuItemConfig, RadioConfig, SwitchConfig, ToastConfig, TooltipConfig, buildConfigSchema, cartesianProduct, coalesceConfigVariant, createComponentStates, createConfigurableProperty, createLayerConfig, createSubComponentConfig, createVariantConfig, createVariantConfigWithComponentStates, createVariantConfigWithProperties, findFixtureType, generateClassName, generateConfigStyles, generateDeclaration, generateDefaultClassName, generateKeyFromFlatConfigPath, generateSchemaKey, generateStyles, getConfigDefaultValue, getConfigSubcomponents, getConfigVariantComponentStates, getConfigVariantComponentStatesMatrix, getConfigVariantProperties, getConfigVariantPseudoStates, getConfigVariants, isConfigDefaultValue, statePseudoMapDocsMode };
@@ -4,6 +4,7 @@ import { ComponentSchema, buildConfigSchema, findFixtureType } from "../../autom
4
4
  import { cartesianProduct } from "../../automated-config/dist/utils/cartesianProduct.js";
5
5
  import { coalesceConfigVariant } from "../../automated-config/dist/utils/coalesceConfigVariant.js";
6
6
  import { getConfigDefaultValue, isConfigDefaultValue } from "../../automated-config/dist/utils/defaults.js";
7
+ import { generateDefaultClassName } from "../../automated-config/dist/utils/generateDefaultClassName.js";
7
8
  import { generateKeyFromFlatConfigPath } from "../../automated-config/dist/utils/generateKeyFromFlatConfigPath.js";
8
9
  import { generateSchemaKey } from "../../automated-config/dist/utils/generateSchemaKey.js";
9
10
  import { getConfigVariantComponentStates, getConfigVariantComponentStatesMatrix } from "../../automated-config/dist/utils/getConfigVariantComponentStatesMatrix.js";
@@ -11,5 +12,5 @@ import { getConfigVariantProperties } from "../../automated-config/dist/utils/ge
11
12
  import { getConfigVariantPseudoStates } from "../../automated-config/dist/utils/getConfigVariantPseudoStates.js";
12
13
  import { getConfigVariants } from "../../automated-config/dist/utils/getConfigVariants.js";
13
14
  import { getConfigSubcomponents } from "../../automated-config/dist/utils/subcomponents.js";
14
- import { createComponentStates, createConfigurableProperty, createLayerConfig, createSubComponentConfig, createVariantConfig, createVariantConfigWithComponentStates, createVariantConfigWithProperties, generateClassName, generateConfigStyles, generateDeclaration, generateDefaultClassName, generateStyles, statePseudoMapDocsMode } from "../../automated-config/dist/utils/index.js";
15
+ import { createComponentStates, createConfigurableProperty, createLayerConfig, createSubComponentConfig, createVariantConfig, createVariantConfigWithComponentStates, createVariantConfigWithProperties, generateClassName, generateConfigStyles, generateDeclaration, generateStyles, statePseudoMapDocsMode } from "../../automated-config/dist/utils/index.js";
15
16
  export { AvatarConfig, BadgeConfig, ButtonConfig, CheckboxConfig, ChipConfig, ComponentSchema, DividerConfig, IconButtonConfig, InputConfig, LinkConfig, MenuContentConfig, MenuItemConfig, RadioConfig, SwitchConfig, ToastConfig, TooltipConfig, buildConfigSchema, cartesianProduct, coalesceConfigVariant, createComponentStates, createConfigurableProperty, createLayerConfig, createSubComponentConfig, createVariantConfig, createVariantConfigWithComponentStates, createVariantConfigWithProperties, findFixtureType, generateClassName, generateConfigStyles, generateDeclaration, generateDefaultClassName, generateKeyFromFlatConfigPath, generateSchemaKey, generateStyles, getConfigDefaultValue, getConfigSubcomponents, getConfigVariantComponentStates, getConfigVariantComponentStatesMatrix, getConfigVariantProperties, getConfigVariantPseudoStates, getConfigVariants, isConfigDefaultValue, statePseudoMapDocsMode };