@yahoo/uds 3.113.0 → 3.114.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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/automated-config/dist/utils/getConfigVariantProperties.d.cts +2 -2
- package/dist/automated-config/dist/utils/getConfigVariantProperties.d.ts +2 -2
- 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/cli.cjs +1 -1
- package/dist/cli/dist/cli.js +1 -1
- package/dist/cli/dist/commands/editor-rules.cjs +2 -2
- package/dist/cli/dist/commands/editor-rules.js +2 -2
- package/dist/cli/dist/lib/logger.cjs +66 -0
- package/dist/cli/dist/lib/logger.js +66 -0
- package/dist/cli/dist/utils/rules/config.cjs +1 -1
- package/dist/cli/dist/utils/rules/config.js +1 -1
- package/dist/cli/runner.cjs +11 -2
- package/dist/cli/runner.js +11 -2
- 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 +41 -41
- package/dist/styles/styler.d.ts +41 -41
- 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.d.ts +3 -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/generatePurgeCSSData.d.ts +1 -1
- package/dist/tailwind/dist/commands/purge.cjs +3 -4
- package/dist/tailwind/dist/commands/purge.d.ts +1 -1
- package/dist/tailwind/dist/commands/purge.js +3 -4
- package/dist/tailwind/dist/css/generate.cjs +120 -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 +115 -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 +278 -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 +275 -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 +234 -0
- package/dist/tailwind/dist/css/utils.js +223 -0
- package/dist/tailwind/dist/index.d.cts +1 -0
- package/dist/tailwind/dist/index.d.ts +5 -3
- package/dist/tailwind/dist/purger/legacy/purgeCSS.cjs +4 -3
- package/dist/tailwind/dist/purger/legacy/purgeCSS.js +4 -3
- 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 +11 -10
- package/dist/tailwind/dist/purger/optimized/purge.js +10 -9
- package/dist/tailwind/dist/purger/optimized/purgeFromCode.cjs +232 -127
- package/dist/tailwind/dist/purger/optimized/purgeFromCode.js +232 -127
- package/dist/tailwind/dist/purger/optimized/utils/componentAnalyzer.cjs +330 -262
- package/dist/tailwind/dist/purger/optimized/utils/componentAnalyzer.js +329 -262
- 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 +13 -21
- package/dist/tailwind/dist/purger/optimized/utils/safelist.js +13 -21
- 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/tailwind/utils/getFontStyles.d.cts +1 -1
- package/dist/tailwind/dist/tailwind/utils/getFontStyles.d.ts +1 -1
- 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 +943 -928
- package/dist/uds/generated/componentData.js +943 -928
- package/dist/uds/package.cjs +10 -4
- package/dist/uds/package.js +10 -4
- package/generated/componentData.json +2397 -0
- package/generated/tailwindPurge.ts +4560 -0
- package/package.json +7 -4
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
/*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
|
|
2
|
+
const require_runtime = require('../../../_virtual/_rolldown/runtime.cjs');
|
|
3
|
+
const require_index = require('../../../config/dist/index.cjs');
|
|
4
|
+
const require_colors = require('../../../cli/dist/lib/colors.cjs');
|
|
5
|
+
const require_print = require('../../../cli/dist/lib/print.cjs');
|
|
6
|
+
const require_spinner = require('../../../cli/dist/lib/spinner.cjs');
|
|
7
|
+
const require_logger = require('../../../cli/dist/lib/logger.cjs');
|
|
8
|
+
const require_utils = require('./utils.cjs');
|
|
9
|
+
const require_safelist = require('../purger/optimized/utils/safelist.cjs');
|
|
10
|
+
const require_generate = require('./generate.cjs');
|
|
11
|
+
const require_runner_helpers = require('./runner.helpers.cjs');
|
|
12
|
+
let node_fs = require("node:fs");
|
|
13
|
+
node_fs = require_runtime.__toESM(node_fs);
|
|
14
|
+
let node_path = require("node:path");
|
|
15
|
+
node_path = require_runtime.__toESM(node_path);
|
|
16
|
+
|
|
17
|
+
//#region ../tailwind/dist/css/runner.js
|
|
18
|
+
/*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
|
|
19
|
+
const DEFAULT_ENTRY = "./src";
|
|
20
|
+
const SOURCE_FILE_PATTERN = /\.(jsx?|tsx?)$/i;
|
|
21
|
+
const getWatchDirs = (dirs) => [...new Set(dirs.filter((dir) => !dir.split(node_path.default.sep).includes("node_modules")))];
|
|
22
|
+
const watchSourceFiles = (dirs, onFileChange) => {
|
|
23
|
+
dirs.forEach((dir) => {
|
|
24
|
+
node_fs.default.watch(dir, { recursive: true }, (_eventType, filename) => {
|
|
25
|
+
if (filename && SOURCE_FILE_PATTERN.test(filename)) onFileChange();
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
const createDebouncedAction = (action, delayMs) => {
|
|
30
|
+
let debounceTimer = null;
|
|
31
|
+
return () => {
|
|
32
|
+
if (debounceTimer) clearTimeout(debounceTimer);
|
|
33
|
+
debounceTimer = setTimeout(action, delayMs);
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
const createQueuedRegenerator = (options) => {
|
|
37
|
+
let isGenerating = false;
|
|
38
|
+
let pendingRegenerate = false;
|
|
39
|
+
const regenerate = async () => {
|
|
40
|
+
if (isGenerating) {
|
|
41
|
+
pendingRegenerate = true;
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
isGenerating = true;
|
|
45
|
+
try {
|
|
46
|
+
options.onStart?.();
|
|
47
|
+
const result = await options.regenerateOnce();
|
|
48
|
+
options.onSuccess?.(result);
|
|
49
|
+
} catch (error) {
|
|
50
|
+
const message = error instanceof Error ? error.message : "CSS generation failed";
|
|
51
|
+
options.onError(message);
|
|
52
|
+
} finally {
|
|
53
|
+
isGenerating = false;
|
|
54
|
+
if (pendingRegenerate) {
|
|
55
|
+
pendingRegenerate = false;
|
|
56
|
+
await regenerate();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
return regenerate;
|
|
61
|
+
};
|
|
62
|
+
const runCssCommand = async (options, context) => {
|
|
63
|
+
if (!node_fs.default.existsSync(node_path.default.join(options.workspaceDir, String(options.themeConfigPath)))) {
|
|
64
|
+
await runSimpleMode(options, context);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
await runThemeMode(options, context);
|
|
68
|
+
};
|
|
69
|
+
const runSimpleMode = async (options, context) => {
|
|
70
|
+
const entry = typeof options.entryOption === "string" ? options.entryOption : DEFAULT_ENTRY;
|
|
71
|
+
const configPath = typeof options.configOption === "string" ? options.configOption : void 0;
|
|
72
|
+
if (!options.watch && !options.silent) require_spinner.spinStart("Generating CSS...");
|
|
73
|
+
try {
|
|
74
|
+
const result = await require_generate.generateSimpleModeCSS({
|
|
75
|
+
workspaceDir: options.workspaceDir,
|
|
76
|
+
entry,
|
|
77
|
+
outFile: String(options.outFile),
|
|
78
|
+
variants: context.variants,
|
|
79
|
+
autoVariants: context.autoVariants,
|
|
80
|
+
componentData: context.componentData,
|
|
81
|
+
scope: options.scope,
|
|
82
|
+
configPath,
|
|
83
|
+
isWatch: options.watch,
|
|
84
|
+
silent: options.silent
|
|
85
|
+
});
|
|
86
|
+
if (options.watch) await runSimpleModeWatch(options, context, entry, configPath, result.packageDirs ?? []);
|
|
87
|
+
} catch (error) {
|
|
88
|
+
require_spinner.spinStop("❌", error instanceof Error ? error.message : "CSS generation failed");
|
|
89
|
+
process.exitCode = 1;
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
const runSimpleModeWatch = async (options, context, entry, configPath, packageDirs) => {
|
|
93
|
+
const entryDir = node_path.default.join(options.workspaceDir, entry);
|
|
94
|
+
const watchDirs = getWatchDirs(packageDirs.length > 0 ? packageDirs : [entryDir]);
|
|
95
|
+
if (!options.silent) {
|
|
96
|
+
require_print.print("");
|
|
97
|
+
require_print.print(`${require_colors.magenta("Watching for changes...")}`);
|
|
98
|
+
watchDirs.forEach((dir) => require_print.print(` ${require_colors.gray("•")} ${dir}`));
|
|
99
|
+
require_print.print(`${require_colors.gray("Press Ctrl+C to stop")}`);
|
|
100
|
+
require_print.print("");
|
|
101
|
+
}
|
|
102
|
+
const regenerate = createQueuedRegenerator({
|
|
103
|
+
onStart: () => {
|
|
104
|
+
if (!options.silent) require_print.print(`${require_colors.gray(`[${(/* @__PURE__ */ new Date()).toLocaleTimeString()}]`)} Change detected, regenerating...`);
|
|
105
|
+
},
|
|
106
|
+
regenerateOnce: async () => {
|
|
107
|
+
await require_generate.generateSimpleModeCSS({
|
|
108
|
+
workspaceDir: options.workspaceDir,
|
|
109
|
+
entry,
|
|
110
|
+
outFile: String(options.outFile),
|
|
111
|
+
variants: context.variants,
|
|
112
|
+
autoVariants: context.autoVariants,
|
|
113
|
+
componentData: context.componentData,
|
|
114
|
+
scope: options.scope,
|
|
115
|
+
configPath,
|
|
116
|
+
isWatch: true,
|
|
117
|
+
silent: true
|
|
118
|
+
});
|
|
119
|
+
},
|
|
120
|
+
onSuccess: () => {
|
|
121
|
+
if (!options.silent) {
|
|
122
|
+
require_print.print(`${require_colors.gray(`[${(/* @__PURE__ */ new Date()).toLocaleTimeString()}]`)} ${require_colors.green("CSS updated")}`);
|
|
123
|
+
require_print.print("");
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
onError: (message) => {
|
|
127
|
+
require_print.print(`Error: ${message}`);
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
watchSourceFiles(watchDirs, createDebouncedAction(() => {
|
|
131
|
+
regenerate();
|
|
132
|
+
}, 100));
|
|
133
|
+
await new Promise(() => {});
|
|
134
|
+
};
|
|
135
|
+
const loadThemeModeSetup = async (options) => {
|
|
136
|
+
const themeConfigInput = await require_utils.loadConfigFile(String(options.themeConfigPath));
|
|
137
|
+
if (!themeConfigInput) return null;
|
|
138
|
+
const themeContext = {
|
|
139
|
+
cwd: options.workspaceDir,
|
|
140
|
+
watch: options.watch
|
|
141
|
+
};
|
|
142
|
+
const themeConfig = typeof themeConfigInput === "function" ? await themeConfigInput(themeContext) : themeConfigInput;
|
|
143
|
+
let appConfig = require_index.defaultTokensConfig;
|
|
144
|
+
if (themeConfig.config) {
|
|
145
|
+
const loadedConfig = await require_utils.loadConfigFile(themeConfig.config);
|
|
146
|
+
if (loadedConfig) appConfig = loadedConfig;
|
|
147
|
+
}
|
|
148
|
+
return {
|
|
149
|
+
themeConfig,
|
|
150
|
+
colorModes: themeConfig.colorModes ?? ["dark"],
|
|
151
|
+
entry: themeConfig.entry ?? "/src/",
|
|
152
|
+
appConfig,
|
|
153
|
+
appVariantDefaults: require_utils.extractVariantDefaults(appConfig),
|
|
154
|
+
effectiveSilent: options.silent || themeConfig.silent === true
|
|
155
|
+
};
|
|
156
|
+
};
|
|
157
|
+
const runThemeMode = async (options, context) => {
|
|
158
|
+
const workspaceDir = options.workspaceDir;
|
|
159
|
+
const outputPath = node_path.default.isAbsolute(options.outFile) ? options.outFile : node_path.default.join(workspaceDir, String(options.outFile));
|
|
160
|
+
let effectiveSilent = options.silent;
|
|
161
|
+
let log = require_logger.createLogger({ silent: effectiveSilent });
|
|
162
|
+
log.spinStart("Loading theme configuration...");
|
|
163
|
+
try {
|
|
164
|
+
const setup = await loadThemeModeSetup(options);
|
|
165
|
+
if (!setup) {
|
|
166
|
+
log.spinStop("❌", `Theme config not found: ${options.themeConfigPath}`);
|
|
167
|
+
process.exitCode = 1;
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
const { themeConfig, colorModes, entry, appConfig, appVariantDefaults } = setup;
|
|
171
|
+
effectiveSilent = setup.effectiveSilent;
|
|
172
|
+
log = require_logger.createLogger({ silent: effectiveSilent });
|
|
173
|
+
if (!effectiveSilent) log.spinStop("✅", "Theme configuration loaded");
|
|
174
|
+
if (themeConfig.config && appConfig === require_index.defaultTokensConfig) log.warn(`App config not found: ${themeConfig.config}, using defaults`);
|
|
175
|
+
const packageDirs = [];
|
|
176
|
+
const generateThemeModeCSS = async (opts) => {
|
|
177
|
+
const genStartTime = performance.now();
|
|
178
|
+
const genLog = opts?.isWatch ? require_logger.createLogger({ silent: true }) : log;
|
|
179
|
+
genLog.spinStart("Scanning app code...");
|
|
180
|
+
const appScanResult = await require_utils.scanDirectoryForSafelist(node_path.default.join(workspaceDir, entry), colorModes, context.variants, context.autoVariants, context.componentData, appVariantDefaults);
|
|
181
|
+
genLog.spinStop("✅", `Scanned ${appScanResult.filesScanned} files`);
|
|
182
|
+
genLog.spinStart("Generating main CSS...");
|
|
183
|
+
const inheritedClasses = [...appScanResult.safelist];
|
|
184
|
+
const inheritedComponents = new Set(appScanResult.components);
|
|
185
|
+
const processInheritedPackage = async (packageName) => {
|
|
186
|
+
genLog.spinStart(`Processing package: ${packageName}...`);
|
|
187
|
+
const packageDir = require_utils.findPackageSourceDir(packageName);
|
|
188
|
+
if (!packageDir) {
|
|
189
|
+
genLog.spinStop("⚠️", `Package not found: ${packageName}`);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
if (!packageDirs.includes(packageDir)) packageDirs.push(packageDir);
|
|
193
|
+
const packageScanResult = await require_utils.scanDirectoryForSafelist(packageDir, colorModes, context.variants, context.autoVariants, context.componentData, appVariantDefaults, true);
|
|
194
|
+
inheritedClasses.push(...packageScanResult.safelist);
|
|
195
|
+
packageScanResult.components.forEach((comp) => inheritedComponents.add(comp));
|
|
196
|
+
genLog.spinStop("✅", `${packageName}: ${packageScanResult.filesScanned} files (inherit)`);
|
|
197
|
+
};
|
|
198
|
+
await (themeConfig.inherit ?? []).reduce(async (promise, packageName) => {
|
|
199
|
+
await promise;
|
|
200
|
+
await processInheritedPackage(packageName);
|
|
201
|
+
}, Promise.resolve());
|
|
202
|
+
const mainSafelist = require_safelist.deduplicateSafelist([...inheritedClasses, ...require_safelist.getThemeAndScaleClasses(colorModes)]);
|
|
203
|
+
const allMotionComponents = [...inheritedComponents];
|
|
204
|
+
const mainCssResult = await require_generate.generateCSS([...themeConfig.css?.safelist ?? [], ...mainSafelist], appConfig, {
|
|
205
|
+
scope: options.scope,
|
|
206
|
+
contentDir: node_path.default.join(workspaceDir, entry),
|
|
207
|
+
cssOptions: themeConfig.css,
|
|
208
|
+
safeVarPrefixes: [...require_utils.getMotionVarPrefixes(context.componentData, allMotionComponents), ...require_utils.getConfigurableCssVariables()]
|
|
209
|
+
});
|
|
210
|
+
const outputDir = node_path.default.dirname(outputPath);
|
|
211
|
+
if (!node_fs.default.existsSync(outputDir)) node_fs.default.mkdirSync(outputDir, { recursive: true });
|
|
212
|
+
node_fs.default.writeFileSync(outputPath, mainCssResult.css);
|
|
213
|
+
genLog.spinStop("✅", require_runner_helpers.getMainCssSummaryMessage({
|
|
214
|
+
sizeGzipBytes: mainCssResult.sizeGzipBytes,
|
|
215
|
+
optimizationStats: mainCssResult.optimizationStats,
|
|
216
|
+
formatBytes: require_utils.formatBytes
|
|
217
|
+
}));
|
|
218
|
+
const duration = Math.round(performance.now() - genStartTime);
|
|
219
|
+
genLog.newline();
|
|
220
|
+
genLog.print(require_colors.green("CSS generation complete!"));
|
|
221
|
+
genLog.newline();
|
|
222
|
+
genLog.label("Output file:", outputPath);
|
|
223
|
+
genLog.newline();
|
|
224
|
+
genLog.print(`${require_colors.magenta("Total time:")} ${duration}ms`);
|
|
225
|
+
return {
|
|
226
|
+
duration,
|
|
227
|
+
outputPath,
|
|
228
|
+
packageDirs
|
|
229
|
+
};
|
|
230
|
+
};
|
|
231
|
+
await generateThemeModeCSS();
|
|
232
|
+
if (options.watch) {
|
|
233
|
+
const entryDir = node_path.default.join(workspaceDir, entry);
|
|
234
|
+
const { watchDirs, filteredPackageDirs } = require_runner_helpers.getWatchDirectoryGroups(entryDir, [entryDir, ...packageDirs]);
|
|
235
|
+
if (!effectiveSilent) {
|
|
236
|
+
log.newline();
|
|
237
|
+
log.print(`${require_colors.magenta("Watching for changes...")}`);
|
|
238
|
+
log.listItem(`App: ${entryDir}`);
|
|
239
|
+
filteredPackageDirs.forEach((dir) => {
|
|
240
|
+
log.listItem(`Package: ${dir}`);
|
|
241
|
+
});
|
|
242
|
+
log.print(`${require_colors.gray("Press Ctrl+C to stop")}`);
|
|
243
|
+
log.newline();
|
|
244
|
+
}
|
|
245
|
+
const regenerate = createQueuedRegenerator({
|
|
246
|
+
onStart: () => {
|
|
247
|
+
if (!effectiveSilent) {
|
|
248
|
+
const timestamp = (/* @__PURE__ */ new Date()).toLocaleTimeString();
|
|
249
|
+
log.print(`${require_colors.gray(`[${timestamp}]`)} Change detected, regenerating...`);
|
|
250
|
+
}
|
|
251
|
+
},
|
|
252
|
+
regenerateOnce: async () => generateThemeModeCSS({ isWatch: true }),
|
|
253
|
+
onSuccess: (result) => {
|
|
254
|
+
if (!effectiveSilent) {
|
|
255
|
+
const updatedAt = (/* @__PURE__ */ new Date()).toLocaleTimeString();
|
|
256
|
+
log.print(`${require_colors.gray(`[${updatedAt}]`)} ${require_colors.green(`CSS updated (${result?.duration}ms)`)}`);
|
|
257
|
+
log.newline();
|
|
258
|
+
}
|
|
259
|
+
},
|
|
260
|
+
onError: (message) => {
|
|
261
|
+
log.print(message);
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
watchSourceFiles(watchDirs, createDebouncedAction(() => {
|
|
265
|
+
regenerate();
|
|
266
|
+
}, themeConfig.css?.watchDebounce ?? 100));
|
|
267
|
+
await new Promise(() => {});
|
|
268
|
+
}
|
|
269
|
+
} catch (error) {
|
|
270
|
+
const message = error instanceof Error ? error.message : "CSS generation failed";
|
|
271
|
+
if (effectiveSilent) require_spinner.spinStop("❌", message);
|
|
272
|
+
else log.spinStop("❌", message);
|
|
273
|
+
process.exitCode = 1;
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
//#endregion
|
|
278
|
+
exports.runCssCommand = runCssCommand;
|
|
@@ -0,0 +1,26 @@
|
|
|
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
|
+
|
|
6
|
+
//#region ../tailwind/dist/css/runner.helpers.js
|
|
7
|
+
/*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
|
|
8
|
+
const getMainCssSummaryMessage = (options) => {
|
|
9
|
+
const { optimizationStats, sizeGzipBytes, formatBytes } = options;
|
|
10
|
+
if (!optimizationStats) return `Main CSS: ${formatBytes(sizeGzipBytes)} gzip`;
|
|
11
|
+
const { originalSizeGzip, fontFacesRemoved, emptyRulesRemoved } = optimizationStats;
|
|
12
|
+
const savedBytesGzip = originalSizeGzip - sizeGzipBytes;
|
|
13
|
+
if (savedBytesGzip <= 0) return `Main CSS: ${formatBytes(sizeGzipBytes)} gzip`;
|
|
14
|
+
return `Main CSS: ${formatBytes(sizeGzipBytes)} gzip)(optimized: saved ${formatBytes(savedBytesGzip)} gzip, ${fontFacesRemoved} unused @font-face, ${emptyRulesRemoved} empty rules removed)`;
|
|
15
|
+
};
|
|
16
|
+
const getWatchDirectoryGroups = (entryDir, dirs) => {
|
|
17
|
+
const watchDirs = [...new Set(dirs.filter((dir) => !dir.split(node_path.default.sep).includes("node_modules")))];
|
|
18
|
+
return {
|
|
19
|
+
watchDirs,
|
|
20
|
+
filteredPackageDirs: watchDirs.filter((dir) => dir !== entryDir)
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
//#endregion
|
|
25
|
+
exports.getMainCssSummaryMessage = getMainCssSummaryMessage;
|
|
26
|
+
exports.getWatchDirectoryGroups = getWatchDirectoryGroups;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
|
|
4
|
+
//#region ../tailwind/dist/css/runner.helpers.js
|
|
5
|
+
/*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
|
|
6
|
+
const getMainCssSummaryMessage = (options) => {
|
|
7
|
+
const { optimizationStats, sizeGzipBytes, formatBytes } = options;
|
|
8
|
+
if (!optimizationStats) return `Main CSS: ${formatBytes(sizeGzipBytes)} gzip`;
|
|
9
|
+
const { originalSizeGzip, fontFacesRemoved, emptyRulesRemoved } = optimizationStats;
|
|
10
|
+
const savedBytesGzip = originalSizeGzip - sizeGzipBytes;
|
|
11
|
+
if (savedBytesGzip <= 0) return `Main CSS: ${formatBytes(sizeGzipBytes)} gzip`;
|
|
12
|
+
return `Main CSS: ${formatBytes(sizeGzipBytes)} gzip)(optimized: saved ${formatBytes(savedBytesGzip)} gzip, ${fontFacesRemoved} unused @font-face, ${emptyRulesRemoved} empty rules removed)`;
|
|
13
|
+
};
|
|
14
|
+
const getWatchDirectoryGroups = (entryDir, dirs) => {
|
|
15
|
+
const watchDirs = [...new Set(dirs.filter((dir) => !dir.split(path.sep).includes("node_modules")))];
|
|
16
|
+
return {
|
|
17
|
+
watchDirs,
|
|
18
|
+
filteredPackageDirs: watchDirs.filter((dir) => dir !== entryDir)
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
//#endregion
|
|
23
|
+
export { getMainCssSummaryMessage, getWatchDirectoryGroups };
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
/*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
|
|
2
|
+
import { defaultTokensConfig } from "../../../config/dist/index.js";
|
|
3
|
+
import { gray, green, magenta } from "../../../cli/dist/lib/colors.js";
|
|
4
|
+
import { print } from "../../../cli/dist/lib/print.js";
|
|
5
|
+
import { spinStart, spinStop } from "../../../cli/dist/lib/spinner.js";
|
|
6
|
+
import { createLogger } from "../../../cli/dist/lib/logger.js";
|
|
7
|
+
import { extractVariantDefaults, findPackageSourceDir, formatBytes, getConfigurableCssVariables, getMotionVarPrefixes, loadConfigFile, scanDirectoryForSafelist } from "./utils.js";
|
|
8
|
+
import { deduplicateSafelist, getThemeAndScaleClasses } from "../purger/optimized/utils/safelist.js";
|
|
9
|
+
import { generateCSS, generateSimpleModeCSS } from "./generate.js";
|
|
10
|
+
import { getMainCssSummaryMessage, getWatchDirectoryGroups } from "./runner.helpers.js";
|
|
11
|
+
import fs from "node:fs";
|
|
12
|
+
import path from "node:path";
|
|
13
|
+
|
|
14
|
+
//#region ../tailwind/dist/css/runner.js
|
|
15
|
+
/*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
|
|
16
|
+
const DEFAULT_ENTRY = "./src";
|
|
17
|
+
const SOURCE_FILE_PATTERN = /\.(jsx?|tsx?)$/i;
|
|
18
|
+
const getWatchDirs = (dirs) => [...new Set(dirs.filter((dir) => !dir.split(path.sep).includes("node_modules")))];
|
|
19
|
+
const watchSourceFiles = (dirs, onFileChange) => {
|
|
20
|
+
dirs.forEach((dir) => {
|
|
21
|
+
fs.watch(dir, { recursive: true }, (_eventType, filename) => {
|
|
22
|
+
if (filename && SOURCE_FILE_PATTERN.test(filename)) onFileChange();
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
const createDebouncedAction = (action, delayMs) => {
|
|
27
|
+
let debounceTimer = null;
|
|
28
|
+
return () => {
|
|
29
|
+
if (debounceTimer) clearTimeout(debounceTimer);
|
|
30
|
+
debounceTimer = setTimeout(action, delayMs);
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
const createQueuedRegenerator = (options) => {
|
|
34
|
+
let isGenerating = false;
|
|
35
|
+
let pendingRegenerate = false;
|
|
36
|
+
const regenerate = async () => {
|
|
37
|
+
if (isGenerating) {
|
|
38
|
+
pendingRegenerate = true;
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
isGenerating = true;
|
|
42
|
+
try {
|
|
43
|
+
options.onStart?.();
|
|
44
|
+
const result = await options.regenerateOnce();
|
|
45
|
+
options.onSuccess?.(result);
|
|
46
|
+
} catch (error) {
|
|
47
|
+
const message = error instanceof Error ? error.message : "CSS generation failed";
|
|
48
|
+
options.onError(message);
|
|
49
|
+
} finally {
|
|
50
|
+
isGenerating = false;
|
|
51
|
+
if (pendingRegenerate) {
|
|
52
|
+
pendingRegenerate = false;
|
|
53
|
+
await regenerate();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
return regenerate;
|
|
58
|
+
};
|
|
59
|
+
const runCssCommand = async (options, context) => {
|
|
60
|
+
if (!fs.existsSync(path.join(options.workspaceDir, String(options.themeConfigPath)))) {
|
|
61
|
+
await runSimpleMode(options, context);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
await runThemeMode(options, context);
|
|
65
|
+
};
|
|
66
|
+
const runSimpleMode = async (options, context) => {
|
|
67
|
+
const entry = typeof options.entryOption === "string" ? options.entryOption : DEFAULT_ENTRY;
|
|
68
|
+
const configPath = typeof options.configOption === "string" ? options.configOption : void 0;
|
|
69
|
+
if (!options.watch && !options.silent) spinStart("Generating CSS...");
|
|
70
|
+
try {
|
|
71
|
+
const result = await generateSimpleModeCSS({
|
|
72
|
+
workspaceDir: options.workspaceDir,
|
|
73
|
+
entry,
|
|
74
|
+
outFile: String(options.outFile),
|
|
75
|
+
variants: context.variants,
|
|
76
|
+
autoVariants: context.autoVariants,
|
|
77
|
+
componentData: context.componentData,
|
|
78
|
+
scope: options.scope,
|
|
79
|
+
configPath,
|
|
80
|
+
isWatch: options.watch,
|
|
81
|
+
silent: options.silent
|
|
82
|
+
});
|
|
83
|
+
if (options.watch) await runSimpleModeWatch(options, context, entry, configPath, result.packageDirs ?? []);
|
|
84
|
+
} catch (error) {
|
|
85
|
+
spinStop("❌", error instanceof Error ? error.message : "CSS generation failed");
|
|
86
|
+
process.exitCode = 1;
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
const runSimpleModeWatch = async (options, context, entry, configPath, packageDirs) => {
|
|
90
|
+
const entryDir = path.join(options.workspaceDir, entry);
|
|
91
|
+
const watchDirs = getWatchDirs(packageDirs.length > 0 ? packageDirs : [entryDir]);
|
|
92
|
+
if (!options.silent) {
|
|
93
|
+
print("");
|
|
94
|
+
print(`${magenta("Watching for changes...")}`);
|
|
95
|
+
watchDirs.forEach((dir) => print(` ${gray("•")} ${dir}`));
|
|
96
|
+
print(`${gray("Press Ctrl+C to stop")}`);
|
|
97
|
+
print("");
|
|
98
|
+
}
|
|
99
|
+
const regenerate = createQueuedRegenerator({
|
|
100
|
+
onStart: () => {
|
|
101
|
+
if (!options.silent) print(`${gray(`[${(/* @__PURE__ */ new Date()).toLocaleTimeString()}]`)} Change detected, regenerating...`);
|
|
102
|
+
},
|
|
103
|
+
regenerateOnce: async () => {
|
|
104
|
+
await generateSimpleModeCSS({
|
|
105
|
+
workspaceDir: options.workspaceDir,
|
|
106
|
+
entry,
|
|
107
|
+
outFile: String(options.outFile),
|
|
108
|
+
variants: context.variants,
|
|
109
|
+
autoVariants: context.autoVariants,
|
|
110
|
+
componentData: context.componentData,
|
|
111
|
+
scope: options.scope,
|
|
112
|
+
configPath,
|
|
113
|
+
isWatch: true,
|
|
114
|
+
silent: true
|
|
115
|
+
});
|
|
116
|
+
},
|
|
117
|
+
onSuccess: () => {
|
|
118
|
+
if (!options.silent) {
|
|
119
|
+
print(`${gray(`[${(/* @__PURE__ */ new Date()).toLocaleTimeString()}]`)} ${green("CSS updated")}`);
|
|
120
|
+
print("");
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
onError: (message) => {
|
|
124
|
+
print(`Error: ${message}`);
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
watchSourceFiles(watchDirs, createDebouncedAction(() => {
|
|
128
|
+
regenerate();
|
|
129
|
+
}, 100));
|
|
130
|
+
await new Promise(() => {});
|
|
131
|
+
};
|
|
132
|
+
const loadThemeModeSetup = async (options) => {
|
|
133
|
+
const themeConfigInput = await loadConfigFile(String(options.themeConfigPath));
|
|
134
|
+
if (!themeConfigInput) return null;
|
|
135
|
+
const themeContext = {
|
|
136
|
+
cwd: options.workspaceDir,
|
|
137
|
+
watch: options.watch
|
|
138
|
+
};
|
|
139
|
+
const themeConfig = typeof themeConfigInput === "function" ? await themeConfigInput(themeContext) : themeConfigInput;
|
|
140
|
+
let appConfig = defaultTokensConfig;
|
|
141
|
+
if (themeConfig.config) {
|
|
142
|
+
const loadedConfig = await loadConfigFile(themeConfig.config);
|
|
143
|
+
if (loadedConfig) appConfig = loadedConfig;
|
|
144
|
+
}
|
|
145
|
+
return {
|
|
146
|
+
themeConfig,
|
|
147
|
+
colorModes: themeConfig.colorModes ?? ["dark"],
|
|
148
|
+
entry: themeConfig.entry ?? "/src/",
|
|
149
|
+
appConfig,
|
|
150
|
+
appVariantDefaults: extractVariantDefaults(appConfig),
|
|
151
|
+
effectiveSilent: options.silent || themeConfig.silent === true
|
|
152
|
+
};
|
|
153
|
+
};
|
|
154
|
+
const runThemeMode = async (options, context) => {
|
|
155
|
+
const workspaceDir = options.workspaceDir;
|
|
156
|
+
const outputPath = path.isAbsolute(options.outFile) ? options.outFile : path.join(workspaceDir, String(options.outFile));
|
|
157
|
+
let effectiveSilent = options.silent;
|
|
158
|
+
let log = createLogger({ silent: effectiveSilent });
|
|
159
|
+
log.spinStart("Loading theme configuration...");
|
|
160
|
+
try {
|
|
161
|
+
const setup = await loadThemeModeSetup(options);
|
|
162
|
+
if (!setup) {
|
|
163
|
+
log.spinStop("❌", `Theme config not found: ${options.themeConfigPath}`);
|
|
164
|
+
process.exitCode = 1;
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
const { themeConfig, colorModes, entry, appConfig, appVariantDefaults } = setup;
|
|
168
|
+
effectiveSilent = setup.effectiveSilent;
|
|
169
|
+
log = createLogger({ silent: effectiveSilent });
|
|
170
|
+
if (!effectiveSilent) log.spinStop("✅", "Theme configuration loaded");
|
|
171
|
+
if (themeConfig.config && appConfig === defaultTokensConfig) log.warn(`App config not found: ${themeConfig.config}, using defaults`);
|
|
172
|
+
const packageDirs = [];
|
|
173
|
+
const generateThemeModeCSS = async (opts) => {
|
|
174
|
+
const genStartTime = performance.now();
|
|
175
|
+
const genLog = opts?.isWatch ? createLogger({ silent: true }) : log;
|
|
176
|
+
genLog.spinStart("Scanning app code...");
|
|
177
|
+
const appScanResult = await scanDirectoryForSafelist(path.join(workspaceDir, entry), colorModes, context.variants, context.autoVariants, context.componentData, appVariantDefaults);
|
|
178
|
+
genLog.spinStop("✅", `Scanned ${appScanResult.filesScanned} files`);
|
|
179
|
+
genLog.spinStart("Generating main CSS...");
|
|
180
|
+
const inheritedClasses = [...appScanResult.safelist];
|
|
181
|
+
const inheritedComponents = new Set(appScanResult.components);
|
|
182
|
+
const processInheritedPackage = async (packageName) => {
|
|
183
|
+
genLog.spinStart(`Processing package: ${packageName}...`);
|
|
184
|
+
const packageDir = findPackageSourceDir(packageName);
|
|
185
|
+
if (!packageDir) {
|
|
186
|
+
genLog.spinStop("⚠️", `Package not found: ${packageName}`);
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
if (!packageDirs.includes(packageDir)) packageDirs.push(packageDir);
|
|
190
|
+
const packageScanResult = await scanDirectoryForSafelist(packageDir, colorModes, context.variants, context.autoVariants, context.componentData, appVariantDefaults, true);
|
|
191
|
+
inheritedClasses.push(...packageScanResult.safelist);
|
|
192
|
+
packageScanResult.components.forEach((comp) => inheritedComponents.add(comp));
|
|
193
|
+
genLog.spinStop("✅", `${packageName}: ${packageScanResult.filesScanned} files (inherit)`);
|
|
194
|
+
};
|
|
195
|
+
await (themeConfig.inherit ?? []).reduce(async (promise, packageName) => {
|
|
196
|
+
await promise;
|
|
197
|
+
await processInheritedPackage(packageName);
|
|
198
|
+
}, Promise.resolve());
|
|
199
|
+
const mainSafelist = deduplicateSafelist([...inheritedClasses, ...getThemeAndScaleClasses(colorModes)]);
|
|
200
|
+
const allMotionComponents = [...inheritedComponents];
|
|
201
|
+
const mainCssResult = await generateCSS([...themeConfig.css?.safelist ?? [], ...mainSafelist], appConfig, {
|
|
202
|
+
scope: options.scope,
|
|
203
|
+
contentDir: path.join(workspaceDir, entry),
|
|
204
|
+
cssOptions: themeConfig.css,
|
|
205
|
+
safeVarPrefixes: [...getMotionVarPrefixes(context.componentData, allMotionComponents), ...getConfigurableCssVariables()]
|
|
206
|
+
});
|
|
207
|
+
const outputDir = path.dirname(outputPath);
|
|
208
|
+
if (!fs.existsSync(outputDir)) fs.mkdirSync(outputDir, { recursive: true });
|
|
209
|
+
fs.writeFileSync(outputPath, mainCssResult.css);
|
|
210
|
+
genLog.spinStop("✅", getMainCssSummaryMessage({
|
|
211
|
+
sizeGzipBytes: mainCssResult.sizeGzipBytes,
|
|
212
|
+
optimizationStats: mainCssResult.optimizationStats,
|
|
213
|
+
formatBytes
|
|
214
|
+
}));
|
|
215
|
+
const duration = Math.round(performance.now() - genStartTime);
|
|
216
|
+
genLog.newline();
|
|
217
|
+
genLog.print(green("CSS generation complete!"));
|
|
218
|
+
genLog.newline();
|
|
219
|
+
genLog.label("Output file:", outputPath);
|
|
220
|
+
genLog.newline();
|
|
221
|
+
genLog.print(`${magenta("Total time:")} ${duration}ms`);
|
|
222
|
+
return {
|
|
223
|
+
duration,
|
|
224
|
+
outputPath,
|
|
225
|
+
packageDirs
|
|
226
|
+
};
|
|
227
|
+
};
|
|
228
|
+
await generateThemeModeCSS();
|
|
229
|
+
if (options.watch) {
|
|
230
|
+
const entryDir = path.join(workspaceDir, entry);
|
|
231
|
+
const { watchDirs, filteredPackageDirs } = getWatchDirectoryGroups(entryDir, [entryDir, ...packageDirs]);
|
|
232
|
+
if (!effectiveSilent) {
|
|
233
|
+
log.newline();
|
|
234
|
+
log.print(`${magenta("Watching for changes...")}`);
|
|
235
|
+
log.listItem(`App: ${entryDir}`);
|
|
236
|
+
filteredPackageDirs.forEach((dir) => {
|
|
237
|
+
log.listItem(`Package: ${dir}`);
|
|
238
|
+
});
|
|
239
|
+
log.print(`${gray("Press Ctrl+C to stop")}`);
|
|
240
|
+
log.newline();
|
|
241
|
+
}
|
|
242
|
+
const regenerate = createQueuedRegenerator({
|
|
243
|
+
onStart: () => {
|
|
244
|
+
if (!effectiveSilent) {
|
|
245
|
+
const timestamp = (/* @__PURE__ */ new Date()).toLocaleTimeString();
|
|
246
|
+
log.print(`${gray(`[${timestamp}]`)} Change detected, regenerating...`);
|
|
247
|
+
}
|
|
248
|
+
},
|
|
249
|
+
regenerateOnce: async () => generateThemeModeCSS({ isWatch: true }),
|
|
250
|
+
onSuccess: (result) => {
|
|
251
|
+
if (!effectiveSilent) {
|
|
252
|
+
const updatedAt = (/* @__PURE__ */ new Date()).toLocaleTimeString();
|
|
253
|
+
log.print(`${gray(`[${updatedAt}]`)} ${green(`CSS updated (${result?.duration}ms)`)}`);
|
|
254
|
+
log.newline();
|
|
255
|
+
}
|
|
256
|
+
},
|
|
257
|
+
onError: (message) => {
|
|
258
|
+
log.print(message);
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
watchSourceFiles(watchDirs, createDebouncedAction(() => {
|
|
262
|
+
regenerate();
|
|
263
|
+
}, themeConfig.css?.watchDebounce ?? 100));
|
|
264
|
+
await new Promise(() => {});
|
|
265
|
+
}
|
|
266
|
+
} catch (error) {
|
|
267
|
+
const message = error instanceof Error ? error.message : "CSS generation failed";
|
|
268
|
+
if (effectiveSilent) spinStop("❌", message);
|
|
269
|
+
else log.spinStop("❌", message);
|
|
270
|
+
process.exitCode = 1;
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
//#endregion
|
|
275
|
+
export { runCssCommand };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
|
|
2
|
+
|
|
3
|
+
//#region ../tailwind/dist/css/theme.js
|
|
4
|
+
/*! © 2026 Yahoo, Inc. UDS Tailwind and Purger v0.0.0-development */
|
|
5
|
+
/**
|
|
6
|
+
* Helper function to define theme configuration with full type support.
|
|
7
|
+
* Supports both static config objects and dynamic functions.
|
|
8
|
+
*/
|
|
9
|
+
const defineTheme = (config) => config;
|
|
10
|
+
|
|
11
|
+
//#endregion
|
|
12
|
+
exports.defineTheme = defineTheme;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
|
|
2
|
+
import { UDSCSSOptions } from "./generate.cjs";
|
|
3
|
+
|
|
4
|
+
//#region ../tailwind/dist/css/theme.d.ts
|
|
5
|
+
//#region src/css/theme.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* Context passed to theme config function
|
|
8
|
+
*/
|
|
9
|
+
interface UDSThemeContext {
|
|
10
|
+
/** Current working directory */
|
|
11
|
+
cwd: string;
|
|
12
|
+
/** Whether the CLI is running in watch mode */
|
|
13
|
+
watch?: boolean;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* CSS optimization options for uds.theme.ts
|
|
17
|
+
*/
|
|
18
|
+
interface UDSCSSOptimizationOptions {
|
|
19
|
+
/** Enable all CSS optimizations (default: true) */
|
|
20
|
+
enabled?: boolean;
|
|
21
|
+
/** Remove @font-face declarations for fonts not used in the CSS (default: false) */
|
|
22
|
+
removeUnusedFonts?: boolean;
|
|
23
|
+
/** Remove empty CSS rules (default: true) */
|
|
24
|
+
removeEmptyRules?: boolean;
|
|
25
|
+
/** Aggregate duplicate selectors (default: true) */
|
|
26
|
+
aggregateDuplicateSelectors?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Remove duplicate content from scoped CSS that already exists in main CSS (default: true)
|
|
29
|
+
* Currently deduplicates @font-face declarations. Reduces bundle size when scoped packages
|
|
30
|
+
* share fonts with the main app.
|
|
31
|
+
*/
|
|
32
|
+
deduplicateScopedCss?: boolean;
|
|
33
|
+
/** Prune unused CSS variables (default: true) */
|
|
34
|
+
pruneVars?: boolean;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Theme configuration structure for uds.theme.ts
|
|
38
|
+
*/
|
|
39
|
+
interface UDSThemeConfig {
|
|
40
|
+
/** Path to app's uds.config (relative to project root) */
|
|
41
|
+
config?: string;
|
|
42
|
+
/** Entry directory for app code scanning (default: '/src/') */
|
|
43
|
+
entry?: string;
|
|
44
|
+
/** Suppress log output during generation (default: false) */
|
|
45
|
+
silent?: boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Packages that inherit the app's theme configuration.
|
|
48
|
+
* These packages' styles are merged into the main uds.css file.
|
|
49
|
+
*/
|
|
50
|
+
inherit?: string[];
|
|
51
|
+
/** Color modes to include (default: ['dark']) - light mode is always in :root */
|
|
52
|
+
colorModes?: ('dark' | 'light')[];
|
|
53
|
+
/** CSS generation options */
|
|
54
|
+
css?: UDSCSSOptions;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Theme config can be an object or a function that receives context
|
|
58
|
+
*/
|
|
59
|
+
type UDSThemeConfigInput = UDSThemeConfig | ((ctx: UDSThemeContext) => UDSThemeConfig | Promise<UDSThemeConfig>);
|
|
60
|
+
/**
|
|
61
|
+
* Helper function to define theme configuration with full type support.
|
|
62
|
+
* Supports both static config objects and dynamic functions.
|
|
63
|
+
*/
|
|
64
|
+
declare const defineTheme: (config: UDSThemeConfigInput) => UDSThemeConfigInput; //#endregion
|
|
65
|
+
//#endregion
|
|
66
|
+
export { type UDSCSSOptimizationOptions, defineTheme };
|