@happyvertical/smrt-ui 0.53.1 → 0.53.3

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 (205) hide show
  1. package/package.json +3 -3
  2. package/dist/actions/__tests__/ripple.test.js +0 -82
  3. package/dist/actions/__tests__/swipe-dismiss.test.js +0 -69
  4. package/dist/components/calendar/__tests__/CalendarView.test.js +0 -226
  5. package/dist/components/calendar/__tests__/calendar-model.test.js +0 -138
  6. package/dist/components/chat/__tests__/chat-primitives.test.js +0 -118
  7. package/dist/components/data/__tests__/CollectionList.test.js +0 -37
  8. package/dist/components/data/__tests__/DataTable.test.js +0 -807
  9. package/dist/components/data/__tests__/DataTableConformance.test.js +0 -212
  10. package/dist/components/data/__tests__/DataTableController.test.js +0 -371
  11. package/dist/components/data/__tests__/DataTableIdentity.test.js +0 -29
  12. package/dist/components/data/__tests__/DataTableLayout.test.js +0 -195
  13. package/dist/components/data/__tests__/DataTablePerformance.test.js +0 -21
  14. package/dist/components/data/__tests__/DataTableResponsive.test.js +0 -80
  15. package/dist/components/data/__tests__/DataTableVirtualization.test.js +0 -80
  16. package/dist/components/data/__tests__/DataTableVirtualizationComponent.test.js +0 -255
  17. package/dist/components/data/__tests__/SortableHeader.test.js +0 -101
  18. package/dist/components/data/__tests__/data-surface.test.js +0 -746
  19. package/dist/components/data/__tests__/data-table-helpers.test.js +0 -36
  20. package/dist/components/data/__tests__/data-table-surface.test.js +0 -49
  21. package/dist/components/data/__tests__/link-step-surface.test.js +0 -172
  22. package/dist/components/data/__tests__/list-sort-state.svelte.test.js +0 -71
  23. package/dist/components/data/__tests__/list-sort.test.js +0 -91
  24. package/dist/components/data/__tests__/mounted-data-surface.test.js +0 -794
  25. package/dist/components/data/__tests__/responsive-table.fixture.svelte +0 -29
  26. package/dist/components/data/__tests__/responsive-table.fixture.svelte.d.ts +0 -7
  27. package/dist/components/data/__tests__/responsive-table.fixture.svelte.d.ts.map +0 -1
  28. package/dist/components/data/__tests__/surface-navigation.test.js +0 -121
  29. package/dist/components/display/__tests__/ConfidenceBadge.test.js +0 -109
  30. package/dist/components/display/__tests__/CurrencyDisplay.test.js +0 -304
  31. package/dist/components/display/__tests__/CurrencyDisplayI18nHarness.svelte +0 -20
  32. package/dist/components/display/__tests__/CurrencyDisplayI18nHarness.svelte.d.ts +0 -19
  33. package/dist/components/display/__tests__/CurrencyDisplayI18nHarness.svelte.d.ts.map +0 -1
  34. package/dist/components/display/__tests__/CurrencyDisplaySsrHarness.svelte +0 -7
  35. package/dist/components/display/__tests__/CurrencyDisplaySsrHarness.svelte.d.ts +0 -19
  36. package/dist/components/display/__tests__/CurrencyDisplaySsrHarness.svelte.d.ts.map +0 -1
  37. package/dist/components/display/__tests__/DateDisplay.test.js +0 -195
  38. package/dist/components/display/__tests__/Icon.test.js +0 -223
  39. package/dist/components/display/__tests__/StatusBadge.test.js +0 -191
  40. package/dist/components/feedback/__tests__/ConfirmDialog.test.js +0 -181
  41. package/dist/components/feedback/__tests__/LoadingOverlay.test.js +0 -113
  42. package/dist/components/feedback/__tests__/Modal.test.js +0 -72
  43. package/dist/components/feedback/__tests__/PhoneSheet.test.js +0 -101
  44. package/dist/components/feedback/__tests__/ProgressBar.test.js +0 -89
  45. package/dist/components/feedback/__tests__/WorkingStrip.test.js +0 -172
  46. package/dist/components/feedback/__tests__/confirm-message.fixture.svelte +0 -9
  47. package/dist/components/feedback/__tests__/confirm-message.fixture.svelte.d.ts +0 -19
  48. package/dist/components/feedback/__tests__/confirm-message.fixture.svelte.d.ts.map +0 -1
  49. package/dist/components/feedback/__tests__/toast.test.js +0 -190
  50. package/dist/components/forms/__tests__/CameraCapture.test.js +0 -504
  51. package/dist/components/forms/__tests__/Combobox.test.js +0 -354
  52. package/dist/components/forms/__tests__/ControlHitArea.test.js +0 -73
  53. package/dist/components/forms/__tests__/DictationButton.test.js +0 -176
  54. package/dist/components/forms/__tests__/Fieldset.test.js +0 -37
  55. package/dist/components/forms/__tests__/Form.test.js +0 -201
  56. package/dist/components/forms/__tests__/FormActionBar.test.js +0 -22
  57. package/dist/components/forms/__tests__/FormGroup.test.js +0 -48
  58. package/dist/components/forms/__tests__/Input.test.js +0 -49
  59. package/dist/components/forms/__tests__/Listbox.test.js +0 -303
  60. package/dist/components/forms/__tests__/MultiSelect.test.js +0 -281
  61. package/dist/components/forms/__tests__/SearchInput.test.js +0 -92
  62. package/dist/components/forms/__tests__/Select.test.js +0 -37
  63. package/dist/components/forms/__tests__/SignaturePad.test.js +0 -338
  64. package/dist/components/forms/__tests__/StagedControlReview.test.js +0 -702
  65. package/dist/components/forms/__tests__/Textarea.test.js +0 -39
  66. package/dist/components/forms/__tests__/Toggle.test.js +0 -87
  67. package/dist/components/forms/__tests__/camera-capture-session.test.js +0 -207
  68. package/dist/components/forms/__tests__/capture-form-retry.test.js +0 -166
  69. package/dist/components/forms/__tests__/capture-form.fixture.svelte +0 -38
  70. package/dist/components/forms/__tests__/capture-form.fixture.svelte.d.ts +0 -10
  71. package/dist/components/forms/__tests__/capture-form.fixture.svelte.d.ts.map +0 -1
  72. package/dist/components/forms/__tests__/capture-test-env.d.ts +0 -70
  73. package/dist/components/forms/__tests__/capture-test-env.d.ts.map +0 -1
  74. package/dist/components/forms/__tests__/capture-test-env.js +0 -122
  75. package/dist/components/forms/__tests__/capture-touch.fixture.svelte +0 -15
  76. package/dist/components/forms/__tests__/capture-touch.fixture.svelte.d.ts +0 -8
  77. package/dist/components/forms/__tests__/capture-touch.fixture.svelte.d.ts.map +0 -1
  78. package/dist/components/forms/__tests__/combobox-form.fixture.svelte +0 -29
  79. package/dist/components/forms/__tests__/combobox-form.fixture.svelte.d.ts +0 -14
  80. package/dist/components/forms/__tests__/combobox-form.fixture.svelte.d.ts.map +0 -1
  81. package/dist/components/forms/__tests__/combobox-labels.fixture.svelte +0 -19
  82. package/dist/components/forms/__tests__/combobox-labels.fixture.svelte.d.ts +0 -11
  83. package/dist/components/forms/__tests__/combobox-labels.fixture.svelte.d.ts.map +0 -1
  84. package/dist/components/forms/__tests__/composite-controls.fixture.svelte +0 -47
  85. package/dist/components/forms/__tests__/composite-controls.fixture.svelte.d.ts +0 -12
  86. package/dist/components/forms/__tests__/composite-controls.fixture.svelte.d.ts.map +0 -1
  87. package/dist/components/forms/__tests__/composite-controls.test.js +0 -128
  88. package/dist/components/forms/__tests__/composite-registration.fixture.svelte +0 -29
  89. package/dist/components/forms/__tests__/composite-registration.fixture.svelte.d.ts +0 -8
  90. package/dist/components/forms/__tests__/composite-registration.fixture.svelte.d.ts.map +0 -1
  91. package/dist/components/forms/__tests__/composite-user-edit.fixture.svelte +0 -41
  92. package/dist/components/forms/__tests__/composite-user-edit.fixture.svelte.d.ts +0 -13
  93. package/dist/components/forms/__tests__/composite-user-edit.fixture.svelte.d.ts.map +0 -1
  94. package/dist/components/forms/__tests__/control-interaction.test.js +0 -3421
  95. package/dist/components/forms/__tests__/control-proposals.test.js +0 -63
  96. package/dist/components/forms/__tests__/core-controls.fixture.svelte +0 -50
  97. package/dist/components/forms/__tests__/core-controls.fixture.svelte.d.ts +0 -9
  98. package/dist/components/forms/__tests__/core-controls.fixture.svelte.d.ts.map +0 -1
  99. package/dist/components/forms/__tests__/core-controls.test.js +0 -311
  100. package/dist/components/forms/__tests__/decimal-sliders.fixture.svelte +0 -25
  101. package/dist/components/forms/__tests__/decimal-sliders.fixture.svelte.d.ts +0 -8
  102. package/dist/components/forms/__tests__/decimal-sliders.fixture.svelte.d.ts.map +0 -1
  103. package/dist/components/forms/__tests__/dictation-recording.test.js +0 -582
  104. package/dist/components/forms/__tests__/dictation.test.js +0 -486
  105. package/dist/components/forms/__tests__/form-attachment.fixture.svelte +0 -28
  106. package/dist/components/forms/__tests__/form-attachment.fixture.svelte.d.ts +0 -11
  107. package/dist/components/forms/__tests__/form-attachment.fixture.svelte.d.ts.map +0 -1
  108. package/dist/components/forms/__tests__/form-group-input.fixture.svelte +0 -16
  109. package/dist/components/forms/__tests__/form-group-input.fixture.svelte.d.ts +0 -9
  110. package/dist/components/forms/__tests__/form-group-input.fixture.svelte.d.ts.map +0 -1
  111. package/dist/components/forms/__tests__/form-retry-form.fixture.svelte +0 -31
  112. package/dist/components/forms/__tests__/form-retry-form.fixture.svelte.d.ts +0 -13
  113. package/dist/components/forms/__tests__/form-retry-form.fixture.svelte.d.ts.map +0 -1
  114. package/dist/components/forms/__tests__/form-retry-form.test.js +0 -107
  115. package/dist/components/forms/__tests__/hidden-controls-form-retry.test.js +0 -69
  116. package/dist/components/forms/__tests__/hidden-controls-form.fixture.svelte +0 -29
  117. package/dist/components/forms/__tests__/hidden-controls-form.fixture.svelte.d.ts +0 -9
  118. package/dist/components/forms/__tests__/hidden-controls-form.fixture.svelte.d.ts.map +0 -1
  119. package/dist/components/forms/__tests__/listbox-form.fixture.svelte +0 -27
  120. package/dist/components/forms/__tests__/listbox-form.fixture.svelte.d.ts +0 -13
  121. package/dist/components/forms/__tests__/listbox-form.fixture.svelte.d.ts.map +0 -1
  122. package/dist/components/forms/__tests__/long-press.test.js +0 -175
  123. package/dist/components/forms/__tests__/multiselect-form.fixture.svelte +0 -27
  124. package/dist/components/forms/__tests__/multiselect-form.fixture.svelte.d.ts +0 -13
  125. package/dist/components/forms/__tests__/multiselect-form.fixture.svelte.d.ts.map +0 -1
  126. package/dist/components/forms/__tests__/native-file-field.test.js +0 -177
  127. package/dist/components/forms/__tests__/place-picker.fixture.svelte +0 -33
  128. package/dist/components/forms/__tests__/place-picker.fixture.svelte.d.ts +0 -12
  129. package/dist/components/forms/__tests__/place-picker.fixture.svelte.d.ts.map +0 -1
  130. package/dist/components/forms/__tests__/segmented-posting.fixture.svelte +0 -28
  131. package/dist/components/forms/__tests__/segmented-posting.fixture.svelte.d.ts +0 -12
  132. package/dist/components/forms/__tests__/segmented-posting.fixture.svelte.d.ts.map +0 -1
  133. package/dist/components/forms/__tests__/segmented-posting.test.js +0 -92
  134. package/dist/components/forms/__tests__/select-interaction.fixture.svelte +0 -25
  135. package/dist/components/forms/__tests__/select-interaction.fixture.svelte.d.ts +0 -9
  136. package/dist/components/forms/__tests__/select-interaction.fixture.svelte.d.ts.map +0 -1
  137. package/dist/components/forms/__tests__/signature-pad-logic.test.js +0 -54
  138. package/dist/components/forms/__tests__/staged-review-fieldset.fixture.svelte +0 -21
  139. package/dist/components/forms/__tests__/staged-review-fieldset.fixture.svelte.d.ts +0 -8
  140. package/dist/components/forms/__tests__/staged-review-fieldset.fixture.svelte.d.ts.map +0 -1
  141. package/dist/components/forms/__tests__/staged-review-outer-fieldset.fixture.svelte +0 -23
  142. package/dist/components/forms/__tests__/staged-review-outer-fieldset.fixture.svelte.d.ts +0 -8
  143. package/dist/components/forms/__tests__/staged-review-outer-fieldset.fixture.svelte.d.ts.map +0 -1
  144. package/dist/components/forms/__tests__/staged-review.fixture.svelte +0 -56
  145. package/dist/components/forms/__tests__/staged-review.fixture.svelte.d.ts +0 -12
  146. package/dist/components/forms/__tests__/staged-review.fixture.svelte.d.ts.map +0 -1
  147. package/dist/components/forms/__tests__/touch-density.fixture.svelte +0 -34
  148. package/dist/components/forms/__tests__/touch-density.fixture.svelte.d.ts +0 -8
  149. package/dist/components/forms/__tests__/touch-density.fixture.svelte.d.ts.map +0 -1
  150. package/dist/components/forms/__tests__/touch-density.test.js +0 -66
  151. package/dist/components/forms/form-retry/__tests__/boundaries.test.js +0 -23
  152. package/dist/components/forms/form-retry/__tests__/content-digest.test.js +0 -70
  153. package/dist/components/forms/form-retry/__tests__/controller.test.js +0 -802
  154. package/dist/components/forms/form-retry/__tests__/fake-kit.d.ts +0 -82
  155. package/dist/components/forms/form-retry/__tests__/fake-kit.d.ts.map +0 -1
  156. package/dist/components/forms/form-retry/__tests__/fake-kit.js +0 -180
  157. package/dist/components/forms/form-retry/__tests__/form-draft.test.js +0 -169
  158. package/dist/components/forms/form-retry/__tests__/ssr.test.js +0 -37
  159. package/dist/components/forms/form-retry/__tests__/storage.d.ts +0 -26
  160. package/dist/components/forms/form-retry/__tests__/storage.d.ts.map +0 -1
  161. package/dist/components/forms/form-retry/__tests__/storage.js +0 -63
  162. package/dist/components/forms/form-retry/__tests__/submission-key.test.js +0 -236
  163. package/dist/components/forms/form-retry/__tests__/submitted-draft.test.js +0 -334
  164. package/dist/components/layout/__tests__/Container.test.js +0 -62
  165. package/dist/components/layout/__tests__/EmptyState.test.js +0 -83
  166. package/dist/components/layout/__tests__/Footer.test.js +0 -50
  167. package/dist/components/layout/__tests__/Grid.test.js +0 -121
  168. package/dist/components/layout/__tests__/Header.test.js +0 -48
  169. package/dist/components/layout/__tests__/Masthead.test.js +0 -93
  170. package/dist/components/layout/__tests__/PageHeader.test.js +0 -166
  171. package/dist/components/layout/__tests__/SummaryCard.test.js +0 -104
  172. package/dist/components/nav/__tests__/FilterChips.test.js +0 -94
  173. package/dist/components/nav/__tests__/LinkTabs.test.js +0 -117
  174. package/dist/components/nav/__tests__/Tabs.test.js +0 -128
  175. package/dist/components/roles/__tests__/RoleSelector.test.js +0 -134
  176. package/dist/components/ui/__tests__/Badge.test.js +0 -76
  177. package/dist/components/ui/__tests__/Button.test.js +0 -166
  178. package/dist/components/ui/__tests__/Card.test.js +0 -103
  179. package/dist/components/ui/__tests__/IconToggle.test.js +0 -59
  180. package/dist/components/ui/__tests__/IconToggleGroup.test.js +0 -30
  181. package/dist/components/ui/__tests__/Pagination.test.js +0 -113
  182. package/dist/components/ui/__tests__/Popover.test.js +0 -44
  183. package/dist/components/ui/__tests__/dropdown-popover-icon.test.js +0 -125
  184. package/dist/components/ui/__tests__/gap-primitives-interactive.test.js +0 -112
  185. package/dist/components/ui/__tests__/gap-primitives.test.js +0 -84
  186. package/dist/components/ui/__tests__/interaction-primitives.fixture.svelte +0 -13
  187. package/dist/components/ui/__tests__/interaction-primitives.fixture.svelte.d.ts +0 -19
  188. package/dist/components/ui/__tests__/interaction-primitives.fixture.svelte.d.ts.map +0 -1
  189. package/dist/components/ui/__tests__/interaction-primitives.test.js +0 -31
  190. package/dist/components/ui/__tests__/phone-touch-targets.test.js +0 -39
  191. package/dist/i18n/__tests__/i18n.test.js +0 -74
  192. package/dist/i18n/__tests__/render-parity.spec.js +0 -37
  193. package/dist/svelte/__tests__/playground.test.js +0 -20
  194. package/dist/themes/__tests__/control-boundary-contrast.test.js +0 -112
  195. package/dist/themes/__tests__/create-theme.test.js +0 -79
  196. package/dist/themes/__tests__/css-generator.test.js +0 -129
  197. package/dist/themes/__tests__/happyvertical-theme.test.js +0 -231
  198. package/dist/themes/__tests__/registry.test.js +0 -43
  199. package/dist/themes/__tests__/styles-lockstep.test.js +0 -32
  200. package/dist/themes/__tests__/theme-provider.test.js +0 -147
  201. package/dist/themes/__tests__/theme-script.test.js +0 -130
  202. package/dist/themes/__tests__/token-aliases.test.js +0 -178
  203. package/dist/utils/forms/__tests__/formatters.test.js +0 -27
  204. package/dist/utils/theme/__tests__/color.test.js +0 -89
  205. package/dist/utils/theme/__tests__/typography.test.js +0 -11
@@ -1,130 +0,0 @@
1
- /**
2
- * Tests for the themeScript() pre-paint bootstrap generator. The generated
3
- * script must mirror ThemeProvider's persistence resolution so apps stop
4
- * hand-duplicating it in app.html.
5
- */
6
- import { beforeEach, describe, expect, it, vi } from 'vitest';
7
- import { createTheme, registerTheme } from '../create-theme.js';
8
- import { themeScript } from '../theme-script.js';
9
- function mockSystemDark(matches) {
10
- window.matchMedia = vi.fn().mockImplementation((query) => ({
11
- matches,
12
- media: query,
13
- }));
14
- }
15
- function run(script) {
16
- // biome-ignore lint/security/noGlobalEval: the browser evals this inline bootstrap; testing that is the point
17
- (0, eval)(script);
18
- }
19
- describe('themeScript', () => {
20
- beforeEach(() => {
21
- vi.restoreAllMocks();
22
- localStorage.clear();
23
- document.documentElement.removeAttribute('data-theme');
24
- document.documentElement.removeAttribute('data-color-scheme');
25
- document.documentElement.classList.remove('dark');
26
- });
27
- it("uses Vitest's original jsdom Storage rather than Node host storage", () => {
28
- expect(localStorage).toBe(globalThis.jsdom
29
- .window.localStorage);
30
- });
31
- it('resolves system preference when nothing is stored', () => {
32
- mockSystemDark(true);
33
- run(themeScript({ preset: 'material' }));
34
- expect(document.documentElement.getAttribute('data-theme')).toBe('material');
35
- expect(document.documentElement.getAttribute('data-color-scheme')).toBe('dark');
36
- expect(document.documentElement.classList.contains('dark')).toBe(true);
37
- });
38
- it('honours a stored scheme and preset over system and defaults', () => {
39
- mockSystemDark(true);
40
- localStorage.setItem('smrt-theme', JSON.stringify({ preset: 'studio', colorScheme: 'light' }));
41
- run(themeScript({ preset: 'material' }));
42
- expect(document.documentElement.getAttribute('data-theme')).toBe('studio');
43
- expect(document.documentElement.getAttribute('data-color-scheme')).toBe('light');
44
- expect(document.documentElement.classList.contains('dark')).toBe(false);
45
- });
46
- it('ships no inline variable payload — static CSS owns the values', () => {
47
- mockSystemDark(false);
48
- const script = themeScript({ preset: 'studio' });
49
- // The pre-paint script only stamps attributes; variable values come from
50
- // the static per-preset stylesheets selected by those attributes.
51
- expect(script).not.toContain('--smrt-');
52
- expect(script).not.toContain('bootstrap');
53
- expect(script.length).toBeLessThan(1024);
54
- run(script);
55
- for (const property of Array.from(document.documentElement.style)) {
56
- expect(property.startsWith('--smrt-')).toBe(false);
57
- }
58
- });
59
- it('uses the custom storageKey', () => {
60
- mockSystemDark(false);
61
- localStorage.setItem('my-theme', JSON.stringify({ colorScheme: 'dark' }));
62
- run(themeScript({ storageKey: 'my-theme' }));
63
- expect(document.documentElement.getAttribute('data-color-scheme')).toBe('dark');
64
- });
65
- it('does not read stored preferences when persistence is disabled', () => {
66
- mockSystemDark(false);
67
- localStorage.setItem('smrt-theme', JSON.stringify({ preset: 'studio', colorScheme: 'dark' }));
68
- run(themeScript({
69
- persist: false,
70
- preset: 'material',
71
- defaultColorScheme: 'light',
72
- }));
73
- expect(document.documentElement.getAttribute('data-theme')).toBe('material');
74
- expect(document.documentElement.getAttribute('data-color-scheme')).toBe('light');
75
- });
76
- it('ignores a raw (non-JSON) stored value like ThemeProvider', () => {
77
- mockSystemDark(true);
78
- localStorage.setItem('smrt-theme', 'light');
79
- run(themeScript());
80
- expect(document.documentElement.getAttribute('data-color-scheme')).toBe('dark');
81
- expect(document.documentElement.classList.contains('dark')).toBe(true);
82
- });
83
- it('ignores invalid persisted enum values', () => {
84
- mockSystemDark(false);
85
- localStorage.setItem('smrt-theme', JSON.stringify({
86
- preset: 'not-a-theme',
87
- colorScheme: 'sepia',
88
- }));
89
- run(themeScript({ preset: 'material', defaultColorScheme: 'light' }));
90
- expect(document.documentElement.getAttribute('data-theme')).toBe('material');
91
- expect(document.documentElement.getAttribute('data-color-scheme')).toBe('light');
92
- });
93
- it('stamps a persisted registered custom theme pre-paint', () => {
94
- const brandTheme = createTheme({
95
- id: 'bootstrap-test-brand',
96
- name: 'Bootstrap Test Brand',
97
- light: { primary: '#336699', background: '#fefefe' },
98
- dark: { primary: '#99ccff', background: '#101820' },
99
- });
100
- registerTheme(brandTheme);
101
- mockSystemDark(false);
102
- localStorage.setItem('smrt-theme', JSON.stringify({
103
- preset: 'bootstrap-test-brand',
104
- colorScheme: 'dark',
105
- }));
106
- run(themeScript());
107
- expect(document.documentElement.getAttribute('data-theme')).toBe('bootstrap-test-brand');
108
- expect(document.documentElement.getAttribute('data-color-scheme')).toBe('dark');
109
- expect(document.documentElement.classList.contains('dark')).toBe(true);
110
- });
111
- it('still applies the fallback when localStorage access throws', () => {
112
- mockSystemDark(true);
113
- vi.spyOn(Storage.prototype, 'getItem').mockImplementation(() => {
114
- throw new DOMException('denied', 'SecurityError');
115
- });
116
- run(themeScript({ preset: 'studio' }));
117
- expect(document.documentElement.getAttribute('data-theme')).toBe('studio');
118
- expect(document.documentElement.getAttribute('data-color-scheme')).toBe('dark');
119
- expect(document.documentElement.classList.contains('dark')).toBe(true);
120
- });
121
- it('escapes executable inline-script terminators and separators', () => {
122
- const script = themeScript({
123
- storageKey: '</script><script>alert(1)</script>\u2028\u2029',
124
- });
125
- expect(script.toLowerCase()).not.toContain('</script');
126
- expect(script).not.toContain('\u2028');
127
- expect(script).not.toContain('\u2029');
128
- expect(script).toContain('\\u003c/script>');
129
- });
130
- });
@@ -1,178 +0,0 @@
1
- /**
2
- * Design-token alias contract (issue #1431).
3
- *
4
- * Components consume a Material-3 token vocabulary (`radius-small`,
5
- * `duration-short2`, `spacing-md`, `typography-*-font`, …) that must resolve to
6
- * real values across every preset. These tests pin the additive aliases emitted
7
- * by the canonical preset generator (`css-generator.ts`) and the simple
8
- * `src/theme/` ThemeProvider so a regression that drops a consumed alias fails
9
- * here as well as in scripts/check-svelte-tokens.mjs.
10
- */
11
- import { readFileSync } from 'node:fs';
12
- import { join } from 'node:path';
13
- import { describe, expect, it } from 'vitest';
14
- import { generateThemeVariables as generateSimpleThemeVariables } from '../../theme/tokens.js';
15
- import { generateThemeVariables } from '../css-generator.js';
16
- import { themes } from '../registry.js';
17
- /** Material-3 + helper aliases that components consume and expect emitted. */
18
- const REQUIRED_ALIASES = [
19
- // Radius (Material-3 named scale)
20
- '--smrt-radius-extra-small',
21
- '--smrt-radius-small',
22
- '--smrt-radius-medium',
23
- '--smrt-radius-large',
24
- '--smrt-radius-extra-large',
25
- // Spacing (named aliases)
26
- '--smrt-spacing-xs',
27
- '--smrt-spacing-sm',
28
- '--smrt-spacing-md',
29
- '--smrt-spacing-lg',
30
- '--smrt-spacing-xl',
31
- '--smrt-spacing-2xl',
32
- '--smrt-spacing-3xl',
33
- // Motion (Material-3 duration scale)
34
- '--smrt-duration-short1',
35
- '--smrt-duration-short2',
36
- '--smrt-duration-short3',
37
- '--smrt-duration-short4',
38
- '--smrt-duration-medium1',
39
- '--smrt-duration-medium2',
40
- '--smrt-duration-medium3',
41
- '--smrt-duration-medium4',
42
- '--smrt-duration-long1',
43
- '--smrt-duration-long2',
44
- '--smrt-duration-long3',
45
- '--smrt-duration-long4',
46
- // Helper tokens (theme-independent)
47
- '--smrt-font-family-mono',
48
- '--smrt-typography-weight-normal',
49
- '--smrt-typography-weight-medium',
50
- '--smrt-typography-weight-semibold',
51
- '--smrt-typography-weight-bold',
52
- '--smrt-z-index-dialog',
53
- '--smrt-z-index-loading',
54
- ];
55
- const SPACING_NUMERIC_TOKENS = [
56
- '--smrt-spacing-0',
57
- '--smrt-spacing-0_5',
58
- '--smrt-spacing-1',
59
- '--smrt-spacing-1_5',
60
- '--smrt-spacing-2',
61
- '--smrt-spacing-2_5',
62
- '--smrt-spacing-3',
63
- '--smrt-spacing-3_5',
64
- '--smrt-spacing-4',
65
- '--smrt-spacing-5',
66
- '--smrt-spacing-6',
67
- '--smrt-spacing-7',
68
- '--smrt-spacing-8',
69
- '--smrt-spacing-9',
70
- '--smrt-spacing-10',
71
- '--smrt-spacing-11',
72
- '--smrt-spacing-12',
73
- '--smrt-spacing-14',
74
- '--smrt-spacing-16',
75
- '--smrt-spacing-20',
76
- '--smrt-spacing-24',
77
- ];
78
- const TYPOGRAPHY_FONT_SHORTHANDS = [
79
- '--smrt-typography-body-large-font',
80
- '--smrt-typography-body-medium-font',
81
- '--smrt-typography-body-small-font',
82
- '--smrt-typography-label-large-font',
83
- '--smrt-typography-label-medium-font',
84
- '--smrt-typography-label-small-font',
85
- '--smrt-typography-title-large-font',
86
- '--smrt-typography-title-medium-font',
87
- '--smrt-typography-title-small-font',
88
- '--smrt-typography-headline-small-font',
89
- '--smrt-typography-headline-medium-font',
90
- ];
91
- const BASE_COMPONENT_COLOR_TOKENS = [
92
- '--smrt-color-surface-container-highest',
93
- '--smrt-color-surface-container-lowest',
94
- '--smrt-color-surface-dim',
95
- '--smrt-color-surface-bright',
96
- '--smrt-color-shadow',
97
- ];
98
- const packageRoot = process.cwd().endsWith('packages/smrt-ui')
99
- ? process.cwd()
100
- : join(process.cwd(), 'packages/smrt-ui');
101
- const STATIC_STYLE_PATHS = {
102
- material: join(packageRoot, 'src/themes/styles/material.css'),
103
- glass: join(packageRoot, 'src/themes/styles/glass.css'),
104
- studio: join(packageRoot, 'src/themes/styles/studio.css'),
105
- smrt: join(packageRoot, 'src/themes/styles/smrt.css'),
106
- happyvertical: join(packageRoot, 'src/themes/styles/happyvertical.css'),
107
- };
108
- function collectDefinedTokens(css) {
109
- return new Set([...css.matchAll(/(--smrt-[a-z0-9_-]+)\s*:/gi)].map((match) => match[1]));
110
- }
111
- describe('preset generator alias emission (#1431)', () => {
112
- for (const theme of Object.values(themes)) {
113
- for (const isDark of [false, true]) {
114
- it(`${theme.id} ${isDark ? 'dark' : 'light'} emits every consumed alias`, () => {
115
- const vars = generateThemeVariables(theme, isDark);
116
- for (const token of [
117
- ...REQUIRED_ALIASES,
118
- ...SPACING_NUMERIC_TOKENS,
119
- ...TYPOGRAPHY_FONT_SHORTHANDS,
120
- ]) {
121
- expect(vars[token], `${token} should be emitted`).toBeDefined();
122
- expect(vars[token]).not.toBe('');
123
- }
124
- });
125
- }
126
- }
127
- it('maps Material-3 radius aliases onto canonical t-shirt values', () => {
128
- const vars = generateThemeVariables(themes.material, false);
129
- expect(vars['--smrt-radius-small']).toBe(vars['--smrt-radius-sm']);
130
- expect(vars['--smrt-radius-medium']).toBe(vars['--smrt-radius-md']);
131
- expect(vars['--smrt-radius-large']).toBe(vars['--smrt-radius-lg']);
132
- });
133
- it('maps named spacing aliases onto numeric-scale values', () => {
134
- const vars = generateThemeVariables(themes.material, false);
135
- expect(vars['--smrt-spacing-sm']).toBe(vars['--smrt-spacing-2']);
136
- expect(vars['--smrt-spacing-md']).toBe(vars['--smrt-spacing-4']);
137
- expect(vars['--smrt-spacing-xl']).toBe(vars['--smrt-spacing-8']);
138
- });
139
- it('builds the typography `font` shorthand from the emitted longhands', () => {
140
- const vars = generateThemeVariables(themes.material, false);
141
- const shorthand = vars['--smrt-typography-body-medium-font'];
142
- expect(shorthand).toContain(vars['--smrt-typography-body-medium-size']);
143
- // weight size/line-height family
144
- expect(shorthand).toMatch(/^\d+\s+\S+\/\S+\s+.+$/);
145
- });
146
- });
147
- describe('static preset CSS token surface (#1431)', () => {
148
- for (const theme of Object.values(themes)) {
149
- it(`${theme.id} stylesheet contains the generated token surface`, () => {
150
- const css = readFileSync(STATIC_STYLE_PATHS[theme.id], 'utf8');
151
- const defined = collectDefinedTokens(css);
152
- const generatedTokens = new Set([
153
- ...Object.keys(generateThemeVariables(theme, false)),
154
- ...Object.keys(generateThemeVariables(theme, true)),
155
- ]);
156
- const missing = [...generatedTokens]
157
- .filter((token) => !defined.has(token))
158
- .sort();
159
- expect(missing).toEqual([]);
160
- });
161
- }
162
- });
163
- describe('simple ThemeProvider alias emission (#1431)', () => {
164
- for (const isDark of [false, true]) {
165
- it(`${isDark ? 'dark' : 'light'} emits shared aliases and component scale tokens`, () => {
166
- const vars = generateSimpleThemeVariables(isDark);
167
- for (const token of [
168
- ...REQUIRED_ALIASES,
169
- ...SPACING_NUMERIC_TOKENS,
170
- ...TYPOGRAPHY_FONT_SHORTHANDS,
171
- ...BASE_COMPONENT_COLOR_TOKENS,
172
- ]) {
173
- expect(vars[token], `${token} should be emitted`).toBeDefined();
174
- expect(vars[token]).not.toBe('');
175
- }
176
- });
177
- }
178
- });
@@ -1,27 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { formatEmail, formatText, matchOption, parseSpokenBoolean, } from '../formatters';
3
- describe('Form Formatters', () => {
4
- it('should format email correctly', () => {
5
- expect(formatEmail('john at example dot com')).toBe('john@example.com');
6
- expect(formatEmail('JOHN DOT DOE AT GMAIL DOT COM')).toBe('john.doe@gmail.com');
7
- });
8
- it('should format text correctly', () => {
9
- expect(formatText('my name is John')).toBe('John');
10
- expect(formatText('um so well hello')).toBe('hello');
11
- });
12
- it('should parse spoken boolean correctly', () => {
13
- expect(parseSpokenBoolean('yes please')).toBe(true);
14
- expect(parseSpokenBoolean('no way')).toBe(false);
15
- expect(parseSpokenBoolean('maybe')).toBe(null);
16
- });
17
- it('should match options correctly', () => {
18
- const options = [
19
- { label: 'Red', value: 'red' },
20
- { label: 'Green', value: 'green' },
21
- { label: 'Blue', value: 'blue' },
22
- ];
23
- expect(matchOption('red', options)).toBe('red');
24
- expect(matchOption('I want green', options)).toBe('green');
25
- expect(matchOption('yellow', options)).toBe(null);
26
- });
27
- });
@@ -1,89 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { generateTheme, getContrastRatio, getLuminance, hexToRgb, meetsContrastAA, meetsContrastAAA, rgbToHex, } from '../color';
3
- describe('Theme Color Utilities', () => {
4
- it('should convert hex to rgb correctly', () => {
5
- expect(hexToRgb('#000000')).toEqual({ r: 0, g: 0, b: 0 });
6
- expect(hexToRgb('#ffffff')).toEqual({ r: 255, g: 255, b: 255 });
7
- expect(hexToRgb('#FF5733')).toEqual({ r: 255, g: 87, b: 51 });
8
- });
9
- it('expands 3-digit shorthand hex (#abc -> #aabbcc) (#1586)', () => {
10
- // Regression: shorthand hex used to NaN-poison the b channel (only the first
11
- // 2 chars were read), corrupting any palette generated from a 3-digit seed.
12
- expect(hexToRgb('#abc')).toEqual({ r: 170, g: 187, b: 204 });
13
- expect(hexToRgb('#000')).toEqual({ r: 0, g: 0, b: 0 });
14
- expect(hexToRgb('#fff')).toEqual({ r: 255, g: 255, b: 255 });
15
- });
16
- it('parses functional rgb()/rgba() notation (#1586)', () => {
17
- expect(hexToRgb('rgb(0, 122, 255)')).toEqual({ r: 0, g: 122, b: 255 });
18
- expect(hexToRgb('rgb(0 122 255)')).toEqual({ r: 0, g: 122, b: 255 });
19
- expect(hexToRgb('rgba(0, 122, 255, 0.5)')).toEqual({
20
- r: 0,
21
- g: 122,
22
- b: 255,
23
- });
24
- expect(hexToRgb('rgb(100%, 0%, 50%)')).toEqual({ r: 255, g: 0, b: 128 });
25
- });
26
- it('should convert rgb to hex correctly', () => {
27
- expect(rgbToHex(0, 0, 0)).toBe('#000000');
28
- expect(rgbToHex(255, 255, 255)).toBe('#ffffff');
29
- expect(rgbToHex(255, 87, 51)).toBe('#ff5733');
30
- });
31
- it('should generate a theme palette from a seed color', () => {
32
- const seed = '#6750A4'; // M3 Baseline Purple
33
- const theme = generateTheme(seed);
34
- // Check for critical M3 keys
35
- expect(theme).toHaveProperty('primary');
36
- expect(theme).toHaveProperty('onPrimary');
37
- expect(theme).toHaveProperty('primaryContainer');
38
- expect(theme).toHaveProperty('onPrimaryContainer');
39
- expect(theme).toHaveProperty('secondary');
40
- expect(theme).toHaveProperty('surface');
41
- expect(theme).toHaveProperty('background');
42
- expect(theme).toHaveProperty('error');
43
- // Basic validity check (strings should be hex colors)
44
- expect(theme.primary).toMatch(/^#[0-9a-fA-F]{6}$/);
45
- });
46
- it('should generate different palettes for light and dark modes', () => {
47
- const seed = '#6750A4';
48
- const lightTheme = generateTheme(seed, 'light');
49
- const darkTheme = generateTheme(seed, 'dark');
50
- expect(lightTheme.primary).not.toBe(darkTheme.primary);
51
- // In M3, dark mode primary is usually lighter/desaturated compared to light mode
52
- });
53
- });
54
- describe('Color Contrast Utilities', () => {
55
- it('should calculate luminance correctly', () => {
56
- // Black has luminance 0
57
- expect(getLuminance({ r: 0, g: 0, b: 0 })).toBe(0);
58
- // White has luminance 1
59
- expect(getLuminance({ r: 255, g: 255, b: 255 })).toBe(1);
60
- // Mid gray should be around 0.2
61
- const midGray = getLuminance({ r: 128, g: 128, b: 128 });
62
- expect(midGray).toBeGreaterThan(0.1);
63
- expect(midGray).toBeLessThan(0.3);
64
- });
65
- it('should calculate contrast ratio correctly', () => {
66
- const black = { r: 0, g: 0, b: 0 };
67
- const white = { r: 255, g: 255, b: 255 };
68
- // Black on white should be 21:1 (maximum contrast)
69
- expect(getContrastRatio(black, white)).toBeCloseTo(21, 0);
70
- // Same color should be 1:1 (no contrast)
71
- expect(getContrastRatio(black, black)).toBe(1);
72
- });
73
- it('should validate WCAG AA contrast requirements', () => {
74
- // Black on white passes AA
75
- expect(meetsContrastAA('#000000', '#ffffff')).toBe(true);
76
- // Light gray on white fails AA for normal text
77
- expect(meetsContrastAA('#999999', '#ffffff')).toBe(false);
78
- // Light gray on white passes AA for large text (3:1 threshold)
79
- expect(meetsContrastAA('#767676', '#ffffff', true)).toBe(true);
80
- });
81
- it('should validate WCAG AAA contrast requirements', () => {
82
- // Black on white passes AAA
83
- expect(meetsContrastAAA('#000000', '#ffffff')).toBe(true);
84
- // Medium gray on white fails AAA for normal text (needs 7:1)
85
- expect(meetsContrastAAA('#666666', '#ffffff')).toBe(false);
86
- // Darker gray passes AAA for large text (4.5:1 threshold)
87
- expect(meetsContrastAAA('#595959', '#ffffff', true)).toBe(true);
88
- });
89
- });
@@ -1,11 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { elevationTokens, typographyTokens } from '../typography';
3
- describe('Typography & Elevation Tokens', () => {
4
- it('should have valid typography tokens', () => {
5
- expect(typographyTokens['--md-sys-typescale-body-large-font']).toBeDefined();
6
- expect(typographyTokens['--md-sys-typescale-display-large-font']).toContain('Roboto');
7
- });
8
- it('should have valid elevation tokens', () => {
9
- expect(elevationTokens['--md-sys-elevation-level1']).toBeDefined();
10
- });
11
- });