@yahoo/uds 3.174.1 → 3.175.1

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 (29) hide show
  1. package/dist/components/client/Menu/Menu.ItemCheckbox.d.cts +1 -1
  2. package/dist/components/client/Menu/Menu.ItemCheckbox.d.ts +1 -1
  3. package/dist/components/client/Toast/UDSToastConfigProvider.d.cts +5 -5
  4. package/dist/components/client/Toast/UDSToastConfigProvider.d.ts +5 -5
  5. package/dist/css/dist/commands/css.cjs +1 -0
  6. package/dist/css/dist/commands/css.helpers.cjs +6 -0
  7. package/dist/css/dist/commands/css.helpers.js +6 -0
  8. package/dist/css/dist/commands/css.js +1 -0
  9. package/dist/css/dist/commands/generateComponentData.d.cts +1 -0
  10. package/dist/css/dist/commands/generateComponentData.d.ts +1 -0
  11. package/dist/css/dist/css/generate.cjs +3 -1
  12. package/dist/css/dist/css/generate.d.cts +21 -1
  13. package/dist/css/dist/css/generate.d.ts +21 -1
  14. package/dist/css/dist/css/generate.helpers.cjs +9 -5
  15. package/dist/css/dist/css/generate.helpers.d.cts +7 -1
  16. package/dist/css/dist/css/generate.helpers.d.ts +7 -1
  17. package/dist/css/dist/css/generate.helpers.js +9 -5
  18. package/dist/css/dist/css/generate.js +3 -1
  19. package/dist/css/dist/css/runner.cjs +7 -2
  20. package/dist/css/dist/css/runner.js +7 -2
  21. package/dist/css/dist/purger/optimized/purgeFromCode.cjs +62 -0
  22. package/dist/css/dist/purger/optimized/purgeFromCode.js +62 -0
  23. package/dist/uds/generated/componentData.cjs +368 -190
  24. package/dist/uds/generated/componentData.js +368 -190
  25. package/dist/uds/generated/tailwindPurge.cjs +40 -3
  26. package/dist/uds/generated/tailwindPurge.js +40 -3
  27. package/generated/componentData.json +398 -212
  28. package/generated/tailwindPurge.ts +3 -3
  29. package/package.json +1 -1
@@ -5,5 +5,11 @@ type TailwindSafelistConfig = string | {
5
5
  pattern: RegExp;
6
6
  variants?: string[];
7
7
  };
8
+ /**
9
+ * Who owns utility (non-component) CSS in a generated bundle. `'emit'`
10
+ * compiles utilities from the entry content scan into the bundle;
11
+ * `'app-sheet'` omits them because the app's own Tailwind sheet supplies them.
12
+ */
13
+ type UtilitiesMode = 'emit' | 'app-sheet';
8
14
  //#endregion
9
- export { TailwindSafelistConfig };
15
+ export { TailwindSafelistConfig, UtilitiesMode };
@@ -7,5 +7,11 @@ type TailwindSafelistConfig = string | {
7
7
  pattern: RegExp;
8
8
  variants?: string[];
9
9
  };
10
+ /**
11
+ * Who owns utility (non-component) CSS in a generated bundle. `'emit'`
12
+ * compiles utilities from the entry content scan into the bundle;
13
+ * `'app-sheet'` omits them because the app's own Tailwind sheet supplies them.
14
+ */
15
+ type UtilitiesMode = 'emit' | 'app-sheet';
10
16
  //#endregion
11
- export { TailwindSafelistConfig };
17
+ export { TailwindSafelistConfig, UtilitiesMode };
@@ -41,6 +41,10 @@ const getRawContentEntries = (rawContents) => rawContents.map((rawContent) => ({
41
41
  raw: rawContent,
42
42
  extension: "html"
43
43
  }));
44
+ const getTailwindContentSources = (options) => {
45
+ const sources = [...options.utilities === "app-sheet" ? [] : getContentGlobs(options.contentDir), ...getRawContentEntries(options.rawContents)];
46
+ return sources.length > 0 ? sources : getRawContentEntries([""]);
47
+ };
44
48
  const getTailwindEntrypointCandidates = () => [new URL("../../../tailwind-internal/dist/vendor/tailwindcss/lib/index.js", import.meta.url), new URL("../vendor/tailwindcss/lib/index.js", import.meta.url)];
45
49
  const loadTailwindcss = async () => {
46
50
  for (const candidate of getTailwindEntrypointCandidates()) {
@@ -64,11 +68,11 @@ const getInternalIconModeCss = (scopeClass) => {
64
68
  };
65
69
  const createTailwindPlugin = async (options) => {
66
70
  return (await loadTailwindcss())({
67
- content: [
68
- ...getContentGlobs(options.contentDir),
69
- ...getRawContentEntries(getInternalSafelistRawContent(options.safelist)),
70
- ...getRawContentEntries(options.rawContents ?? [])
71
- ],
71
+ content: getTailwindContentSources({
72
+ contentDir: options.contentDir,
73
+ utilities: options.utilities,
74
+ rawContents: [...getInternalSafelistRawContent(options.safelist), ...options.rawContents ?? []]
75
+ }),
72
76
  safelist: options.safelist,
73
77
  corePlugins: { preflight: options.enablePreflight },
74
78
  plugins: [tailwindPlugin({
@@ -45,7 +45,8 @@ const generateCSS = async (safelist, config, options) => {
45
45
  config,
46
46
  enablePreflight: cssFlags.enablePreflight,
47
47
  enableFontFaceDeclarations: cssFlags.enableFontFaceDeclarations,
48
- emit: options?.cssOptions?.emit
48
+ emit: options?.cssOptions?.emit,
49
+ utilities: options?.cssOptions?.utilities
49
50
  }),
50
51
  shouldPruneVars: cssFlags.shouldPruneVars,
51
52
  safeVarPrefixes: options?.safeVarPrefixes ?? [],
@@ -105,6 +106,7 @@ const generateSimpleModeCSS = async (options) => {
105
106
  scope: options.scope,
106
107
  contentDir: entryDirs,
107
108
  variantClassMaps: [options.variants, options.autoVariants],
109
+ cssOptions: { utilities: options.utilities },
108
110
  safeVarPrefixes: [...getMotionVarPrefixes(options.componentData, [...allComponents]), ...getConfigurableCssVariables()]
109
111
  });
110
112
  const outputPath = path.isAbsolute(options.outFile) ? options.outFile : path.join(options.workspaceDir, options.outFile);
@@ -151,6 +151,7 @@ const runSimpleMode = async (options, context) => {
151
151
  autoVariants: context.autoVariants,
152
152
  componentData: context.componentData,
153
153
  scope: options.scope,
154
+ utilities: options.utilities,
154
155
  configPath,
155
156
  isWatch: options.watch,
156
157
  silent: options.silent,
@@ -348,6 +349,8 @@ const runThemeMode = async (options, context) => {
348
349
  ]);
349
350
  const allMotionComponents = [...inheritedComponents];
350
351
  const emit = options.emit ?? themeConfig.css?.emit ?? "exhaustive";
352
+ const utilities = options.utilities ?? themeConfig.css?.utilities ?? "emit";
353
+ if (utilities === "app-sheet" && scopedPackageTargets.length > 0) genLog.warn(`css.utilities 'app-sheet' ignored for scoped bundles (${scopedPackageTargets.map((target) => target.packageName).join(", ")}): package sources aren't in any app sheet's content scan; utilities still emitted (scoped).`);
351
354
  const allBoundarySelectors = [...emit === "selective" ? scopedPackageTargets.map((target) => target.scopeClass) : [], ...themeConfig.css?.excludeBoundaries ?? []];
352
355
  require_perf.captureMemory("before-gen");
353
356
  const mainCssResult = await require_perf.measureAsync("gen", () => require_generate.generateCSS([...themeConfig.css?.safelist ?? [], ...mainSafelist], appConfig, {
@@ -355,7 +358,8 @@ const runThemeMode = async (options, context) => {
355
358
  contentDir: entryDirs,
356
359
  cssOptions: {
357
360
  ...themeConfig.css,
358
- emit
361
+ emit,
362
+ utilities
359
363
  },
360
364
  otherBoundaryScopes: allBoundarySelectors,
361
365
  variantClassMaps: [context.variants, context.autoVariants],
@@ -391,7 +395,8 @@ const runThemeMode = async (options, context) => {
391
395
  contentDir: scopedPackageTarget.entryDirs,
392
396
  cssOptions: {
393
397
  ...themeConfig.css,
394
- emit
398
+ emit,
399
+ utilities: "emit"
395
400
  },
396
401
  otherBoundaryScopes: allBoundarySelectors.filter((selector) => selector !== scopedPackageTarget.scopeClass),
397
402
  variantClassMaps: [context.variants, context.autoVariants],
@@ -149,6 +149,7 @@ const runSimpleMode = async (options, context) => {
149
149
  autoVariants: context.autoVariants,
150
150
  componentData: context.componentData,
151
151
  scope: options.scope,
152
+ utilities: options.utilities,
152
153
  configPath,
153
154
  isWatch: options.watch,
154
155
  silent: options.silent,
@@ -346,6 +347,8 @@ const runThemeMode = async (options, context) => {
346
347
  ]);
347
348
  const allMotionComponents = [...inheritedComponents];
348
349
  const emit = options.emit ?? themeConfig.css?.emit ?? "exhaustive";
350
+ const utilities = options.utilities ?? themeConfig.css?.utilities ?? "emit";
351
+ if (utilities === "app-sheet" && scopedPackageTargets.length > 0) genLog.warn(`css.utilities 'app-sheet' ignored for scoped bundles (${scopedPackageTargets.map((target) => target.packageName).join(", ")}): package sources aren't in any app sheet's content scan; utilities still emitted (scoped).`);
349
352
  const allBoundarySelectors = [...emit === "selective" ? scopedPackageTargets.map((target) => target.scopeClass) : [], ...themeConfig.css?.excludeBoundaries ?? []];
350
353
  captureMemory("before-gen");
351
354
  const mainCssResult = await measureAsync("gen", () => generateCSS([...themeConfig.css?.safelist ?? [], ...mainSafelist], appConfig, {
@@ -353,7 +356,8 @@ const runThemeMode = async (options, context) => {
353
356
  contentDir: entryDirs,
354
357
  cssOptions: {
355
358
  ...themeConfig.css,
356
- emit
359
+ emit,
360
+ utilities
357
361
  },
358
362
  otherBoundaryScopes: allBoundarySelectors,
359
363
  variantClassMaps: [context.variants, context.autoVariants],
@@ -389,7 +393,8 @@ const runThemeMode = async (options, context) => {
389
393
  contentDir: scopedPackageTarget.entryDirs,
390
394
  cssOptions: {
391
395
  ...themeConfig.css,
392
- emit
396
+ emit,
397
+ utilities: "emit"
393
398
  },
394
399
  otherBoundaryScopes: allBoundarySelectors.filter((selector) => selector !== scopedPackageTarget.scopeClass),
395
400
  variantClassMaps: [context.variants, context.autoVariants],
@@ -238,6 +238,37 @@ const purgeFromCodeOptimized = async (code, options) => {
238
238
  if (!componentProps.has(imp)) componentProps.set(imp, /* @__PURE__ */ new Map());
239
239
  if (!componentUnresolvedSpreadProps.has(imp)) componentUnresolvedSpreadProps.set(imp, /* @__PURE__ */ new Set());
240
240
  });
241
+ imports.forEach((imp) => {
242
+ const factoryInfo = resolveComponentInfo(imp);
243
+ const targetName = factoryInfo?.factoryTarget;
244
+ const targetInfo = targetName ? resolveComponentInfo(targetName) : void 0;
245
+ if (!factoryInfo || !targetInfo) return;
246
+ referencedComponents.add(targetInfo.name);
247
+ const propsMap = componentProps.get(targetInfo.name) ?? /* @__PURE__ */ new Map();
248
+ const addPropValues = (propName, values) => {
249
+ if (values.length === 0) return;
250
+ const existing = propsMap.get(propName) ?? /* @__PURE__ */ new Set();
251
+ values.forEach((value) => existing.add(value));
252
+ propsMap.set(propName, existing);
253
+ };
254
+ Object.entries(factoryInfo.internalComponentProps[targetInfo.name] ?? {}).forEach(([propName, values]) => addPropValues(propName, values));
255
+ const localNames = getFactoryLocalNames(source, imp);
256
+ const apiNames = /* @__PURE__ */ new Set();
257
+ source.callExpressions.forEach((call) => {
258
+ if (call.callee.type !== "Identifier" || !localNames.has(call.callee.name)) return;
259
+ extractFactoryCallArgProps(call.arguments[0], source).forEach(([propName, values]) => addPropValues(propName, values));
260
+ const parent = source.parents.get(call);
261
+ if (parent?.type === "VariableDeclarator" && parent.id.type === "Identifier") apiNames.add(parent.id.name);
262
+ stats.expressionsResolved++;
263
+ });
264
+ if (apiNames.size > 0) source.callExpressions.forEach((call) => {
265
+ const callee = call.callee;
266
+ if (callee.type !== "MemberExpression" || callee.object.type !== "Identifier" || !apiNames.has(callee.object.name) || callee.property.type !== "Identifier" || callee.property.name !== "update") return;
267
+ extractFactoryCallArgProps(call.arguments[0], source).forEach(([propName, values]) => addPropValues(propName, values));
268
+ });
269
+ componentProps.set(targetInfo.name, propsMap);
270
+ if (!componentUnresolvedSpreadProps.has(targetInfo.name)) componentUnresolvedSpreadProps.set(targetInfo.name, /* @__PURE__ */ new Set());
271
+ });
241
272
  const jsxAnalysisMs = performance.now() - jsxAnalysisStart;
242
273
  const safelistGenStart = performance.now();
243
274
  const allComponents = [];
@@ -392,6 +423,37 @@ const purgeFromCodeOptimized = async (code, options) => {
392
423
  };
393
424
  };
394
425
  /**
426
+ * Local aliases a UDS import is bound to in this file (handles `import { createToast as x }`)
427
+ */
428
+ const getFactoryLocalNames = (source, importName) => {
429
+ const localNames = /* @__PURE__ */ new Set();
430
+ source.staticImports.forEach((staticImport) => {
431
+ if (!isUdsComponentModule(staticImport.moduleRequest.value)) return;
432
+ staticImport.entries.forEach((entry) => {
433
+ if (entry.importName.kind === "Name" && entry.importName.name === importName && !entry.isType) localNames.add(entry.localName.value);
434
+ });
435
+ });
436
+ return localNames;
437
+ };
438
+ /**
439
+ * Extract prop literals from a factory call's first argument: an inline object
440
+ * literal, or a same-file object variable (reuses spread tracing).
441
+ */
442
+ const extractFactoryCallArgProps = (firstArg, source) => {
443
+ if (!firstArg) return [];
444
+ if (firstArg.type === "Identifier") return traceSpreadInFile(firstArg.name, source);
445
+ const props = [];
446
+ getSpreadObjectLiteralCandidates(firstArg).forEach((objLiteral) => {
447
+ objLiteral.properties.forEach((prop) => {
448
+ if (prop.type !== "Property") return;
449
+ const propName = require_oxc.getPropertyName(source, prop);
450
+ const values = prop.value ? require_expressions.extractStringLiterals(prop.value, source) : [];
451
+ props.push([propName, values]);
452
+ });
453
+ });
454
+ return props;
455
+ };
456
+ /**
395
457
  * Find JSX references for a component in the source file
396
458
  */
397
459
  const findComponentReferences = (source, componentName) => {
@@ -238,6 +238,37 @@ const purgeFromCodeOptimized = async (code, options) => {
238
238
  if (!componentProps.has(imp)) componentProps.set(imp, /* @__PURE__ */ new Map());
239
239
  if (!componentUnresolvedSpreadProps.has(imp)) componentUnresolvedSpreadProps.set(imp, /* @__PURE__ */ new Set());
240
240
  });
241
+ imports.forEach((imp) => {
242
+ const factoryInfo = resolveComponentInfo(imp);
243
+ const targetName = factoryInfo?.factoryTarget;
244
+ const targetInfo = targetName ? resolveComponentInfo(targetName) : void 0;
245
+ if (!factoryInfo || !targetInfo) return;
246
+ referencedComponents.add(targetInfo.name);
247
+ const propsMap = componentProps.get(targetInfo.name) ?? /* @__PURE__ */ new Map();
248
+ const addPropValues = (propName, values) => {
249
+ if (values.length === 0) return;
250
+ const existing = propsMap.get(propName) ?? /* @__PURE__ */ new Set();
251
+ values.forEach((value) => existing.add(value));
252
+ propsMap.set(propName, existing);
253
+ };
254
+ Object.entries(factoryInfo.internalComponentProps[targetInfo.name] ?? {}).forEach(([propName, values]) => addPropValues(propName, values));
255
+ const localNames = getFactoryLocalNames(source, imp);
256
+ const apiNames = /* @__PURE__ */ new Set();
257
+ source.callExpressions.forEach((call) => {
258
+ if (call.callee.type !== "Identifier" || !localNames.has(call.callee.name)) return;
259
+ extractFactoryCallArgProps(call.arguments[0], source).forEach(([propName, values]) => addPropValues(propName, values));
260
+ const parent = source.parents.get(call);
261
+ if (parent?.type === "VariableDeclarator" && parent.id.type === "Identifier") apiNames.add(parent.id.name);
262
+ stats.expressionsResolved++;
263
+ });
264
+ if (apiNames.size > 0) source.callExpressions.forEach((call) => {
265
+ const callee = call.callee;
266
+ if (callee.type !== "MemberExpression" || callee.object.type !== "Identifier" || !apiNames.has(callee.object.name) || callee.property.type !== "Identifier" || callee.property.name !== "update") return;
267
+ extractFactoryCallArgProps(call.arguments[0], source).forEach(([propName, values]) => addPropValues(propName, values));
268
+ });
269
+ componentProps.set(targetInfo.name, propsMap);
270
+ if (!componentUnresolvedSpreadProps.has(targetInfo.name)) componentUnresolvedSpreadProps.set(targetInfo.name, /* @__PURE__ */ new Set());
271
+ });
241
272
  const jsxAnalysisMs = performance.now() - jsxAnalysisStart;
242
273
  const safelistGenStart = performance.now();
243
274
  const allComponents = [];
@@ -392,6 +423,37 @@ const purgeFromCodeOptimized = async (code, options) => {
392
423
  };
393
424
  };
394
425
  /**
426
+ * Local aliases a UDS import is bound to in this file (handles `import { createToast as x }`)
427
+ */
428
+ const getFactoryLocalNames = (source, importName) => {
429
+ const localNames = /* @__PURE__ */ new Set();
430
+ source.staticImports.forEach((staticImport) => {
431
+ if (!isUdsComponentModule(staticImport.moduleRequest.value)) return;
432
+ staticImport.entries.forEach((entry) => {
433
+ if (entry.importName.kind === "Name" && entry.importName.name === importName && !entry.isType) localNames.add(entry.localName.value);
434
+ });
435
+ });
436
+ return localNames;
437
+ };
438
+ /**
439
+ * Extract prop literals from a factory call's first argument: an inline object
440
+ * literal, or a same-file object variable (reuses spread tracing).
441
+ */
442
+ const extractFactoryCallArgProps = (firstArg, source) => {
443
+ if (!firstArg) return [];
444
+ if (firstArg.type === "Identifier") return traceSpreadInFile(firstArg.name, source);
445
+ const props = [];
446
+ getSpreadObjectLiteralCandidates(firstArg).forEach((objLiteral) => {
447
+ objLiteral.properties.forEach((prop) => {
448
+ if (prop.type !== "Property") return;
449
+ const propName = getPropertyName(source, prop);
450
+ const values = prop.value ? extractStringLiterals(prop.value, source) : [];
451
+ props.push([propName, values]);
452
+ });
453
+ });
454
+ return props;
455
+ };
456
+ /**
395
457
  * Find JSX references for a component in the source file
396
458
  */
397
459
  const findComponentReferences = (source, componentName) => {