@ethlete/core 5.0.0-next.17 ā 5.0.0-next.19
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.
|
@@ -5,6 +5,10 @@ export default async function generate(tree, schema) {
|
|
|
5
5
|
const themesPath = schema.themesPath || 'src/themes.ts';
|
|
6
6
|
const outputPath = schema.outputPath || 'src/styles/generated-tailwind-themes.css';
|
|
7
7
|
const prefix = schema.prefix || 'et';
|
|
8
|
+
// The runtime prefix drives the theme-swap CSS variables (--<runtimePrefix>-color-primary)
|
|
9
|
+
// and selectors (.<runtimePrefix>-color--<name>). It defaults to `prefix` so existing
|
|
10
|
+
// consumers who only ever passed one prefix see no change in output.
|
|
11
|
+
const runtimePrefix = schema.runtimePrefix || prefix;
|
|
8
12
|
// Step 1: Check if themes file exists
|
|
9
13
|
if (!tree.exists(themesPath)) {
|
|
10
14
|
logger.error(`ā Themes file not found at: ${themesPath}`);
|
|
@@ -43,7 +47,7 @@ export default async function generate(tree, schema) {
|
|
|
43
47
|
}
|
|
44
48
|
// Step 5: Generate Tailwind CSS
|
|
45
49
|
logger.log('\nšØ Generating Tailwind theme CSS...');
|
|
46
|
-
const css = generateTailwindThemeCss(themes, prefix, schema);
|
|
50
|
+
const css = generateTailwindThemeCss(themes, prefix, runtimePrefix, schema);
|
|
47
51
|
// Step 6: Write the generated CSS file
|
|
48
52
|
const outputDir = outputPath.substring(0, outputPath.lastIndexOf('/'));
|
|
49
53
|
if (outputDir && !tree.exists(outputDir)) {
|
|
@@ -298,18 +302,18 @@ function createCssThemeName(name) {
|
|
|
298
302
|
.replace(/\s+/g, '-')
|
|
299
303
|
.replace(/[^a-z0-9-]/g, '');
|
|
300
304
|
}
|
|
301
|
-
function generateTailwindThemeCss(themes,
|
|
305
|
+
function generateTailwindThemeCss(themes, utilityPrefix, runtimePrefix, schema) {
|
|
302
306
|
const tailwindVars = [];
|
|
303
307
|
const themeVars = [];
|
|
304
308
|
const themesPath = schema.themesPath || 'src/themes.ts';
|
|
305
309
|
const outputPath = schema.outputPath || 'src/styles/generated-tailwind-themes.css';
|
|
306
|
-
const header = `/*
|
|
310
|
+
const header = `/*
|
|
307
311
|
* Auto-generated Tailwind 4 theme colors from @ethlete/core
|
|
308
312
|
* DO NOT EDIT THIS FILE MANUALLY
|
|
309
|
-
*
|
|
313
|
+
*
|
|
310
314
|
* Generated from your theme definitions
|
|
311
315
|
* This file can be regenerated by running:
|
|
312
|
-
* nx g @ethlete/core:tailwind-4-color-theme --themesPath=${themesPath}${schema.outputPath ? ` --outputPath=${outputPath}` : ''}${schema.prefix && schema.prefix !== 'et' ? ` --prefix=${schema.prefix}` : ''}
|
|
316
|
+
* nx g @ethlete/core:tailwind-4-color-theme --themesPath=${themesPath}${schema.outputPath ? ` --outputPath=${outputPath}` : ''}${schema.prefix && schema.prefix !== 'et' ? ` --prefix=${schema.prefix}` : ''}${schema.runtimePrefix && schema.runtimePrefix !== utilityPrefix ? ` --runtimePrefix=${schema.runtimePrefix}` : ''}
|
|
313
317
|
*/
|
|
314
318
|
|
|
315
319
|
`;
|
|
@@ -322,26 +326,26 @@ function generateTailwindThemeCss(themes, prefix, schema) {
|
|
|
322
326
|
// Add comment for theme section
|
|
323
327
|
tailwindVars.push(` /* ${theme.name} theme */`);
|
|
324
328
|
// Primary colors for Tailwind utilities
|
|
325
|
-
addTailwindColorVariants(tailwindVars, `${
|
|
329
|
+
addTailwindColorVariants(tailwindVars, `${utilityPrefix}-${name}`, theme.primary.color);
|
|
326
330
|
tailwindVars.push('');
|
|
327
331
|
// On colors for Tailwind utilities
|
|
328
|
-
addTailwindColorVariants(tailwindVars, `${
|
|
332
|
+
addTailwindColorVariants(tailwindVars, `${utilityPrefix}-on-${name}`, theme.primary.onColor);
|
|
329
333
|
tailwindVars.push('');
|
|
330
334
|
// Ink colors for standalone foreground usage
|
|
331
|
-
addTailwindColorVariants(tailwindVars, `${
|
|
335
|
+
addTailwindColorVariants(tailwindVars, `${utilityPrefix}-${name}-ink`, theme.primary.inkColor || theme.primary.color);
|
|
332
336
|
tailwindVars.push('');
|
|
333
337
|
// Secondary colors if present
|
|
334
338
|
if (theme.secondary) {
|
|
335
|
-
addTailwindColorVariants(tailwindVars, `${
|
|
339
|
+
addTailwindColorVariants(tailwindVars, `${utilityPrefix}-${name}-secondary`, theme.secondary.color);
|
|
336
340
|
tailwindVars.push('');
|
|
337
|
-
addTailwindColorVariants(tailwindVars, `${
|
|
341
|
+
addTailwindColorVariants(tailwindVars, `${utilityPrefix}-on-${name}-secondary`, theme.secondary.onColor);
|
|
338
342
|
tailwindVars.push('');
|
|
339
343
|
}
|
|
340
344
|
// Tertiary colors if present
|
|
341
345
|
if (theme.tertiary) {
|
|
342
|
-
addTailwindColorVariants(tailwindVars, `${
|
|
346
|
+
addTailwindColorVariants(tailwindVars, `${utilityPrefix}-${name}-tertiary`, theme.tertiary.color);
|
|
343
347
|
tailwindVars.push('');
|
|
344
|
-
addTailwindColorVariants(tailwindVars, `${
|
|
348
|
+
addTailwindColorVariants(tailwindVars, `${utilityPrefix}-on-${name}-tertiary`, theme.tertiary.onColor);
|
|
345
349
|
tailwindVars.push('');
|
|
346
350
|
}
|
|
347
351
|
}
|
|
@@ -351,50 +355,50 @@ function generateTailwindThemeCss(themes, prefix, schema) {
|
|
|
351
355
|
const hasSecondary = mainThemes.some((t) => t.secondary);
|
|
352
356
|
const hasTertiary = mainThemes.some((t) => t.tertiary);
|
|
353
357
|
tailwindVars.push(' /* Dynamic theme colors (references runtime CSS variables) */');
|
|
354
|
-
addDynamicThemeColors(tailwindVars,
|
|
355
|
-
addDynamicInkColors(tailwindVars,
|
|
358
|
+
addDynamicThemeColors(tailwindVars, utilityPrefix, runtimePrefix, 'theme', 'primary', true);
|
|
359
|
+
addDynamicInkColors(tailwindVars, utilityPrefix, runtimePrefix, 'theme-ink', 'primary-ink');
|
|
356
360
|
if (hasSecondary) {
|
|
357
|
-
addDynamicThemeColors(tailwindVars,
|
|
361
|
+
addDynamicThemeColors(tailwindVars, utilityPrefix, runtimePrefix, 'theme-secondary', 'secondary', false);
|
|
358
362
|
}
|
|
359
363
|
if (hasTertiary) {
|
|
360
|
-
addDynamicThemeColors(tailwindVars,
|
|
364
|
+
addDynamicThemeColors(tailwindVars, utilityPrefix, runtimePrefix, 'theme-tertiary', 'tertiary', false);
|
|
361
365
|
}
|
|
362
366
|
// Generate runtime CSS for all themes
|
|
363
367
|
themes.forEach((theme) => {
|
|
364
368
|
const name = createCssThemeName(theme.name);
|
|
365
369
|
// Determine if this is the default theme
|
|
366
370
|
const isDefault = theme.isDefault;
|
|
367
|
-
// Generate color variant (
|
|
371
|
+
// Generate color variant (.<runtimePrefix>-color--{name})
|
|
368
372
|
if (isDefault) {
|
|
369
|
-
// Default color gets :root and
|
|
370
|
-
const selectors = [':root', `.${
|
|
373
|
+
// Default color gets :root and .<runtimePrefix>-color--default selectors
|
|
374
|
+
const selectors = [':root', `.${runtimePrefix}-color--default`, `.${runtimePrefix}-color--${name}`];
|
|
371
375
|
themeVars.push(`${selectors.join(', ')} {`);
|
|
372
376
|
}
|
|
373
377
|
else {
|
|
374
378
|
// Regular colors just get their own class
|
|
375
|
-
themeVars.push(`.${
|
|
379
|
+
themeVars.push(`.${runtimePrefix}-color--${name} {`);
|
|
376
380
|
}
|
|
377
|
-
addThemeColorVariants(themeVars,
|
|
381
|
+
addThemeColorVariants(themeVars, runtimePrefix, '', theme);
|
|
378
382
|
themeVars.push('}\n');
|
|
379
383
|
});
|
|
380
384
|
// Convenience var aliases ā available on any element with a color class (or root for default)
|
|
381
385
|
const aliasBlock = `/* Convenience aliases (rgb + solid + opacity variants) */
|
|
382
386
|
@layer base {
|
|
383
|
-
:root, :where([class*="${
|
|
384
|
-
--${
|
|
385
|
-
--${
|
|
386
|
-
--${
|
|
387
|
-
--${
|
|
387
|
+
:root, :where([class*="${runtimePrefix}-color--"]) {
|
|
388
|
+
--${runtimePrefix}-theme-color-primary-rgb: var(--${runtimePrefix}-color-primary);
|
|
389
|
+
--${runtimePrefix}-theme-color-primary-opacity: 1;
|
|
390
|
+
--${runtimePrefix}-theme-color-primary-solid: rgb(var(--${runtimePrefix}-theme-color-primary-rgb));
|
|
391
|
+
--${runtimePrefix}-theme-color-primary: rgb(var(--${runtimePrefix}-theme-color-primary-rgb) / var(--${runtimePrefix}-theme-color-primary-opacity));
|
|
388
392
|
|
|
389
|
-
--${
|
|
390
|
-
--${
|
|
391
|
-
--${
|
|
392
|
-
--${
|
|
393
|
+
--${runtimePrefix}-theme-color-on-primary-rgb: var(--${runtimePrefix}-color-on-primary);
|
|
394
|
+
--${runtimePrefix}-theme-color-on-primary-opacity: 1;
|
|
395
|
+
--${runtimePrefix}-theme-color-on-primary-solid: rgb(var(--${runtimePrefix}-theme-color-on-primary-rgb) / var(--${runtimePrefix}-theme-color-on-primary-opacity));
|
|
396
|
+
--${runtimePrefix}-theme-color-on-primary: rgb(var(--${runtimePrefix}-theme-color-on-primary-rgb) / var(--${runtimePrefix}-theme-color-on-primary-opacity));
|
|
393
397
|
|
|
394
|
-
--${
|
|
395
|
-
--${
|
|
396
|
-
--${
|
|
397
|
-
--${
|
|
398
|
+
--${runtimePrefix}-theme-color-ink-rgb: var(--${runtimePrefix}-color-primary-ink, var(--${runtimePrefix}-color-primary));
|
|
399
|
+
--${runtimePrefix}-theme-color-ink-opacity: 1;
|
|
400
|
+
--${runtimePrefix}-theme-color-ink-solid: rgb(var(--${runtimePrefix}-theme-color-ink-rgb) / var(--${runtimePrefix}-theme-color-ink-opacity));
|
|
401
|
+
--${runtimePrefix}-theme-color-ink: rgb(var(--${runtimePrefix}-theme-color-ink-rgb) / var(--${runtimePrefix}-theme-color-ink-opacity));
|
|
398
402
|
}
|
|
399
403
|
}
|
|
400
404
|
`;
|
|
@@ -408,31 +412,31 @@ ${themeVars.join('\n')}
|
|
|
408
412
|
|
|
409
413
|
${aliasBlock}`;
|
|
410
414
|
}
|
|
411
|
-
function addDynamicThemeColors(vars,
|
|
415
|
+
function addDynamicThemeColors(vars, utilityPrefix, runtimePrefix, tailwindName, cssVarName, addSpacingBefore) {
|
|
412
416
|
if (addSpacingBefore && vars.length > 0 && vars[vars.length - 1] !== '') {
|
|
413
417
|
vars.push('');
|
|
414
418
|
}
|
|
415
419
|
// Color variants
|
|
416
|
-
vars.push(` --color-${
|
|
417
|
-
vars.push(` --color-${
|
|
418
|
-
vars.push(` --color-${
|
|
419
|
-
vars.push(` --color-${
|
|
420
|
-
vars.push(` --color-${
|
|
420
|
+
vars.push(` --color-${utilityPrefix}-${tailwindName}: rgb(var(--${runtimePrefix}-color-${cssVarName}));`);
|
|
421
|
+
vars.push(` --color-${utilityPrefix}-${tailwindName}-hover: rgb(var(--${runtimePrefix}-color-${cssVarName}-hover));`);
|
|
422
|
+
vars.push(` --color-${utilityPrefix}-${tailwindName}-focus: rgb(var(--${runtimePrefix}-color-${cssVarName}-focus));`);
|
|
423
|
+
vars.push(` --color-${utilityPrefix}-${tailwindName}-active: rgb(var(--${runtimePrefix}-color-${cssVarName}-active));`);
|
|
424
|
+
vars.push(` --color-${utilityPrefix}-${tailwindName}-disabled: rgb(var(--${runtimePrefix}-color-${cssVarName}-disabled));`);
|
|
421
425
|
vars.push('');
|
|
422
426
|
// On-color variants
|
|
423
|
-
vars.push(` --color-${
|
|
424
|
-
vars.push(` --color-${
|
|
425
|
-
vars.push(` --color-${
|
|
426
|
-
vars.push(` --color-${
|
|
427
|
-
vars.push(` --color-${
|
|
427
|
+
vars.push(` --color-${utilityPrefix}-on-${tailwindName}: rgb(var(--${runtimePrefix}-color-on-${cssVarName}));`);
|
|
428
|
+
vars.push(` --color-${utilityPrefix}-on-${tailwindName}-hover: rgb(var(--${runtimePrefix}-color-on-${cssVarName}-hover));`);
|
|
429
|
+
vars.push(` --color-${utilityPrefix}-on-${tailwindName}-focus: rgb(var(--${runtimePrefix}-color-on-${cssVarName}-focus));`);
|
|
430
|
+
vars.push(` --color-${utilityPrefix}-on-${tailwindName}-active: rgb(var(--${runtimePrefix}-color-on-${cssVarName}-active));`);
|
|
431
|
+
vars.push(` --color-${utilityPrefix}-on-${tailwindName}-disabled: rgb(var(--${runtimePrefix}-color-on-${cssVarName}-disabled));`);
|
|
428
432
|
vars.push('');
|
|
429
433
|
}
|
|
430
|
-
function addDynamicInkColors(vars,
|
|
431
|
-
vars.push(` --color-${
|
|
432
|
-
vars.push(` --color-${
|
|
433
|
-
vars.push(` --color-${
|
|
434
|
-
vars.push(` --color-${
|
|
435
|
-
vars.push(` --color-${
|
|
434
|
+
function addDynamicInkColors(vars, utilityPrefix, runtimePrefix, tailwindName, cssVarName) {
|
|
435
|
+
vars.push(` --color-${utilityPrefix}-${tailwindName}: rgb(var(--${runtimePrefix}-color-${cssVarName}));`);
|
|
436
|
+
vars.push(` --color-${utilityPrefix}-${tailwindName}-hover: rgb(var(--${runtimePrefix}-color-${cssVarName}-hover));`);
|
|
437
|
+
vars.push(` --color-${utilityPrefix}-${tailwindName}-focus: rgb(var(--${runtimePrefix}-color-${cssVarName}-focus));`);
|
|
438
|
+
vars.push(` --color-${utilityPrefix}-${tailwindName}-active: rgb(var(--${runtimePrefix}-color-${cssVarName}-active));`);
|
|
439
|
+
vars.push(` --color-${utilityPrefix}-${tailwindName}-disabled: rgb(var(--${runtimePrefix}-color-${cssVarName}-disabled));`);
|
|
436
440
|
vars.push('');
|
|
437
441
|
}
|
|
438
442
|
function addTailwindColorVariants(vars, colorName, colorSet) {
|
|
@@ -19,9 +19,13 @@
|
|
|
19
19
|
},
|
|
20
20
|
"prefix": {
|
|
21
21
|
"type": "string",
|
|
22
|
-
"description": "Prefix for color variable names (e.g., 'et' creates --color-et-primary)",
|
|
22
|
+
"description": "Prefix for Tailwind utility color variable names (e.g., 'et' creates --color-et-primary, usable as bg-et-primary)",
|
|
23
23
|
"default": "et"
|
|
24
24
|
},
|
|
25
|
+
"runtimePrefix": {
|
|
26
|
+
"type": "string",
|
|
27
|
+
"description": "Prefix for the runtime theme-swap mechanism: the CSS custom properties (--<runtimePrefix>-color-primary) and selectors (.<runtimePrefix>-color--<name>) that ProvideColorDirective (etProvideColor) toggles between. Defaults to the same value as 'prefix'. Set this separately when your Tailwind utility prefix needs to differ from your runtime theme-switching prefix (e.g. because '--color-primary' is already a documented public API elsewhere in your app)."
|
|
28
|
+
},
|
|
25
29
|
"skipFormat": {
|
|
26
30
|
"type": "boolean",
|
|
27
31
|
"description": "Skip formatting files after generation",
|