@ethlete/core 5.0.0-next.64 ā 5.0.0-next.66
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/CHANGELOG.md +26 -0
- package/design/interactive-styles.ts +5 -0
- package/design/theme-css.js +392 -0
- package/design/theme-css.ts +547 -0
- package/fesm2022/ethlete-core.mjs +528 -383
- package/fesm2022/ethlete-core.mjs.map +1 -1
- package/generators/tailwind-4-color-theme/generator.js +4 -187
- package/generators/tailwind-4-surface-theme/generator.js +4 -234
- package/package.json +16 -10
- package/src/lib/animations/easing-tokens-styles.component.css +155 -0
- package/src/lib/providers/visually-hidden-styles.component.css +13 -0
- package/src/lib/resize-handles/resize-handles.component.css +137 -0
- package/src/lib/theming/color-interactive-styles.component.css +147 -0
- package/src/lib/theming/surface-interactive-styles.component.css +42 -0
- package/types/ethlete-core.d.ts +58 -11
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { formatFiles, logger, visitNotIgnoredFiles } from '@nx/devkit';
|
|
2
2
|
import { posix } from 'path';
|
|
3
3
|
import { Project, SyntaxKind } from 'ts-morph';
|
|
4
|
+
import { colorThemeCss, cssThemeName } from '../../design/theme-css.js';
|
|
4
5
|
export default async function generate(tree, schema) {
|
|
5
6
|
logger.log('\nš Starting Tailwind 4 theme generator...\n');
|
|
6
7
|
const themesPath = schema.themesPath || 'src/themes.ts';
|
|
@@ -200,8 +201,8 @@ function parseThemeObject(obj, sourceFile, context) {
|
|
|
200
201
|
return theme;
|
|
201
202
|
}
|
|
202
203
|
function applyDefaultThemeOverride(themes, defaultTheme) {
|
|
203
|
-
const wanted =
|
|
204
|
-
const target = themes.find((t) => t.name === defaultTheme ||
|
|
204
|
+
const wanted = cssThemeName(defaultTheme);
|
|
205
|
+
const target = themes.find((t) => t.name === defaultTheme || cssThemeName(t.name) === wanted);
|
|
205
206
|
if (!target) {
|
|
206
207
|
throw new Error(`No theme named "${defaultTheme}" found. Available themes: ${themes.map((t) => t.name).join(', ')}`);
|
|
207
208
|
}
|
|
@@ -362,12 +363,6 @@ function parseColorMap(initializer, sourceFile, context) {
|
|
|
362
363
|
}
|
|
363
364
|
return null;
|
|
364
365
|
}
|
|
365
|
-
function createCssThemeName(name) {
|
|
366
|
-
return name
|
|
367
|
-
.toLowerCase()
|
|
368
|
-
.replace(/\s+/g, '-')
|
|
369
|
-
.replace(/[^a-z0-9-]/g, '');
|
|
370
|
-
}
|
|
371
366
|
function generateColorThemeNameTypes(themes, schema) {
|
|
372
367
|
const themesPath = schema.themesPath || 'src/themes.ts';
|
|
373
368
|
const outputPath = schema.outputPath || 'src/styles/generated-tailwind-themes.css';
|
|
@@ -391,8 +386,6 @@ export {};
|
|
|
391
386
|
`;
|
|
392
387
|
}
|
|
393
388
|
function generateTailwindThemeCss(themes, utilityPrefix, runtimePrefix, schema) {
|
|
394
|
-
const tailwindVars = [];
|
|
395
|
-
const themeVars = [];
|
|
396
389
|
const themesPath = schema.themesPath || 'src/themes.ts';
|
|
397
390
|
const outputPath = schema.outputPath || 'src/styles/generated-tailwind-themes.css';
|
|
398
391
|
const header = `/*
|
|
@@ -405,183 +398,7 @@ function generateTailwindThemeCss(themes, utilityPrefix, runtimePrefix, schema)
|
|
|
405
398
|
*/
|
|
406
399
|
|
|
407
400
|
`;
|
|
408
|
-
|
|
409
|
-
const name = createCssThemeName(theme.name);
|
|
410
|
-
tailwindVars.push(` /* ${theme.name} theme */`);
|
|
411
|
-
addTailwindColorVariants(tailwindVars, `${utilityPrefix}-${name}`, theme.primary.color);
|
|
412
|
-
tailwindVars.push('');
|
|
413
|
-
addTailwindColorVariants(tailwindVars, `${utilityPrefix}-on-${name}`, theme.primary.onColor);
|
|
414
|
-
tailwindVars.push('');
|
|
415
|
-
addTailwindColorVariants(tailwindVars, `${utilityPrefix}-${name}-ink`, theme.primary.inkColor || theme.primary.color);
|
|
416
|
-
tailwindVars.push('');
|
|
417
|
-
if (theme.secondary) {
|
|
418
|
-
addTailwindColorVariants(tailwindVars, `${utilityPrefix}-${name}-secondary`, theme.secondary.color);
|
|
419
|
-
tailwindVars.push('');
|
|
420
|
-
addTailwindColorVariants(tailwindVars, `${utilityPrefix}-on-${name}-secondary`, theme.secondary.onColor);
|
|
421
|
-
tailwindVars.push('');
|
|
422
|
-
}
|
|
423
|
-
if (theme.tertiary) {
|
|
424
|
-
addTailwindColorVariants(tailwindVars, `${utilityPrefix}-${name}-tertiary`, theme.tertiary.color);
|
|
425
|
-
tailwindVars.push('');
|
|
426
|
-
addTailwindColorVariants(tailwindVars, `${utilityPrefix}-on-${name}-tertiary`, theme.tertiary.onColor);
|
|
427
|
-
tailwindVars.push('');
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
tailwindVars.push('');
|
|
431
|
-
const hasSecondary = themes.some((t) => t.secondary);
|
|
432
|
-
const hasTertiary = themes.some((t) => t.tertiary);
|
|
433
|
-
// Collect the dynamic theme colors once. They are emitted in `@theme` (so Tailwind generates
|
|
434
|
-
// the utilities) and ALSO re-declared on every color selector in the alias block below. A
|
|
435
|
-
// Tailwind `@theme` variable only lands on `:root`, so `rgb(var(--<runtime>-color-*))` resolves
|
|
436
|
-
// once against the root color scope and inherits that concrete color into descendants - which
|
|
437
|
-
// means `bg-<prefix>-theme-*` utilities would ignore nested `.<runtime>-color--*` scopes.
|
|
438
|
-
// Re-declaring them per color selector makes the utilities resolve against the nearest scope.
|
|
439
|
-
const dynamicColorVars = [];
|
|
440
|
-
addDynamicThemeColors(dynamicColorVars, utilityPrefix, runtimePrefix, 'theme', 'primary', false);
|
|
441
|
-
addDynamicInkColors(dynamicColorVars, utilityPrefix, runtimePrefix, 'theme-ink', 'primary-ink');
|
|
442
|
-
if (hasSecondary) {
|
|
443
|
-
addDynamicThemeColors(dynamicColorVars, utilityPrefix, runtimePrefix, 'theme-secondary', 'secondary', false);
|
|
444
|
-
}
|
|
445
|
-
if (hasTertiary) {
|
|
446
|
-
addDynamicThemeColors(dynamicColorVars, utilityPrefix, runtimePrefix, 'theme-tertiary', 'tertiary', false);
|
|
447
|
-
}
|
|
448
|
-
tailwindVars.push(' /* Dynamic theme colors (references runtime CSS variables) */');
|
|
449
|
-
tailwindVars.push(...dynamicColorVars);
|
|
450
|
-
themes.forEach((theme) => {
|
|
451
|
-
const name = createCssThemeName(theme.name);
|
|
452
|
-
const isDefault = theme.isDefault;
|
|
453
|
-
if (isDefault) {
|
|
454
|
-
const selectors = [':root', `.${runtimePrefix}-color--default`, `.${runtimePrefix}-color--${name}`];
|
|
455
|
-
themeVars.push(`${selectors.join(', ')} {`);
|
|
456
|
-
}
|
|
457
|
-
else {
|
|
458
|
-
themeVars.push(`.${runtimePrefix}-color--${name} {`);
|
|
459
|
-
}
|
|
460
|
-
addThemeColorVariants(themeVars, runtimePrefix, '', theme);
|
|
461
|
-
themeVars.push('}\n');
|
|
462
|
-
});
|
|
463
|
-
// Re-indent the dynamic theme colors (from 2-space `@theme` indent to the 4-space alias-block
|
|
464
|
-
// indent) and drop trailing blank lines so they slot cleanly into the alias selector below.
|
|
465
|
-
const dynamicColorAliasLines = dynamicColorVars.map((line) => (line === '' ? '' : ` ${line}`));
|
|
466
|
-
while (dynamicColorAliasLines.length && dynamicColorAliasLines[dynamicColorAliasLines.length - 1] === '') {
|
|
467
|
-
dynamicColorAliasLines.pop();
|
|
468
|
-
}
|
|
469
|
-
const aliasBlock = `/* Convenience aliases (rgb + solid + opacity variants) */
|
|
470
|
-
@layer base {
|
|
471
|
-
:root, :where([class*="${runtimePrefix}-color--"]) {
|
|
472
|
-
--${runtimePrefix}-theme-color-primary-rgb: var(--${runtimePrefix}-color-primary);
|
|
473
|
-
--${runtimePrefix}-theme-color-primary-opacity: 1;
|
|
474
|
-
--${runtimePrefix}-theme-color-primary-solid: rgb(var(--${runtimePrefix}-theme-color-primary-rgb));
|
|
475
|
-
--${runtimePrefix}-theme-color-primary: rgb(var(--${runtimePrefix}-theme-color-primary-rgb) / var(--${runtimePrefix}-theme-color-primary-opacity));
|
|
476
|
-
|
|
477
|
-
--${runtimePrefix}-theme-color-on-primary-rgb: var(--${runtimePrefix}-color-on-primary);
|
|
478
|
-
--${runtimePrefix}-theme-color-on-primary-opacity: 1;
|
|
479
|
-
--${runtimePrefix}-theme-color-on-primary-solid: rgb(var(--${runtimePrefix}-theme-color-on-primary-rgb) / var(--${runtimePrefix}-theme-color-on-primary-opacity));
|
|
480
|
-
--${runtimePrefix}-theme-color-on-primary: rgb(var(--${runtimePrefix}-theme-color-on-primary-rgb) / var(--${runtimePrefix}-theme-color-on-primary-opacity));
|
|
481
|
-
|
|
482
|
-
--${runtimePrefix}-theme-color-ink-rgb: var(--${runtimePrefix}-color-primary-ink, var(--${runtimePrefix}-color-primary));
|
|
483
|
-
--${runtimePrefix}-theme-color-ink-opacity: 1;
|
|
484
|
-
--${runtimePrefix}-theme-color-ink-solid: rgb(var(--${runtimePrefix}-theme-color-ink-rgb) / var(--${runtimePrefix}-theme-color-ink-opacity));
|
|
485
|
-
--${runtimePrefix}-theme-color-ink: rgb(var(--${runtimePrefix}-theme-color-ink-rgb) / var(--${runtimePrefix}-theme-color-ink-opacity));
|
|
486
|
-
|
|
487
|
-
/* Dynamic Tailwind theme colors - re-declared per color scope so that
|
|
488
|
-
bg-${utilityPrefix}-theme-* utilities resolve against the nearest .${runtimePrefix}-color--*
|
|
489
|
-
scope instead of the value computed once at :root. */
|
|
490
|
-
${dynamicColorAliasLines.join('\n')}
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
`;
|
|
494
|
-
return `${header}@theme {
|
|
495
|
-
${tailwindVars.join('\n')}
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
@layer base {
|
|
499
|
-
${themeVars.join('\n')}
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
${aliasBlock}`;
|
|
503
|
-
}
|
|
504
|
-
function addDynamicThemeColors(vars, utilityPrefix, runtimePrefix, tailwindName, cssVarName, addSpacingBefore) {
|
|
505
|
-
if (addSpacingBefore && vars.length > 0 && vars[vars.length - 1] !== '') {
|
|
506
|
-
vars.push('');
|
|
507
|
-
}
|
|
508
|
-
vars.push(` --color-${utilityPrefix}-${tailwindName}: rgb(var(--${runtimePrefix}-color-${cssVarName}));`);
|
|
509
|
-
vars.push(` --color-${utilityPrefix}-${tailwindName}-hover: rgb(var(--${runtimePrefix}-color-${cssVarName}-hover));`);
|
|
510
|
-
vars.push(` --color-${utilityPrefix}-${tailwindName}-focus: rgb(var(--${runtimePrefix}-color-${cssVarName}-focus));`);
|
|
511
|
-
vars.push(` --color-${utilityPrefix}-${tailwindName}-active: rgb(var(--${runtimePrefix}-color-${cssVarName}-active));`);
|
|
512
|
-
vars.push(` --color-${utilityPrefix}-${tailwindName}-disabled: rgb(var(--${runtimePrefix}-color-${cssVarName}-disabled));`);
|
|
513
|
-
vars.push('');
|
|
514
|
-
vars.push(` --color-${utilityPrefix}-on-${tailwindName}: rgb(var(--${runtimePrefix}-color-on-${cssVarName}));`);
|
|
515
|
-
vars.push(` --color-${utilityPrefix}-on-${tailwindName}-hover: rgb(var(--${runtimePrefix}-color-on-${cssVarName}-hover));`);
|
|
516
|
-
vars.push(` --color-${utilityPrefix}-on-${tailwindName}-focus: rgb(var(--${runtimePrefix}-color-on-${cssVarName}-focus));`);
|
|
517
|
-
vars.push(` --color-${utilityPrefix}-on-${tailwindName}-active: rgb(var(--${runtimePrefix}-color-on-${cssVarName}-active));`);
|
|
518
|
-
vars.push(` --color-${utilityPrefix}-on-${tailwindName}-disabled: rgb(var(--${runtimePrefix}-color-on-${cssVarName}-disabled));`);
|
|
519
|
-
vars.push('');
|
|
520
|
-
}
|
|
521
|
-
function addDynamicInkColors(vars, utilityPrefix, runtimePrefix, tailwindName, cssVarName) {
|
|
522
|
-
vars.push(` --color-${utilityPrefix}-${tailwindName}: rgb(var(--${runtimePrefix}-color-${cssVarName}));`);
|
|
523
|
-
vars.push(` --color-${utilityPrefix}-${tailwindName}-hover: rgb(var(--${runtimePrefix}-color-${cssVarName}-hover));`);
|
|
524
|
-
vars.push(` --color-${utilityPrefix}-${tailwindName}-focus: rgb(var(--${runtimePrefix}-color-${cssVarName}-focus));`);
|
|
525
|
-
vars.push(` --color-${utilityPrefix}-${tailwindName}-active: rgb(var(--${runtimePrefix}-color-${cssVarName}-active));`);
|
|
526
|
-
vars.push(` --color-${utilityPrefix}-${tailwindName}-disabled: rgb(var(--${runtimePrefix}-color-${cssVarName}-disabled));`);
|
|
527
|
-
vars.push('');
|
|
528
|
-
}
|
|
529
|
-
function addTailwindColorVariants(vars, colorName, colorSet) {
|
|
530
|
-
vars.push(` --color-${colorName}: rgb(${colorSet.default});`);
|
|
531
|
-
const hoverValue = 'hover' in colorSet && colorSet.hover ? colorSet.hover : colorSet.default;
|
|
532
|
-
vars.push(` --color-${colorName}-hover: rgb(${hoverValue});`);
|
|
533
|
-
const focusValue = 'focus' in colorSet && colorSet.focus ? colorSet.focus : hoverValue;
|
|
534
|
-
vars.push(` --color-${colorName}-focus: rgb(${focusValue});`);
|
|
535
|
-
const activeValue = 'active' in colorSet && colorSet.active ? colorSet.active : hoverValue;
|
|
536
|
-
vars.push(` --color-${colorName}-active: rgb(${activeValue});`);
|
|
537
|
-
const disabledValue = 'disabled' in colorSet && colorSet.disabled ? colorSet.disabled : colorSet.default;
|
|
538
|
-
vars.push(` --color-${colorName}-disabled: rgb(${disabledValue});`);
|
|
539
|
-
}
|
|
540
|
-
function addThemeColorVariants(vars, prefix, altPrefix, theme) {
|
|
541
|
-
const addSwatch = (level, swatch) => {
|
|
542
|
-
const defaultColor = swatch.color.default;
|
|
543
|
-
const hoverColor = swatch.color.hover || defaultColor;
|
|
544
|
-
const focusColor = swatch.color.focus || hoverColor;
|
|
545
|
-
const activeColor = swatch.color.active || hoverColor;
|
|
546
|
-
const disabledColor = swatch.color.disabled || defaultColor;
|
|
547
|
-
vars.push(` --${prefix}-color-${altPrefix}${level}: ${defaultColor};`);
|
|
548
|
-
vars.push(` --${prefix}-color-${altPrefix}${level}-hover: ${hoverColor};`);
|
|
549
|
-
vars.push(` --${prefix}-color-${altPrefix}${level}-focus: ${focusColor};`);
|
|
550
|
-
vars.push(` --${prefix}-color-${altPrefix}${level}-active: ${activeColor};`);
|
|
551
|
-
vars.push(` --${prefix}-color-${altPrefix}${level}-disabled: ${disabledColor};`);
|
|
552
|
-
vars.push('');
|
|
553
|
-
const onDefaultColor = swatch.onColor.default;
|
|
554
|
-
const onHoverColor = swatch.onColor.hover || onDefaultColor;
|
|
555
|
-
const onFocusColor = swatch.onColor.focus || onHoverColor;
|
|
556
|
-
const onActiveColor = swatch.onColor.active || onDefaultColor;
|
|
557
|
-
const onDisabledColor = swatch.onColor.disabled || onDefaultColor;
|
|
558
|
-
vars.push(` --${prefix}-color-${altPrefix}on-${level}: ${onDefaultColor};`);
|
|
559
|
-
vars.push(` --${prefix}-color-${altPrefix}on-${level}-hover: ${onHoverColor};`);
|
|
560
|
-
vars.push(` --${prefix}-color-${altPrefix}on-${level}-focus: ${onFocusColor};`);
|
|
561
|
-
vars.push(` --${prefix}-color-${altPrefix}on-${level}-active: ${onActiveColor};`);
|
|
562
|
-
vars.push(` --${prefix}-color-${altPrefix}on-${level}-disabled: ${onDisabledColor};`);
|
|
563
|
-
const inkDefaultColor = swatch.inkColor?.default || defaultColor;
|
|
564
|
-
const inkHoverColor = swatch.inkColor?.hover || inkDefaultColor;
|
|
565
|
-
const inkFocusColor = swatch.inkColor?.focus || inkHoverColor;
|
|
566
|
-
const inkActiveColor = swatch.inkColor?.active || inkDefaultColor;
|
|
567
|
-
const inkDisabledColor = swatch.inkColor?.disabled || inkDefaultColor;
|
|
568
|
-
vars.push('');
|
|
569
|
-
vars.push(` --${prefix}-color-${altPrefix}${level}-ink: ${inkDefaultColor};`);
|
|
570
|
-
vars.push(` --${prefix}-color-${altPrefix}${level}-ink-hover: ${inkHoverColor};`);
|
|
571
|
-
vars.push(` --${prefix}-color-${altPrefix}${level}-ink-focus: ${inkFocusColor};`);
|
|
572
|
-
vars.push(` --${prefix}-color-${altPrefix}${level}-ink-active: ${inkActiveColor};`);
|
|
573
|
-
vars.push(` --${prefix}-color-${altPrefix}${level}-ink-disabled: ${inkDisabledColor};`);
|
|
574
|
-
if (theme.secondary || theme.tertiary) {
|
|
575
|
-
vars.push('');
|
|
576
|
-
}
|
|
577
|
-
};
|
|
578
|
-
addSwatch('primary', theme.primary);
|
|
579
|
-
if (theme.secondary) {
|
|
580
|
-
addSwatch('secondary', theme.secondary);
|
|
581
|
-
}
|
|
582
|
-
if (theme.tertiary) {
|
|
583
|
-
addSwatch('tertiary', theme.tertiary);
|
|
584
|
-
}
|
|
401
|
+
return `${header}${colorThemeCss(themes, { prefix: utilityPrefix, runtimePrefix })}`;
|
|
585
402
|
}
|
|
586
403
|
function findMainStylesFile(tree) {
|
|
587
404
|
const potentialFiles = [];
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { formatFiles, logger, visitNotIgnoredFiles } from '@nx/devkit';
|
|
2
2
|
import { Project, SyntaxKind } from 'ts-morph';
|
|
3
|
+
import { cssThemeName, surfaceThemeCss } from '../../design/theme-css.js';
|
|
3
4
|
export default async function generate(tree, schema) {
|
|
4
5
|
logger.log('\nš Starting Tailwind 4 surface theme generator...\n');
|
|
5
6
|
const themesPath = schema.themesPath || 'src/surface-themes.ts';
|
|
@@ -293,8 +294,8 @@ function parseSurfaceThemeObject(obj, sourceFile) {
|
|
|
293
294
|
// flags on themes of that type. Matches the theme's name or its CSS-safe form. Themes of
|
|
294
295
|
// the other type keep their flags. Returns the resolved name.
|
|
295
296
|
function applyDefaultSurfaceThemeOverride(themes, defaultTheme, type) {
|
|
296
|
-
const wanted =
|
|
297
|
-
const matches = themes.filter((t) => t.name === defaultTheme ||
|
|
297
|
+
const wanted = cssThemeName(defaultTheme);
|
|
298
|
+
const matches = themes.filter((t) => t.name === defaultTheme || cssThemeName(t.name) === wanted);
|
|
298
299
|
const target = matches.find((t) => t.type === type);
|
|
299
300
|
if (!target) {
|
|
300
301
|
const [firstMatch] = matches;
|
|
@@ -329,12 +330,6 @@ function validateSurfaceThemeConfiguration(themes) {
|
|
|
329
330
|
}
|
|
330
331
|
//#endregion
|
|
331
332
|
//#region CSS Generation
|
|
332
|
-
function createCssSurfaceName(name) {
|
|
333
|
-
return name
|
|
334
|
-
.toLowerCase()
|
|
335
|
-
.replace(/\s+/g, '-')
|
|
336
|
-
.replace(/[^a-z0-9-]/g, '');
|
|
337
|
-
}
|
|
338
333
|
function generateSurfaceThemeNameTypes(themes, schema) {
|
|
339
334
|
const themesPath = schema.themesPath || 'src/surface-themes.ts';
|
|
340
335
|
const outputPath = schema.outputPath || 'src/styles/generated-tailwind-surface-themes.css';
|
|
@@ -358,8 +353,6 @@ export {};
|
|
|
358
353
|
`;
|
|
359
354
|
}
|
|
360
355
|
function generateSurfaceThemeCss(themes, utilityPrefix, runtimePrefix, schema) {
|
|
361
|
-
const tailwindVars = [];
|
|
362
|
-
const themeVars = [];
|
|
363
356
|
const themesPath = schema.themesPath || 'src/surface-themes.ts';
|
|
364
357
|
const outputPath = schema.outputPath || 'src/styles/generated-tailwind-surface-themes.css';
|
|
365
358
|
const header = `/*
|
|
@@ -372,230 +365,7 @@ function generateSurfaceThemeCss(themes, utilityPrefix, runtimePrefix, schema) {
|
|
|
372
365
|
*/
|
|
373
366
|
|
|
374
367
|
`;
|
|
375
|
-
|
|
376
|
-
for (const theme of themes) {
|
|
377
|
-
const name = createCssSurfaceName(theme.name);
|
|
378
|
-
tailwindVars.push(` /* ${theme.name} surface */`);
|
|
379
|
-
tailwindVars.push(` --color-${utilityPrefix}-surface-${name}-bg: rgb(${theme.background});`);
|
|
380
|
-
tailwindVars.push(` --color-${utilityPrefix}-surface-${name}: rgb(${theme.color});`);
|
|
381
|
-
tailwindVars.push(` --color-${utilityPrefix}-surface-${name}-muted: rgb(${theme.colorMuted});`);
|
|
382
|
-
tailwindVars.push(` --color-${utilityPrefix}-surface-${name}-subtle: rgb(${theme.colorSubtle});`);
|
|
383
|
-
tailwindVars.push(` --color-${utilityPrefix}-surface-${name}-border: rgb(${theme.border});`);
|
|
384
|
-
if (theme.interactionColor) {
|
|
385
|
-
const { color, onColor, inkColor } = theme.interactionColor;
|
|
386
|
-
pushStaticInteractionColors(tailwindVars, `--color-${utilityPrefix}-surface-${name}-interaction`, color);
|
|
387
|
-
if (onColor) {
|
|
388
|
-
pushStaticInteractionColors(tailwindVars, `--color-${utilityPrefix}-surface-${name}-on-interaction`, onColor);
|
|
389
|
-
}
|
|
390
|
-
if (inkColor) {
|
|
391
|
-
pushStaticInteractionColors(tailwindVars, `--color-${utilityPrefix}-surface-${name}-interaction-ink`, inkColor);
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
tailwindVars.push('');
|
|
395
|
-
}
|
|
396
|
-
// Dynamic surface colors (reference runtime CSS variables).
|
|
397
|
-
// These are ALSO re-declared on every surface selector in the alias block below. A Tailwind
|
|
398
|
-
// `@theme` variable only lands on `:root`, so `rgb(var(--<runtime>-surface-*))` resolves once
|
|
399
|
-
// against the root surface and inherits that concrete color into descendants - which means
|
|
400
|
-
// `bg-<prefix>-surface-*` utilities would ignore nested surface scopes (e.g. an elevated
|
|
401
|
-
// surface). Re-declaring them per surface selector makes the utilities resolve against the
|
|
402
|
-
// nearest surface instead.
|
|
403
|
-
const dynamicSurfaceColors = buildDynamicSurfaceColors(utilityPrefix, runtimePrefix);
|
|
404
|
-
tailwindVars.push(' /* Dynamic surface colors (references runtime CSS variables) */');
|
|
405
|
-
tailwindVars.push(...dynamicSurfaceColors.map((decl) => ` ${decl}`));
|
|
406
|
-
// Runtime CSS - theme selector classes
|
|
407
|
-
for (const theme of themes) {
|
|
408
|
-
const name = createCssSurfaceName(theme.name);
|
|
409
|
-
const isDefault = theme.isDefault;
|
|
410
|
-
if (isDefault) {
|
|
411
|
-
const selectors = [`.${runtimePrefix}-surface--default-${theme.type}`, `.${runtimePrefix}-surface--${name}`];
|
|
412
|
-
themeVars.push(`${selectors.join(', ')} {`);
|
|
413
|
-
}
|
|
414
|
-
else {
|
|
415
|
-
themeVars.push(`.${runtimePrefix}-surface--${name} {`);
|
|
416
|
-
}
|
|
417
|
-
pushSurfaceVars(themeVars, runtimePrefix, theme, ' ');
|
|
418
|
-
themeVars.push('}\n');
|
|
419
|
-
}
|
|
420
|
-
// Root defaults - apply the default surface vars to :root
|
|
421
|
-
const defaultLight = themes.find((t) => t.isDefault && t.type === 'light');
|
|
422
|
-
const defaultDark = themes.find((t) => t.isDefault && t.type === 'dark');
|
|
423
|
-
if (defaultLight && defaultDark) {
|
|
424
|
-
pushSchemeSurfaceVars(themeVars, runtimePrefix, defaultLight);
|
|
425
|
-
pushSchemeSurfaceVars(themeVars, runtimePrefix, defaultDark);
|
|
426
|
-
pushForcedSchemeSurfaceVars(themeVars, runtimePrefix, defaultLight);
|
|
427
|
-
pushForcedSchemeSurfaceVars(themeVars, runtimePrefix, defaultDark);
|
|
428
|
-
}
|
|
429
|
-
else {
|
|
430
|
-
// A single registered surface type has no other scheme to switch to, so its default must
|
|
431
|
-
// land on :root unconditionally - behind prefers-color-scheme it would leave every surface
|
|
432
|
-
// variable undefined for users whose OS asks for the scheme the app lacks.
|
|
433
|
-
pushRootSurfaceVars(themeVars, runtimePrefix, defaultLight ?? defaultDark);
|
|
434
|
-
}
|
|
435
|
-
// Convenience var aliases - available on any element with a surface class or :root (via media queries)
|
|
436
|
-
const aliasBlock = `/* Convenience aliases (rgb + solid variants) */
|
|
437
|
-
@layer base {
|
|
438
|
-
:root, :where([class*="${runtimePrefix}-surface--"]) {
|
|
439
|
-
--${runtimePrefix}-surface-background-rgb: var(--${runtimePrefix}-surface-background);
|
|
440
|
-
--${runtimePrefix}-surface-background-solid: rgb(var(--${runtimePrefix}-surface-background-rgb));
|
|
441
|
-
|
|
442
|
-
--${runtimePrefix}-surface-color-rgb: var(--${runtimePrefix}-surface-color);
|
|
443
|
-
--${runtimePrefix}-surface-color-solid: rgb(var(--${runtimePrefix}-surface-color-rgb));
|
|
444
|
-
|
|
445
|
-
--${runtimePrefix}-surface-color-muted-rgb: var(--${runtimePrefix}-surface-color-muted);
|
|
446
|
-
--${runtimePrefix}-surface-color-muted-solid: rgb(var(--${runtimePrefix}-surface-color-muted-rgb));
|
|
447
|
-
|
|
448
|
-
--${runtimePrefix}-surface-color-subtle-rgb: var(--${runtimePrefix}-surface-color-subtle);
|
|
449
|
-
--${runtimePrefix}-surface-color-subtle-solid: rgb(var(--${runtimePrefix}-surface-color-subtle-rgb));
|
|
450
|
-
|
|
451
|
-
--${runtimePrefix}-surface-border-rgb: var(--${runtimePrefix}-surface-border);
|
|
452
|
-
--${runtimePrefix}-surface-border-solid: rgb(var(--${runtimePrefix}-surface-border-rgb));
|
|
453
|
-
|
|
454
|
-
--${runtimePrefix}-surface-interaction-rgb: var(--${runtimePrefix}-surface-interaction);
|
|
455
|
-
--${runtimePrefix}-surface-interaction-solid: rgb(var(--${runtimePrefix}-surface-interaction-rgb));
|
|
456
|
-
|
|
457
|
-
--${runtimePrefix}-surface-interaction-hover-rgb: var(--${runtimePrefix}-surface-interaction-hover);
|
|
458
|
-
--${runtimePrefix}-surface-interaction-hover-solid: rgb(var(--${runtimePrefix}-surface-interaction-hover-rgb));
|
|
459
|
-
|
|
460
|
-
--${runtimePrefix}-surface-interaction-focus-rgb: var(--${runtimePrefix}-surface-interaction-focus);
|
|
461
|
-
--${runtimePrefix}-surface-interaction-focus-solid: rgb(var(--${runtimePrefix}-surface-interaction-focus-rgb));
|
|
462
|
-
|
|
463
|
-
--${runtimePrefix}-surface-interaction-active-rgb: var(--${runtimePrefix}-surface-interaction-active);
|
|
464
|
-
--${runtimePrefix}-surface-interaction-active-solid: rgb(var(--${runtimePrefix}-surface-interaction-active-rgb));
|
|
465
|
-
|
|
466
|
-
--${runtimePrefix}-surface-interaction-disabled-rgb: var(--${runtimePrefix}-surface-interaction-disabled);
|
|
467
|
-
--${runtimePrefix}-surface-interaction-disabled-solid: rgb(var(--${runtimePrefix}-surface-interaction-disabled-rgb));
|
|
468
|
-
|
|
469
|
-
/* Dynamic Tailwind surface colors - re-declared per surface scope so that
|
|
470
|
-
bg-${utilityPrefix}-surface-* utilities resolve against the nearest surface
|
|
471
|
-
(e.g. a nested elevated surface) instead of the value computed once at :root. */
|
|
472
|
-
${dynamicSurfaceColors.map((decl) => ` ${decl}`).join('\n')}
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
`;
|
|
476
|
-
return `${header}@theme {
|
|
477
|
-
${tailwindVars.join('\n')}
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
@layer base {
|
|
481
|
-
${themeVars.join('\n')}
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
${aliasBlock}
|
|
485
|
-
${buildSurfaceColorScope(runtimePrefix)}`;
|
|
486
|
-
}
|
|
487
|
-
// The reserved `surface` color scope. It bridges the two theming systems - color variables out of
|
|
488
|
-
// surface variables - so `[etProvideColor]="'surface'"` renders a component in the neutral of
|
|
489
|
-
// whatever surface it sits on. It lives here rather than in the SDK's own CSS because a stylesheet
|
|
490
|
-
// shipped with `ProvideColorDirective` would land in every bundle that themes anything, and only
|
|
491
|
-
// apps that use the scope should pay for it.
|
|
492
|
-
function buildSurfaceColorScope(runtimePrefix) {
|
|
493
|
-
const tint = `var(--${runtimePrefix}-surface-interaction, var(--${runtimePrefix}-surface-color))`;
|
|
494
|
-
const on = `var(--${runtimePrefix}-surface-on-interaction, var(--${runtimePrefix}-surface-background))`;
|
|
495
|
-
const ink = `var(--${runtimePrefix}-surface-interaction-ink, var(--${runtimePrefix}-surface-color))`;
|
|
496
|
-
const state = (name, source, fallback) => INTERACTION_STATE_SUFFIXES.map((suffix) => ` --${runtimePrefix}-color-${name}${suffix}: ${suffix ? `var(--${runtimePrefix}-surface-${source}${suffix}, ${fallback})` : fallback};`).join('\n');
|
|
497
|
-
return `/* The reserved \`surface\` color: resolves the color tokens from the ambient surface's neutral swatch. */
|
|
498
|
-
@layer base {
|
|
499
|
-
.${runtimePrefix}-color--surface {
|
|
500
|
-
${state('primary', 'interaction', tint)}
|
|
501
|
-
|
|
502
|
-
${state('on-primary', 'on-interaction', on)}
|
|
503
|
-
|
|
504
|
-
${state('primary-ink', 'interaction-ink', ink)}
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
`;
|
|
508
|
-
}
|
|
509
|
-
// Dynamic surface color declarations (unindented). Emitted in `@theme` (so Tailwind generates
|
|
510
|
-
// the utilities) and re-declared on every surface selector (so the utilities resolve per scope).
|
|
511
|
-
function buildDynamicSurfaceColors(utilityPrefix, runtimePrefix) {
|
|
512
|
-
// `on-interaction` and `interaction-ink` are optional per theme, so each falls back to the
|
|
513
|
-
// surface's own background/color - the same defaults the `.<runtimePrefix>-color--surface`
|
|
514
|
-
// bridge applies.
|
|
515
|
-
const onFallback = `var(--${runtimePrefix}-surface-background)`;
|
|
516
|
-
const inkFallback = `var(--${runtimePrefix}-surface-color)`;
|
|
517
|
-
return [
|
|
518
|
-
`--color-${utilityPrefix}-surface-bg: rgb(var(--${runtimePrefix}-surface-background));`,
|
|
519
|
-
`--color-${utilityPrefix}-surface: rgb(var(--${runtimePrefix}-surface-color));`,
|
|
520
|
-
`--color-${utilityPrefix}-surface-muted: rgb(var(--${runtimePrefix}-surface-color-muted));`,
|
|
521
|
-
`--color-${utilityPrefix}-surface-subtle: rgb(var(--${runtimePrefix}-surface-color-subtle));`,
|
|
522
|
-
`--color-${utilityPrefix}-surface-border: rgb(var(--${runtimePrefix}-surface-border));`,
|
|
523
|
-
`--color-${utilityPrefix}-surface-interaction: rgb(var(--${runtimePrefix}-surface-interaction));`,
|
|
524
|
-
`--color-${utilityPrefix}-surface-interaction-hover: rgb(var(--${runtimePrefix}-surface-interaction-hover));`,
|
|
525
|
-
`--color-${utilityPrefix}-surface-interaction-focus: rgb(var(--${runtimePrefix}-surface-interaction-focus));`,
|
|
526
|
-
`--color-${utilityPrefix}-surface-interaction-active: rgb(var(--${runtimePrefix}-surface-interaction-active));`,
|
|
527
|
-
`--color-${utilityPrefix}-surface-interaction-disabled: rgb(var(--${runtimePrefix}-surface-interaction-disabled));`,
|
|
528
|
-
...INTERACTION_STATE_SUFFIXES.map((suffix) => `--color-${utilityPrefix}-surface-on-interaction${suffix}: rgb(var(--${runtimePrefix}-surface-on-interaction${suffix}, ${onFallback}));`),
|
|
529
|
-
...INTERACTION_STATE_SUFFIXES.map((suffix) => `--color-${utilityPrefix}-surface-interaction-ink${suffix}: rgb(var(--${runtimePrefix}-surface-interaction-ink${suffix}, ${inkFallback}));`),
|
|
530
|
-
];
|
|
531
|
-
}
|
|
532
|
-
const INTERACTION_STATE_SUFFIXES = ['', '-hover', '-focus', '-active', '-disabled'];
|
|
533
|
-
// Fills the optional states from the ones that are set, matching how the color theme generator
|
|
534
|
-
// resolves a swatch: hover falls back to default, focus to hover, active and disabled to default.
|
|
535
|
-
function resolveInteractionStates(map) {
|
|
536
|
-
const hover = map.hover || map.default;
|
|
537
|
-
return {
|
|
538
|
-
'': map.default,
|
|
539
|
-
'-hover': hover,
|
|
540
|
-
'-focus': map.focus || hover,
|
|
541
|
-
'-active': map.active || map.default,
|
|
542
|
-
'-disabled': map.disabled || map.default,
|
|
543
|
-
};
|
|
544
|
-
}
|
|
545
|
-
function pushStaticInteractionColors(vars, name, map) {
|
|
546
|
-
const states = resolveInteractionStates(map);
|
|
547
|
-
for (const suffix of INTERACTION_STATE_SUFFIXES) {
|
|
548
|
-
vars.push(` ${name}${suffix}: rgb(${states[suffix]});`);
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
function pushRuntimeInteractionVars(vars, name, map, indent) {
|
|
552
|
-
const states = resolveInteractionStates(map);
|
|
553
|
-
for (const suffix of INTERACTION_STATE_SUFFIXES) {
|
|
554
|
-
vars.push(`${indent}${name}${suffix}: ${states[suffix]};`);
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
function pushRootSurfaceVars(vars, runtimePrefix, theme) {
|
|
558
|
-
if (!theme)
|
|
559
|
-
return;
|
|
560
|
-
vars.push(`:root {`);
|
|
561
|
-
pushSurfaceVars(vars, runtimePrefix, theme, ' ');
|
|
562
|
-
vars.push(` color-scheme: ${theme.type};`);
|
|
563
|
-
vars.push(`}\n`);
|
|
564
|
-
}
|
|
565
|
-
function pushSchemeSurfaceVars(vars, runtimePrefix, theme) {
|
|
566
|
-
vars.push(`@media (prefers-color-scheme: ${theme.type}) {`);
|
|
567
|
-
vars.push(` :root {`);
|
|
568
|
-
pushSurfaceVars(vars, runtimePrefix, theme, ' ');
|
|
569
|
-
vars.push(` color-scheme: ${theme.type};`);
|
|
570
|
-
vars.push(` }`);
|
|
571
|
-
vars.push(`}\n`);
|
|
572
|
-
}
|
|
573
|
-
// `:root.<prefix>-scheme--<type>` must out-specify the `:root` inside the media query above, so the
|
|
574
|
-
// class set by `provideColorScheme()` overrides the OS preference regardless of source order.
|
|
575
|
-
function pushForcedSchemeSurfaceVars(vars, runtimePrefix, theme) {
|
|
576
|
-
vars.push(`:root.${runtimePrefix}-scheme--${theme.type} {`);
|
|
577
|
-
pushSurfaceVars(vars, runtimePrefix, theme, ' ');
|
|
578
|
-
vars.push(` color-scheme: ${theme.type};`);
|
|
579
|
-
vars.push(`}\n`);
|
|
580
|
-
}
|
|
581
|
-
function pushSurfaceVars(vars, runtimePrefix, theme, indent) {
|
|
582
|
-
vars.push(`${indent}--${runtimePrefix}-surface-background: ${theme.background};`);
|
|
583
|
-
vars.push(`${indent}--${runtimePrefix}-surface-color: ${theme.color};`);
|
|
584
|
-
vars.push(`${indent}--${runtimePrefix}-surface-color-muted: ${theme.colorMuted};`);
|
|
585
|
-
vars.push(`${indent}--${runtimePrefix}-surface-color-subtle: ${theme.colorSubtle};`);
|
|
586
|
-
vars.push(`${indent}--${runtimePrefix}-surface-border: ${theme.border};`);
|
|
587
|
-
vars.push(`${indent}--${runtimePrefix}-surface-type: ${theme.type};`);
|
|
588
|
-
vars.push(`${indent}--${runtimePrefix}-surface-elevation: ${theme.elevation};`);
|
|
589
|
-
if (theme.interactionColor) {
|
|
590
|
-
const { color, onColor, inkColor } = theme.interactionColor;
|
|
591
|
-
pushRuntimeInteractionVars(vars, `--${runtimePrefix}-surface-interaction`, color, indent);
|
|
592
|
-
if (onColor) {
|
|
593
|
-
pushRuntimeInteractionVars(vars, `--${runtimePrefix}-surface-on-interaction`, onColor, indent);
|
|
594
|
-
}
|
|
595
|
-
if (inkColor) {
|
|
596
|
-
pushRuntimeInteractionVars(vars, `--${runtimePrefix}-surface-interaction-ink`, inkColor, indent);
|
|
597
|
-
}
|
|
598
|
-
}
|
|
368
|
+
return `${header}${surfaceThemeCss(themes, { prefix: utilityPrefix, runtimePrefix })}`;
|
|
599
369
|
}
|
|
600
370
|
function findMainStylesFile(tree) {
|
|
601
371
|
const potentialFiles = [];
|
package/package.json
CHANGED
|
@@ -1,8 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ethlete/core",
|
|
3
|
-
"version": "5.0.0-next.
|
|
3
|
+
"version": "5.0.0-next.66",
|
|
4
|
+
"repository": {
|
|
5
|
+
"type": "git",
|
|
6
|
+
"url": "https://github.com/ethlete-io/ethdk",
|
|
7
|
+
"directory": "libs/core"
|
|
8
|
+
},
|
|
4
9
|
"license": "MIT",
|
|
5
10
|
"sideEffects": false,
|
|
11
|
+
"exports": {
|
|
12
|
+
"./design/*": "./design/*.ts",
|
|
13
|
+
"./package.json": {
|
|
14
|
+
"default": "./package.json"
|
|
15
|
+
},
|
|
16
|
+
".": {
|
|
17
|
+
"types": "./types/ethlete-core.d.ts",
|
|
18
|
+
"default": "./fesm2022/ethlete-core.mjs"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
6
21
|
"peerDependencies": {
|
|
7
22
|
"@angular/common": "^22.1.0",
|
|
8
23
|
"@angular/core": "^22.1.0",
|
|
@@ -33,15 +48,6 @@
|
|
|
33
48
|
"generators": "./generators/generators.json",
|
|
34
49
|
"module": "fesm2022/ethlete-core.mjs",
|
|
35
50
|
"typings": "types/ethlete-core.d.ts",
|
|
36
|
-
"exports": {
|
|
37
|
-
"./package.json": {
|
|
38
|
-
"default": "./package.json"
|
|
39
|
-
},
|
|
40
|
-
".": {
|
|
41
|
-
"types": "./types/ethlete-core.d.ts",
|
|
42
|
-
"default": "./fesm2022/ethlete-core.mjs"
|
|
43
|
-
}
|
|
44
|
-
},
|
|
45
51
|
"type": "module",
|
|
46
52
|
"dependencies": {
|
|
47
53
|
"tslib": "^2.3.0"
|