@happyvertical/smrt-ui 0.40.68 → 0.40.70

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/components/data/DataTable.svelte +1 -1
  2. package/dist/components/feedback/LoadingOverlay.svelte +1 -1
  3. package/dist/components/forms/Combobox.svelte +1 -1
  4. package/dist/components/forms/FilePicker.svelte +1 -1
  5. package/dist/components/forms/Input.svelte +1 -1
  6. package/dist/components/forms/InputGroup.svelte +1 -1
  7. package/dist/components/forms/Listbox.svelte +1 -1
  8. package/dist/components/forms/MultiSelect.svelte +1 -1
  9. package/dist/components/forms/RangeSlider.svelte +1 -1
  10. package/dist/components/forms/Select.svelte +1 -1
  11. package/dist/components/forms/Slider.svelte +1 -1
  12. package/dist/components/forms/TagsInput.svelte +1 -1
  13. package/dist/components/forms/Textarea.svelte +1 -1
  14. package/dist/components/roles/RoleSelector.svelte +10 -3
  15. package/dist/components/ui/Dropdown.svelte +11 -3
  16. package/dist/components/ui/Popover.svelte +1 -1
  17. package/dist/themes/ThemeProvider.svelte +40 -42
  18. package/dist/themes/ThemeProvider.svelte.d.ts +10 -0
  19. package/dist/themes/ThemeProvider.svelte.d.ts.map +1 -1
  20. package/dist/themes/__tests__/control-boundary-contrast.test.js +112 -0
  21. package/dist/themes/__tests__/css-generator.test.js +42 -0
  22. package/dist/themes/__tests__/styles-lockstep.test.js +32 -0
  23. package/dist/themes/__tests__/theme-provider.test.js +46 -8
  24. package/dist/themes/__tests__/theme-script.test.js +16 -11
  25. package/dist/themes/css-generator.d.ts +5 -0
  26. package/dist/themes/css-generator.d.ts.map +1 -1
  27. package/dist/themes/css-generator.js +5 -0
  28. package/dist/themes/glass/index.d.ts.map +1 -1
  29. package/dist/themes/glass/index.js +12 -4
  30. package/dist/themes/smrt/index.d.ts.map +1 -1
  31. package/dist/themes/smrt/index.js +8 -2
  32. package/dist/themes/studio/index.d.ts.map +1 -1
  33. package/dist/themes/studio/index.js +6 -2
  34. package/dist/themes/styles/glass.css +316 -84
  35. package/dist/themes/styles/material.css +355 -53
  36. package/dist/themes/styles/smrt.css +4 -4
  37. package/dist/themes/styles/studio.css +308 -72
  38. package/dist/themes/theme-script.d.ts +12 -4
  39. package/dist/themes/theme-script.d.ts.map +1 -1
  40. package/dist/themes/theme-script.js +14 -19
  41. package/package.json +3 -2
@@ -5,8 +5,6 @@
5
5
  */
6
6
  import { beforeEach, describe, expect, it, vi } from 'vitest';
7
7
  import { createTheme, registerTheme } from '../create-theme.js';
8
- import { generateThemeVariables } from '../css-generator.js';
9
- import { studioTheme } from '../studio/index.js';
10
8
  import { themeScript } from '../theme-script.js';
11
9
  function mockSystemDark(matches) {
12
10
  window.matchMedia = vi.fn().mockImplementation((query) => ({
@@ -24,13 +22,7 @@ describe('themeScript', () => {
24
22
  localStorage.clear();
25
23
  document.documentElement.removeAttribute('data-theme');
26
24
  document.documentElement.removeAttribute('data-color-scheme');
27
- document.documentElement.removeAttribute('data-smrt-theme-bootstrap');
28
25
  document.documentElement.classList.remove('dark');
29
- for (const property of Array.from(document.documentElement.style)) {
30
- if (property.startsWith('--smrt-bootstrap-')) {
31
- document.documentElement.style.removeProperty(property);
32
- }
33
- }
34
26
  });
35
27
  it('resolves system preference when nothing is stored', () => {
36
28
  mockSystemDark(true);
@@ -46,7 +38,19 @@ describe('themeScript', () => {
46
38
  expect(document.documentElement.getAttribute('data-theme')).toBe('studio');
47
39
  expect(document.documentElement.getAttribute('data-color-scheme')).toBe('light');
48
40
  expect(document.documentElement.classList.contains('dark')).toBe(false);
49
- expect(document.documentElement.style.getPropertyValue('--smrt-bootstrap-color-background')).toBe(generateThemeVariables(studioTheme, false)['--smrt-color-background']);
41
+ });
42
+ it('ships no inline variable payload — static CSS owns the values', () => {
43
+ mockSystemDark(false);
44
+ const script = themeScript({ preset: 'studio' });
45
+ // The pre-paint script only stamps attributes; variable values come from
46
+ // the static per-preset stylesheets selected by those attributes.
47
+ expect(script).not.toContain('--smrt-');
48
+ expect(script).not.toContain('bootstrap');
49
+ expect(script.length).toBeLessThan(1024);
50
+ run(script);
51
+ for (const property of Array.from(document.documentElement.style)) {
52
+ expect(property.startsWith('--smrt-')).toBe(false);
53
+ }
50
54
  });
51
55
  it('uses the custom storageKey', () => {
52
56
  mockSystemDark(false);
@@ -82,7 +86,7 @@ describe('themeScript', () => {
82
86
  expect(document.documentElement.getAttribute('data-theme')).toBe('material');
83
87
  expect(document.documentElement.getAttribute('data-color-scheme')).toBe('light');
84
88
  });
85
- it('bootstraps a registered custom theme from persistence', () => {
89
+ it('stamps a persisted registered custom theme pre-paint', () => {
86
90
  const brandTheme = createTheme({
87
91
  id: 'bootstrap-test-brand',
88
92
  name: 'Bootstrap Test Brand',
@@ -97,7 +101,8 @@ describe('themeScript', () => {
97
101
  }));
98
102
  run(themeScript());
99
103
  expect(document.documentElement.getAttribute('data-theme')).toBe('bootstrap-test-brand');
100
- expect(document.documentElement.style.getPropertyValue('--smrt-bootstrap-color-background')).toBe(generateThemeVariables(brandTheme, true)['--smrt-color-background']);
104
+ expect(document.documentElement.getAttribute('data-color-scheme')).toBe('dark');
105
+ expect(document.documentElement.classList.contains('dark')).toBe(true);
101
106
  });
102
107
  it('still applies the fallback when localStorage access throws', () => {
103
108
  mockSystemDark(true);
@@ -20,6 +20,11 @@ export interface GenerateCSSOptions {
20
20
  * @param isDark - Whether to use dark mode colors
21
21
  * @param options - Generation options
22
22
  * @returns Object with CSS variable names and values
23
+ * @deprecated Prefer the static per-preset stylesheets
24
+ * (`themes/styles/<preset>.css`) selected by `data-theme`/`data-color-scheme`
25
+ * attributes — ThemeProvider uses them by default for built-in presets. This
26
+ * runtime path remains for custom registered themes, which have no static
27
+ * stylesheet, and for the `inlineVariables` escape hatch.
23
28
  */
24
29
  export declare function generateThemeVariables(theme: Theme, isDark: boolean, options?: GenerateCSSOptions): Record<string, string>;
25
30
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"css-generator.d.ts","sourceRoot":"","sources":["../../src/themes/css-generator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAWH,OAAO,KAAK,EAQV,KAAK,EAEN,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,4CAA4C;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kDAAkD;IAClD,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAwMD;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,OAAO,EACf,OAAO,GAAE,kBAAuB,GAC/B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA0CxB;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAChC,MAAM,CAIR;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,OAAO,EACf,OAAO,GAAE,kBAAuB,GAC/B,MAAM,CAaR;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC,CAS5D"}
1
+ {"version":3,"file":"css-generator.d.ts","sourceRoot":"","sources":["../../src/themes/css-generator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAWH,OAAO,KAAK,EAQV,KAAK,EAEN,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,4CAA4C;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kDAAkD;IAClD,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAwMD;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,OAAO,EACf,OAAO,GAAE,kBAAuB,GAC/B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA0CxB;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAChC,MAAM,CAIR;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,OAAO,EACf,OAAO,GAAE,kBAAuB,GAC/B,MAAM,CAaR;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC,CAS5D"}
@@ -160,6 +160,11 @@ function generateStaticTokens(prefix, fontFamilyMono) {
160
160
  * @param isDark - Whether to use dark mode colors
161
161
  * @param options - Generation options
162
162
  * @returns Object with CSS variable names and values
163
+ * @deprecated Prefer the static per-preset stylesheets
164
+ * (`themes/styles/<preset>.css`) selected by `data-theme`/`data-color-scheme`
165
+ * attributes — ThemeProvider uses them by default for built-in presets. This
166
+ * runtime path remains for custom registered themes, which have no static
167
+ * stylesheet, and for the `inlineVariables` escape hatch.
163
168
  */
164
169
  export function generateThemeVariables(theme, isDark, options = {}) {
165
170
  const { prefix = '--smrt' } = options;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/themes/glass/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAQH,OAAO,KAAK,EAIV,KAAK,EAEN,MAAM,aAAa,CAAC;AAiSrB;;GAEG;AACH,eAAO,MAAM,UAAU,EAAE,KAcxB,CAAC;AAEF,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/themes/glass/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAQH,OAAO,KAAK,EAIV,KAAK,EAEN,MAAM,aAAa,CAAC;AAySrB;;GAEG;AACH,eAAO,MAAM,UAAU,EAAE,KAcxB,CAAC;AAEF,eAAe,UAAU,CAAC"}
@@ -56,8 +56,14 @@ const lightColors = {
56
56
  // Background - Vibrant light background
57
57
  background: '#f2f2f7',
58
58
  onBackground: '#000000',
59
- // Outline - Subtle translucent borders
60
- outline: 'rgba(120, 120, 128, 0.29)',
59
+ // Outline - Translucent borders.
60
+ // `outline` is the boundary role and must clear 3:1 non-text once its alpha
61
+ // is composited over the frosted surface (WCAG 1.4.11). At the original
62
+ // rgba(120, 120, 128, 0.29) it composited to 1.42:1 — a control border no one
63
+ // could see. Darkened the hue rather than pushing alpha toward opaque, which
64
+ // keeps the translucent character (#2322). `outlineVariant` stays the quiet
65
+ // hairline for dividers and panel edges.
66
+ outline: 'rgba(80, 80, 88, 0.75)',
61
67
  outlineVariant: 'rgba(120, 120, 128, 0.16)',
62
68
  // Inverse
63
69
  inverseSurface: '#1c1c1e',
@@ -120,8 +126,10 @@ const darkColors = {
120
126
  // Background - Deep dark with subtle tint
121
127
  background: '#000000',
122
128
  onBackground: '#ffffff',
123
- // Outline
124
- outline: 'rgba(84, 84, 88, 0.65)',
129
+ // Outline — see the light-scheme note. Composited over the dark frosted
130
+ // surface the original rgba(84, 84, 88, 0.65) measured 1.70:1; lightening the
131
+ // hue clears 3:1 while staying translucent (#2322).
132
+ outline: 'rgba(160, 160, 166, 0.8)',
125
133
  outlineVariant: 'rgba(84, 84, 88, 0.35)',
126
134
  // Inverse
127
135
  inverseSurface: '#f2f2f7',
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/themes/smrt/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAIV,KAAK,EAEN,MAAM,aAAa,CAAC;AAsTrB;;GAEG;AACH,eAAO,MAAM,SAAS,EAAE,KAavB,CAAC;AAEF,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/themes/smrt/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAIV,KAAK,EAEN,MAAM,aAAa,CAAC;AA4TrB;;GAEG;AACH,eAAO,MAAM,SAAS,EAAE,KAavB,CAAC;AAEF,eAAe,SAAS,CAAC"}
@@ -68,7 +68,11 @@ const lightColors = {
68
68
  background: '#edeff2',
69
69
  onBackground: '#14171c',
70
70
  // Outline - Hairline / line greys
71
- outline: '#c6ccd4',
71
+ // Boundary role: clears 3:1 non-text on every surface in this scheme so
72
+ // control borders are perceivable (WCAG 1.4.11). Was #c6ccd4 (1.29–1.62:1),
73
+ // which read as a divider, not a boundary (#2322). outlineVariant below
74
+ // remains the hairline for dividers, readout rows, and panel edges.
75
+ outline: '#7c7f85',
72
76
  outlineVariant: '#dfe3e8',
73
77
  // Inverse
74
78
  inverseSurface: '#14171c',
@@ -131,7 +135,9 @@ const darkColors = {
131
135
  background: '#0b0c0e',
132
136
  onBackground: '#c9cdd3',
133
137
  // Outline - Line / hairline strokes
134
- outline: '#333842',
138
+ // See the light-scheme note: boundary role, 3:1 on every dark surface.
139
+ // Was #333842 (1.23–1.57:1).
140
+ outline: '#70747b',
135
141
  outlineVariant: '#23272e',
136
142
  // Inverse
137
143
  inverseSurface: '#edeff2',
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/themes/studio/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAQH,OAAO,KAAK,EAGV,KAAK,EAEN,MAAM,aAAa,CAAC;AAiSrB;;GAEG;AACH,eAAO,MAAM,WAAW,EAAE,KAazB,CAAC;AAEF,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/themes/studio/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAQH,OAAO,KAAK,EAGV,KAAK,EAEN,MAAM,aAAa,CAAC;AAqSrB;;GAEG;AACH,eAAO,MAAM,WAAW,EAAE,KAazB,CAAC;AAEF,eAAe,WAAW,CAAC"}
@@ -57,7 +57,11 @@ const lightColors = {
57
57
  background: '#ffffff',
58
58
  onBackground: '#202124',
59
59
  // Outline - Light gray borders
60
- outline: '#dadce0',
60
+ // Boundary role: must clear 3:1 non-text on every surface in this scheme so
61
+ // control borders are perceivable (WCAG 1.4.11). Was #dadce0, a divider-weight
62
+ // grey measuring 1.21–1.37:1 — invisible as a control boundary (#2322).
63
+ // outlineVariant below stays the quiet hairline for dividers and panels.
64
+ outline: '#78797b',
61
65
  outlineVariant: '#e8eaed',
62
66
  // Inverse
63
67
  inverseSurface: '#3c4043',
@@ -118,7 +122,7 @@ const darkColors = {
118
122
  background: '#0e0e0e',
119
123
  onBackground: '#e8eaed',
120
124
  // Outline
121
- outline: '#5f6368',
125
+ outline: '#8c8e92',
122
126
  outlineVariant: '#3c4043',
123
127
  // Inverse
124
128
  inverseSurface: '#e8eaed',