@yahoo/uds 3.114.0 → 3.115.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/automated-config/dist/mapTextVariantFixtureToValue.cjs +12 -1
- package/dist/automated-config/dist/mapTextVariantFixtureToValue.js +12 -1
- package/dist/automated-config/dist/properties.cjs +1 -1
- package/dist/automated-config/dist/properties.js +1 -1
- package/dist/cli/commands/sync.cjs +1 -3
- package/dist/cli/commands/sync.d.cts +1 -1
- package/dist/cli/commands/sync.d.ts +1 -1
- package/dist/cli/commands/sync.js +1 -3
- package/dist/cli/commands/version.cjs +0 -2
- package/dist/cli/commands/version.d.cts +1 -1
- package/dist/cli/commands/version.d.ts +1 -1
- package/dist/cli/commands/version.js +0 -2
- package/dist/cli/dist/commands/editor-rules.cjs +1 -1
- package/dist/cli/dist/commands/editor-rules.js +1 -1
- package/dist/cli/dist/lib/logger.cjs +66 -0
- package/dist/cli/dist/lib/logger.js +66 -0
- package/dist/cli/runner.cjs +9 -0
- package/dist/cli/runner.js +9 -0
- package/dist/components/client/Menu/Menu.ItemCheckbox.d.cts +1 -1
- package/dist/components/client/Menu/Menu.ItemCheckbox.d.ts +1 -1
- package/dist/index.cjs +2 -0
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +2 -1
- package/dist/styles/styler.d.cts +29 -29
- package/dist/styles/styler.d.ts +29 -29
- package/dist/styles/variants.cjs +278 -278
- package/dist/styles/variants.js +278 -278
- package/dist/tailwind/dist/commands/css.cjs +79 -0
- package/dist/tailwind/dist/commands/css.helpers.cjs +32 -0
- package/dist/tailwind/dist/commands/css.helpers.js +28 -0
- package/dist/tailwind/dist/commands/css.js +79 -0
- package/dist/tailwind/dist/commands/generateComponentData.cjs +33 -31
- package/dist/tailwind/dist/commands/generateComponentData.d.ts +1 -1
- package/dist/tailwind/dist/commands/generateComponentData.js +33 -31
- package/dist/tailwind/dist/commands/purge.cjs +3 -4
- package/dist/tailwind/dist/commands/purge.js +3 -4
- package/dist/tailwind/dist/css/generate.cjs +121 -0
- package/dist/tailwind/dist/css/generate.d.cts +30 -0
- package/dist/tailwind/dist/css/generate.d.ts +31 -0
- package/dist/tailwind/dist/css/generate.helpers.cjs +112 -0
- package/dist/tailwind/dist/css/generate.helpers.js +100 -0
- package/dist/tailwind/dist/css/generate.js +116 -0
- package/dist/tailwind/dist/css/nodeUtils.cjs +156 -0
- package/dist/tailwind/dist/css/nodeUtils.js +149 -0
- package/dist/tailwind/dist/css/postcss.cjs +35 -0
- package/dist/tailwind/dist/css/postcss.helpers.cjs +27 -0
- package/dist/tailwind/dist/css/postcss.helpers.js +26 -0
- package/dist/tailwind/dist/css/postcss.js +35 -0
- package/dist/tailwind/dist/css/runner.cjs +279 -0
- package/dist/tailwind/dist/css/runner.helpers.cjs +26 -0
- package/dist/tailwind/dist/css/runner.helpers.js +23 -0
- package/dist/tailwind/dist/css/runner.js +276 -0
- package/dist/tailwind/dist/css/theme.cjs +12 -0
- package/dist/tailwind/dist/css/theme.d.cts +66 -0
- package/dist/tailwind/dist/css/theme.d.ts +66 -0
- package/dist/tailwind/dist/css/theme.js +11 -0
- package/dist/tailwind/dist/css/utils.cjs +72 -0
- package/dist/tailwind/dist/css/utils.js +69 -0
- package/dist/tailwind/dist/index.d.cts +1 -0
- package/dist/tailwind/dist/index.d.ts +2 -4
- package/dist/tailwind/dist/purger/legacy/purgeCSS.cjs +2 -1
- package/dist/tailwind/dist/purger/legacy/purgeCSS.js +2 -1
- package/dist/tailwind/dist/purger/optimized/ast/expressions.cjs +122 -125
- package/dist/tailwind/dist/purger/optimized/ast/expressions.js +122 -125
- package/dist/tailwind/dist/purger/optimized/ast/jsx.cjs +1 -8
- package/dist/tailwind/dist/purger/optimized/ast/jsx.js +1 -8
- package/dist/tailwind/dist/purger/optimized/purge.cjs +9 -8
- package/dist/tailwind/dist/purger/optimized/purge.js +9 -8
- package/dist/tailwind/dist/purger/optimized/purgeFromCode.cjs +238 -127
- package/dist/tailwind/dist/purger/optimized/purgeFromCode.js +238 -127
- package/dist/tailwind/dist/purger/optimized/utils/componentAnalyzer.cjs +352 -260
- package/dist/tailwind/dist/purger/optimized/utils/componentAnalyzer.js +351 -260
- package/dist/tailwind/dist/purger/optimized/utils/files.cjs +4 -3
- package/dist/tailwind/dist/purger/optimized/utils/files.js +4 -3
- package/dist/tailwind/dist/purger/optimized/utils/safelist.cjs +12 -20
- package/dist/tailwind/dist/purger/optimized/utils/safelist.js +12 -20
- package/dist/tailwind/dist/tailwind/components/getResponsiveTextStyles.cjs +1 -1
- package/dist/tailwind/dist/tailwind/components/getResponsiveTextStyles.js +1 -1
- package/dist/tailwind/dist/tailwind/plugins/breakpoints.cjs +1 -1
- package/dist/tailwind/dist/tailwind/plugins/breakpoints.js +1 -1
- package/dist/tailwind/dist/tailwind/plugins/typography.cjs +41 -13
- package/dist/tailwind/dist/tailwind/plugins/typography.js +41 -13
- package/dist/tailwind/dist/tailwind/utils/composeTailwindPlugins.cjs +4 -2
- package/dist/tailwind/dist/tailwind/utils/composeTailwindPlugins.d.cts +10 -1
- package/dist/tailwind/dist/tailwind/utils/composeTailwindPlugins.d.ts +10 -1
- package/dist/tailwind/dist/tailwind/utils/composeTailwindPlugins.js +4 -2
- package/dist/tailwind/dist/utils/optimizeCSS.cjs +405 -0
- package/dist/tailwind/dist/utils/optimizeCSS.js +403 -0
- package/dist/tailwind/dist/utils/postcssPreserveVars.cjs +67 -0
- package/dist/tailwind/dist/utils/postcssPreserveVars.js +65 -0
- package/dist/tailwind/dist/utils/tsMorph.cjs +1 -1
- package/dist/uds/generated/componentData.cjs +1218 -1182
- package/dist/uds/generated/componentData.js +1218 -1182
- package/dist/uds/package.cjs +10 -4
- package/dist/uds/package.js +10 -4
- package/generated/componentData.json +2683 -0
- package/generated/tailwindPurge.ts +4591 -0
- package/package.json +7 -4
- package/dist/tailwind/dist/commands/generatePurgeCSSData.d.ts +0 -3
- package/dist/tailwind/dist/commands/purge.d.ts +0 -4
- package/dist/tailwind/dist/purger/legacy/purgeCSS.d.ts +0 -2
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
|
|
2
|
+
const require_runtime = require('../../../_virtual/_rolldown/runtime.cjs');
|
|
3
|
+
const require_utils = require('./utils.cjs');
|
|
4
|
+
const require_plugin = require('../plugin.cjs');
|
|
5
|
+
const require_optimizeCSS = require('../utils/optimizeCSS.cjs');
|
|
6
|
+
const require_postcssPreserveVars = require('../utils/postcssPreserveVars.cjs');
|
|
7
|
+
const require_postcss = require('./postcss.cjs');
|
|
8
|
+
let node_path = require("node:path");
|
|
9
|
+
node_path = require_runtime.__toESM(node_path);
|
|
10
|
+
let postcss = require("postcss");
|
|
11
|
+
postcss = require_runtime.__toESM(postcss);
|
|
12
|
+
let autoprefixer = require("autoprefixer");
|
|
13
|
+
autoprefixer = require_runtime.__toESM(autoprefixer);
|
|
14
|
+
let postcss_prune_var = require("postcss-prune-var");
|
|
15
|
+
postcss_prune_var = require_runtime.__toESM(postcss_prune_var);
|
|
16
|
+
let postcss_scope = require("postcss-scope");
|
|
17
|
+
postcss_scope = require_runtime.__toESM(postcss_scope);
|
|
18
|
+
let tailwindcss = require("tailwindcss");
|
|
19
|
+
tailwindcss = require_runtime.__toESM(tailwindcss);
|
|
20
|
+
|
|
21
|
+
//#region ../tailwind/dist/css/generate.helpers.js
|
|
22
|
+
/*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
|
|
23
|
+
const getCssFeatureFlags = (cssOptions) => {
|
|
24
|
+
const optimizationConfig = cssOptions?.optimization;
|
|
25
|
+
const shouldOptimize = optimizationConfig?.enabled !== false;
|
|
26
|
+
return {
|
|
27
|
+
enablePreflight: cssOptions?.preflight !== false,
|
|
28
|
+
enableFontFaceDeclarations: cssOptions?.fontFaceDeclarations !== false,
|
|
29
|
+
shouldOptimize,
|
|
30
|
+
shouldPruneVars: shouldOptimize && optimizationConfig?.pruneVars !== false
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
const getContentGlobs = (contentDir) => [node_path.default.join(contentDir, "**/*.{js,jsx,ts,tsx}")];
|
|
34
|
+
const createTailwindPlugin = (options) => {
|
|
35
|
+
return (0, tailwindcss.default)({
|
|
36
|
+
content: getContentGlobs(options.contentDir),
|
|
37
|
+
safelist: options.safelist,
|
|
38
|
+
corePlugins: { preflight: options.enablePreflight },
|
|
39
|
+
plugins: [require_plugin.tailwindPlugin({
|
|
40
|
+
config: options.config,
|
|
41
|
+
disableFontFaceDeclarations: !options.enableFontFaceDeclarations,
|
|
42
|
+
ignorePluginSafelists: true
|
|
43
|
+
})]
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
const getPruneVarPlugins = (safeVarPrefixes) => {
|
|
47
|
+
if (safeVarPrefixes.length === 0) return [(0, postcss_prune_var.default)()];
|
|
48
|
+
return [
|
|
49
|
+
require_postcssPreserveVars.preserveVars({ preserve: safeVarPrefixes }),
|
|
50
|
+
(0, postcss_prune_var.default)(),
|
|
51
|
+
require_postcssPreserveVars.preserveVarsCleanup()
|
|
52
|
+
];
|
|
53
|
+
};
|
|
54
|
+
const buildPostcssPlugins = (options) => {
|
|
55
|
+
const plugins = [options.tailwindPlugin, (0, autoprefixer.default)()];
|
|
56
|
+
if (options.shouldPruneVars) plugins.push(...getPruneVarPlugins(options.safeVarPrefixes));
|
|
57
|
+
if (options.scopeClass) plugins.push((0, postcss_scope.default)(options.scopeClass));
|
|
58
|
+
return plugins;
|
|
59
|
+
};
|
|
60
|
+
const applyScopedColorModeFix = async (css, scopeClass) => {
|
|
61
|
+
if (!scopeClass) return css;
|
|
62
|
+
return (await (0, postcss.default)([require_postcss.fixScopedColorModeSelectorsPlugin(scopeClass)]).process(css, { from: void 0 })).css;
|
|
63
|
+
};
|
|
64
|
+
const optimizeGeneratedCss = async (options) => {
|
|
65
|
+
if (!options.shouldOptimize) return { css: options.css };
|
|
66
|
+
const optimizationOptions = {
|
|
67
|
+
removeUnusedFonts: options.optimizationConfig?.removeUnusedFonts,
|
|
68
|
+
removeEmptyRules: options.optimizationConfig?.removeEmptyRules,
|
|
69
|
+
aggregateDuplicateSelectors: options.optimizationConfig?.aggregateDuplicateSelectors,
|
|
70
|
+
referenceCss: options.referenceCss,
|
|
71
|
+
scopeClass: options.scopeClass
|
|
72
|
+
};
|
|
73
|
+
const optimized = await require_optimizeCSS.optimizeCSS(options.css, optimizationOptions);
|
|
74
|
+
return {
|
|
75
|
+
css: optimized.css,
|
|
76
|
+
optimizationStats: {
|
|
77
|
+
originalSize: optimized.stats.originalSize,
|
|
78
|
+
originalSizeGzip: optimized.stats.originalSizeGzip,
|
|
79
|
+
fontFacesRemoved: optimized.stats.fontFacesRemoved,
|
|
80
|
+
emptyRulesRemoved: optimized.stats.emptyRulesRemoved,
|
|
81
|
+
validationErrors: optimized.validation.errors
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
const printSimpleModeStats = (options) => {
|
|
86
|
+
const { print, magenta, cyan, yellow } = options;
|
|
87
|
+
print("");
|
|
88
|
+
print(`${magenta("Output:")} ${cyan(options.outputPath)}`);
|
|
89
|
+
print(`${magenta("Stats:")}`);
|
|
90
|
+
print(` Files scanned: ${options.totalFilesScanned}`);
|
|
91
|
+
print(` Classes: ${options.classCount}`);
|
|
92
|
+
print(` Size: ${require_utils.formatBytes(options.sizeBytes)} (${require_utils.formatBytes(options.sizeGzipBytes)} gzipped)`);
|
|
93
|
+
const optimizationStats = options.optimizationStats;
|
|
94
|
+
if (optimizationStats) {
|
|
95
|
+
const savedBytesGzip = optimizationStats.originalSizeGzip - options.sizeGzipBytes;
|
|
96
|
+
if (savedBytesGzip > 0) print(` Optimized: saved ${require_utils.formatBytes(savedBytesGzip)} gzip (${optimizationStats.fontFacesRemoved} unused @font-face, ${optimizationStats.emptyRulesRemoved} empty rules removed)`);
|
|
97
|
+
if (optimizationStats.validationErrors.length > 0) {
|
|
98
|
+
print(` ${yellow("Validation warnings:")}`);
|
|
99
|
+
optimizationStats.validationErrors.forEach((error) => print(` ${yellow("•")} ${error}`));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
print(` Time: ${options.duration}ms`);
|
|
103
|
+
if (options.scope) print(` Scope: ${cyan(options.scope)}`);
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
//#endregion
|
|
107
|
+
exports.applyScopedColorModeFix = applyScopedColorModeFix;
|
|
108
|
+
exports.buildPostcssPlugins = buildPostcssPlugins;
|
|
109
|
+
exports.createTailwindPlugin = createTailwindPlugin;
|
|
110
|
+
exports.getCssFeatureFlags = getCssFeatureFlags;
|
|
111
|
+
exports.optimizeGeneratedCss = optimizeGeneratedCss;
|
|
112
|
+
exports.printSimpleModeStats = printSimpleModeStats;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
|
|
2
|
+
import { formatBytes } from "./utils.js";
|
|
3
|
+
import { tailwindPlugin } from "../plugin.js";
|
|
4
|
+
import { optimizeCSS } from "../utils/optimizeCSS.js";
|
|
5
|
+
import { preserveVars, preserveVarsCleanup } from "../utils/postcssPreserveVars.js";
|
|
6
|
+
import { fixScopedColorModeSelectorsPlugin } from "./postcss.js";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
import postcss from "postcss";
|
|
9
|
+
import autoprefixer from "autoprefixer";
|
|
10
|
+
import pruneVar from "postcss-prune-var";
|
|
11
|
+
import postcssScope from "postcss-scope";
|
|
12
|
+
import tailwindcss from "tailwindcss";
|
|
13
|
+
|
|
14
|
+
//#region ../tailwind/dist/css/generate.helpers.js
|
|
15
|
+
/*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
|
|
16
|
+
const getCssFeatureFlags = (cssOptions) => {
|
|
17
|
+
const optimizationConfig = cssOptions?.optimization;
|
|
18
|
+
const shouldOptimize = optimizationConfig?.enabled !== false;
|
|
19
|
+
return {
|
|
20
|
+
enablePreflight: cssOptions?.preflight !== false,
|
|
21
|
+
enableFontFaceDeclarations: cssOptions?.fontFaceDeclarations !== false,
|
|
22
|
+
shouldOptimize,
|
|
23
|
+
shouldPruneVars: shouldOptimize && optimizationConfig?.pruneVars !== false
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
const getContentGlobs = (contentDir) => [path.join(contentDir, "**/*.{js,jsx,ts,tsx}")];
|
|
27
|
+
const createTailwindPlugin = (options) => {
|
|
28
|
+
return tailwindcss({
|
|
29
|
+
content: getContentGlobs(options.contentDir),
|
|
30
|
+
safelist: options.safelist,
|
|
31
|
+
corePlugins: { preflight: options.enablePreflight },
|
|
32
|
+
plugins: [tailwindPlugin({
|
|
33
|
+
config: options.config,
|
|
34
|
+
disableFontFaceDeclarations: !options.enableFontFaceDeclarations,
|
|
35
|
+
ignorePluginSafelists: true
|
|
36
|
+
})]
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
const getPruneVarPlugins = (safeVarPrefixes) => {
|
|
40
|
+
if (safeVarPrefixes.length === 0) return [pruneVar()];
|
|
41
|
+
return [
|
|
42
|
+
preserveVars({ preserve: safeVarPrefixes }),
|
|
43
|
+
pruneVar(),
|
|
44
|
+
preserveVarsCleanup()
|
|
45
|
+
];
|
|
46
|
+
};
|
|
47
|
+
const buildPostcssPlugins = (options) => {
|
|
48
|
+
const plugins = [options.tailwindPlugin, autoprefixer()];
|
|
49
|
+
if (options.shouldPruneVars) plugins.push(...getPruneVarPlugins(options.safeVarPrefixes));
|
|
50
|
+
if (options.scopeClass) plugins.push(postcssScope(options.scopeClass));
|
|
51
|
+
return plugins;
|
|
52
|
+
};
|
|
53
|
+
const applyScopedColorModeFix = async (css, scopeClass) => {
|
|
54
|
+
if (!scopeClass) return css;
|
|
55
|
+
return (await postcss([fixScopedColorModeSelectorsPlugin(scopeClass)]).process(css, { from: void 0 })).css;
|
|
56
|
+
};
|
|
57
|
+
const optimizeGeneratedCss = async (options) => {
|
|
58
|
+
if (!options.shouldOptimize) return { css: options.css };
|
|
59
|
+
const optimizationOptions = {
|
|
60
|
+
removeUnusedFonts: options.optimizationConfig?.removeUnusedFonts,
|
|
61
|
+
removeEmptyRules: options.optimizationConfig?.removeEmptyRules,
|
|
62
|
+
aggregateDuplicateSelectors: options.optimizationConfig?.aggregateDuplicateSelectors,
|
|
63
|
+
referenceCss: options.referenceCss,
|
|
64
|
+
scopeClass: options.scopeClass
|
|
65
|
+
};
|
|
66
|
+
const optimized = await optimizeCSS(options.css, optimizationOptions);
|
|
67
|
+
return {
|
|
68
|
+
css: optimized.css,
|
|
69
|
+
optimizationStats: {
|
|
70
|
+
originalSize: optimized.stats.originalSize,
|
|
71
|
+
originalSizeGzip: optimized.stats.originalSizeGzip,
|
|
72
|
+
fontFacesRemoved: optimized.stats.fontFacesRemoved,
|
|
73
|
+
emptyRulesRemoved: optimized.stats.emptyRulesRemoved,
|
|
74
|
+
validationErrors: optimized.validation.errors
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
const printSimpleModeStats = (options) => {
|
|
79
|
+
const { print, magenta, cyan, yellow } = options;
|
|
80
|
+
print("");
|
|
81
|
+
print(`${magenta("Output:")} ${cyan(options.outputPath)}`);
|
|
82
|
+
print(`${magenta("Stats:")}`);
|
|
83
|
+
print(` Files scanned: ${options.totalFilesScanned}`);
|
|
84
|
+
print(` Classes: ${options.classCount}`);
|
|
85
|
+
print(` Size: ${formatBytes(options.sizeBytes)} (${formatBytes(options.sizeGzipBytes)} gzipped)`);
|
|
86
|
+
const optimizationStats = options.optimizationStats;
|
|
87
|
+
if (optimizationStats) {
|
|
88
|
+
const savedBytesGzip = optimizationStats.originalSizeGzip - options.sizeGzipBytes;
|
|
89
|
+
if (savedBytesGzip > 0) print(` Optimized: saved ${formatBytes(savedBytesGzip)} gzip (${optimizationStats.fontFacesRemoved} unused @font-face, ${optimizationStats.emptyRulesRemoved} empty rules removed)`);
|
|
90
|
+
if (optimizationStats.validationErrors.length > 0) {
|
|
91
|
+
print(` ${yellow("Validation warnings:")}`);
|
|
92
|
+
optimizationStats.validationErrors.forEach((error) => print(` ${yellow("•")} ${error}`));
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
print(` Time: ${options.duration}ms`);
|
|
96
|
+
if (options.scope) print(` Scope: ${cyan(options.scope)}`);
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
//#endregion
|
|
100
|
+
export { applyScopedColorModeFix, buildPostcssPlugins, createTailwindPlugin, getCssFeatureFlags, optimizeGeneratedCss, printSimpleModeStats };
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
|
|
2
|
+
import { defaultTokensConfig } from "../../../config/dist/index.js";
|
|
3
|
+
import { cyan, magenta, yellow } from "../../../cli/dist/lib/colors.js";
|
|
4
|
+
import { print } from "../../../cli/dist/lib/print.js";
|
|
5
|
+
import { spinStop } from "../../../cli/dist/lib/spinner.js";
|
|
6
|
+
import { loadConfigFile, scanDirectoryForSafelist } from "./nodeUtils.js";
|
|
7
|
+
import { deduplicateSafelist, getThemeAndScaleClasses } from "../purger/optimized/utils/safelist.js";
|
|
8
|
+
import { extractVariantDefaults, getConfigurableCssVariables, getMotionVarPrefixes } from "./utils.js";
|
|
9
|
+
import { applyScopedColorModeFix, buildPostcssPlugins, createTailwindPlugin, getCssFeatureFlags, optimizeGeneratedCss, printSimpleModeStats } from "./generate.helpers.js";
|
|
10
|
+
import path from "node:path";
|
|
11
|
+
import fs from "node:fs";
|
|
12
|
+
import { gzipSync } from "node:zlib";
|
|
13
|
+
import postcss from "postcss";
|
|
14
|
+
|
|
15
|
+
//#region ../tailwind/dist/css/generate.js
|
|
16
|
+
/*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
|
|
17
|
+
const normalizeScope = (scope) => {
|
|
18
|
+
const trimmedScope = scope?.trim();
|
|
19
|
+
return trimmedScope ? trimmedScope : void 0;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Generate CSS from a safelist using Tailwind + PostCSS
|
|
23
|
+
* @param safelist - UDS component classes to include
|
|
24
|
+
* @param config - Token configuration
|
|
25
|
+
* @param options - Additional options
|
|
26
|
+
*/
|
|
27
|
+
const generateCSS = async (safelist, config, options) => {
|
|
28
|
+
const sourceCSS = "@tailwind base; @tailwind components; @tailwind utilities";
|
|
29
|
+
const contentDir = options?.contentDir ?? path.join(process.cwd(), "src");
|
|
30
|
+
const cssFlags = getCssFeatureFlags(options?.cssOptions);
|
|
31
|
+
const optimizationConfig = options?.cssOptions?.optimization;
|
|
32
|
+
const scopeClass = normalizeScope(options?.scope) ?? normalizeScope(options?.cssOptions?.scope);
|
|
33
|
+
let css = await applyScopedColorModeFix((await postcss(buildPostcssPlugins({
|
|
34
|
+
tailwindPlugin: createTailwindPlugin({
|
|
35
|
+
contentDir,
|
|
36
|
+
safelist,
|
|
37
|
+
config,
|
|
38
|
+
enablePreflight: cssFlags.enablePreflight,
|
|
39
|
+
enableFontFaceDeclarations: cssFlags.enableFontFaceDeclarations
|
|
40
|
+
}),
|
|
41
|
+
shouldPruneVars: cssFlags.shouldPruneVars,
|
|
42
|
+
safeVarPrefixes: options?.safeVarPrefixes ?? [],
|
|
43
|
+
scopeClass
|
|
44
|
+
})).process(sourceCSS, { from: void 0 })).css, scopeClass);
|
|
45
|
+
const optimizedCss = await optimizeGeneratedCss({
|
|
46
|
+
css,
|
|
47
|
+
shouldOptimize: cssFlags.shouldOptimize,
|
|
48
|
+
optimizationConfig,
|
|
49
|
+
referenceCss: options?.referenceCss,
|
|
50
|
+
scopeClass
|
|
51
|
+
});
|
|
52
|
+
css = optimizedCss.css;
|
|
53
|
+
const sizeBytes = Buffer.byteLength(css, "utf8");
|
|
54
|
+
const sizeGzipBytes = gzipSync(css).length;
|
|
55
|
+
return {
|
|
56
|
+
css,
|
|
57
|
+
sizeBytes,
|
|
58
|
+
sizeGzipBytes,
|
|
59
|
+
classCount: safelist.length,
|
|
60
|
+
optimizationStats: optimizedCss.optimizationStats
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Generate CSS in simple mode (no uds.theme.ts)
|
|
65
|
+
*/
|
|
66
|
+
const generateSimpleModeCSS = async (options) => {
|
|
67
|
+
const isWatch = options.isWatch === true;
|
|
68
|
+
const shouldLogStats = !(options.silent === true) && !isWatch;
|
|
69
|
+
const startTime = performance.now();
|
|
70
|
+
const colorModes = ["dark"];
|
|
71
|
+
let tokensConfig = defaultTokensConfig;
|
|
72
|
+
if (options.configPath) {
|
|
73
|
+
const loadedConfig = await loadConfigFile(options.configPath);
|
|
74
|
+
if (loadedConfig) tokensConfig = loadedConfig;
|
|
75
|
+
else if (shouldLogStats) spinStop("⚠️", `Config file not found: ${options.configPath}, using defaults`);
|
|
76
|
+
}
|
|
77
|
+
const variantDefaults = extractVariantDefaults(tokensConfig);
|
|
78
|
+
const entryDir = path.join(options.workspaceDir, options.entry);
|
|
79
|
+
const scanResult = await scanDirectoryForSafelist(entryDir, colorModes, options.variants, options.autoVariants, options.componentData, variantDefaults);
|
|
80
|
+
const totalFilesScanned = scanResult.filesScanned;
|
|
81
|
+
const allClasses = [...scanResult.safelist];
|
|
82
|
+
const allComponents = new Set(scanResult.components);
|
|
83
|
+
const packageDirs = [entryDir];
|
|
84
|
+
const cssResult = await generateCSS(deduplicateSafelist([...allClasses, ...getThemeAndScaleClasses(colorModes)]), tokensConfig, {
|
|
85
|
+
scope: options.scope,
|
|
86
|
+
contentDir: entryDir,
|
|
87
|
+
safeVarPrefixes: [...getMotionVarPrefixes(options.componentData, [...allComponents]), ...getConfigurableCssVariables()]
|
|
88
|
+
});
|
|
89
|
+
const outputPath = path.isAbsolute(options.outFile) ? options.outFile : path.join(options.workspaceDir, options.outFile);
|
|
90
|
+
const outputDir = path.dirname(outputPath);
|
|
91
|
+
if (!fs.existsSync(outputDir)) fs.mkdirSync(outputDir, { recursive: true });
|
|
92
|
+
fs.writeFileSync(outputPath, cssResult.css);
|
|
93
|
+
const duration = Math.round(performance.now() - startTime);
|
|
94
|
+
if (shouldLogStats) printSimpleModeStats({
|
|
95
|
+
outputPath,
|
|
96
|
+
totalFilesScanned,
|
|
97
|
+
classCount: cssResult.classCount,
|
|
98
|
+
sizeBytes: cssResult.sizeBytes,
|
|
99
|
+
sizeGzipBytes: cssResult.sizeGzipBytes,
|
|
100
|
+
duration,
|
|
101
|
+
scope: options.scope,
|
|
102
|
+
optimizationStats: cssResult.optimizationStats,
|
|
103
|
+
print,
|
|
104
|
+
magenta,
|
|
105
|
+
cyan,
|
|
106
|
+
yellow
|
|
107
|
+
});
|
|
108
|
+
return {
|
|
109
|
+
success: true,
|
|
110
|
+
outputPath,
|
|
111
|
+
packageDirs
|
|
112
|
+
};
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
//#endregion
|
|
116
|
+
export { generateCSS, generateSimpleModeCSS };
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
|
|
2
|
+
const require_runtime = require('../../../_virtual/_rolldown/runtime.cjs');
|
|
3
|
+
const require_colors = require('../../../cli/dist/lib/colors.cjs');
|
|
4
|
+
const require_print = require('../../../cli/dist/lib/print.cjs');
|
|
5
|
+
const require_purgeFromCode = require('../purger/optimized/purgeFromCode.cjs');
|
|
6
|
+
let node_path = require("node:path");
|
|
7
|
+
node_path = require_runtime.__toESM(node_path);
|
|
8
|
+
let node_fs = require("node:fs");
|
|
9
|
+
node_fs = require_runtime.__toESM(node_fs);
|
|
10
|
+
let node_module = require("node:module");
|
|
11
|
+
let fast_glob = require("fast-glob");
|
|
12
|
+
fast_glob = require_runtime.__toESM(fast_glob);
|
|
13
|
+
|
|
14
|
+
//#region ../tailwind/dist/css/nodeUtils.js
|
|
15
|
+
/*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
|
|
16
|
+
const loadConfigFile = async (configPath) => {
|
|
17
|
+
const absolutePath = node_path.default.isAbsolute(configPath) ? configPath : node_path.default.join(process.cwd(), configPath);
|
|
18
|
+
if (!node_fs.default.existsSync(absolutePath)) return null;
|
|
19
|
+
try {
|
|
20
|
+
const module = await import(absolutePath);
|
|
21
|
+
return module.default ?? module.config ?? module;
|
|
22
|
+
} catch (error) {
|
|
23
|
+
throw new Error(`Failed to load config file: ${absolutePath}\n${error instanceof Error ? error.message : "Unknown error"}`);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
const scanDirectoryForSafelist = async (dir, colorModes, variants, autoVariants, componentData, variantDefaults, includeAllClassNamePrimitives = false) => {
|
|
27
|
+
const files = await (0, fast_glob.default)("**/*.{js,jsx,ts,tsx}", {
|
|
28
|
+
cwd: dir,
|
|
29
|
+
absolute: true,
|
|
30
|
+
ignore: ["**/node_modules/**"]
|
|
31
|
+
});
|
|
32
|
+
const results = await Promise.all(files.map(async (filePath) => {
|
|
33
|
+
return require_purgeFromCode.purgeFromCodeOptimized(node_fs.default.readFileSync(filePath, "utf-8"), {
|
|
34
|
+
colorModes,
|
|
35
|
+
variantDefaults,
|
|
36
|
+
variants,
|
|
37
|
+
autoVariants,
|
|
38
|
+
componentData,
|
|
39
|
+
includeAllClassNamePrimitives
|
|
40
|
+
});
|
|
41
|
+
}));
|
|
42
|
+
return {
|
|
43
|
+
safelist: results.flatMap((result) => result.safelist),
|
|
44
|
+
components: [...new Set(results.flatMap((result) => result.components))],
|
|
45
|
+
filesScanned: files.length
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
const findMonorepoRoot = (startDir) => {
|
|
49
|
+
const findUp = (currentDir) => {
|
|
50
|
+
if (node_fs.default.existsSync(node_path.default.join(currentDir, "packages"))) return currentDir;
|
|
51
|
+
const parentDir = node_path.default.dirname(currentDir);
|
|
52
|
+
return parentDir === currentDir ? null : findUp(parentDir);
|
|
53
|
+
};
|
|
54
|
+
return findUp(startDir);
|
|
55
|
+
};
|
|
56
|
+
const resolvePackageRoot = (workspaceDir, packageName) => {
|
|
57
|
+
const require = (0, node_module.createRequire)(require("url").pathToFileURL(__filename).href);
|
|
58
|
+
try {
|
|
59
|
+
const resolvedPackageJson = require.resolve(node_path.default.join(packageName, "package.json"), { paths: [workspaceDir] });
|
|
60
|
+
return node_path.default.dirname(resolvedPackageJson);
|
|
61
|
+
} catch {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
const findPackageRootInMonorepo = (monorepoRoot, packageName) => {
|
|
66
|
+
const matchingPath = fast_glob.default.sync("packages/**/package.json", {
|
|
67
|
+
cwd: monorepoRoot,
|
|
68
|
+
absolute: true,
|
|
69
|
+
ignore: ["**/node_modules/**", "**/dist/**"]
|
|
70
|
+
}).find((pkgJsonPath) => {
|
|
71
|
+
try {
|
|
72
|
+
return JSON.parse(node_fs.default.readFileSync(pkgJsonPath, "utf8")).name === packageName;
|
|
73
|
+
} catch {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
return matchingPath ? node_path.default.dirname(matchingPath) : null;
|
|
78
|
+
};
|
|
79
|
+
const buildPackageSourceCandidates = (workspaceDir, packageName, packageRoot) => {
|
|
80
|
+
return [
|
|
81
|
+
packageRoot ? node_path.default.join(packageRoot, "src") : null,
|
|
82
|
+
packageRoot ? node_path.default.join(packageRoot, "lib") : null,
|
|
83
|
+
packageRoot ? node_path.default.join(packageRoot, "dist") : null,
|
|
84
|
+
packageRoot,
|
|
85
|
+
node_path.default.join(workspaceDir, "node_modules", packageName, "src"),
|
|
86
|
+
node_path.default.join(workspaceDir, "node_modules", packageName, "lib"),
|
|
87
|
+
node_path.default.join(workspaceDir, "node_modules", packageName, "dist"),
|
|
88
|
+
node_path.default.join(workspaceDir, "node_modules", packageName)
|
|
89
|
+
].filter(Boolean);
|
|
90
|
+
};
|
|
91
|
+
const getFirstExistingPath = (candidates) => candidates.find((candidate) => node_fs.default.existsSync(candidate)) ?? null;
|
|
92
|
+
const findPackageSourceDir = (packageName) => {
|
|
93
|
+
const workspaceDir = process.cwd();
|
|
94
|
+
const monorepoRoot = findMonorepoRoot(workspaceDir);
|
|
95
|
+
let packageRoot = resolvePackageRoot(workspaceDir, packageName);
|
|
96
|
+
if (!packageRoot && monorepoRoot) packageRoot = findPackageRootInMonorepo(monorepoRoot, packageName);
|
|
97
|
+
return getFirstExistingPath(buildPackageSourceCandidates(workspaceDir, packageName, packageRoot));
|
|
98
|
+
};
|
|
99
|
+
const scaffoldThemeConfig = async (options) => {
|
|
100
|
+
const workspaceDir = process.cwd();
|
|
101
|
+
const outputPath = options.outputPath ?? "uds.theme.ts";
|
|
102
|
+
const absoluteOutputPath = node_path.default.isAbsolute(outputPath) ? outputPath : node_path.default.join(workspaceDir, outputPath);
|
|
103
|
+
if (node_fs.default.existsSync(absoluteOutputPath) && !options.force) {
|
|
104
|
+
require_print.print(require_colors.red(`Error: ${outputPath} already exists. Use --force to overwrite.`));
|
|
105
|
+
process.exitCode = 1;
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const template = `import { defineTheme } from '@yahoo/uds';
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* UDS Theme Configuration
|
|
112
|
+
*
|
|
113
|
+
* This file configures CSS generation for your app and shared packages.
|
|
114
|
+
* Run \`uds css\` to generate optimized CSS.
|
|
115
|
+
*/
|
|
116
|
+
export default defineTheme({
|
|
117
|
+
// Path to your uds.config.ts file
|
|
118
|
+
config: '${options.configPath ?? "./uds.config.ts"}',
|
|
119
|
+
|
|
120
|
+
// Entry directory for scanning your app code
|
|
121
|
+
entry: '${options.entry ?? "./src"}',
|
|
122
|
+
|
|
123
|
+
// Color modes to include (light mode is always in :root)
|
|
124
|
+
colorModes: ['dark'],
|
|
125
|
+
|
|
126
|
+
// Packages that inherit your app's theme (merged into main uds.css)
|
|
127
|
+
// inherit: ['@your-org/shared-ui'],
|
|
128
|
+
|
|
129
|
+
// CSS generation options (all optional)
|
|
130
|
+
// css: {
|
|
131
|
+
// safelist: [],
|
|
132
|
+
// preflight: true,
|
|
133
|
+
// fontFaceDeclarations: true,
|
|
134
|
+
// optimization: {
|
|
135
|
+
// removeUnusedFonts: false,
|
|
136
|
+
// removeEmptyRules: true,
|
|
137
|
+
// deduplicateScopedCss: true
|
|
138
|
+
// }
|
|
139
|
+
// }
|
|
140
|
+
});
|
|
141
|
+
`;
|
|
142
|
+
node_fs.default.writeFileSync(absoluteOutputPath, template);
|
|
143
|
+
require_print.print("");
|
|
144
|
+
require_print.print(require_colors.green("✅ Created uds.theme.ts"));
|
|
145
|
+
require_print.print("");
|
|
146
|
+
require_print.print(`${require_colors.magenta("Next steps:")}`);
|
|
147
|
+
require_print.print(` 1. Review and customize ${require_colors.cyan(outputPath)}`);
|
|
148
|
+
require_print.print(` 2. Run ${require_colors.cyan("uds css")} to generate CSS`);
|
|
149
|
+
require_print.print("");
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
//#endregion
|
|
153
|
+
exports.findPackageSourceDir = findPackageSourceDir;
|
|
154
|
+
exports.loadConfigFile = loadConfigFile;
|
|
155
|
+
exports.scaffoldThemeConfig = scaffoldThemeConfig;
|
|
156
|
+
exports.scanDirectoryForSafelist = scanDirectoryForSafelist;
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
|
|
2
|
+
import { cyan, green, magenta, red } from "../../../cli/dist/lib/colors.js";
|
|
3
|
+
import { print } from "../../../cli/dist/lib/print.js";
|
|
4
|
+
import { purgeFromCodeOptimized } from "../purger/optimized/purgeFromCode.js";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import fs from "node:fs";
|
|
7
|
+
import { createRequire } from "node:module";
|
|
8
|
+
import fg from "fast-glob";
|
|
9
|
+
|
|
10
|
+
//#region ../tailwind/dist/css/nodeUtils.js
|
|
11
|
+
/*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
|
|
12
|
+
const loadConfigFile = async (configPath) => {
|
|
13
|
+
const absolutePath = path.isAbsolute(configPath) ? configPath : path.join(process.cwd(), configPath);
|
|
14
|
+
if (!fs.existsSync(absolutePath)) return null;
|
|
15
|
+
try {
|
|
16
|
+
const module = await import(absolutePath);
|
|
17
|
+
return module.default ?? module.config ?? module;
|
|
18
|
+
} catch (error) {
|
|
19
|
+
throw new Error(`Failed to load config file: ${absolutePath}\n${error instanceof Error ? error.message : "Unknown error"}`);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
const scanDirectoryForSafelist = async (dir, colorModes, variants, autoVariants, componentData, variantDefaults, includeAllClassNamePrimitives = false) => {
|
|
23
|
+
const files = await fg("**/*.{js,jsx,ts,tsx}", {
|
|
24
|
+
cwd: dir,
|
|
25
|
+
absolute: true,
|
|
26
|
+
ignore: ["**/node_modules/**"]
|
|
27
|
+
});
|
|
28
|
+
const results = await Promise.all(files.map(async (filePath) => {
|
|
29
|
+
return purgeFromCodeOptimized(fs.readFileSync(filePath, "utf-8"), {
|
|
30
|
+
colorModes,
|
|
31
|
+
variantDefaults,
|
|
32
|
+
variants,
|
|
33
|
+
autoVariants,
|
|
34
|
+
componentData,
|
|
35
|
+
includeAllClassNamePrimitives
|
|
36
|
+
});
|
|
37
|
+
}));
|
|
38
|
+
return {
|
|
39
|
+
safelist: results.flatMap((result) => result.safelist),
|
|
40
|
+
components: [...new Set(results.flatMap((result) => result.components))],
|
|
41
|
+
filesScanned: files.length
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
const findMonorepoRoot = (startDir) => {
|
|
45
|
+
const findUp = (currentDir) => {
|
|
46
|
+
if (fs.existsSync(path.join(currentDir, "packages"))) return currentDir;
|
|
47
|
+
const parentDir = path.dirname(currentDir);
|
|
48
|
+
return parentDir === currentDir ? null : findUp(parentDir);
|
|
49
|
+
};
|
|
50
|
+
return findUp(startDir);
|
|
51
|
+
};
|
|
52
|
+
const resolvePackageRoot = (workspaceDir, packageName) => {
|
|
53
|
+
const require = createRequire(import.meta.url);
|
|
54
|
+
try {
|
|
55
|
+
const resolvedPackageJson = require.resolve(path.join(packageName, "package.json"), { paths: [workspaceDir] });
|
|
56
|
+
return path.dirname(resolvedPackageJson);
|
|
57
|
+
} catch {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
const findPackageRootInMonorepo = (monorepoRoot, packageName) => {
|
|
62
|
+
const matchingPath = fg.sync("packages/**/package.json", {
|
|
63
|
+
cwd: monorepoRoot,
|
|
64
|
+
absolute: true,
|
|
65
|
+
ignore: ["**/node_modules/**", "**/dist/**"]
|
|
66
|
+
}).find((pkgJsonPath) => {
|
|
67
|
+
try {
|
|
68
|
+
return JSON.parse(fs.readFileSync(pkgJsonPath, "utf8")).name === packageName;
|
|
69
|
+
} catch {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
return matchingPath ? path.dirname(matchingPath) : null;
|
|
74
|
+
};
|
|
75
|
+
const buildPackageSourceCandidates = (workspaceDir, packageName, packageRoot) => {
|
|
76
|
+
return [
|
|
77
|
+
packageRoot ? path.join(packageRoot, "src") : null,
|
|
78
|
+
packageRoot ? path.join(packageRoot, "lib") : null,
|
|
79
|
+
packageRoot ? path.join(packageRoot, "dist") : null,
|
|
80
|
+
packageRoot,
|
|
81
|
+
path.join(workspaceDir, "node_modules", packageName, "src"),
|
|
82
|
+
path.join(workspaceDir, "node_modules", packageName, "lib"),
|
|
83
|
+
path.join(workspaceDir, "node_modules", packageName, "dist"),
|
|
84
|
+
path.join(workspaceDir, "node_modules", packageName)
|
|
85
|
+
].filter(Boolean);
|
|
86
|
+
};
|
|
87
|
+
const getFirstExistingPath = (candidates) => candidates.find((candidate) => fs.existsSync(candidate)) ?? null;
|
|
88
|
+
const findPackageSourceDir = (packageName) => {
|
|
89
|
+
const workspaceDir = process.cwd();
|
|
90
|
+
const monorepoRoot = findMonorepoRoot(workspaceDir);
|
|
91
|
+
let packageRoot = resolvePackageRoot(workspaceDir, packageName);
|
|
92
|
+
if (!packageRoot && monorepoRoot) packageRoot = findPackageRootInMonorepo(monorepoRoot, packageName);
|
|
93
|
+
return getFirstExistingPath(buildPackageSourceCandidates(workspaceDir, packageName, packageRoot));
|
|
94
|
+
};
|
|
95
|
+
const scaffoldThemeConfig = async (options) => {
|
|
96
|
+
const workspaceDir = process.cwd();
|
|
97
|
+
const outputPath = options.outputPath ?? "uds.theme.ts";
|
|
98
|
+
const absoluteOutputPath = path.isAbsolute(outputPath) ? outputPath : path.join(workspaceDir, outputPath);
|
|
99
|
+
if (fs.existsSync(absoluteOutputPath) && !options.force) {
|
|
100
|
+
print(red(`Error: ${outputPath} already exists. Use --force to overwrite.`));
|
|
101
|
+
process.exitCode = 1;
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const template = `import { defineTheme } from '@yahoo/uds';
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* UDS Theme Configuration
|
|
108
|
+
*
|
|
109
|
+
* This file configures CSS generation for your app and shared packages.
|
|
110
|
+
* Run \`uds css\` to generate optimized CSS.
|
|
111
|
+
*/
|
|
112
|
+
export default defineTheme({
|
|
113
|
+
// Path to your uds.config.ts file
|
|
114
|
+
config: '${options.configPath ?? "./uds.config.ts"}',
|
|
115
|
+
|
|
116
|
+
// Entry directory for scanning your app code
|
|
117
|
+
entry: '${options.entry ?? "./src"}',
|
|
118
|
+
|
|
119
|
+
// Color modes to include (light mode is always in :root)
|
|
120
|
+
colorModes: ['dark'],
|
|
121
|
+
|
|
122
|
+
// Packages that inherit your app's theme (merged into main uds.css)
|
|
123
|
+
// inherit: ['@your-org/shared-ui'],
|
|
124
|
+
|
|
125
|
+
// CSS generation options (all optional)
|
|
126
|
+
// css: {
|
|
127
|
+
// safelist: [],
|
|
128
|
+
// preflight: true,
|
|
129
|
+
// fontFaceDeclarations: true,
|
|
130
|
+
// optimization: {
|
|
131
|
+
// removeUnusedFonts: false,
|
|
132
|
+
// removeEmptyRules: true,
|
|
133
|
+
// deduplicateScopedCss: true
|
|
134
|
+
// }
|
|
135
|
+
// }
|
|
136
|
+
});
|
|
137
|
+
`;
|
|
138
|
+
fs.writeFileSync(absoluteOutputPath, template);
|
|
139
|
+
print("");
|
|
140
|
+
print(green("✅ Created uds.theme.ts"));
|
|
141
|
+
print("");
|
|
142
|
+
print(`${magenta("Next steps:")}`);
|
|
143
|
+
print(` 1. Review and customize ${cyan(outputPath)}`);
|
|
144
|
+
print(` 2. Run ${cyan("uds css")} to generate CSS`);
|
|
145
|
+
print("");
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
//#endregion
|
|
149
|
+
export { findPackageSourceDir, loadConfigFile, scaffoldThemeConfig, scanDirectoryForSafelist };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
|
|
2
|
+
const require_postcss_helpers = require('./postcss.helpers.cjs');
|
|
3
|
+
|
|
4
|
+
//#region ../tailwind/dist/css/postcss.js
|
|
5
|
+
/*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
|
|
6
|
+
/**
|
|
7
|
+
* PostCSS plugin to fix color mode selectors for scoped CSS.
|
|
8
|
+
*
|
|
9
|
+
* postcss-scope converts selectors like:
|
|
10
|
+
* `.uds-color-mode-dark .foo` → `.scope .uds-color-mode-dark .foo`
|
|
11
|
+
*
|
|
12
|
+
* But the color mode class is typically on <html> or <body>, which is an
|
|
13
|
+
* ANCESTOR of the scope, not a descendant. This plugin adds alternative
|
|
14
|
+
* selectors so color modes work correctly:
|
|
15
|
+
*
|
|
16
|
+
* `.scope .uds-color-mode-dark .foo` → `.scope .uds-color-mode-dark .foo, .uds-color-mode-dark .scope .foo`
|
|
17
|
+
*
|
|
18
|
+
* This ensures styles apply whether the color mode class is inside or outside the scope.
|
|
19
|
+
*/
|
|
20
|
+
const fixScopedColorModeSelectorsPlugin = (scopeClass) => {
|
|
21
|
+
const colorModePattern = /\.(uds-color-mode-(?:dark|light))/;
|
|
22
|
+
return {
|
|
23
|
+
postcssPlugin: "fix-scoped-color-mode-selectors",
|
|
24
|
+
Once(root) {
|
|
25
|
+
root.walkRules((rule) => {
|
|
26
|
+
if (!rule.selector.includes(scopeClass) || !colorModePattern.test(rule.selector)) return;
|
|
27
|
+
const nextSelector = require_postcss_helpers.buildScopedColorModeSelectorList(rule.selector, scopeClass);
|
|
28
|
+
if (nextSelector !== rule.selector) rule.selector = nextSelector;
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
//#endregion
|
|
35
|
+
exports.fixScopedColorModeSelectorsPlugin = fixScopedColorModeSelectorsPlugin;
|