@happyvertical/smrt-ui 0.53.1 → 0.53.2

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,107 +0,0 @@
1
- /**
2
- * `createFormRetry()` with smrt-ui's own `Form` (#3291, deferred on #3265).
3
- *
4
- * `Form` forwards Svelte attachments to its native `<form>` (#3265, shipped in
5
- * #3331), so the pairing is SvelteKit's `enhance` through `fromAction` with
6
- * the retry submit function, plus `retry.attach` for the hidden key field.
7
- * `enhance` is the structural fake from the form-retry tests, attached as the
8
- * real action and driven by real submit events; the action behind it records
9
- * rows the way `runOnce()` does.
10
- */
11
- import { fireEvent, render, screen } from '@testing-library/svelte';
12
- import { beforeEach, describe, expect, it, vi } from 'vitest';
13
- import { fakeEnhanceAction, fakeRunOnceServer, } from '../form-retry/__tests__/fake-kit.js';
14
- import { memoryStorage } from '../form-retry/__tests__/storage.js';
15
- import { createFormRetry } from '../form-retry/controller.js';
16
- import { resetFormRetryMemory } from '../form-retry/submission-key.js';
17
- import FormRetryFormFixture from './form-retry-form.fixture.svelte';
18
- beforeEach(() => {
19
- resetFormRetryMemory();
20
- sessionStorage.clear();
21
- });
22
- function setup() {
23
- const server = fakeRunOnceServer();
24
- const kit = fakeEnhanceAction(server);
25
- const retry = createFormRetry({ form: 'report', storage: memoryStorage() });
26
- const { container } = render(FormRetryFormFixture, {
27
- props: { enhance: kit.action, retry },
28
- });
29
- const form = container.querySelector('form');
30
- const title = screen.getByRole('textbox', { name: 'Title' });
31
- const send = async () => {
32
- await fireEvent.click(screen.getByRole('button', { name: 'Send' }));
33
- };
34
- const type = async (value) => {
35
- await fireEvent.input(title, { target: { value } });
36
- };
37
- return { server, kit, retry, form, title, send, type };
38
- }
39
- describe('createFormRetry with an enhanced smrt-ui Form', () => {
40
- it('keeps the key field inside Form and posts the key in the body', async () => {
41
- const { server, kit, retry, form, send, type } = setup();
42
- const token = retry.token;
43
- const fields = form.querySelectorAll('input[name="submissionKey"]');
44
- expect(fields).toHaveLength(1);
45
- expect(fields[0].value).toBe(token);
46
- await type('Hose');
47
- await send();
48
- await kit.settle();
49
- expect(server.requests).toHaveLength(1);
50
- expect(server.requests[0].get('submissionKey')).toBe(token);
51
- expect(server.requests[0].get('title')).toBe('Hose');
52
- });
53
- it('refuses a double submit while the first is in flight', async () => {
54
- const { server, kit, retry, send, type } = setup();
55
- await type('Hose');
56
- const held = server.hold();
57
- await send();
58
- await vi.waitFor(() => expect(retry.state.status).toBe('submitting'));
59
- await send();
60
- expect(retry.state.status).toBe('busy');
61
- held.release();
62
- await kit.settle();
63
- expect(kit.enhanced.cancelled).toBe(1);
64
- expect(server.requests).toHaveLength(1);
65
- expect(server.rows).toHaveLength(1);
66
- });
67
- it('retries a lost response under the same key, recording one row', async () => {
68
- const { server, kit, retry, title, send, type } = setup();
69
- await type('Hose');
70
- const token = retry.token;
71
- server.next('lost-response');
72
- await send();
73
- await kit.settle();
74
- expect(retry.state.status).toBe('transport-error');
75
- expect(kit.enhanced.unmounted).toBe(0);
76
- expect(title.value).toBe('Hose');
77
- await send();
78
- await kit.settle();
79
- expect(server.requests.map((body) => body.get('submissionKey'))).toEqual([
80
- token,
81
- token,
82
- ]);
83
- expect(server.rows).toHaveLength(1);
84
- });
85
- it('resets on success only when the form is unchanged', async () => {
86
- const { server, kit, retry, title, send, type } = setup();
87
- await type('First');
88
- const token = retry.token;
89
- const held = server.hold();
90
- await send();
91
- await vi.waitFor(() => expect(retry.state.status).toBe('submitting'));
92
- await type('Second');
93
- held.release();
94
- await kit.settle();
95
- expect(retry.state.status).toBe('success');
96
- expect(title.value).toBe('Second');
97
- expect(retry.token).toBe(token);
98
- await send();
99
- await kit.settle();
100
- expect(server.rows.map((row) => row.fields.title)).toEqual([
101
- ['First'],
102
- ['Second'],
103
- ]);
104
- expect(title.value).toBe('');
105
- expect(retry.token).not.toBe(token);
106
- });
107
- });
@@ -1,69 +0,0 @@
1
- /**
2
- * `createFormRetry()` around #3331's choice controls (#3291). `Listbox`,
3
- * `Combobox` and `MultiSelect` post their selection through hidden inputs, so
4
- * the "unchanged since submit" check must compare hidden inputs too — every
5
- * one except the retry helper's own key field, which rotates by design.
6
- *
7
- * A selection changed while a submit is in flight was never sent: the success
8
- * must keep it (and its key), and the next submit must post it.
9
- */
10
- import { render } from '@testing-library/svelte';
11
- import { beforeEach, describe, expect, it, vi } from 'vitest';
12
- import { fakeEnhance, fakeRunOnceServer, } from '../form-retry/__tests__/fake-kit.js';
13
- import { memoryStorage } from '../form-retry/__tests__/storage.js';
14
- import { createFormRetry } from '../form-retry/controller.js';
15
- import { resetFormRetryMemory } from '../form-retry/submission-key.js';
16
- import HiddenControlsForm from './hidden-controls-form.fixture.svelte';
17
- beforeEach(() => {
18
- resetFormRetryMemory();
19
- sessionStorage.clear();
20
- });
21
- function setup() {
22
- const view = render(HiddenControlsForm);
23
- const form = view.container.querySelector('form');
24
- const server = fakeRunOnceServer();
25
- const retry = createFormRetry({ form: 'choices', storage: memoryStorage() });
26
- retry.attach(form);
27
- const kit = fakeEnhance(form, retry.enhance(), server);
28
- const title = form.querySelector('[name=title]');
29
- title.value = 'Hose';
30
- return { ...view, form, server, retry, kit, title };
31
- }
32
- const posted = (body, name) => body.getAll(name);
33
- describe('hidden-input-backed controls under createFormRetry', () => {
34
- it.each([
35
- ['Listbox', 'listbox', 'b'],
36
- ['Combobox', 'combobox', 'b'],
37
- ['MultiSelect', 'multi', ['a', 'b']],
38
- ])('a %s change during an in-flight submit survives the success', async (_name, prop, next) => {
39
- const { form, server, retry, kit, rerender } = setup();
40
- const token = retry.token;
41
- const field = prop;
42
- const before = posted(new FormData(form), field);
43
- const held = server.hold();
44
- const first = kit.submit();
45
- await vi.waitFor(() => expect(retry.state.status).toBe('submitting'));
46
- await rerender({ [prop]: next });
47
- const changed = posted(new FormData(form), field);
48
- expect(changed).not.toEqual(before);
49
- held.release();
50
- await first;
51
- expect(retry.state.status).toBe('success');
52
- expect(kit.updates).toEqual([{ reset: false }]);
53
- expect(posted(new FormData(form), field)).toEqual(changed);
54
- expect(retry.token).toBe(token);
55
- await kit.submit();
56
- expect(posted(server.requests[0], field)).toEqual(before);
57
- expect(posted(server.requests[1], field)).toEqual(changed);
58
- expect(server.rows).toHaveLength(2);
59
- });
60
- it('still resets when only the key field changed', async () => {
61
- const { form, retry, kit, title } = setup();
62
- const token = retry.token;
63
- await kit.submit();
64
- expect(kit.updates).toEqual([{ reset: true }]);
65
- expect(title.value).toBe('');
66
- expect(retry.token).not.toBe(token);
67
- expect(form.querySelector('[name=submissionKey]').value).toBe(retry.token);
68
- });
69
- });
@@ -1,29 +0,0 @@
1
- <script lang="ts">
2
- import Combobox from '../Combobox.svelte';
3
- import Listbox from '../Listbox.svelte';
4
- import MultiSelect from '../MultiSelect.svelte';
5
-
6
- let {
7
- listbox = $bindable('a'),
8
- combobox = $bindable('a'),
9
- multi = $bindable<Array<string | number>>(['a']),
10
- }: {
11
- listbox?: string | number;
12
- combobox?: string;
13
- multi?: Array<string | number>;
14
- } = $props();
15
-
16
- const options = [
17
- { value: 'a', label: 'Alpha' },
18
- { value: 'b', label: 'Bravo' },
19
- ];
20
- </script>
21
-
22
- <!-- #3331's choice controls post through hidden inputs, not visible fields. -->
23
- <form method="POST">
24
- <input name="title" aria-label="Title" />
25
- <Listbox name="listbox" label="Listbox" bind:value={listbox} {options} interaction={false} />
26
- <Combobox name="combobox" label="Combobox" bind:value={combobox} {options} interaction={false} />
27
- <MultiSelect name="multi" label="Multi" bind:values={multi} {options} interaction={false} />
28
- <button type="submit">Send</button>
29
- </form>
@@ -1,9 +0,0 @@
1
- type $$ComponentProps = {
2
- listbox?: string | number;
3
- combobox?: string;
4
- multi?: Array<string | number>;
5
- };
6
- declare const HiddenControlsForm: import("svelte").Component<$$ComponentProps, {}, "combobox" | "listbox" | "multi">;
7
- type HiddenControlsForm = ReturnType<typeof HiddenControlsForm>;
8
- export default HiddenControlsForm;
9
- //# sourceMappingURL=hidden-controls-form.fixture.svelte.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"hidden-controls-form.fixture.svelte.d.ts","sourceRoot":"","sources":["../../../../src/components/forms/__tests__/hidden-controls-form.fixture.svelte.ts"],"names":[],"mappings":"AAOC,KAAK,gBAAgB,GAAI;IACxB,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;CAChC,CAAC;AA6BF,QAAA,MAAM,kBAAkB,oFAAwC,CAAC;AACjE,KAAK,kBAAkB,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAChE,eAAe,kBAAkB,CAAC"}
@@ -1,27 +0,0 @@
1
- <script lang="ts">
2
- import type { ControlInteractionRegistry } from '../control-interaction.js';
3
- import Form from '../Form.svelte';
4
- import Listbox from '../Listbox.svelte';
5
-
6
- interface Props {
7
- name?: string;
8
- unnamed?: boolean;
9
- value?: string | number;
10
- disabled?: boolean;
11
- fieldsetDisabled?: boolean;
12
- registry?: ControlInteractionRegistry;
13
- }
14
- let {
15
- name = 'vendor',
16
- unnamed = false,
17
- value = $bindable(),
18
- disabled = false,
19
- fieldsetDisabled = false,
20
- registry,
21
- }: Props = $props();
22
- </script>
23
- <Form formId="vendor-form" interactionRegistry={registry} aria-label="Vendor form">
24
- <fieldset disabled={fieldsetDisabled}>
25
- <Listbox name={unnamed ? undefined : name} label="Vendor" options={[{ value: 42, label: 'Plate supplier' }, { value: 'steel', label: 'Steel supplier' }, { value: 'blocked', label: 'Disabled supplier', disabled: true }]} bind:value {disabled} interaction={{ id: 'vendor' }} />
26
- </fieldset>
27
- </Form>
@@ -1,13 +0,0 @@
1
- import type { ControlInteractionRegistry } from '../control-interaction.js';
2
- interface Props {
3
- name?: string;
4
- unnamed?: boolean;
5
- value?: string | number;
6
- disabled?: boolean;
7
- fieldsetDisabled?: boolean;
8
- registry?: ControlInteractionRegistry;
9
- }
10
- declare const ListboxForm: import("svelte").Component<Props, {}, "value">;
11
- type ListboxForm = ReturnType<typeof ListboxForm>;
12
- export default ListboxForm;
13
- //# sourceMappingURL=listbox-form.fixture.svelte.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"listbox-form.fixture.svelte.d.ts","sourceRoot":"","sources":["../../../../src/components/forms/__tests__/listbox-form.fixture.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AAK5E,UAAU,KAAK;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,EAAE,0BAA0B,CAAC;CACvC;AAuBD,QAAA,MAAM,WAAW,gDAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
@@ -1,175 +0,0 @@
1
- /**
2
- * Long press vs tap vs drag: only a still, primary press held for the delay
3
- * fires; moving past the tolerance (a drag or scroll) or a native dragstart
4
- * cancels it; the click after a fired press is swallowed; the context menu is
5
- * suppressed only when opted in and only during a tracked press.
6
- */
7
- import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
8
- import { createLongPress, longPress } from '../long-press.js';
9
- function pointer(type, init = {}) {
10
- return {
11
- type,
12
- isPrimary: true,
13
- pointerId: 1,
14
- pointerType: 'touch',
15
- button: 0,
16
- clientX: 100,
17
- clientY: 100,
18
- target: document.body,
19
- ...init,
20
- };
21
- }
22
- describe('createLongPress', () => {
23
- beforeEach(() => vi.useFakeTimers());
24
- afterEach(() => vi.useRealTimers());
25
- it('fires after the delay when the pointer stays still', () => {
26
- const onLongPress = vi.fn();
27
- const press = createLongPress({ onLongPress });
28
- press.handlePointerDown(pointer('pointerdown'));
29
- vi.advanceTimersByTime(499);
30
- expect(onLongPress).not.toHaveBeenCalled();
31
- // Small wobble inside the tolerance still counts as still.
32
- press.handlePointerMove(pointer('pointermove', { clientX: 106, clientY: 104 }));
33
- vi.advanceTimersByTime(1);
34
- expect(onLongPress).toHaveBeenCalledTimes(1);
35
- expect(onLongPress.mock.calls[0][0]).toMatchObject({
36
- pointerType: 'touch',
37
- });
38
- expect(press.fired).toBe(true);
39
- });
40
- it('a quick tap never fires and reports a cancel', () => {
41
- const onLongPress = vi.fn();
42
- const onCancel = vi.fn();
43
- const press = createLongPress({ onLongPress, onCancel });
44
- press.handlePointerDown(pointer('pointerdown'));
45
- vi.advanceTimersByTime(200);
46
- press.handlePointerUp(pointer('pointerup'));
47
- vi.advanceTimersByTime(1000);
48
- expect(onLongPress).not.toHaveBeenCalled();
49
- expect(onCancel).toHaveBeenCalledTimes(1);
50
- });
51
- it('moving past the tolerance is a drag, not a long press', () => {
52
- const onLongPress = vi.fn();
53
- const press = createLongPress({ onLongPress, moveTolerance: 10 });
54
- press.handlePointerDown(pointer('pointerdown'));
55
- vi.advanceTimersByTime(300);
56
- press.handlePointerMove(pointer('pointermove', { clientX: 115 }));
57
- vi.advanceTimersByTime(1000);
58
- expect(onLongPress).not.toHaveBeenCalled();
59
- });
60
- it('a native dragstart cancels a pending press', () => {
61
- const onLongPress = vi.fn();
62
- const press = createLongPress({ onLongPress });
63
- press.handlePointerDown(pointer('pointerdown', { pointerType: 'mouse' }));
64
- press.handleDragStart();
65
- vi.advanceTimersByTime(1000);
66
- expect(onLongPress).not.toHaveBeenCalled();
67
- });
68
- it('ignores right clicks and secondary pointers', () => {
69
- const onLongPress = vi.fn();
70
- const press = createLongPress({ onLongPress });
71
- press.handlePointerDown(pointer('pointerdown', { pointerType: 'mouse', button: 2 }));
72
- press.handlePointerDown(pointer('pointerdown', { isPrimary: false }));
73
- vi.advanceTimersByTime(1000);
74
- expect(onLongPress).not.toHaveBeenCalled();
75
- });
76
- it('only counts presses the filter accepts, about the element it returns', () => {
77
- const picture = document.createElement('img');
78
- const onLongPress = vi.fn();
79
- const press = createLongPress({
80
- onLongPress,
81
- filter: (event) => (event.target === picture ? picture : null),
82
- });
83
- press.handlePointerDown(pointer('pointerdown', { target: document.body }));
84
- vi.advanceTimersByTime(600);
85
- expect(onLongPress).not.toHaveBeenCalled();
86
- press.handlePointerDown(pointer('pointerdown', { target: picture }));
87
- vi.advanceTimersByTime(600);
88
- expect(onLongPress.mock.calls[0][0].target).toBe(picture);
89
- });
90
- it('reports the release after a fired press and swallows the next click', () => {
91
- const onRelease = vi.fn();
92
- const press = createLongPress({ onLongPress: () => { }, onRelease });
93
- press.handlePointerDown(pointer('pointerdown'));
94
- vi.advanceTimersByTime(500);
95
- press.handlePointerUp(pointer('pointerup'));
96
- expect(onRelease).toHaveBeenCalledTimes(1);
97
- const click = {
98
- preventDefault: vi.fn(),
99
- stopPropagation: vi.fn(),
100
- };
101
- press.handleClick(click);
102
- expect(click.preventDefault).toHaveBeenCalled();
103
- // Only the one click right after the release.
104
- const later = {
105
- preventDefault: vi.fn(),
106
- stopPropagation: vi.fn(),
107
- };
108
- press.handleClick(later);
109
- expect(later.preventDefault).not.toHaveBeenCalled();
110
- });
111
- it('suppresses the context menu only when opted in and during a press', () => {
112
- const plain = createLongPress({ onLongPress: () => { } });
113
- const guarded = createLongPress({
114
- onLongPress: () => { },
115
- preventContextMenu: true,
116
- });
117
- const idleMenu = { preventDefault: vi.fn() };
118
- guarded.handleContextMenu(idleMenu);
119
- expect(idleMenu.preventDefault).not.toHaveBeenCalled();
120
- plain.handlePointerDown(pointer('pointerdown'));
121
- guarded.handlePointerDown(pointer('pointerdown'));
122
- vi.advanceTimersByTime(500);
123
- const plainMenu = { preventDefault: vi.fn() };
124
- const guardedMenu = { preventDefault: vi.fn() };
125
- plain.handleContextMenu(plainMenu);
126
- guarded.handleContextMenu(guardedMenu);
127
- expect(plainMenu.preventDefault).not.toHaveBeenCalled();
128
- expect(guardedMenu.preventDefault).toHaveBeenCalled();
129
- });
130
- });
131
- describe('longPress action', () => {
132
- beforeEach(() => vi.useFakeTimers());
133
- afterEach(() => vi.useRealTimers());
134
- function dispatch(target, type, init = {}) {
135
- const event = new Event(type, { bubbles: true, cancelable: true });
136
- Object.assign(event, {
137
- isPrimary: true,
138
- pointerId: 7,
139
- pointerType: 'mouse',
140
- button: 0,
141
- clientX: 10,
142
- clientY: 10,
143
- ...init,
144
- });
145
- target.dispatchEvent(event);
146
- return event;
147
- }
148
- it('wires pointer events on the node and the window, and cleans up', () => {
149
- const node = document.createElement('div');
150
- document.body.append(node);
151
- const onLongPress = vi.fn();
152
- const action = longPress(node, { onLongPress });
153
- dispatch(node, 'pointerdown');
154
- vi.advanceTimersByTime(500);
155
- expect(onLongPress).toHaveBeenCalledTimes(1);
156
- dispatch(window, 'pointerup');
157
- action.destroy();
158
- dispatch(node, 'pointerdown');
159
- vi.advanceTimersByTime(500);
160
- expect(onLongPress).toHaveBeenCalledTimes(1);
161
- node.remove();
162
- });
163
- it('a drag on the node (move past tolerance) never fires', () => {
164
- const node = document.createElement('div');
165
- document.body.append(node);
166
- const onLongPress = vi.fn();
167
- const action = longPress(node, { onLongPress });
168
- dispatch(node, 'pointerdown');
169
- dispatch(window, 'pointermove', { clientX: 40 });
170
- vi.advanceTimersByTime(800);
171
- expect(onLongPress).not.toHaveBeenCalled();
172
- action.destroy();
173
- node.remove();
174
- });
175
- });
@@ -1,27 +0,0 @@
1
- <script lang="ts">
2
- import type { ControlInteractionRegistry } from '../control-interaction.js';
3
- import Form from '../Form.svelte';
4
- import MultiSelect from '../MultiSelect.svelte';
5
-
6
- interface Props {
7
- name?: string;
8
- unnamed?: boolean;
9
- values?: Array<string | number>;
10
- disabled?: boolean;
11
- fieldsetDisabled?: boolean;
12
- registry?: ControlInteractionRegistry;
13
- }
14
- let {
15
- name = 'roles',
16
- unnamed = false,
17
- values = $bindable([]),
18
- disabled = false,
19
- fieldsetDisabled = false,
20
- registry,
21
- }: Props = $props();
22
- </script>
23
- <Form formId="roles-form" interactionRegistry={registry} aria-label="Roles form">
24
- <fieldset disabled={fieldsetDisabled}>
25
- <MultiSelect name={unnamed ? undefined : name} label="Roles" options={[{ value: 42, label: 'Operator' }, { value: 'admin', label: 'Administrator' }, { value: 'blocked', label: 'Disabled role', disabled: true }]} bind:values {disabled} interaction={{ id: 'roles' }} />
26
- </fieldset>
27
- </Form>
@@ -1,13 +0,0 @@
1
- import type { ControlInteractionRegistry } from '../control-interaction.js';
2
- interface Props {
3
- name?: string;
4
- unnamed?: boolean;
5
- values?: Array<string | number>;
6
- disabled?: boolean;
7
- fieldsetDisabled?: boolean;
8
- registry?: ControlInteractionRegistry;
9
- }
10
- declare const MultiselectForm: import("svelte").Component<Props, {}, "values">;
11
- type MultiselectForm = ReturnType<typeof MultiselectForm>;
12
- export default MultiselectForm;
13
- //# sourceMappingURL=multiselect-form.fixture.svelte.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"multiselect-form.fixture.svelte.d.ts","sourceRoot":"","sources":["../../../../src/components/forms/__tests__/multiselect-form.fixture.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AAK5E,UAAU,KAAK;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IAChC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,EAAE,0BAA0B,CAAC;CACvC;AAuBD,QAAA,MAAM,eAAe,iDAAwC,CAAC;AAC9D,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;AAC1D,eAAe,eAAe,CAAC"}
@@ -1,177 +0,0 @@
1
- /**
2
- * Native file-field posting strategies (smrt#3290).
3
- */
4
- import { afterEach, describe, expect, it, vi } from 'vitest';
5
- import { assignFileWithDataTransfer, attachFormDataFallback, attachFormResetListener, clearFileInput, detectNativeFileFieldStrategy, fileNameForType, } from '../native-file-field.js';
6
- import { submittedEntries, TestDataTransfer, TestFormDataEvent, } from './capture-test-env.js';
7
- function fileInput() {
8
- const input = document.createElement('input');
9
- input.type = 'file';
10
- return input;
11
- }
12
- const env = (overrides) => ({
13
- File,
14
- createFileInput: fileInput,
15
- ...overrides,
16
- });
17
- afterEach(() => {
18
- document.body.innerHTML = '';
19
- });
20
- describe('detectNativeFileFieldStrategy', () => {
21
- it('prefers DataTransfer when an input accepts its files', () => {
22
- expect(detectNativeFileFieldStrategy(env({
23
- DataTransfer: TestDataTransfer,
24
- FormDataEvent: TestFormDataEvent,
25
- }))).toBe('data-transfer');
26
- });
27
- it('falls back to the formdata event without DataTransfer', () => {
28
- expect(detectNativeFileFieldStrategy(env({ FormDataEvent: TestFormDataEvent }))).toBe('formdata-event');
29
- });
30
- it('falls back when the DataTransfer constructor throws (old engines)', () => {
31
- class IllegalConstructor {
32
- constructor() {
33
- throw new TypeError('Illegal constructor');
34
- }
35
- }
36
- expect(detectNativeFileFieldStrategy(env({
37
- DataTransfer: IllegalConstructor,
38
- FormDataEvent: TestFormDataEvent,
39
- }))).toBe('formdata-event');
40
- });
41
- it('falls back when the input rejects the files assignment', () => {
42
- class PlainDataTransfer {
43
- items = { add: () => null };
44
- files = [];
45
- }
46
- expect(detectNativeFileFieldStrategy(env({
47
- DataTransfer: PlainDataTransfer,
48
- FormDataEvent: TestFormDataEvent,
49
- }))).toBe('formdata-event');
50
- });
51
- it('reports none when neither API exists, and during SSR', () => {
52
- expect(detectNativeFileFieldStrategy(env({}))).toBe('none');
53
- expect(detectNativeFileFieldStrategy({})).toBe('none');
54
- });
55
- });
56
- describe('assignFileWithDataTransfer / clearFileInput', () => {
57
- it('puts the file into the input so a native submit posts it, then clears it', () => {
58
- const form = document.createElement('form');
59
- const input = fileInput();
60
- input.name = 'photo';
61
- form.append(input);
62
- const file = new File(['jpeg'], 'photo.jpg', { type: 'image/jpeg' });
63
- expect(assignFileWithDataTransfer(input, file, TestDataTransfer)).toBe(true);
64
- expect(new FormData(form).get('photo')).toBe(file);
65
- clearFileInput(input);
66
- const empty = new FormData(form).get('photo');
67
- expect(empty.name).toBe('');
68
- expect(empty.size).toBe(0);
69
- });
70
- it('returns false without a DataTransfer constructor', () => {
71
- expect(assignFileWithDataTransfer(fileInput(), new File([], 'x'), undefined)).toBe(false);
72
- });
73
- });
74
- describe('attachFormDataFallback', () => {
75
- it('appends the committed file to its own form only, until disposed', () => {
76
- const form = document.createElement('form');
77
- const other = document.createElement('form');
78
- document.body.append(form, other);
79
- const file = new File(['png'], 'signature.png', { type: 'image/png' });
80
- const dispose = attachFormDataFallback(document, () => ({
81
- form,
82
- name: 'signature',
83
- file,
84
- }));
85
- expect(submittedEntries(form).getAll('signature')).toEqual([file]);
86
- expect(submittedEntries(other).has('signature')).toBe(false);
87
- dispose();
88
- expect(submittedEntries(form).has('signature')).toBe(false);
89
- });
90
- it('posts the native empty-file entry when nothing is committed', () => {
91
- const form = document.createElement('form');
92
- document.body.append(form);
93
- attachFormDataFallback(document, () => ({
94
- form,
95
- name: 'photo',
96
- file: null,
97
- }));
98
- const entry = submittedEntries(form).get('photo');
99
- expect(entry.name).toBe('');
100
- expect(entry.size).toBe(0);
101
- expect(entry.type).toBe('application/octet-stream');
102
- });
103
- it('contributes nothing while its source input is disabled by a fieldset', () => {
104
- document.body.innerHTML =
105
- '<form><fieldset><input type="file" hidden /></fieldset></form>';
106
- const form = document.querySelector('form');
107
- const fieldset = form.querySelector('fieldset');
108
- const source = form.querySelector('input');
109
- const file = new File(['png'], 'signature.png', { type: 'image/png' });
110
- let committed = file;
111
- attachFormDataFallback(document, () => ({
112
- form,
113
- name: 'signature',
114
- file: committed,
115
- source,
116
- }));
117
- expect(submittedEntries(form).getAll('signature')).toEqual([file]);
118
- fieldset.disabled = true;
119
- // Both a committed file and the empty entry are filtered, as the browser
120
- // filters a disabled native control.
121
- expect(submittedEntries(form).has('signature')).toBe(false);
122
- committed = null;
123
- expect(submittedEntries(form).has('signature')).toBe(false);
124
- fieldset.disabled = false;
125
- expect(submittedEntries(form).get('signature').size).toBe(0);
126
- });
127
- it('contributes nothing when the entry is unavailable', () => {
128
- const form = document.createElement('form');
129
- document.body.append(form);
130
- const read = vi.fn(() => null);
131
- attachFormDataFallback(document, read);
132
- expect([...submittedEntries(form).keys()]).toEqual([]);
133
- expect(read).toHaveBeenCalled();
134
- });
135
- });
136
- describe('fileNameForType', () => {
137
- it('maps known image types and falls back to bin', () => {
138
- expect(fileNameForType('photo', 'image/jpeg')).toBe('photo.jpg');
139
- expect(fileNameForType('photo', 'image/png')).toBe('photo.png');
140
- expect(fileNameForType('photo', 'image/webp')).toBe('photo.webp');
141
- expect(fileNameForType('photo', 'image/heic')).toBe('photo.bin');
142
- });
143
- });
144
- describe('attachFormResetListener', () => {
145
- it('fires for the owning form only, read at dispatch time, until disposed', () => {
146
- document.body.innerHTML = '<form id="a"></form><form id="b"></form>';
147
- const a = document.getElementById('a');
148
- const b = document.getElementById('b');
149
- let owner = a;
150
- const onReset = vi.fn();
151
- const dispose = attachFormResetListener(document, () => owner, onReset);
152
- b.reset();
153
- expect(onReset).not.toHaveBeenCalled();
154
- a.reset();
155
- expect(onReset).toHaveBeenCalledTimes(1);
156
- owner = b;
157
- b.reset();
158
- expect(onReset).toHaveBeenCalledTimes(2);
159
- owner = null;
160
- b.reset();
161
- expect(onReset).toHaveBeenCalledTimes(2);
162
- owner = a;
163
- dispose();
164
- a.reset();
165
- expect(onReset).toHaveBeenCalledTimes(2);
166
- });
167
- it('is not hidden by a page listener that stops propagation', () => {
168
- document.body.innerHTML = '<form></form>';
169
- const form = document.querySelector('form');
170
- form.addEventListener('reset', (event) => event.stopPropagation());
171
- const onReset = vi.fn();
172
- const dispose = attachFormResetListener(document, () => form, onReset);
173
- form.reset();
174
- expect(onReset).toHaveBeenCalledTimes(1);
175
- dispose();
176
- });
177
- });