@happyvertical/smrt-ui 0.52.0 → 0.53.0

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,112 @@
1
+ /**
2
+ * What a form submitted, kept beside its submission key so a reload can put it
3
+ * back (#3291). Opt-in.
4
+ *
5
+ * The key survives a reload, and `runOnce()` derives the claim from that key
6
+ * AND a digest of what was submitted. A lost response followed by a reload
7
+ * used to keep the key but lose the form: the person re-entered it, the retry
8
+ * carried slightly different content, and a second record was written.
9
+ * Restoring the submitted values — plus any non-field state the page names
10
+ * through its `values` hook — makes the retry byte-identical, so it collapses
11
+ * onto the one record.
12
+ *
13
+ * Tablets and kiosks are shared, so:
14
+ * - `sessionStorage` only (per tab, gone when the tab closes), never
15
+ * `localStorage`;
16
+ * - a draft is restored only under the key it was submitted with AND for the
17
+ * owner it was submitted by (the page supplies a stable id for the signed-in
18
+ * person) — someone else signed in on the same tab gets a fresh form;
19
+ * - it is cleared with the key on a confirmed write, and dropped on a
20
+ * validation failure (nothing was recorded to retry);
21
+ * - it expires: a draft older than `maxAgeMs` (default one day), or failing
22
+ * the page's own `fresh()` rule, is never offered as a retry;
23
+ * - password inputs and fields the page names in `exclude` are never written
24
+ * to storage.
25
+ *
26
+ * A native file input cannot be restored from script. The draft keeps each
27
+ * chosen file's name, type and size (never its bytes) so the helper can
28
+ * report that the file must be chosen again instead of silently submitting
29
+ * without it. Re-choosing the same file reproduces the same content digest —
30
+ * `runOnce()` digests a `File` by name, type and size — so the retry is still
31
+ * the same claim.
32
+ *
33
+ * Every storage access is guarded: a browser that refuses storage simply gets
34
+ * a form that is not restored after a reload. Every clear (confirmed write,
35
+ * validation failure, discard, a draft rejected on read, an unserializable
36
+ * later attempt) leaves nothing to restore even when the store refuses to
37
+ * remove the old record: it is overwritten with a cleared marker, or — if the
38
+ * store refuses that write too — hidden in memory for the life of the page.
39
+ * Only a store that accepts no change at all can still hold the old record
40
+ * after a full reload.
41
+ *
42
+ * @module
43
+ */
44
+ import { type FormRetryStorage } from './submission-key.js';
45
+ /** A chosen file, as far as a draft can describe it. */
46
+ export interface SubmittedFileInfo {
47
+ /** The form field the file was chosen in. */
48
+ field: string;
49
+ /** The file's name. */
50
+ name: string;
51
+ /** The file's MIME type. */
52
+ type: string;
53
+ /** The file's size in bytes. */
54
+ size: number;
55
+ }
56
+ /** A submit's values, ready to put back into the form. */
57
+ export interface SubmittedDraft {
58
+ /** The key the submit carried. */
59
+ token: string;
60
+ /** When the submit was made. */
61
+ savedAt: Date;
62
+ /** Text entries in submission order, as `[name, value]`. */
63
+ fields: ReadonlyArray<readonly [string, string]>;
64
+ /** Files that were chosen and must be chosen again after a reload. */
65
+ files: readonly SubmittedFileInfo[];
66
+ /** What the page's `values.capture()` returned; untrusted until validated. */
67
+ values: unknown;
68
+ }
69
+ /** The default draft lifetime: one day. */
70
+ export declare const DEFAULT_DRAFT_MAX_AGE_MS: number;
71
+ /** Whether `value` is a file the person actually chose (not an empty input). */
72
+ export declare function isChosenFile(value: unknown): boolean;
73
+ /**
74
+ * Reduce `formData` to what a draft can hold: text entries (minus `exclude`)
75
+ * and the identity of each chosen file.
76
+ */
77
+ export declare function describeFormData(formData: FormData, exclude: ReadonlySet<string>): {
78
+ fields: Array<[string, string]>;
79
+ files: SubmittedFileInfo[];
80
+ };
81
+ /** Keep what a submit sent, for as long as its key is unresolved. */
82
+ export declare function saveSubmittedDraft(storage: FormRetryStorage | null | undefined, name: string, draft: {
83
+ token: string;
84
+ owner: string;
85
+ savedAt: Date;
86
+ fields: Array<[string, string]>;
87
+ files: SubmittedFileInfo[];
88
+ values?: unknown;
89
+ }): void;
90
+ /** Drop the stored draft. */
91
+ export declare function clearSubmittedDraft(storage: FormRetryStorage | null | undefined, name: string): void;
92
+ /**
93
+ * The draft submitted under `token` by `owner` while `fresh(savedAt)` holds,
94
+ * or `null`. Any other stored draft is stale and is removed. A draft is never
95
+ * restored for an empty owner.
96
+ */
97
+ export declare function readSubmittedDraft(storage: FormRetryStorage | null | undefined, name: string, match: {
98
+ token: string;
99
+ owner: string;
100
+ fresh: (savedAt: Date) => boolean;
101
+ }): SubmittedDraft | null;
102
+ /**
103
+ * Put a draft's text values back into `form`'s controls, by name and in
104
+ * document order. A checkbox or radio is checked exactly when its `value` was
105
+ * submitted under its name (so one submitted unchecked is unchecked again); a
106
+ * multi-select selects exactly the submitted options; repeated text controls
107
+ * of one name take the submitted values in order. Hidden, file and password
108
+ * inputs, and names in `exclude`, are left alone. Each changed control
109
+ * receives `input` and `change` events so framework bindings pick it up.
110
+ */
111
+ export declare function applyDraftToForm(form: HTMLFormElement, draft: Pick<SubmittedDraft, 'fields'>, exclude?: ReadonlySet<string>): void;
112
+ //# sourceMappingURL=submitted-draft.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"submitted-draft.d.ts","sourceRoot":"","sources":["../../../../src/components/forms/form-retry/submitted-draft.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAEH,OAAO,EACL,KAAK,gBAAgB,EAItB,MAAM,qBAAqB,CAAC;AAE7B,wDAAwD;AACxD,MAAM,WAAW,iBAAiB;IAChC,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,uBAAuB;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,0DAA0D;AAC1D,MAAM,WAAW,cAAc;IAC7B,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,gCAAgC;IAChC,OAAO,EAAE,IAAI,CAAC;IACd,4DAA4D;IAC5D,MAAM,EAAE,aAAa,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACjD,sEAAsE;IACtE,KAAK,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACpC,8EAA8E;IAC9E,MAAM,EAAE,OAAO,CAAC;CACjB;AAYD,2CAA2C;AAC3C,eAAO,MAAM,wBAAwB,QAAsB,CAAC;AAM5D,gFAAgF;AAChF,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEpD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,GAC3B;IAAE,MAAM,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAAC,KAAK,EAAE,iBAAiB,EAAE,CAAA;CAAE,CAiBjE;AAED,qEAAqE;AACrE,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,gBAAgB,GAAG,IAAI,GAAG,SAAS,EAC5C,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE;IACL,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,IAAI,CAAC;IACd,MAAM,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAChC,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAC3B,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,GACA,IAAI,CAqBN;AAED,6BAA6B;AAC7B,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,gBAAgB,GAAG,IAAI,GAAG,SAAS,EAC5C,IAAI,EAAE,MAAM,GACX,IAAI,CAEN;AAyCD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,gBAAgB,GAAG,IAAI,GAAG,SAAS,EAC5C,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE;IACL,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,CAAC,OAAO,EAAE,IAAI,KAAK,OAAO,CAAC;CACnC,GACA,cAAc,GAAG,IAAI,CAkCvB;AA4CD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,eAAe,EACrB,KAAK,EAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC,EACrC,OAAO,GAAE,WAAW,CAAC,MAAM,CAAa,GACvC,IAAI,CA6CN"}
@@ -0,0 +1,270 @@
1
+ /**
2
+ * What a form submitted, kept beside its submission key so a reload can put it
3
+ * back (#3291). Opt-in.
4
+ *
5
+ * The key survives a reload, and `runOnce()` derives the claim from that key
6
+ * AND a digest of what was submitted. A lost response followed by a reload
7
+ * used to keep the key but lose the form: the person re-entered it, the retry
8
+ * carried slightly different content, and a second record was written.
9
+ * Restoring the submitted values — plus any non-field state the page names
10
+ * through its `values` hook — makes the retry byte-identical, so it collapses
11
+ * onto the one record.
12
+ *
13
+ * Tablets and kiosks are shared, so:
14
+ * - `sessionStorage` only (per tab, gone when the tab closes), never
15
+ * `localStorage`;
16
+ * - a draft is restored only under the key it was submitted with AND for the
17
+ * owner it was submitted by (the page supplies a stable id for the signed-in
18
+ * person) — someone else signed in on the same tab gets a fresh form;
19
+ * - it is cleared with the key on a confirmed write, and dropped on a
20
+ * validation failure (nothing was recorded to retry);
21
+ * - it expires: a draft older than `maxAgeMs` (default one day), or failing
22
+ * the page's own `fresh()` rule, is never offered as a retry;
23
+ * - password inputs and fields the page names in `exclude` are never written
24
+ * to storage.
25
+ *
26
+ * A native file input cannot be restored from script. The draft keeps each
27
+ * chosen file's name, type and size (never its bytes) so the helper can
28
+ * report that the file must be chosen again instead of silently submitting
29
+ * without it. Re-choosing the same file reproduces the same content digest —
30
+ * `runOnce()` digests a `File` by name, type and size — so the retry is still
31
+ * the same claim.
32
+ *
33
+ * Every storage access is guarded: a browser that refuses storage simply gets
34
+ * a form that is not restored after a reload. Every clear (confirmed write,
35
+ * validation failure, discard, a draft rejected on read, an unserializable
36
+ * later attempt) leaves nothing to restore even when the store refuses to
37
+ * remove the old record: it is overwritten with a cleared marker, or — if the
38
+ * store refuses that write too — hidden in memory for the life of the page.
39
+ * Only a store that accepts no change at all can still hold the old record
40
+ * after a full reload.
41
+ *
42
+ * @module
43
+ */
44
+ import { guardedGet, guardedRemove, guardedSet, } from './submission-key.js';
45
+ /** The default draft lifetime: one day. */
46
+ export const DEFAULT_DRAFT_MAX_AGE_MS = 24 * 60 * 60 * 1000;
47
+ function isFile(value) {
48
+ return typeof File !== 'undefined' && value instanceof File;
49
+ }
50
+ /** Whether `value` is a file the person actually chose (not an empty input). */
51
+ export function isChosenFile(value) {
52
+ return isFile(value) && (value.size > 0 || value.name !== '');
53
+ }
54
+ /**
55
+ * Reduce `formData` to what a draft can hold: text entries (minus `exclude`)
56
+ * and the identity of each chosen file.
57
+ */
58
+ export function describeFormData(formData, exclude) {
59
+ const fields = [];
60
+ const files = [];
61
+ formData.forEach((value, name) => {
62
+ if (exclude.has(name))
63
+ return;
64
+ if (typeof value === 'string') {
65
+ fields.push([name, value]);
66
+ }
67
+ else if (isChosenFile(value)) {
68
+ files.push({
69
+ field: name,
70
+ name: value.name,
71
+ type: value.type,
72
+ size: value.size,
73
+ });
74
+ }
75
+ });
76
+ return { fields, files };
77
+ }
78
+ /** Keep what a submit sent, for as long as its key is unresolved. */
79
+ export function saveSubmittedDraft(storage, name, draft) {
80
+ const stored = {
81
+ v: 1,
82
+ token: draft.token,
83
+ owner: draft.owner,
84
+ savedAt: draft.savedAt.getTime(),
85
+ fields: draft.fields,
86
+ files: draft.files,
87
+ ...(draft.values === undefined ? {} : { values: draft.values }),
88
+ };
89
+ let serialized;
90
+ try {
91
+ serialized = JSON.stringify(stored);
92
+ }
93
+ catch {
94
+ // A `values.capture()` result with no JSON form: nothing to restore. An
95
+ // earlier attempt's draft may be stored under the same (unrotated) key,
96
+ // and it no longer describes what was sent, so it must not be restored.
97
+ clearSubmittedDraft(storage, name);
98
+ return;
99
+ }
100
+ guardedSet(storage, name, serialized);
101
+ }
102
+ /** Drop the stored draft. */
103
+ export function clearSubmittedDraft(storage, name) {
104
+ guardedRemove(storage, name);
105
+ }
106
+ const isString = (value) => typeof value === 'string';
107
+ function parseFields(value) {
108
+ if (!Array.isArray(value))
109
+ return null;
110
+ const fields = [];
111
+ for (const entry of value) {
112
+ if (!Array.isArray(entry) ||
113
+ entry.length !== 2 ||
114
+ !isString(entry[0]) ||
115
+ !isString(entry[1])) {
116
+ return null;
117
+ }
118
+ fields.push([entry[0], entry[1]]);
119
+ }
120
+ return fields;
121
+ }
122
+ function parseFiles(value) {
123
+ if (!Array.isArray(value))
124
+ return null;
125
+ const files = [];
126
+ for (const entry of value) {
127
+ if (typeof entry !== 'object' || entry === null)
128
+ return null;
129
+ const { field, name, type, size } = entry;
130
+ if (!isString(field) ||
131
+ !isString(name) ||
132
+ !isString(type) ||
133
+ typeof size !== 'number' ||
134
+ !Number.isFinite(size)) {
135
+ return null;
136
+ }
137
+ files.push({ field, name, type, size });
138
+ }
139
+ return files;
140
+ }
141
+ /**
142
+ * The draft submitted under `token` by `owner` while `fresh(savedAt)` holds,
143
+ * or `null`. Any other stored draft is stale and is removed. A draft is never
144
+ * restored for an empty owner.
145
+ */
146
+ export function readSubmittedDraft(storage, name, match) {
147
+ const raw = guardedGet(storage, name);
148
+ if (!raw)
149
+ return null;
150
+ let stored;
151
+ try {
152
+ stored = JSON.parse(raw);
153
+ }
154
+ catch {
155
+ stored = null;
156
+ }
157
+ const fields = stored ? parseFields(stored.fields) : null;
158
+ const files = stored ? parseFiles(stored.files) : null;
159
+ const valid = stored !== null &&
160
+ typeof stored === 'object' &&
161
+ stored.v === 1 &&
162
+ stored.token === match.token &&
163
+ match.owner !== '' &&
164
+ stored.owner === match.owner &&
165
+ typeof stored.savedAt === 'number' &&
166
+ Number.isFinite(stored.savedAt) &&
167
+ fields !== null &&
168
+ files !== null &&
169
+ match.fresh(new Date(stored.savedAt));
170
+ if (!valid || !stored || !fields || !files) {
171
+ clearSubmittedDraft(storage, name);
172
+ return null;
173
+ }
174
+ return {
175
+ token: match.token,
176
+ savedAt: new Date(stored.savedAt),
177
+ fields,
178
+ files,
179
+ values: stored.values,
180
+ };
181
+ }
182
+ function isRestorableControl(element) {
183
+ if (!(element instanceof HTMLInputElement) &&
184
+ !(element instanceof HTMLTextAreaElement) &&
185
+ !(element instanceof HTMLSelectElement)) {
186
+ return false;
187
+ }
188
+ if (!element.name || element.disabled)
189
+ return false;
190
+ if (element instanceof HTMLInputElement) {
191
+ const type = element.type;
192
+ // Hidden fields are page-controlled (render their source state through
193
+ // the `values` hook); buttons are not values; files cannot be set;
194
+ // passwords are never stored.
195
+ if (type === 'hidden' ||
196
+ type === 'submit' ||
197
+ type === 'button' ||
198
+ type === 'reset' ||
199
+ type === 'image' ||
200
+ type === 'file' ||
201
+ type === 'password') {
202
+ return false;
203
+ }
204
+ }
205
+ return true;
206
+ }
207
+ function notify(control) {
208
+ // Svelte's `bind:value` / `bind:checked` / `bind:group` listen for these, so
209
+ // bound state follows the restored DOM value.
210
+ control.dispatchEvent(new Event('input', { bubbles: true }));
211
+ control.dispatchEvent(new Event('change', { bubbles: true }));
212
+ }
213
+ /**
214
+ * Put a draft's text values back into `form`'s controls, by name and in
215
+ * document order. A checkbox or radio is checked exactly when its `value` was
216
+ * submitted under its name (so one submitted unchecked is unchecked again); a
217
+ * multi-select selects exactly the submitted options; repeated text controls
218
+ * of one name take the submitted values in order. Hidden, file and password
219
+ * inputs, and names in `exclude`, are left alone. Each changed control
220
+ * receives `input` and `change` events so framework bindings pick it up.
221
+ */
222
+ export function applyDraftToForm(form, draft, exclude = new Set()) {
223
+ const byName = new Map();
224
+ for (const [name, value] of draft.fields) {
225
+ const values = byName.get(name);
226
+ if (values)
227
+ values.push(value);
228
+ else
229
+ byName.set(name, [value]);
230
+ }
231
+ const consumed = new Map();
232
+ for (const element of Array.from(form.elements)) {
233
+ if (!isRestorableControl(element) || exclude.has(element.name))
234
+ continue;
235
+ const values = byName.get(element.name) ?? [];
236
+ if (element instanceof HTMLInputElement &&
237
+ (element.type === 'checkbox' || element.type === 'radio')) {
238
+ const checked = values.includes(element.value);
239
+ if (element.checked !== checked) {
240
+ element.checked = checked;
241
+ notify(element);
242
+ }
243
+ continue;
244
+ }
245
+ if (element instanceof HTMLSelectElement && element.multiple) {
246
+ let changed = false;
247
+ for (const option of Array.from(element.options)) {
248
+ const selected = values.includes(option.value);
249
+ if (option.selected !== selected) {
250
+ option.selected = selected;
251
+ changed = true;
252
+ }
253
+ }
254
+ if (changed)
255
+ notify(element);
256
+ continue;
257
+ }
258
+ // A single-value control takes the next submitted value of its name. One
259
+ // with no submitted value left (it did not take part in the submit) is
260
+ // left as rendered.
261
+ const index = consumed.get(element.name) ?? 0;
262
+ if (index >= values.length)
263
+ continue;
264
+ consumed.set(element.name, index + 1);
265
+ if (element.value !== values[index]) {
266
+ element.value = values[index];
267
+ notify(element);
268
+ }
269
+ }
270
+ }
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Structural types for SvelteKit's `use:enhance` contract (#3291).
3
+ *
4
+ * smrt-ui is the dependency leaf of the Svelte stack and must not depend on
5
+ * `@sveltejs/kit`, so the form-retry helper describes the `SubmitFunction`
6
+ * shape it relies on instead of importing it. The shapes below mirror
7
+ * `SubmitFunction` / `ActionResult` from `@sveltejs/kit` 2.x field for field,
8
+ * narrowed only where the helper needs less: a function of type
9
+ * {@link FormRetrySubmitFunction} is assignable to kit's `SubmitFunction`, so
10
+ * `<form method="POST" use:enhance={retry.enhance()}>` type-checks in any
11
+ * SvelteKit app without smrt-ui knowing about kit.
12
+ */
13
+ /** A value or a promise of it. */
14
+ export type MaybePromise<T> = T | Promise<T>;
15
+ /**
16
+ * The result of a SvelteKit form action, as `enhance` reports it.
17
+ *
18
+ * - `success`: the action returned normally — a write it vouches for.
19
+ * - `failure`: the action returned `fail(...)` — validation; nothing written.
20
+ * - `redirect`: the action redirected; whether it wrote is the app's to say
21
+ * (see `redirectConfirmsWrite`).
22
+ * - `error`: the request never produced an action result — the network
23
+ * dropped, the server threw, or the response was lost.
24
+ */
25
+ export type FormRetryActionResult = {
26
+ type: 'success';
27
+ status: number;
28
+ data?: unknown;
29
+ } | {
30
+ type: 'failure';
31
+ status: number;
32
+ data?: unknown;
33
+ } | {
34
+ type: 'redirect';
35
+ status: number;
36
+ location: string;
37
+ } | {
38
+ type: 'error';
39
+ status?: number;
40
+ error: unknown;
41
+ };
42
+ /** What `enhance` passes to a submit function before it sends anything. */
43
+ export interface FormRetrySubmitInput {
44
+ /** The URL the form posts to. */
45
+ action: URL;
46
+ /** The body about to be sent; mutations here are what the server receives. */
47
+ formData: FormData;
48
+ /** The `<form>` element being submitted. */
49
+ formElement: HTMLFormElement;
50
+ /** Aborting it abandons the request without a result. */
51
+ controller: AbortController;
52
+ /** The button that submitted the form, if any. */
53
+ submitter: HTMLElement | null;
54
+ /** Prevent the submission; nothing is sent. */
55
+ cancel: () => void;
56
+ }
57
+ /** Options accepted by `enhance`'s default result handler. */
58
+ export interface FormRetryUpdateOptions {
59
+ /** `false` keeps the form's values after a successful submission. */
60
+ reset?: boolean;
61
+ /** `false` skips `invalidateAll()` after a successful submission. */
62
+ invalidateAll?: boolean;
63
+ }
64
+ /** What `enhance` passes to the result callback once a result arrives. */
65
+ export interface FormRetryResultInput {
66
+ /** The body that was sent. */
67
+ formData: FormData;
68
+ /** The `<form>` element that was submitted. */
69
+ formElement: HTMLFormElement;
70
+ /** The URL the form posted to. */
71
+ action: URL;
72
+ /** The action's result. */
73
+ result: FormRetryActionResult;
74
+ /** `enhance`'s default handling: reset on success, invalidate, apply. */
75
+ update: (options?: FormRetryUpdateOptions) => Promise<void>;
76
+ }
77
+ /** The callback a submit function may return to handle the result. */
78
+ export type FormRetryResultCallback = (input: FormRetryResultInput) => MaybePromise<void>;
79
+ /**
80
+ * A submit function in SvelteKit's `SubmitFunction` shape: what
81
+ * `use:enhance={...}` accepts.
82
+ */
83
+ export type FormRetrySubmitFunction = (input: FormRetrySubmitInput) => MaybePromise<void | FormRetryResultCallback>;
84
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/components/forms/form-retry/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,kCAAkC;AAClC,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;AAE7C;;;;;;;;;GASG;AACH,MAAM,MAAM,qBAAqB,GAC7B;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GACnD;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GACnD;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACtD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC;AAEvD,2EAA2E;AAC3E,MAAM,WAAW,oBAAoB;IACnC,iCAAiC;IACjC,MAAM,EAAE,GAAG,CAAC;IACZ,8EAA8E;IAC9E,QAAQ,EAAE,QAAQ,CAAC;IACnB,4CAA4C;IAC5C,WAAW,EAAE,eAAe,CAAC;IAC7B,yDAAyD;IACzD,UAAU,EAAE,eAAe,CAAC;IAC5B,kDAAkD;IAClD,SAAS,EAAE,WAAW,GAAG,IAAI,CAAC;IAC9B,+CAA+C;IAC/C,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAED,8DAA8D;AAC9D,MAAM,WAAW,sBAAsB;IACrC,qEAAqE;IACrE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,qEAAqE;IACrE,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,0EAA0E;AAC1E,MAAM,WAAW,oBAAoB;IACnC,8BAA8B;IAC9B,QAAQ,EAAE,QAAQ,CAAC;IACnB,+CAA+C;IAC/C,WAAW,EAAE,eAAe,CAAC;IAC7B,kCAAkC;IAClC,MAAM,EAAE,GAAG,CAAC;IACZ,2BAA2B;IAC3B,MAAM,EAAE,qBAAqB,CAAC;IAC9B,yEAAyE;IACzE,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,sBAAsB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7D;AAED,sEAAsE;AACtE,MAAM,MAAM,uBAAuB,GAAG,CACpC,KAAK,EAAE,oBAAoB,KACxB,YAAY,CAAC,IAAI,CAAC,CAAC;AAExB;;;GAGG;AACH,MAAM,MAAM,uBAAuB,GAAG,CACpC,KAAK,EAAE,oBAAoB,KAExB,YAAY,CAAC,IAAI,GAAG,uBAAuB,CAAC,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Structural types for SvelteKit's `use:enhance` contract (#3291).
3
+ *
4
+ * smrt-ui is the dependency leaf of the Svelte stack and must not depend on
5
+ * `@sveltejs/kit`, so the form-retry helper describes the `SubmitFunction`
6
+ * shape it relies on instead of importing it. The shapes below mirror
7
+ * `SubmitFunction` / `ActionResult` from `@sveltejs/kit` 2.x field for field,
8
+ * narrowed only where the helper needs less: a function of type
9
+ * {@link FormRetrySubmitFunction} is assignable to kit's `SubmitFunction`, so
10
+ * `<form method="POST" use:enhance={retry.enhance()}>` type-checks in any
11
+ * SvelteKit app without smrt-ui knowing about kit.
12
+ */
13
+ export {};
@@ -12,8 +12,10 @@
12
12
  * `MoneyInput`, the rich `Form`, …) stay in `@happyvertical/smrt-svelte/forms`.
13
13
  */
14
14
  export { canCaptureDictationAudio, createMediaRecorderCapture, DICTATION_AUDIO_MIME_TYPES, DICTATION_MAX_BYTES, DICTATION_MAX_DURATION_MS, type DictationAudioCapture, type DictationAudioCaptureFactory, type DictationAudioCaptureOptions, DictationError, type DictationRecording, pickDictationMimeType, } from './audio-capture.js';
15
+ export { default as CameraCapture } from './CameraCapture.svelte';
15
16
  export { default as Checkbox } from './Checkbox.svelte';
16
17
  export { default as Combobox } from './Combobox.svelte';
18
+ export { type CameraCaptureErrorKind, type CameraFacingMode, type CameraSession, type CameraSessionDeps, type CameraSessionResult, classifyGetUserMediaError, createCameraSession, isCameraApiSupported, type MediaDevicesLike, } from './camera-capture-session.js';
17
19
  export { emitControlChange, focusControl, highlightControl, revealControl, } from './control-dom.js';
18
20
  export { type ControlBatchResult, type ControlCapability, type ControlCommand, type ControlCommandAction, type ControlCommandContext, type ControlCommandResult, type ControlCommandSource, type ControlConstraints, type ControlExtensionContext, type ControlIdentity, type ControlInteractionEvent, type ControlInteractionOptions, type ControlInteractionPolicy, type ControlInteractionRegistry, type ControlKind, type ControlMetadata, type ControlOption, type ControlRegistration, type ControlRuntimeState, type ControlSensitivity, type ControlSnapshot, type ControlStagedEntry, type ControlStagedProvenance, type ControlSubject, type ControlValueValidationResult, createControlInteractionRegistry, executeLocalControlBatch, executeLocalControlCommand, } from './control-interaction.js';
19
21
  export { type ControlInteractionContextValue, getControlInteractionContext, recordControlUserEdit, setControlInteractionContext, tryGetControlInteractionContext, } from './control-interaction-context.js';
@@ -30,12 +32,14 @@ export { default as Form } from './Form.svelte';
30
32
  export { default as FormActionBar } from './FormActionBar.svelte';
31
33
  export { default as Field, default as FormGroup } from './FormGroup.svelte';
32
34
  export { type FormGroupContextValue, nextFieldId, setFormGroupContext, tryGetFormGroupContext, } from './form-group-context.js';
35
+ export * from './form-retry/index.js';
33
36
  export { default as Input } from './Input.svelte';
34
37
  export { default as InputGroup } from './InputGroup.svelte';
35
38
  export { insertTextAtCursor } from './insert-text.js';
36
39
  export { default as Listbox } from './Listbox.svelte';
37
40
  export { createLongPress, LONG_PRESS_DEFAULT_DELAY_MS, LONG_PRESS_DEFAULT_MOVE_TOLERANCE_PX, type LongPressController, type LongPressDetail, type LongPressOptions, longPress, } from './long-press.js';
38
41
  export { default as MultiSelect } from './MultiSelect.svelte';
42
+ export { detectNativeFileFieldStrategy, type NativeFileFieldStrategy, } from './native-file-field.js';
39
43
  export { default as Radio } from './Radio.svelte';
40
44
  export { default as RadioGroup } from './RadioGroup.svelte';
41
45
  export { default as RangeSlider } from './RangeSlider.svelte';
@@ -43,15 +47,17 @@ export { playReadyBeep, primeReadyBeep, type ReadyBeepOptions, } from './ready-b
43
47
  export { default as SearchInput } from './SearchInput.svelte';
44
48
  export { default as SegmentedControl } from './SegmentedControl.svelte';
45
49
  export { default as Select } from './Select.svelte';
50
+ export { default as SignaturePad } from './SignaturePad.svelte';
46
51
  export { default as Slider } from './Slider.svelte';
47
52
  export { default as StagedControlReview } from './StagedControlReview.svelte';
48
53
  export { default as Switch } from './Switch.svelte';
54
+ export { isAcceptedPointerType, mapPointerToCanvasPoint, type SignaturePointerType, } from './signature-pad-logic.js';
49
55
  export type { StagedControlReviewLabels } from './staged-control-review.js';
50
56
  export { default as TagsInput } from './TagsInput.svelte';
51
57
  export { default as Textarea } from './Textarea.svelte';
52
58
  export { default as TimePicker } from './TimePicker.svelte';
53
59
  export { default as Toggle } from './Toggle.svelte';
54
60
  export { default as ToggleButton } from './ToggleButton.svelte';
55
- export type { FormError, RangeSliderValue, SegmentedControlOption, } from './types.js';
61
+ export type { CameraCaptureLabels, CameraCaptureState, CaptureResult, FormError, RangeSliderValue, SegmentedControlOption, SignaturePadLabels, SignaturePadState, } from './types.js';
56
62
  export { type ControlRegistrationDescriptor, useControlRegistration, } from './use-control-registration.svelte.js';
57
63
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/forms/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/forms/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EACL,wBAAwB,EACxB,0BAA0B,EAC1B,0BAA0B,EAC1B,mBAAmB,EACnB,yBAAyB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,4BAA4B,EACjC,KAAK,4BAA4B,EACjC,cAAc,EACd,KAAK,kBAAkB,EACvB,qBAAqB,GACtB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EACL,KAAK,sBAAsB,EAC3B,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,yBAAyB,EACzB,mBAAmB,EACnB,oBAAoB,EACpB,KAAK,gBAAgB,GACtB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,gBAAgB,EAChB,aAAa,GACd,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,EAC5B,KAAK,eAAe,EACpB,KAAK,uBAAuB,EAC5B,KAAK,yBAAyB,EAC9B,KAAK,wBAAwB,EAC7B,KAAK,0BAA0B,EAC/B,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,EAC5B,KAAK,cAAc,EACnB,KAAK,4BAA4B,EACjC,gCAAgC,EAChC,wBAAwB,EACxB,0BAA0B,GAC3B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,KAAK,8BAA8B,EACnC,4BAA4B,EAC5B,qBAAqB,EACrB,4BAA4B,EAC5B,+BAA+B,GAChC,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,KAAK,sBAAsB,EAC3B,0BAA0B,EAC1B,yBAAyB,EACzB,qBAAqB,EACrB,uBAAuB,EACvB,mBAAmB,EACnB,kBAAkB,EAClB,KAAK,2BAA2B,EAChC,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EACL,sBAAsB,EACtB,SAAS,EACT,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC1B,KAAK,cAAc,EACnB,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,qBAAqB,EACrB,KAAK,mBAAmB,EACxB,KAAK,0BAA0B,EAC/B,KAAK,sBAAsB,GAC5B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EACL,KAAK,qBAAqB,EAC1B,WAAW,EACX,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,yBAAyB,CAAC;AAEjC,cAAc,uBAAuB,CAAC;AACtC,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EACL,eAAe,EACf,2BAA2B,EAC3B,oCAAoC,EACpC,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,SAAS,GACV,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EACL,6BAA6B,EAC7B,KAAK,uBAAuB,GAC7B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EACL,aAAa,EACb,cAAc,EACd,KAAK,gBAAgB,GACtB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EACL,qBAAqB,EACrB,uBAAuB,EACvB,KAAK,oBAAoB,GAC1B,MAAM,0BAA0B,CAAC;AAClC,YAAY,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AAC5E,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAChE,YAAY,EACV,mBAAmB,EACnB,kBAAkB,EAClB,aAAa,EACb,SAAS,EACT,gBAAgB,EAChB,sBAAsB,EACtB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,KAAK,6BAA6B,EAClC,sBAAsB,GACvB,MAAM,sCAAsC,CAAC"}
@@ -12,8 +12,11 @@
12
12
  * `MoneyInput`, the rich `Form`, …) stay in `@happyvertical/smrt-svelte/forms`.
13
13
  */
14
14
  export { canCaptureDictationAudio, createMediaRecorderCapture, DICTATION_AUDIO_MIME_TYPES, DICTATION_MAX_BYTES, DICTATION_MAX_DURATION_MS, DictationError, pickDictationMimeType, } from './audio-capture.js';
15
+ // Camera and signature capture (smrt#3290).
16
+ export { default as CameraCapture } from './CameraCapture.svelte';
15
17
  export { default as Checkbox } from './Checkbox.svelte';
16
18
  export { default as Combobox } from './Combobox.svelte';
19
+ export { classifyGetUserMediaError, createCameraSession, isCameraApiSupported, } from './camera-capture-session.js';
17
20
  export { emitControlChange, focusControl, highlightControl, revealControl, } from './control-dom.js';
18
21
  export { createControlInteractionRegistry, executeLocalControlBatch, executeLocalControlCommand, } from './control-interaction.js';
19
22
  export { getControlInteractionContext, recordControlUserEdit, setControlInteractionContext, tryGetControlInteractionContext, } from './control-interaction-context.js';
@@ -30,12 +33,15 @@ export { default as Form } from './Form.svelte';
30
33
  export { default as FormActionBar } from './FormActionBar.svelte';
31
34
  export { default as Field, default as FormGroup } from './FormGroup.svelte';
32
35
  export { nextFieldId, setFormGroupContext, tryGetFormGroupContext, } from './form-group-context.js';
36
+ // Form retry (#3291): also published Svelte-free at `@happyvertical/smrt-ui/form-retry`.
37
+ export * from './form-retry/index.js';
33
38
  export { default as Input } from './Input.svelte';
34
39
  export { default as InputGroup } from './InputGroup.svelte';
35
40
  export { insertTextAtCursor } from './insert-text.js';
36
41
  export { default as Listbox } from './Listbox.svelte';
37
42
  export { createLongPress, LONG_PRESS_DEFAULT_DELAY_MS, LONG_PRESS_DEFAULT_MOVE_TOLERANCE_PX, longPress, } from './long-press.js';
38
43
  export { default as MultiSelect } from './MultiSelect.svelte';
44
+ export { detectNativeFileFieldStrategy, } from './native-file-field.js';
39
45
  export { default as Radio } from './Radio.svelte';
40
46
  export { default as RadioGroup } from './RadioGroup.svelte';
41
47
  export { default as RangeSlider } from './RangeSlider.svelte';
@@ -43,9 +49,11 @@ export { playReadyBeep, primeReadyBeep, } from './ready-beep.js';
43
49
  export { default as SearchInput } from './SearchInput.svelte';
44
50
  export { default as SegmentedControl } from './SegmentedControl.svelte';
45
51
  export { default as Select } from './Select.svelte';
52
+ export { default as SignaturePad } from './SignaturePad.svelte';
46
53
  export { default as Slider } from './Slider.svelte';
47
54
  export { default as StagedControlReview } from './StagedControlReview.svelte';
48
55
  export { default as Switch } from './Switch.svelte';
56
+ export { isAcceptedPointerType, mapPointerToCanvasPoint, } from './signature-pad-logic.js';
49
57
  export { default as TagsInput } from './TagsInput.svelte';
50
58
  export { default as Textarea } from './Textarea.svelte';
51
59
  export { default as TimePicker } from './TimePicker.svelte';