@happyvertical/smrt-ui 0.52.0 → 0.53.1

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 (208) hide show
  1. package/AGENTS.md +11 -1
  2. package/README.md +300 -2
  3. package/dist/components/data/DataTable.svelte +60 -15
  4. package/dist/components/data/DataTable.svelte.d.ts.map +1 -1
  5. package/dist/components/data/DataTableResponsive.d.ts +4 -0
  6. package/dist/components/data/DataTableResponsive.d.ts.map +1 -0
  7. package/dist/components/data/DataTableResponsive.js +22 -0
  8. package/dist/components/data/__tests__/DataTableResponsive.test.js +80 -0
  9. package/dist/components/data/__tests__/responsive-table.fixture.svelte +29 -0
  10. package/dist/components/data/__tests__/responsive-table.fixture.svelte.d.ts +7 -0
  11. package/dist/components/data/__tests__/responsive-table.fixture.svelte.d.ts.map +1 -0
  12. package/dist/components/data/types.d.ts +8 -0
  13. package/dist/components/data/types.d.ts.map +1 -1
  14. package/dist/components/display/DateDisplay.svelte +76 -14
  15. package/dist/components/display/DateDisplay.svelte.d.ts +2 -0
  16. package/dist/components/display/DateDisplay.svelte.d.ts.map +1 -1
  17. package/dist/components/display/Icon.svelte +3 -16
  18. package/dist/components/display/Icon.svelte.d.ts +0 -9
  19. package/dist/components/display/Icon.svelte.d.ts.map +1 -1
  20. package/dist/components/display/StatusBadge.svelte +29 -2
  21. package/dist/components/display/StatusBadge.svelte.d.ts +4 -2
  22. package/dist/components/display/StatusBadge.svelte.d.ts.map +1 -1
  23. package/dist/components/display/__tests__/DateDisplay.test.js +82 -1
  24. package/dist/components/display/__tests__/Icon.test.js +132 -2
  25. package/dist/components/display/__tests__/StatusBadge.test.js +78 -0
  26. package/dist/components/display/icons.svelte.d.ts +11 -0
  27. package/dist/components/display/icons.svelte.d.ts.map +1 -0
  28. package/dist/components/display/icons.svelte.js +60 -0
  29. package/dist/components/display/index.d.ts +3 -1
  30. package/dist/components/display/index.d.ts.map +1 -1
  31. package/dist/components/display/index.js +1 -0
  32. package/dist/components/display/types.d.ts +2 -0
  33. package/dist/components/display/types.d.ts.map +1 -1
  34. package/dist/components/feedback/ConfirmDialog.svelte +59 -48
  35. package/dist/components/feedback/ConfirmDialog.svelte.d.ts +14 -2
  36. package/dist/components/feedback/ConfirmDialog.svelte.d.ts.map +1 -1
  37. package/dist/components/feedback/ToastViewport.svelte +156 -8
  38. package/dist/components/feedback/ToastViewport.svelte.d.ts +5 -1
  39. package/dist/components/feedback/ToastViewport.svelte.d.ts.map +1 -1
  40. package/dist/components/feedback/__tests__/ConfirmDialog.test.js +38 -20
  41. package/dist/components/feedback/__tests__/confirm-message.fixture.svelte +9 -0
  42. package/dist/components/feedback/__tests__/confirm-message.fixture.svelte.d.ts +19 -0
  43. package/dist/components/feedback/__tests__/confirm-message.fixture.svelte.d.ts.map +1 -0
  44. package/dist/components/feedback/__tests__/toast.test.js +142 -1
  45. package/dist/components/feedback/index.d.ts +1 -1
  46. package/dist/components/feedback/index.d.ts.map +1 -1
  47. package/dist/components/feedback/toast.d.ts +13 -1
  48. package/dist/components/feedback/toast.d.ts.map +1 -1
  49. package/dist/components/feedback/toast.js +51 -10
  50. package/dist/components/forms/CameraCapture.svelte +619 -0
  51. package/dist/components/forms/CameraCapture.svelte.d.ts +42 -0
  52. package/dist/components/forms/CameraCapture.svelte.d.ts.map +1 -0
  53. package/dist/components/forms/Checkbox.svelte +8 -1
  54. package/dist/components/forms/Checkbox.svelte.d.ts +2 -0
  55. package/dist/components/forms/Checkbox.svelte.d.ts.map +1 -1
  56. package/dist/components/forms/Combobox.svelte +40 -0
  57. package/dist/components/forms/Combobox.svelte.d.ts.map +1 -1
  58. package/dist/components/forms/Form.svelte +5 -0
  59. package/dist/components/forms/Form.svelte.d.ts +1 -0
  60. package/dist/components/forms/Form.svelte.d.ts.map +1 -1
  61. package/dist/components/forms/Input.svelte +8 -1
  62. package/dist/components/forms/Input.svelte.d.ts +2 -0
  63. package/dist/components/forms/Input.svelte.d.ts.map +1 -1
  64. package/dist/components/forms/Listbox.svelte +39 -1
  65. package/dist/components/forms/Listbox.svelte.d.ts.map +1 -1
  66. package/dist/components/forms/MultiSelect.svelte +41 -1
  67. package/dist/components/forms/MultiSelect.svelte.d.ts.map +1 -1
  68. package/dist/components/forms/Radio.svelte +1 -0
  69. package/dist/components/forms/RadioGroup.svelte +7 -1
  70. package/dist/components/forms/RadioGroup.svelte.d.ts +2 -0
  71. package/dist/components/forms/RadioGroup.svelte.d.ts.map +1 -1
  72. package/dist/components/forms/SegmentedControl.svelte +152 -11
  73. package/dist/components/forms/SegmentedControl.svelte.d.ts +4 -0
  74. package/dist/components/forms/SegmentedControl.svelte.d.ts.map +1 -1
  75. package/dist/components/forms/Select.svelte +8 -1
  76. package/dist/components/forms/Select.svelte.d.ts +2 -0
  77. package/dist/components/forms/Select.svelte.d.ts.map +1 -1
  78. package/dist/components/forms/SignaturePad.svelte +436 -0
  79. package/dist/components/forms/SignaturePad.svelte.d.ts +32 -0
  80. package/dist/components/forms/SignaturePad.svelte.d.ts.map +1 -0
  81. package/dist/components/forms/Switch.svelte +8 -1
  82. package/dist/components/forms/Switch.svelte.d.ts +2 -0
  83. package/dist/components/forms/Switch.svelte.d.ts.map +1 -1
  84. package/dist/components/forms/Textarea.svelte +8 -1
  85. package/dist/components/forms/Textarea.svelte.d.ts +2 -0
  86. package/dist/components/forms/Textarea.svelte.d.ts.map +1 -1
  87. package/dist/components/forms/__tests__/CameraCapture.test.js +504 -0
  88. package/dist/components/forms/__tests__/Combobox.test.js +279 -12
  89. package/dist/components/forms/__tests__/Form.test.js +46 -0
  90. package/dist/components/forms/__tests__/Listbox.test.js +303 -0
  91. package/dist/components/forms/__tests__/MultiSelect.test.js +281 -0
  92. package/dist/components/forms/__tests__/SignaturePad.test.js +338 -0
  93. package/dist/components/forms/__tests__/camera-capture-session.test.js +207 -0
  94. package/dist/components/forms/__tests__/capture-form-retry.test.js +166 -0
  95. package/dist/components/forms/__tests__/capture-form.fixture.svelte +38 -0
  96. package/dist/components/forms/__tests__/capture-form.fixture.svelte.d.ts +10 -0
  97. package/dist/components/forms/__tests__/capture-form.fixture.svelte.d.ts.map +1 -0
  98. package/dist/components/forms/__tests__/capture-test-env.d.ts +70 -0
  99. package/dist/components/forms/__tests__/capture-test-env.d.ts.map +1 -0
  100. package/dist/components/forms/__tests__/capture-test-env.js +122 -0
  101. package/dist/components/forms/__tests__/capture-touch.fixture.svelte +15 -0
  102. package/dist/components/forms/__tests__/capture-touch.fixture.svelte.d.ts +8 -0
  103. package/dist/components/forms/__tests__/capture-touch.fixture.svelte.d.ts.map +1 -0
  104. package/dist/components/forms/__tests__/combobox-form.fixture.svelte +29 -0
  105. package/dist/components/forms/__tests__/combobox-form.fixture.svelte.d.ts +14 -0
  106. package/dist/components/forms/__tests__/combobox-form.fixture.svelte.d.ts.map +1 -0
  107. package/dist/components/forms/__tests__/form-attachment.fixture.svelte +28 -0
  108. package/dist/components/forms/__tests__/form-attachment.fixture.svelte.d.ts +11 -0
  109. package/dist/components/forms/__tests__/form-attachment.fixture.svelte.d.ts.map +1 -0
  110. package/dist/components/forms/__tests__/form-retry-form.fixture.svelte +31 -0
  111. package/dist/components/forms/__tests__/form-retry-form.fixture.svelte.d.ts +13 -0
  112. package/dist/components/forms/__tests__/form-retry-form.fixture.svelte.d.ts.map +1 -0
  113. package/dist/components/forms/__tests__/form-retry-form.test.js +107 -0
  114. package/dist/components/forms/__tests__/hidden-controls-form-retry.test.js +69 -0
  115. package/dist/components/forms/__tests__/hidden-controls-form.fixture.svelte +29 -0
  116. package/dist/components/forms/__tests__/hidden-controls-form.fixture.svelte.d.ts +9 -0
  117. package/dist/components/forms/__tests__/hidden-controls-form.fixture.svelte.d.ts.map +1 -0
  118. package/dist/components/forms/__tests__/listbox-form.fixture.svelte +27 -0
  119. package/dist/components/forms/__tests__/listbox-form.fixture.svelte.d.ts +13 -0
  120. package/dist/components/forms/__tests__/listbox-form.fixture.svelte.d.ts.map +1 -0
  121. package/dist/components/forms/__tests__/multiselect-form.fixture.svelte +27 -0
  122. package/dist/components/forms/__tests__/multiselect-form.fixture.svelte.d.ts +13 -0
  123. package/dist/components/forms/__tests__/multiselect-form.fixture.svelte.d.ts.map +1 -0
  124. package/dist/components/forms/__tests__/native-file-field.test.js +177 -0
  125. package/dist/components/forms/__tests__/segmented-posting.fixture.svelte +28 -0
  126. package/dist/components/forms/__tests__/segmented-posting.fixture.svelte.d.ts +12 -0
  127. package/dist/components/forms/__tests__/segmented-posting.fixture.svelte.d.ts.map +1 -0
  128. package/dist/components/forms/__tests__/segmented-posting.test.js +92 -0
  129. package/dist/components/forms/__tests__/signature-pad-logic.test.js +54 -0
  130. package/dist/components/forms/__tests__/touch-density.fixture.svelte +34 -0
  131. package/dist/components/forms/__tests__/touch-density.fixture.svelte.d.ts +8 -0
  132. package/dist/components/forms/__tests__/touch-density.fixture.svelte.d.ts.map +1 -0
  133. package/dist/components/forms/__tests__/touch-density.test.js +66 -0
  134. package/dist/components/forms/camera-capture-session.d.ts +81 -0
  135. package/dist/components/forms/camera-capture-session.d.ts.map +1 -0
  136. package/dist/components/forms/camera-capture-session.js +130 -0
  137. package/dist/components/forms/form-retry/__tests__/boundaries.test.js +23 -0
  138. package/dist/components/forms/form-retry/__tests__/content-digest.test.js +70 -0
  139. package/dist/components/forms/form-retry/__tests__/controller.test.js +802 -0
  140. package/dist/components/forms/form-retry/__tests__/fake-kit.d.ts +82 -0
  141. package/dist/components/forms/form-retry/__tests__/fake-kit.d.ts.map +1 -0
  142. package/dist/components/forms/form-retry/__tests__/fake-kit.js +180 -0
  143. package/dist/components/forms/form-retry/__tests__/form-draft.test.js +169 -0
  144. package/dist/components/forms/form-retry/__tests__/ssr.test.js +37 -0
  145. package/dist/components/forms/form-retry/__tests__/storage.d.ts +26 -0
  146. package/dist/components/forms/form-retry/__tests__/storage.d.ts.map +1 -0
  147. package/dist/components/forms/form-retry/__tests__/storage.js +63 -0
  148. package/dist/components/forms/form-retry/__tests__/submission-key.test.js +236 -0
  149. package/dist/components/forms/form-retry/__tests__/submitted-draft.test.js +334 -0
  150. package/dist/components/forms/form-retry/content-digest.d.ts +54 -0
  151. package/dist/components/forms/form-retry/content-digest.d.ts.map +1 -0
  152. package/dist/components/forms/form-retry/content-digest.js +169 -0
  153. package/dist/components/forms/form-retry/controller.d.ts +214 -0
  154. package/dist/components/forms/form-retry/controller.d.ts.map +1 -0
  155. package/dist/components/forms/form-retry/controller.js +404 -0
  156. package/dist/components/forms/form-retry/form-draft.d.ts +68 -0
  157. package/dist/components/forms/form-retry/form-draft.d.ts.map +1 -0
  158. package/dist/components/forms/form-retry/form-draft.js +161 -0
  159. package/dist/components/forms/form-retry/index.d.ts +19 -0
  160. package/dist/components/forms/form-retry/index.d.ts.map +1 -0
  161. package/dist/components/forms/form-retry/index.js +16 -0
  162. package/dist/components/forms/form-retry/submission-key.d.ts +244 -0
  163. package/dist/components/forms/form-retry/submission-key.d.ts.map +1 -0
  164. package/dist/components/forms/form-retry/submission-key.js +342 -0
  165. package/dist/components/forms/form-retry/submitted-draft.d.ts +112 -0
  166. package/dist/components/forms/form-retry/submitted-draft.d.ts.map +1 -0
  167. package/dist/components/forms/form-retry/submitted-draft.js +270 -0
  168. package/dist/components/forms/form-retry/types.d.ts +84 -0
  169. package/dist/components/forms/form-retry/types.d.ts.map +1 -0
  170. package/dist/components/forms/form-retry/types.js +13 -0
  171. package/dist/components/forms/index.d.ts +7 -1
  172. package/dist/components/forms/index.d.ts.map +1 -1
  173. package/dist/components/forms/index.js +8 -0
  174. package/dist/components/forms/native-file-field.d.ts +94 -0
  175. package/dist/components/forms/native-file-field.d.ts.map +1 -0
  176. package/dist/components/forms/native-file-field.js +147 -0
  177. package/dist/components/forms/signature-pad-logic.d.ts +50 -0
  178. package/dist/components/forms/signature-pad-logic.d.ts.map +1 -0
  179. package/dist/components/forms/signature-pad-logic.js +48 -0
  180. package/dist/components/forms/types.d.ts +41 -0
  181. package/dist/components/forms/types.d.ts.map +1 -1
  182. package/dist/components/nav/FilterChips.svelte +8 -1
  183. package/dist/components/nav/FilterChips.svelte.d.ts +2 -0
  184. package/dist/components/nav/FilterChips.svelte.d.ts.map +1 -1
  185. package/dist/components/ui/Button.svelte +9 -2
  186. package/dist/components/ui/Button.svelte.d.ts +2 -0
  187. package/dist/components/ui/Button.svelte.d.ts.map +1 -1
  188. package/dist/i18n/strings.ui.d.ts +24 -0
  189. package/dist/i18n/strings.ui.d.ts.map +1 -1
  190. package/dist/i18n/strings.ui.js +26 -0
  191. package/dist/styles/tokens.css +2 -0
  192. package/dist/svelte/__tests__/playground.test.js +2 -1
  193. package/dist/svelte/playground/CapturePreview.svelte +56 -0
  194. package/dist/svelte/playground/CapturePreview.svelte.d.ts +4 -0
  195. package/dist/svelte/playground/CapturePreview.svelte.d.ts.map +1 -0
  196. package/dist/svelte/playground.d.ts.map +1 -1
  197. package/dist/svelte/playground.js +10 -0
  198. package/dist/themes/ThemeProvider.svelte +9 -0
  199. package/dist/themes/ThemeProvider.svelte.d.ts +2 -0
  200. package/dist/themes/ThemeProvider.svelte.d.ts.map +1 -1
  201. package/dist/themes/css-generator.d.ts.map +1 -1
  202. package/dist/themes/css-generator.js +3 -0
  203. package/dist/themes/styles/glass.css +4 -0
  204. package/dist/themes/styles/happyvertical.css +4 -0
  205. package/dist/themes/styles/material.css +4 -0
  206. package/dist/themes/styles/smrt.css +4 -0
  207. package/dist/themes/styles/studio.css +4 -0
  208. package/package.json +8 -2
@@ -0,0 +1,80 @@
1
+ import { render, screen, waitFor } from '@testing-library/svelte';
2
+ import { describe, expect, it } from 'vitest';
3
+ import DataTable from '../DataTable.svelte';
4
+ import { createDataTableController } from '../DataTableController.js';
5
+ import { responsiveColumns } from '../DataTableResponsive.js';
6
+ const columns = Array.from({ length: 6 }, (_, index) => ({
7
+ id: `c${index}`,
8
+ label: `Column ${index}`,
9
+ responsive: { priority: index, keepVisible: index === 0 },
10
+ headerPath: [{ id: 'group', label: 'Group' }],
11
+ }));
12
+ const data = [
13
+ {
14
+ id: 'row',
15
+ ...Object.fromEntries(columns.map((column) => [column.id, column.label])),
16
+ },
17
+ ];
18
+ async function resize(container, width) {
19
+ const root = container.querySelector('.data-table-container');
20
+ Object.defineProperty(root, 'clientWidth', {
21
+ configurable: true,
22
+ value: width,
23
+ });
24
+ window.dispatchEvent(new Event('resize'));
25
+ await waitFor(() => expect(root).toHaveClass(width <= 800 ? 'data-table-container--narrow' : 'data-table-container'));
26
+ }
27
+ describe('responsive column collapse', () => {
28
+ it('keeps mandatory columns and highest priorities in display order', () => {
29
+ expect(responsiveColumns(columns, 390, 160).map((column) => column.id)).toEqual(['c0', 'c5']);
30
+ expect(responsiveColumns(columns, 768, 160).map((column) => column.id)).toEqual(['c0', 'c3', 'c4', 'c5']);
31
+ });
32
+ it('handles missing metadata, equal priorities, invalid numbers, and oversized mandatory sets', () => {
33
+ const plain = columns.map((column) => ({
34
+ ...column,
35
+ responsive: undefined,
36
+ }));
37
+ expect(responsiveColumns(plain, 320, Number.NaN).map((column) => column.id)).toEqual(['c0', 'c1']);
38
+ expect(responsiveColumns([{ ...plain[0], responsive: { priority: Number.NaN } }, plain[1]], 160, 160).map((column) => column.id)).toEqual(['c0']);
39
+ expect(responsiveColumns(columns.map((column) => ({
40
+ ...column,
41
+ responsive: { keepVisible: true },
42
+ })), 100, 160)).toHaveLength(6);
43
+ expect(responsiveColumns([], 0, 160)).toEqual([]);
44
+ });
45
+ it('matches headers/cells/groups to container width and restores without mutating controller visibility', async () => {
46
+ const controller = createDataTableController({
47
+ initialState: { columnVisibility: [{ columnId: 'c5', visible: false }] },
48
+ });
49
+ const { container } = render(DataTable, {
50
+ props: {
51
+ data,
52
+ columns,
53
+ rowKey: 'id',
54
+ controller,
55
+ responsiveMode: 'hide-columns',
56
+ },
57
+ });
58
+ const visibility = controller.getState().columnVisibility;
59
+ await resize(container, 390);
60
+ await waitFor(() => expect(screen.getAllByRole('cell')).toHaveLength(2));
61
+ expect(screen.getByRole('columnheader', { name: 'Group' })).toHaveAttribute('colspan', '2');
62
+ expect(screen.queryByRole('columnheader', { name: 'Column 5' })).toBeNull();
63
+ expect(screen.getByRole('columnheader', { name: 'Column 4' })).toBeInTheDocument();
64
+ expect(controller.getState().columnVisibility).toEqual(visibility);
65
+ await resize(container, 1200);
66
+ await waitFor(() => expect(screen.getAllByRole('cell')).toHaveLength(5));
67
+ expect(screen.getByRole('columnheader', { name: 'Group' })).toHaveAttribute('colspan', '5');
68
+ });
69
+ it('preserves the scroll default regardless of narrow width', async () => {
70
+ const { container } = render(DataTable, { props: { data, columns } });
71
+ const root = container.querySelector('.data-table-container');
72
+ Object.defineProperty(root, 'clientWidth', {
73
+ configurable: true,
74
+ value: 390,
75
+ });
76
+ window.dispatchEvent(new Event('resize'));
77
+ await waitFor(() => expect(screen.getAllByRole('cell')).toHaveLength(6));
78
+ expect(root).not.toHaveClass('data-table-container--narrow');
79
+ });
80
+ });
@@ -0,0 +1,29 @@
1
+ <script lang="ts">
2
+ import ThemeProvider from '../../../themes/ThemeProvider.svelte';
3
+ import DataTable from '../DataTable.svelte';
4
+
5
+ let { mode = 'hide-columns' }: { mode?: 'scroll' | 'hide-columns' } = $props();
6
+ const columns = Array.from({ length: 7 }, (_, index) => ({
7
+ id: `c${index}`,
8
+ label: `Column ${index}`,
9
+ sortable: true,
10
+ width: '200px',
11
+ minWidth: '180px',
12
+ responsive: { priority: index, keepVisible: index === 0 },
13
+ headerPath: [{ id: 'group', label: 'Group' }],
14
+ }));
15
+ const data = [
16
+ {
17
+ id: 'one',
18
+ ...Object.fromEntries(
19
+ columns.map((column) => [
20
+ column.id,
21
+ `${column.label}LongUnbrokenTextThatMustWrap`,
22
+ ]),
23
+ ),
24
+ },
25
+ ];
26
+ </script>
27
+ <ThemeProvider density="touch" persist={false} inlineVariables>
28
+ <DataTable {columns} {data} responsiveMode={mode} rowKey="id" sortable caption="Responsive table" />
29
+ </ThemeProvider>
@@ -0,0 +1,7 @@
1
+ type $$ComponentProps = {
2
+ mode?: 'scroll' | 'hide-columns';
3
+ };
4
+ declare const ResponsiveTable: import("svelte").Component<$$ComponentProps, {}, "">;
5
+ type ResponsiveTable = ReturnType<typeof ResponsiveTable>;
6
+ export default ResponsiveTable;
7
+ //# sourceMappingURL=responsive-table.fixture.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"responsive-table.fixture.svelte.d.ts","sourceRoot":"","sources":["../../../../src/components/data/__tests__/responsive-table.fixture.svelte.ts"],"names":[],"mappings":"AAMC,KAAK,gBAAgB,GAAI;IAAE,IAAI,CAAC,EAAE,QAAQ,GAAG,cAAc,CAAA;CAAE,CAAC;AAiC/D,QAAA,MAAM,eAAe,sDAAwC,CAAC;AAC9D,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;AAC1D,eAAe,eAAe,CAAC"}
@@ -145,6 +145,14 @@ export interface SortState {
145
145
  * DataTable props
146
146
  */
147
147
  export interface DataTableProps<T> {
148
+ /** Sort-control target density; omit to inherit ThemeProvider. */
149
+ density?: 'comfortable' | 'touch';
150
+ /** Opt-in container-width column collapse; default keeps horizontal scrolling. */
151
+ responsiveMode?: 'scroll' | 'hide-columns';
152
+ /** Container-width threshold in pixels for narrow mode (default 800). */
153
+ responsiveBreakpoint?: number;
154
+ /** Target width per retained column in narrow mode (default 160 pixels). */
155
+ responsiveColumnMinWidth?: number;
148
156
  /** Data rows */
149
157
  data: T[];
150
158
  /** Column definitions */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/data/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/data/types.ts"],"names":[],"mappings":"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"}
@@ -17,6 +17,8 @@ export interface Props {
17
17
  showTime?: boolean;
18
18
  /** Locale for formatting (defaults to en-CA) */
19
19
  locale?: string;
20
+ /** IANA zone for timestamps and relative calendar-day boundaries. */
21
+ timeZone?: string;
20
22
  /** Optional CSS class */
21
23
  class?: string;
22
24
  }
@@ -27,15 +29,22 @@ const {
27
29
  fallback = 'N/A',
28
30
  showTime = false,
29
31
  locale = 'en-CA',
32
+ timeZone,
30
33
  class: className = '',
31
34
  }: Props = $props();
32
35
 
33
- // Parse the date
36
+ const isCalendarDate = $derived(
37
+ typeof date === 'string' && /^\d{4}-\d{2}-\d{2}$/.test(date),
38
+ );
39
+
40
+ // Bare dates denote a calendar day, never a browser-local instant.
34
41
  const parsedDate = $derived.by(() => {
35
42
  if (date === null || date === undefined) return null;
36
- if (date instanceof Date) return date;
43
+ if (date instanceof Date) return Number.isNaN(date.getTime()) ? null : date;
37
44
  const d = new Date(date);
38
- return Number.isNaN(d.getTime()) ? null : d;
45
+ if (Number.isNaN(d.getTime())) return null;
46
+ if (isCalendarDate && d.toISOString().slice(0, 10) !== date) return null;
47
+ return d;
39
48
  });
40
49
 
41
50
  // Format options for Intl.DateTimeFormat
@@ -45,8 +54,52 @@ const dateOptions: Record<string, Intl.DateTimeFormatOptions> = {
45
54
  long: { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' },
46
55
  };
47
56
 
48
- // Format relative time
57
+ // Convert zone-local Gregorian dates to ordinals so DST does not alter day counts.
58
+ function calendarDay(d: Date, zone?: string): number {
59
+ const parts = new Intl.DateTimeFormat('en-US', {
60
+ timeZone: zone,
61
+ year: 'numeric',
62
+ month: 'numeric',
63
+ day: 'numeric',
64
+ }).formatToParts(d);
65
+ const part = (type: string) =>
66
+ Number(parts.find((entry) => entry.type === type)?.value);
67
+ const midnight = new Date(0);
68
+ midnight.setUTCFullYear(part('year'), part('month') - 1, part('day'));
69
+ return midnight.getTime() / 86400000;
70
+ }
71
+
72
+ function formatCalendarRelative(d: Date): string {
73
+ const now = new Date();
74
+ const days =
75
+ calendarDay(now, timeZone) -
76
+ (isCalendarDate ? d.getTime() / 86400000 : calendarDay(d, timeZone));
77
+ if (days === 0) {
78
+ if (isCalendarDate || d > now) return 'today';
79
+ const minutes = Math.floor((now.getTime() - d.getTime()) / 60000);
80
+ if (minutes === 0) return 'just now';
81
+ return minutes < 60
82
+ ? `${minutes}m ago`
83
+ : `${Math.floor(minutes / 60)}h ago`;
84
+ }
85
+ if (days === 1) return 'yesterday';
86
+ if (days === -1) return 'tomorrow';
87
+ const count = Math.abs(days);
88
+ const [amount, unit] =
89
+ count < 7
90
+ ? [count, 'days']
91
+ : count < 30
92
+ ? [Math.floor(count / 7), 'weeks']
93
+ : count < 365
94
+ ? [Math.floor(count / 30), 'months']
95
+ : [Math.floor(count / 365), 'years'];
96
+ return days < 0 ? `in ${amount} ${unit}` : `${amount} ${unit} ago`;
97
+ }
98
+
99
+ // Preserve duration-based relative defaults for instant inputs without a zone.
49
100
  function formatRelative(d: Date): string {
101
+ if (timeZone !== undefined || isCalendarDate)
102
+ return formatCalendarRelative(d);
50
103
  const now = new Date();
51
104
  const diffMs = now.getTime() - d.getTime();
52
105
  const diffSec = Math.floor(diffMs / 1000);
@@ -83,21 +136,30 @@ function formatRelative(d: Date): string {
83
136
  const formatted = $derived.by(() => {
84
137
  if (!parsedDate) return fallback;
85
138
 
86
- if (format === 'relative') {
87
- return formatRelative(parsedDate);
88
- }
139
+ try {
140
+ if (format === 'relative') return formatRelative(parsedDate);
89
141
 
90
- const options = { ...dateOptions[format] };
91
- if (showTime) {
92
- options.hour = 'numeric';
93
- options.minute = '2-digit';
142
+ const options = {
143
+ ...dateOptions[format],
144
+ timeZone: isCalendarDate ? 'UTC' : timeZone,
145
+ };
146
+ if (showTime && !isCalendarDate) {
147
+ options.hour = 'numeric';
148
+ options.minute = '2-digit';
149
+ }
150
+ return new Intl.DateTimeFormat(locale, options).format(parsedDate);
151
+ } catch (error) {
152
+ if (error instanceof RangeError) return fallback;
153
+ throw error;
94
154
  }
95
-
96
- return new Intl.DateTimeFormat(locale, options).format(parsedDate);
97
155
  });
98
156
 
99
157
  // ISO string for datetime attribute
100
- const isoString = $derived(parsedDate?.toISOString() ?? '');
158
+ const isoString = $derived(
159
+ isCalendarDate && parsedDate
160
+ ? String(date)
161
+ : (parsedDate?.toISOString() ?? ''),
162
+ );
101
163
  </script>
102
164
 
103
165
  {#if parsedDate}
@@ -15,6 +15,8 @@ export interface Props {
15
15
  showTime?: boolean;
16
16
  /** Locale for formatting (defaults to en-CA) */
17
17
  locale?: string;
18
+ /** IANA zone for timestamps and relative calendar-day boundaries. */
19
+ timeZone?: string;
18
20
  /** Optional CSS class */
19
21
  class?: string;
20
22
  }
@@ -1 +1 @@
1
- {"version":3,"file":"DateDisplay.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/display/DateDisplay.svelte.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AAEH,sCAAsC;AACtC,MAAM,WAAW,KAAK;IACpB,uDAAuD;IACvD,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAChD,qBAAqB;IACrB,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;IAClD,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gCAAgC;IAChC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gDAAgD;IAChD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yBAAyB;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAiGD,QAAA,MAAM,WAAW,2CAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"DateDisplay.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/display/DateDisplay.svelte.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AAEH,sCAAsC;AACtC,MAAM,WAAW,KAAK;IACpB,uDAAuD;IACvD,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAChD,qBAAqB;IACrB,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;IAClD,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gCAAgC;IAChC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gDAAgD;IAChD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yBAAyB;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA6JD,QAAA,MAAM,WAAW,2CAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
@@ -9,6 +9,8 @@
9
9
  * - Uses aria-hidden="true" by default (decorative)
10
10
  */
11
11
 
12
+ import { resolveIconPath } from './icons.svelte.js';
13
+
12
14
  /** Props for Icon component */
13
15
  export interface Props {
14
16
  /** Preset icon name */
@@ -36,22 +38,7 @@ const {
36
38
 
37
39
  const isInformative = $derived(!!ariaLabel);
38
40
 
39
- // Common M3 Icon Paths (Simplified)
40
- const presets: Record<string, string> = {
41
- menu: 'M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z',
42
- search:
43
- 'M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z',
44
- close:
45
- 'M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z',
46
- 'chevron-right': 'M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6-6-6z',
47
- 'chevron-left': 'M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12l4.58-4.59z',
48
- 'chevron-down': 'M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z',
49
- check: 'M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41L9 16.17z',
50
- add: 'M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z',
51
- mic: 'M12 14c1.66 0 3-1.34 3-3V5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3z M17 11c0 2.76-2.24 5-5 5s-5-2.24-5-5H5c0 3.53 2.04 6.43 5 7.07V21h4v-2.93c2.96-.64 5-3.54 5-7.07h-2z',
52
- };
53
-
54
- const finalPath = $derived(path ?? (name ? presets[name] : ''));
41
+ const finalPath = $derived(path ?? (name ? resolveIconPath(name) : ''));
55
42
  const pxSize = $derived(typeof size === 'number' ? `${size}px` : size);
56
43
  </script>
57
44
 
@@ -1,12 +1,3 @@
1
- /**
2
- * Icon - SVG icon component
3
- *
4
- * Displays SVG icons from presets or custom paths.
5
- *
6
- * Accessibility:
7
- * - Use aria-label for informative icons
8
- * - Uses aria-hidden="true" by default (decorative)
9
- */
10
1
  /** Props for Icon component */
11
2
  export interface Props {
12
3
  /** Preset icon name */
@@ -1 +1 @@
1
- {"version":3,"file":"Icon.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/display/Icon.svelte.ts"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AAEH,+BAA+B;AAC/B,MAAM,WAAW,KAAK;IACpB,uBAAuB;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,sBAAsB;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0DAA0D;IAC1D,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,iBAAiB;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kBAAkB;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gDAAgD;IAChD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AA0CD,QAAA,MAAM,IAAI,2CAAwC,CAAC;AACnD,KAAK,IAAI,GAAG,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC;AACpC,eAAe,IAAI,CAAC"}
1
+ {"version":3,"file":"Icon.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/display/Icon.svelte.ts"],"names":[],"mappings":"AAeA,+BAA+B;AAC/B,MAAM,WAAW,KAAK;IACpB,uBAAuB;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,sBAAsB;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0DAA0D;IAC1D,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,iBAAiB;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kBAAkB;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gDAAgD;IAChD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AA8BD,QAAA,MAAM,IAAI,2CAAwC,CAAC;AACnD,KAAK,IAAI,GAAG,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC;AACpC,eAAe,IAAI,CAAC"}
@@ -3,10 +3,10 @@
3
3
  * StatusBadge - Generic status indicator badge
4
4
  *
5
5
  * Provides pre-defined color schemes for common status domains (invoice, project, etc.)
6
- * or allows custom styling via CSS variables.
6
+ * or an explicit semantic tone for custom status vocabulary.
7
7
  */
8
8
 
9
- import type { StatusType } from './types.js';
9
+ import type { StatusTone, StatusType } from './types.js';
10
10
 
11
11
  /** Props for StatusBadge component */
12
12
  export interface Props {
@@ -14,6 +14,8 @@ export interface Props {
14
14
  status: string;
15
15
  /** Pre-defined color scheme type */
16
16
  type?: StatusType;
17
+ /** Semantic tone overriding the domain color scheme. */
18
+ tone?: StatusTone;
17
19
  /** Badge size */
18
20
  size?: 'sm' | 'md' | 'lg';
19
21
  /** Visual variant */
@@ -25,6 +27,7 @@ export interface Props {
25
27
  const {
26
28
  status,
27
29
  type = 'default',
30
+ tone,
28
31
  size = 'md',
29
32
  variant = 'filled',
30
33
  label,
@@ -201,11 +204,35 @@ const colorSchemes: Record<
201
204
  },
202
205
  };
203
206
 
207
+ const toneSchemes: Record<StatusTone, { bg: string; text: string }> = {
208
+ success: {
209
+ bg: 'var(--smrt-color-success-container)',
210
+ text: 'var(--smrt-color-on-success-container)',
211
+ },
212
+ warning: {
213
+ bg: 'var(--smrt-color-warning-container)',
214
+ text: 'var(--smrt-color-on-warning-container)',
215
+ },
216
+ danger: {
217
+ bg: 'var(--smrt-color-error-container)',
218
+ text: 'var(--smrt-color-on-error-container)',
219
+ },
220
+ info: {
221
+ bg: 'var(--smrt-color-primary-container)',
222
+ text: 'var(--smrt-color-on-primary-container)',
223
+ },
224
+ neutral: {
225
+ bg: 'var(--smrt-color-surface-container-highest)',
226
+ text: 'var(--smrt-color-on-surface-variant)',
227
+ },
228
+ };
229
+
204
230
  // Normalize status for lookup (lowercase, handle spaces/underscores)
205
231
  const normalizedStatus = $derived(status.toLowerCase().replace(/[\s-]/g, '_'));
206
232
 
207
233
  // Get colors for current status
208
234
  const colors = $derived.by(() => {
235
+ if (tone && Object.hasOwn(toneSchemes, tone)) return toneSchemes[tone];
209
236
  const scheme = colorSchemes[type] ?? colorSchemes.default;
210
237
  return (
211
238
  scheme[normalizedStatus] ?? {
@@ -2,15 +2,17 @@
2
2
  * StatusBadge - Generic status indicator badge
3
3
  *
4
4
  * Provides pre-defined color schemes for common status domains (invoice, project, etc.)
5
- * or allows custom styling via CSS variables.
5
+ * or an explicit semantic tone for custom status vocabulary.
6
6
  */
7
- import type { StatusType } from './types.js';
7
+ import type { StatusTone, StatusType } from './types.js';
8
8
  /** Props for StatusBadge component */
9
9
  export interface Props {
10
10
  /** The status value to display */
11
11
  status: string;
12
12
  /** Pre-defined color scheme type */
13
13
  type?: StatusType;
14
+ /** Semantic tone overriding the domain color scheme. */
15
+ tone?: StatusTone;
14
16
  /** Badge size */
15
17
  size?: 'sm' | 'md' | 'lg';
16
18
  /** Visual variant */
@@ -1 +1 @@
1
- {"version":3,"file":"StatusBadge.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/display/StatusBadge.svelte.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG7C,sCAAsC;AACtC,MAAM,WAAW,KAAK;IACpB,kCAAkC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,oCAAoC;IACpC,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,iBAAiB;IACjB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,qBAAqB;IACrB,OAAO,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC/B,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAoND,QAAA,MAAM,WAAW,2CAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"StatusBadge.svelte.d.ts","sourceRoot":"","sources":["../../../src/components/display/StatusBadge.svelte.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAGzD,sCAAsC;AACtC,MAAM,WAAW,KAAK;IACpB,kCAAkC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,oCAAoC;IACpC,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,wDAAwD;IACxD,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,iBAAiB;IACjB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,qBAAqB;IACrB,OAAO,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC/B,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA6OD,QAAA,MAAM,WAAW,2CAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
@@ -8,7 +8,7 @@
8
8
  * offsets from `now`. Tests assert the real API from DateDisplay.svelte.
9
9
  */
10
10
  import { render, screen } from '@testing-library/svelte';
11
- import { describe, expect, it } from 'vitest';
11
+ import { afterEach, describe, expect, it, vi } from 'vitest';
12
12
  import { expectNoA11yViolations } from '../../../test-support/a11y';
13
13
  import DateDisplay from '../DateDisplay.svelte';
14
14
  const LOCALE = 'en-CA';
@@ -25,6 +25,83 @@ const LONG = {
25
25
  day: 'numeric',
26
26
  };
27
27
  describe('DateDisplay', () => {
28
+ afterEach(() => vi.useRealTimers());
29
+ it.each([
30
+ 'America/Edmonton',
31
+ 'UTC',
32
+ 'Asia/Tokyo',
33
+ ])('formats timestamp dates and times in %s', (timeZone) => {
34
+ const instant = '2026-10-01T04:00:00Z';
35
+ const { container } = render(DateDisplay, {
36
+ props: { date: instant, timeZone, showTime: true },
37
+ });
38
+ expect(container.querySelector('time')?.textContent?.trim()).toBe(expected(new Date(instant), {
39
+ ...MEDIUM,
40
+ timeZone,
41
+ hour: 'numeric',
42
+ minute: '2-digit',
43
+ }));
44
+ });
45
+ it.each([
46
+ 'America/Edmonton',
47
+ 'Asia/Tokyo',
48
+ ])('keeps a bare calendar date in %s', (timeZone) => {
49
+ const { container } = render(DateDisplay, {
50
+ props: { date: '2026-09-30', timeZone },
51
+ });
52
+ expect(container.querySelector('time')).toHaveAttribute('datetime', '2026-09-30');
53
+ expect(container.querySelector('time')?.textContent?.trim()).toBe(expected(new Date('2026-09-30T00:00:00Z'), {
54
+ ...MEDIUM,
55
+ timeZone: 'UTC',
56
+ }));
57
+ });
58
+ it('keeps date-only values stable in the default browser zone', () => {
59
+ render(DateDisplay, { props: { date: '2026-09-30' } });
60
+ expect(screen.getByText(expected(new Date('2026-09-30T00:00:00Z'), {
61
+ ...MEDIUM,
62
+ timeZone: 'UTC',
63
+ }))).toBeInTheDocument();
64
+ });
65
+ it.each([
66
+ '2026-02-30',
67
+ '2025-02-29',
68
+ '2026-13-01',
69
+ ])('rejects impossible calendar date %s', (date) => {
70
+ render(DateDisplay, { props: { date, fallback: 'Invalid date' } });
71
+ expect(screen.getByText('Invalid date')).toBeInTheDocument();
72
+ });
73
+ it('accepts a leap day', () => {
74
+ const { container } = render(DateDisplay, {
75
+ props: { date: '2028-02-29' },
76
+ });
77
+ expect(container.querySelector('time')).toHaveAttribute('datetime', '2028-02-29');
78
+ });
79
+ it.each([
80
+ ['2026-10-01T06:30:00Z', '2026-10-01T05:30:00Z', 'yesterday'],
81
+ ['2026-10-01T05:30:00Z', '2026-10-01T06:30:00Z', 'tomorrow'],
82
+ ['2026-10-01T06:30:00Z', '2026-10-01T07:30:00Z', 'today'],
83
+ ['2026-03-09T06:30:00Z', '2026-03-08T07:30:00Z', 'yesterday'],
84
+ ['2026-10-01T05:30:00Z', '2026-09-30', 'today'],
85
+ ['2026-10-01T05:30:00Z', '2026-10-01', 'tomorrow'],
86
+ ['2026-10-01T05:30:00Z', '2026-09-29', 'yesterday'],
87
+ ])('uses calendar boundaries for %s → %s', (now, date, text) => {
88
+ vi.useFakeTimers({ toFake: ['Date'] });
89
+ vi.setSystemTime(new Date(now));
90
+ render(DateDisplay, {
91
+ props: { date, format: 'relative', timeZone: 'America/Edmonton' },
92
+ });
93
+ expect(screen.getByText(text)).toBeInTheDocument();
94
+ });
95
+ it('uses the fallback for an invalid explicit zone', () => {
96
+ render(DateDisplay, {
97
+ props: {
98
+ date: '2026-09-30T00:00:00Z',
99
+ timeZone: 'not/a/zone',
100
+ fallback: 'Invalid date',
101
+ },
102
+ });
103
+ expect(screen.getByText('Invalid date')).toBeInTheDocument();
104
+ });
28
105
  // Use a fixed local-noon date so date-part is timezone-stable.
29
106
  const sample = new Date(2024, 0, 15, 12, 0, 0); // 15 Jan 2024, local noon
30
107
  it('renders a <time> element with the ISO datetime attribute', () => {
@@ -79,6 +156,10 @@ describe('DateDisplay', () => {
79
156
  const span = screen.getByText('No date');
80
157
  expect(span).toHaveClass('date-fallback');
81
158
  });
159
+ it('renders the fallback for an invalid Date instance', () => {
160
+ render(DateDisplay, { props: { date: new Date(Number.NaN) } });
161
+ expect(screen.getByText('N/A')).toBeInTheDocument();
162
+ });
82
163
  it('renders the default fallback for an invalid date string', () => {
83
164
  render(DateDisplay, { props: { date: 'not-a-date' } });
84
165
  expect(screen.getByText('N/A')).toBeInTheDocument();