@fieldia/widgets 0.9.1 → 0.10.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 (211) hide show
  1. package/package.json +2 -2
  2. package/src/index.d.mts +2 -0
  3. package/src/index.d.ts +2 -0
  4. package/src/index.js +4 -0
  5. package/src/index.js.map +1 -1
  6. package/src/index.mjs +2 -0
  7. package/src/index.mjs.map +1 -1
  8. package/src/lib/address.d.mts +4 -0
  9. package/src/lib/address.d.ts +4 -0
  10. package/src/lib/address.js +105 -0
  11. package/src/lib/address.js.map +1 -0
  12. package/src/lib/address.mjs +100 -0
  13. package/src/lib/address.mjs.map +1 -0
  14. package/src/lib/cards.d.mts +2 -0
  15. package/src/lib/cards.d.ts +2 -0
  16. package/src/lib/cards.js +152 -0
  17. package/src/lib/cards.js.map +1 -0
  18. package/src/lib/cards.mjs +148 -0
  19. package/src/lib/cards.mjs.map +1 -0
  20. package/src/lib/choice-images.d.mts +2 -0
  21. package/src/lib/choice-images.d.ts +2 -0
  22. package/src/lib/choice-images.js +99 -0
  23. package/src/lib/choice-images.js.map +1 -0
  24. package/src/lib/choice-images.mjs +95 -0
  25. package/src/lib/choice-images.mjs.map +1 -0
  26. package/src/lib/choice-rules.d.mts +22 -0
  27. package/src/lib/choice-rules.d.ts +22 -0
  28. package/src/lib/choice-rules.js +46 -0
  29. package/src/lib/choice-rules.js.map +1 -0
  30. package/src/lib/choice-rules.mjs +41 -0
  31. package/src/lib/choice-rules.mjs.map +1 -0
  32. package/src/lib/choice-tags.d.mts +17 -0
  33. package/src/lib/choice-tags.d.ts +17 -0
  34. package/src/lib/choice-tags.js +187 -0
  35. package/src/lib/choice-tags.js.map +1 -0
  36. package/src/lib/choice-tags.mjs +182 -0
  37. package/src/lib/choice-tags.mjs.map +1 -0
  38. package/src/lib/choices-from.d.mts +8 -0
  39. package/src/lib/choices-from.d.ts +8 -0
  40. package/src/lib/choices-from.js +63 -0
  41. package/src/lib/choices-from.js.map +1 -0
  42. package/src/lib/choices-from.mjs +60 -0
  43. package/src/lib/choices-from.mjs.map +1 -0
  44. package/src/lib/display.js +4 -3
  45. package/src/lib/display.js.map +1 -1
  46. package/src/lib/display.mjs +5 -4
  47. package/src/lib/display.mjs.map +1 -1
  48. package/src/lib/extras.js +8 -4
  49. package/src/lib/extras.js.map +1 -1
  50. package/src/lib/extras.mjs +8 -4
  51. package/src/lib/extras.mjs.map +1 -1
  52. package/src/lib/files.d.mts +2 -0
  53. package/src/lib/files.d.ts +2 -0
  54. package/src/lib/files.js +180 -80
  55. package/src/lib/files.js.map +1 -1
  56. package/src/lib/files.mjs +179 -80
  57. package/src/lib/files.mjs.map +1 -1
  58. package/src/lib/focus-trap.d.mts +7 -0
  59. package/src/lib/focus-trap.d.ts +7 -0
  60. package/src/lib/focus-trap.js +26 -0
  61. package/src/lib/focus-trap.js.map +1 -0
  62. package/src/lib/focus-trap.mjs +23 -0
  63. package/src/lib/focus-trap.mjs.map +1 -0
  64. package/src/lib/icons.js +1 -0
  65. package/src/lib/icons.js.map +1 -1
  66. package/src/lib/icons.mjs +1 -0
  67. package/src/lib/icons.mjs.map +1 -1
  68. package/src/lib/kind-parts.d.mts +56 -0
  69. package/src/lib/kind-parts.d.ts +56 -0
  70. package/src/lib/kind-parts.js +121 -0
  71. package/src/lib/kind-parts.js.map +1 -0
  72. package/src/lib/kind-parts.mjs +107 -0
  73. package/src/lib/kind-parts.mjs.map +1 -0
  74. package/src/lib/labels.d.mts +80 -0
  75. package/src/lib/labels.d.ts +80 -0
  76. package/src/lib/labels.js +107 -189
  77. package/src/lib/labels.js.map +1 -1
  78. package/src/lib/labels.mjs +107 -189
  79. package/src/lib/labels.mjs.map +1 -1
  80. package/src/lib/layout-styles.d.mts +11 -0
  81. package/src/lib/layout-styles.d.ts +11 -0
  82. package/src/lib/layout-styles.js +176 -0
  83. package/src/lib/layout-styles.js.map +1 -0
  84. package/src/lib/layout-styles.mjs +173 -0
  85. package/src/lib/layout-styles.mjs.map +1 -0
  86. package/src/lib/limits.d.mts +20 -0
  87. package/src/lib/limits.d.ts +20 -0
  88. package/src/lib/limits.js +71 -0
  89. package/src/lib/limits.js.map +1 -0
  90. package/src/lib/limits.mjs +66 -0
  91. package/src/lib/limits.mjs.map +1 -0
  92. package/src/lib/line-moves.d.mts +8 -0
  93. package/src/lib/line-moves.d.ts +8 -0
  94. package/src/lib/line-moves.js +20 -0
  95. package/src/lib/line-moves.js.map +1 -0
  96. package/src/lib/line-moves.mjs +17 -0
  97. package/src/lib/line-moves.mjs.map +1 -0
  98. package/src/lib/lines.js +85 -7
  99. package/src/lib/lines.js.map +1 -1
  100. package/src/lib/lines.mjs +86 -8
  101. package/src/lib/lines.mjs.map +1 -1
  102. package/src/lib/locales/all.d.mts +8 -0
  103. package/src/lib/locales/all.d.ts +8 -0
  104. package/src/lib/locales/all.js +13 -0
  105. package/src/lib/locales/all.js.map +1 -0
  106. package/src/lib/locales/all.mjs +10 -0
  107. package/src/lib/locales/all.mjs.map +1 -0
  108. package/src/lib/locales/ar.d.mts +3 -0
  109. package/src/lib/locales/ar.d.ts +3 -0
  110. package/src/lib/locales/ar.js +104 -0
  111. package/src/lib/locales/ar.js.map +1 -0
  112. package/src/lib/locales/ar.mjs +101 -0
  113. package/src/lib/locales/ar.mjs.map +1 -0
  114. package/src/lib/locales/de.d.mts +3 -0
  115. package/src/lib/locales/de.d.ts +3 -0
  116. package/src/lib/locales/de.js +104 -0
  117. package/src/lib/locales/de.js.map +1 -0
  118. package/src/lib/locales/de.mjs +101 -0
  119. package/src/lib/locales/de.mjs.map +1 -0
  120. package/src/lib/locales/fr.d.mts +3 -0
  121. package/src/lib/locales/fr.d.ts +3 -0
  122. package/src/lib/locales/fr.js +104 -0
  123. package/src/lib/locales/fr.js.map +1 -0
  124. package/src/lib/locales/fr.mjs +101 -0
  125. package/src/lib/locales/fr.mjs.map +1 -0
  126. package/src/lib/matrix.d.mts +10 -0
  127. package/src/lib/matrix.d.ts +10 -0
  128. package/src/lib/matrix.js +86 -0
  129. package/src/lib/matrix.js.map +1 -0
  130. package/src/lib/matrix.mjs +82 -0
  131. package/src/lib/matrix.mjs.map +1 -0
  132. package/src/lib/numbers.d.mts +7 -0
  133. package/src/lib/numbers.d.ts +7 -0
  134. package/src/lib/numbers.js +15 -0
  135. package/src/lib/numbers.js.map +1 -1
  136. package/src/lib/numbers.mjs +14 -0
  137. package/src/lib/numbers.mjs.map +1 -1
  138. package/src/lib/progress.js +8 -4
  139. package/src/lib/progress.js.map +1 -1
  140. package/src/lib/progress.mjs +8 -4
  141. package/src/lib/progress.mjs.map +1 -1
  142. package/src/lib/ranking.d.mts +2 -0
  143. package/src/lib/ranking.d.ts +2 -0
  144. package/src/lib/ranking.js +172 -0
  145. package/src/lib/ranking.js.map +1 -0
  146. package/src/lib/ranking.mjs +168 -0
  147. package/src/lib/ranking.mjs.map +1 -0
  148. package/src/lib/relations.d.mts +1 -1
  149. package/src/lib/relations.d.ts +1 -1
  150. package/src/lib/relations.js +43 -18
  151. package/src/lib/relations.js.map +1 -1
  152. package/src/lib/relations.mjs +43 -18
  153. package/src/lib/relations.mjs.map +1 -1
  154. package/src/lib/shuffle.d.mts +7 -0
  155. package/src/lib/shuffle.d.ts +7 -0
  156. package/src/lib/shuffle.js +60 -0
  157. package/src/lib/shuffle.js.map +1 -0
  158. package/src/lib/shuffle.mjs +57 -0
  159. package/src/lib/shuffle.mjs.map +1 -0
  160. package/src/lib/signature.d.mts +2 -0
  161. package/src/lib/signature.d.ts +2 -0
  162. package/src/lib/signature.js +223 -0
  163. package/src/lib/signature.js.map +1 -0
  164. package/src/lib/signature.mjs +219 -0
  165. package/src/lib/signature.mjs.map +1 -0
  166. package/src/lib/slider.d.mts +10 -0
  167. package/src/lib/slider.d.ts +10 -0
  168. package/src/lib/slider.js +57 -0
  169. package/src/lib/slider.js.map +1 -0
  170. package/src/lib/slider.mjs +53 -0
  171. package/src/lib/slider.mjs.map +1 -0
  172. package/src/lib/styles-choices.d.mts +7 -0
  173. package/src/lib/styles-choices.d.ts +7 -0
  174. package/src/lib/styles-choices.js +47 -0
  175. package/src/lib/styles-choices.js.map +1 -0
  176. package/src/lib/styles-choices.mjs +44 -0
  177. package/src/lib/styles-choices.mjs.map +1 -0
  178. package/src/lib/styles-inputs.d.mts +9 -0
  179. package/src/lib/styles-inputs.d.ts +9 -0
  180. package/src/lib/styles-inputs.js +41 -0
  181. package/src/lib/styles-inputs.js.map +1 -0
  182. package/src/lib/styles-inputs.mjs +38 -0
  183. package/src/lib/styles-inputs.mjs.map +1 -0
  184. package/src/lib/styles-kinds.d.mts +7 -0
  185. package/src/lib/styles-kinds.d.ts +7 -0
  186. package/src/lib/styles-kinds.js +119 -0
  187. package/src/lib/styles-kinds.js.map +1 -0
  188. package/src/lib/styles-kinds.mjs +116 -0
  189. package/src/lib/styles-kinds.mjs.map +1 -0
  190. package/src/lib/styles.d.mts +2 -14
  191. package/src/lib/styles.d.ts +2 -14
  192. package/src/lib/styles.js +180 -66
  193. package/src/lib/styles.js.map +1 -1
  194. package/src/lib/styles.mjs +180 -66
  195. package/src/lib/styles.mjs.map +1 -1
  196. package/src/lib/units.d.mts +10 -0
  197. package/src/lib/units.d.ts +10 -0
  198. package/src/lib/units.js +19 -0
  199. package/src/lib/units.js.map +1 -0
  200. package/src/lib/units.mjs +16 -0
  201. package/src/lib/units.mjs.map +1 -0
  202. package/src/lib/widgets.js +215 -57
  203. package/src/lib/widgets.js.map +1 -1
  204. package/src/lib/widgets.mjs +215 -57
  205. package/src/lib/widgets.mjs.map +1 -1
  206. package/src/lib/yes-no.d.mts +9 -0
  207. package/src/lib/yes-no.d.ts +9 -0
  208. package/src/lib/yes-no.js +58 -0
  209. package/src/lib/yes-no.js.map +1 -0
  210. package/src/lib/yes-no.mjs +54 -0
  211. package/src/lib/yes-no.mjs.map +1 -0
@@ -0,0 +1,223 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.signatureWidget = void 0;
4
+ const files_1 = require("./files");
5
+ const kind_parts_1 = require("./kind-parts");
6
+ /**
7
+ * A signature on a file field (`binary.signature`): drawn on a pad with a
8
+ * mouse, a finger or a pen, or — for anyone without a pointer — typed as a
9
+ * name and drawn as a signature, the name kept as the value's `text`. Kept
10
+ * as a PNG picture, the value a file upload has. A signature already kept
11
+ * shows as its picture until Clear. Undo takes the last stroke away.
12
+ *
13
+ * `options.color` (#rrggbb) and `options.penWidth` set the pen; the node's
14
+ * `placeholder` is the words on the blank pad ("Sign here"); `options.footerLabel`
15
+ * the words kept under it; `options.upload` lets a picture of a signature be
16
+ * uploaded as a third way.
17
+ */
18
+ /** The pad's own size, in the picture's pixels; it is drawn at whatever width its box has. */
19
+ const WIDTH = 600;
20
+ const HEIGHT = 180;
21
+ /** Blue-black ink on a clear ground, so the picture reads on any paper. */
22
+ const INK = '#1b2a5c';
23
+ const SCRIPT = '"Segoe Script", "Snell Roundhand", "Brush Script MT", "Apple Chancery", cursive';
24
+ /** The bytes a base64 text holds. */
25
+ const bytesOf = (base64) => Math.floor((base64.length * 3) / 4) - (base64.endsWith('==') ? 2 : base64.endsWith('=') ? 1 : 0);
26
+ const keyOf = (file) => file.data ?? file.url ?? '';
27
+ const signatureWidget = ({ form, name, field, node, id, document, labels, locale }) => {
28
+ const words = (0, kind_parts_1.wordsFor)(labels, locale);
29
+ const make = (0, kind_parts_1.maker)(document);
30
+ const options = node.options ?? {};
31
+ const color = options['color'];
32
+ const ink = typeof color === 'string' && /^#[\da-f]{6}$/i.test(color) ? color : INK;
33
+ const penWidth = options['penWidth'];
34
+ const width = typeof penWidth === 'number' && penWidth > 0 ? penWidth : 3;
35
+ const footerWords = options['footerLabel'];
36
+ const canvas = make('canvas', { class: 'fd-signature-pad', width: String(WIDTH), height: String(HEIGHT), role: 'img', 'aria-label': words.signaturePad });
37
+ const hint = make('span', { class: 'fd-signature-hint', 'aria-hidden': 'true' }, node.placeholder || words.signHere);
38
+ const image = make('img', { class: 'fd-signature-image', alt: field.label, hidden: '' });
39
+ const typed = make('input', { type: 'text', class: 'fd-input fd-signature-typed', 'aria-label': words.typeSignature, placeholder: words.typeSignature, autocomplete: 'name' });
40
+ const button = (words) => make('button', { type: 'button', class: 'fd-button fd-button-link', hidden: '' }, words);
41
+ const undo = button(words.undo);
42
+ const clear = button(words.clearDrawing);
43
+ clear.classList.add('fd-signature-clear');
44
+ // A picture of a signature, from this computer or a phone's camera.
45
+ const upload = options['upload'] === true ? button(words.uploadSignature) : null;
46
+ const file = make('input', { type: 'file', accept: 'image/*', class: 'fd-sr-only', tabindex: '-1', 'aria-hidden': 'true' });
47
+ const element = make('div', { id, class: 'fd-signature', role: 'group' }, make('div', { class: 'fd-signature-box' }, canvas, image, hint), ...(typeof footerWords === 'string' && footerWords ? [make('span', { class: 'fd-signature-footer' }, footerWords)] : []), make('div', { class: 'fd-signature-tools' }, typed, undo, ...(upload ? [upload, file] : []), clear));
48
+ const pen = () => {
49
+ const context = canvas.getContext('2d');
50
+ if (context) {
51
+ context.strokeStyle = context.fillStyle = ink;
52
+ context.lineWidth = width;
53
+ context.lineCap = context.lineJoin = 'round';
54
+ }
55
+ return context;
56
+ };
57
+ /** The picture this pad last kept: coming back from the form, it leaves the pad as it is. */
58
+ let mine = null;
59
+ let readonly = false;
60
+ /** What is on the pad: a typed name, and the strokes drawn, each its points. */
61
+ let typedName = null;
62
+ let strokes = [];
63
+ let last = null;
64
+ const blank = () => !strokes.length && !typedName;
65
+ /** The pad drawn again from what is on it: the name, then each stroke — a dot for a press that never moved. */
66
+ function redraw() {
67
+ const context = pen();
68
+ if (!context)
69
+ return;
70
+ context.clearRect(0, 0, WIDTH, HEIGHT);
71
+ if (typedName) {
72
+ context.font = `italic 64px ${SCRIPT}`;
73
+ context.textAlign = 'center';
74
+ context.textBaseline = 'middle';
75
+ context.fillText(typedName, WIDTH / 2, HEIGHT / 2, WIDTH - 40);
76
+ }
77
+ for (const stroke of strokes) {
78
+ context.beginPath();
79
+ context.arc(stroke[0].x, stroke[0].y, width / 2, 0, Math.PI * 2);
80
+ context.fill();
81
+ for (let i = 1; i < stroke.length; i++)
82
+ line(stroke[i - 1], stroke[i]);
83
+ }
84
+ }
85
+ function line(from, to) {
86
+ const context = pen();
87
+ context?.beginPath();
88
+ context?.moveTo(from.x, from.y);
89
+ context?.lineTo(to.x, to.y);
90
+ context?.stroke();
91
+ }
92
+ function wipe() {
93
+ strokes = [];
94
+ typedName = null;
95
+ redraw();
96
+ }
97
+ /** What is on the pad, as the field's value: nothing when it is blank. */
98
+ function keep() {
99
+ hint.hidden = !blank();
100
+ if (blank()) {
101
+ mine = null;
102
+ return form.setValue(name, null);
103
+ }
104
+ let url;
105
+ try {
106
+ url = canvas.toDataURL('image/png');
107
+ }
108
+ catch {
109
+ return; // a pad that cannot be read back keeps nothing
110
+ }
111
+ if (!url)
112
+ return;
113
+ const data = url.slice(url.indexOf(',') + 1);
114
+ mine = data;
115
+ form.setValue(name, { name: 'signature.png', type: 'image/png', size: bytesOf(data), data, ...(typedName && !strokes.length ? { text: typedName } : {}) });
116
+ }
117
+ /** The pad's point under the pointer: the pad is drawn smaller or larger than its own size. */
118
+ function at(event) {
119
+ const box = canvas.getBoundingClientRect();
120
+ return { x: ((event.clientX - box.left) * WIDTH) / (box.width || WIDTH), y: ((event.clientY - box.top) * HEIGHT) / (box.height || HEIGHT) };
121
+ }
122
+ canvas.addEventListener('pointerdown', (event) => {
123
+ if (readonly || event.button !== 0)
124
+ return;
125
+ event.preventDefault();
126
+ canvas.setPointerCapture?.(event.pointerId);
127
+ last = at(event);
128
+ strokes.push([last]);
129
+ hint.hidden = true;
130
+ redraw();
131
+ });
132
+ canvas.addEventListener('pointermove', (event) => {
133
+ if (!last)
134
+ return;
135
+ const next = at(event);
136
+ line(last, next);
137
+ strokes[strokes.length - 1].push(next);
138
+ last = next;
139
+ });
140
+ const end = () => {
141
+ if (!last)
142
+ return;
143
+ last = null;
144
+ keep();
145
+ };
146
+ canvas.addEventListener('pointerup', end);
147
+ canvas.addEventListener('pointercancel', end);
148
+ // A name typed is drawn in a hand's script, in place of whatever was drawn.
149
+ typed.addEventListener('input', () => {
150
+ showPad();
151
+ strokes = [];
152
+ typedName = typed.value.trim() || null;
153
+ redraw();
154
+ keep();
155
+ });
156
+ undo.addEventListener('click', () => {
157
+ strokes.pop();
158
+ redraw();
159
+ keep();
160
+ });
161
+ upload?.addEventListener('click', () => file.click());
162
+ file.addEventListener('change', () => {
163
+ const chosen = file.files?.[0];
164
+ file.value = '';
165
+ if (chosen)
166
+ void (0, files_1.readFile)(chosen).then((value) => form.setValue(name, value));
167
+ });
168
+ clear.addEventListener('click', () => {
169
+ wipe();
170
+ mine = null;
171
+ typed.value = '';
172
+ showPad();
173
+ form.setValue(name, null);
174
+ typed.focus();
175
+ });
176
+ function showPad() {
177
+ image.hidden = true;
178
+ canvas.hidden = false;
179
+ }
180
+ return {
181
+ element,
182
+ focus: () => (typed.hidden ? clear : typed).focus(),
183
+ update(state) {
184
+ readonly = state.readonly;
185
+ const value = state.value && typeof state.value === 'object' && !Array.isArray(state.value) ? state.value : null;
186
+ const away = document.activeElement !== typed;
187
+ if (value && keyOf(value) !== mine) {
188
+ // Kept before, uploaded, or set from outside: its picture, until Clear.
189
+ const src = value.data ? `data:${value.type};base64,${value.data}` : (value.url ?? '');
190
+ if (image.getAttribute('src') !== src)
191
+ image.src = src;
192
+ image.hidden = false;
193
+ canvas.hidden = true;
194
+ mine = null;
195
+ wipe();
196
+ if (away)
197
+ typed.value = value.text ?? '';
198
+ }
199
+ else if (!value) {
200
+ if (mine !== null || !image.hidden) {
201
+ // Emptied from outside.
202
+ mine = null;
203
+ wipe();
204
+ if (away)
205
+ typed.value = '';
206
+ }
207
+ showPad();
208
+ }
209
+ hint.hidden = readonly || !blank() || !image.hidden;
210
+ typed.hidden = readonly;
211
+ typed.readOnly = readonly;
212
+ clear.hidden = readonly || !value;
213
+ undo.hidden = readonly || !strokes.length || !image.hidden;
214
+ if (upload)
215
+ upload.hidden = readonly;
216
+ canvas.classList.toggle('fd-signature-locked', readonly);
217
+ (0, kind_parts_1.describeState)(element, state);
218
+ typed.setAttribute('aria-invalid', String(state.invalid));
219
+ },
220
+ };
221
+ };
222
+ exports.signatureWidget = signatureWidget;
223
+ //# sourceMappingURL=signature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signature.js","sourceRoot":"","sources":["../../../../../libs/widgets/src/lib/signature.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,219 @@
1
+ import { readFile } from './files.mjs';
2
+ import { describeState, maker, wordsFor } from './kind-parts.mjs';
3
+ /**
4
+ * A signature on a file field (`binary.signature`): drawn on a pad with a
5
+ * mouse, a finger or a pen, or — for anyone without a pointer — typed as a
6
+ * name and drawn as a signature, the name kept as the value's `text`. Kept
7
+ * as a PNG picture, the value a file upload has. A signature already kept
8
+ * shows as its picture until Clear. Undo takes the last stroke away.
9
+ *
10
+ * `options.color` (#rrggbb) and `options.penWidth` set the pen; the node's
11
+ * `placeholder` is the words on the blank pad ("Sign here"); `options.footerLabel`
12
+ * the words kept under it; `options.upload` lets a picture of a signature be
13
+ * uploaded as a third way.
14
+ */
15
+ /** The pad's own size, in the picture's pixels; it is drawn at whatever width its box has. */
16
+ const WIDTH = 600;
17
+ const HEIGHT = 180;
18
+ /** Blue-black ink on a clear ground, so the picture reads on any paper. */
19
+ const INK = '#1b2a5c';
20
+ const SCRIPT = '"Segoe Script", "Snell Roundhand", "Brush Script MT", "Apple Chancery", cursive';
21
+ /** The bytes a base64 text holds. */
22
+ const bytesOf = (base64) => Math.floor((base64.length * 3) / 4) - (base64.endsWith('==') ? 2 : base64.endsWith('=') ? 1 : 0);
23
+ const keyOf = (file) => file.data ?? file.url ?? '';
24
+ export const signatureWidget = ({ form, name, field, node, id, document, labels, locale }) => {
25
+ const words = wordsFor(labels, locale);
26
+ const make = maker(document);
27
+ const options = node.options ?? {};
28
+ const color = options['color'];
29
+ const ink = typeof color === 'string' && /^#[\da-f]{6}$/i.test(color) ? color : INK;
30
+ const penWidth = options['penWidth'];
31
+ const width = typeof penWidth === 'number' && penWidth > 0 ? penWidth : 3;
32
+ const footerWords = options['footerLabel'];
33
+ const canvas = make('canvas', { class: 'fd-signature-pad', width: String(WIDTH), height: String(HEIGHT), role: 'img', 'aria-label': words.signaturePad });
34
+ const hint = make('span', { class: 'fd-signature-hint', 'aria-hidden': 'true' }, node.placeholder || words.signHere);
35
+ const image = make('img', { class: 'fd-signature-image', alt: field.label, hidden: '' });
36
+ const typed = make('input', { type: 'text', class: 'fd-input fd-signature-typed', 'aria-label': words.typeSignature, placeholder: words.typeSignature, autocomplete: 'name' });
37
+ const button = (words) => make('button', { type: 'button', class: 'fd-button fd-button-link', hidden: '' }, words);
38
+ const undo = button(words.undo);
39
+ const clear = button(words.clearDrawing);
40
+ clear.classList.add('fd-signature-clear');
41
+ // A picture of a signature, from this computer or a phone's camera.
42
+ const upload = options['upload'] === true ? button(words.uploadSignature) : null;
43
+ const file = make('input', { type: 'file', accept: 'image/*', class: 'fd-sr-only', tabindex: '-1', 'aria-hidden': 'true' });
44
+ const element = make('div', { id, class: 'fd-signature', role: 'group' }, make('div', { class: 'fd-signature-box' }, canvas, image, hint), ...(typeof footerWords === 'string' && footerWords ? [make('span', { class: 'fd-signature-footer' }, footerWords)] : []), make('div', { class: 'fd-signature-tools' }, typed, undo, ...(upload ? [upload, file] : []), clear));
45
+ const pen = () => {
46
+ const context = canvas.getContext('2d');
47
+ if (context) {
48
+ context.strokeStyle = context.fillStyle = ink;
49
+ context.lineWidth = width;
50
+ context.lineCap = context.lineJoin = 'round';
51
+ }
52
+ return context;
53
+ };
54
+ /** The picture this pad last kept: coming back from the form, it leaves the pad as it is. */
55
+ let mine = null;
56
+ let readonly = false;
57
+ /** What is on the pad: a typed name, and the strokes drawn, each its points. */
58
+ let typedName = null;
59
+ let strokes = [];
60
+ let last = null;
61
+ const blank = () => !strokes.length && !typedName;
62
+ /** The pad drawn again from what is on it: the name, then each stroke — a dot for a press that never moved. */
63
+ function redraw() {
64
+ const context = pen();
65
+ if (!context)
66
+ return;
67
+ context.clearRect(0, 0, WIDTH, HEIGHT);
68
+ if (typedName) {
69
+ context.font = `italic 64px ${SCRIPT}`;
70
+ context.textAlign = 'center';
71
+ context.textBaseline = 'middle';
72
+ context.fillText(typedName, WIDTH / 2, HEIGHT / 2, WIDTH - 40);
73
+ }
74
+ for (const stroke of strokes) {
75
+ context.beginPath();
76
+ context.arc(stroke[0].x, stroke[0].y, width / 2, 0, Math.PI * 2);
77
+ context.fill();
78
+ for (let i = 1; i < stroke.length; i++)
79
+ line(stroke[i - 1], stroke[i]);
80
+ }
81
+ }
82
+ function line(from, to) {
83
+ const context = pen();
84
+ context?.beginPath();
85
+ context?.moveTo(from.x, from.y);
86
+ context?.lineTo(to.x, to.y);
87
+ context?.stroke();
88
+ }
89
+ function wipe() {
90
+ strokes = [];
91
+ typedName = null;
92
+ redraw();
93
+ }
94
+ /** What is on the pad, as the field's value: nothing when it is blank. */
95
+ function keep() {
96
+ hint.hidden = !blank();
97
+ if (blank()) {
98
+ mine = null;
99
+ return form.setValue(name, null);
100
+ }
101
+ let url;
102
+ try {
103
+ url = canvas.toDataURL('image/png');
104
+ }
105
+ catch {
106
+ return; // a pad that cannot be read back keeps nothing
107
+ }
108
+ if (!url)
109
+ return;
110
+ const data = url.slice(url.indexOf(',') + 1);
111
+ mine = data;
112
+ form.setValue(name, { name: 'signature.png', type: 'image/png', size: bytesOf(data), data, ...(typedName && !strokes.length ? { text: typedName } : {}) });
113
+ }
114
+ /** The pad's point under the pointer: the pad is drawn smaller or larger than its own size. */
115
+ function at(event) {
116
+ const box = canvas.getBoundingClientRect();
117
+ return { x: ((event.clientX - box.left) * WIDTH) / (box.width || WIDTH), y: ((event.clientY - box.top) * HEIGHT) / (box.height || HEIGHT) };
118
+ }
119
+ canvas.addEventListener('pointerdown', (event) => {
120
+ if (readonly || event.button !== 0)
121
+ return;
122
+ event.preventDefault();
123
+ canvas.setPointerCapture?.(event.pointerId);
124
+ last = at(event);
125
+ strokes.push([last]);
126
+ hint.hidden = true;
127
+ redraw();
128
+ });
129
+ canvas.addEventListener('pointermove', (event) => {
130
+ if (!last)
131
+ return;
132
+ const next = at(event);
133
+ line(last, next);
134
+ strokes[strokes.length - 1].push(next);
135
+ last = next;
136
+ });
137
+ const end = () => {
138
+ if (!last)
139
+ return;
140
+ last = null;
141
+ keep();
142
+ };
143
+ canvas.addEventListener('pointerup', end);
144
+ canvas.addEventListener('pointercancel', end);
145
+ // A name typed is drawn in a hand's script, in place of whatever was drawn.
146
+ typed.addEventListener('input', () => {
147
+ showPad();
148
+ strokes = [];
149
+ typedName = typed.value.trim() || null;
150
+ redraw();
151
+ keep();
152
+ });
153
+ undo.addEventListener('click', () => {
154
+ strokes.pop();
155
+ redraw();
156
+ keep();
157
+ });
158
+ upload?.addEventListener('click', () => file.click());
159
+ file.addEventListener('change', () => {
160
+ const chosen = file.files?.[0];
161
+ file.value = '';
162
+ if (chosen)
163
+ void readFile(chosen).then((value) => form.setValue(name, value));
164
+ });
165
+ clear.addEventListener('click', () => {
166
+ wipe();
167
+ mine = null;
168
+ typed.value = '';
169
+ showPad();
170
+ form.setValue(name, null);
171
+ typed.focus();
172
+ });
173
+ function showPad() {
174
+ image.hidden = true;
175
+ canvas.hidden = false;
176
+ }
177
+ return {
178
+ element,
179
+ focus: () => (typed.hidden ? clear : typed).focus(),
180
+ update(state) {
181
+ readonly = state.readonly;
182
+ const value = state.value && typeof state.value === 'object' && !Array.isArray(state.value) ? state.value : null;
183
+ const away = document.activeElement !== typed;
184
+ if (value && keyOf(value) !== mine) {
185
+ // Kept before, uploaded, or set from outside: its picture, until Clear.
186
+ const src = value.data ? `data:${value.type};base64,${value.data}` : (value.url ?? '');
187
+ if (image.getAttribute('src') !== src)
188
+ image.src = src;
189
+ image.hidden = false;
190
+ canvas.hidden = true;
191
+ mine = null;
192
+ wipe();
193
+ if (away)
194
+ typed.value = value.text ?? '';
195
+ }
196
+ else if (!value) {
197
+ if (mine !== null || !image.hidden) {
198
+ // Emptied from outside.
199
+ mine = null;
200
+ wipe();
201
+ if (away)
202
+ typed.value = '';
203
+ }
204
+ showPad();
205
+ }
206
+ hint.hidden = readonly || !blank() || !image.hidden;
207
+ typed.hidden = readonly;
208
+ typed.readOnly = readonly;
209
+ clear.hidden = readonly || !value;
210
+ undo.hidden = readonly || !strokes.length || !image.hidden;
211
+ if (upload)
212
+ upload.hidden = readonly;
213
+ canvas.classList.toggle('fd-signature-locked', readonly);
214
+ describeState(element, state);
215
+ typed.setAttribute('aria-invalid', String(state.invalid));
216
+ },
217
+ };
218
+ };
219
+ //# sourceMappingURL=signature.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signature.mjs","sourceRoot":"","sources":["../../../../../libs/widgets/src/lib/signature.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { WidgetFactory } from './widgets.mjs';
2
+ /**
3
+ * A number picked on a slider (`integer.slider`, `float.slider`): the field's
4
+ * `min` to `max` (0 to 100 when it has none), `options.step` at a time (1),
5
+ * the value shown beside it and the ends under it, written as the page's
6
+ * readers write numbers. A native range, so the arrow keys, Home and End move
7
+ * it, a screen reader reads it, and it runs right to left on such a page.
8
+ * Until it is slid it is not answered, and says so.
9
+ */
10
+ export declare const sliderWidget: WidgetFactory;
@@ -0,0 +1,10 @@
1
+ import type { WidgetFactory } from './widgets';
2
+ /**
3
+ * A number picked on a slider (`integer.slider`, `float.slider`): the field's
4
+ * `min` to `max` (0 to 100 when it has none), `options.step` at a time (1),
5
+ * the value shown beside it and the ends under it, written as the page's
6
+ * readers write numbers. A native range, so the arrow keys, Home and End move
7
+ * it, a screen reader reads it, and it runs right to left on such a page.
8
+ * Until it is slid it is not answered, and says so.
9
+ */
10
+ export declare const sliderWidget: WidgetFactory;
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sliderWidget = void 0;
4
+ const kind_parts_1 = require("./kind-parts");
5
+ const numbers_1 = require("./numbers");
6
+ /**
7
+ * A number picked on a slider (`integer.slider`, `float.slider`): the field's
8
+ * `min` to `max` (0 to 100 when it has none), `options.step` at a time (1),
9
+ * the value shown beside it and the ends under it, written as the page's
10
+ * readers write numbers. A native range, so the arrow keys, Home and End move
11
+ * it, a screen reader reads it, and it runs right to left on such a page.
12
+ * Until it is slid it is not answered, and says so.
13
+ */
14
+ const sliderWidget = ({ form, name, field, node, id, document, labels, locale = 'en' }) => {
15
+ const words = (0, kind_parts_1.wordsFor)(labels, locale);
16
+ const make = (0, kind_parts_1.maker)(document);
17
+ const has = (key) => (key in field && typeof field[key] === 'number' ? field[key] : undefined);
18
+ const min = has('min') ?? 0;
19
+ const max = has('max') ?? 100;
20
+ const step = typeof node.options?.['step'] === 'number' && node.options['step'] > 0 ? node.options['step'] : 1;
21
+ const decimals = field.type === 'integer' ? 0 : field.type === 'float' && field.digits ? field.digits[1] : Math.max(0, -Math.floor(Math.log10(step)));
22
+ const written = (n) => (0, numbers_1.formatNumber)(n, decimals, locale);
23
+ const input = make('input', { id, type: 'range', class: 'fd-slider-input', min: String(min), max: String(max), step: String(step) });
24
+ const output = make('output', { class: 'fd-slider-value', for: id, 'aria-hidden': 'true' });
25
+ // Words under the ends' numbers, when the page has them: "Never" … "Every day".
26
+ const endWords = [node.options?.['startLabel'], node.options?.['endLabel']].map((v) => (typeof v === 'string' ? v : ''));
27
+ const end = (n, i) => make('span', { class: i ? 'fd-slider-last' : undefined }, written(n), ...(endWords[i] ? [make('span', { class: 'fd-slider-word' }, endWords[i])] : []));
28
+ const ends = make('div', { class: 'fd-slider-ends', 'aria-hidden': 'true' }, end(min, 0), end(max, 1));
29
+ const clear = (0, kind_parts_1.clearSelection)(document, words, () => {
30
+ form.setValue(name, null);
31
+ input.focus();
32
+ });
33
+ const element = make('div', { class: 'fd-slider' }, make('div', { class: 'fd-slider-track' }, input, output), ends, clear.button);
34
+ if (endWords.some(Boolean))
35
+ input.setAttribute('aria-description', endWords.filter(Boolean).join(' … '));
36
+ input.addEventListener('input', () => form.setValue(name, Number(input.value)));
37
+ return {
38
+ element,
39
+ focus: () => input.focus(),
40
+ update(state) {
41
+ const value = typeof state.value === 'number' ? state.value : null;
42
+ element.classList.toggle('fd-slider-empty', value === null);
43
+ // Not answered: the thumb waits halfway, dimmed, and says so.
44
+ const at = String(value ?? (min + max) / 2);
45
+ if (input.value !== at)
46
+ input.value = at;
47
+ output.textContent = value === null ? '–' : written(value);
48
+ input.setAttribute('aria-valuetext', value === null ? words.notAnswered : written(value));
49
+ input.disabled = state.readonly;
50
+ clear.allow(state);
51
+ clear.show(value !== null);
52
+ (0, kind_parts_1.describeState)(input, state);
53
+ },
54
+ };
55
+ };
56
+ exports.sliderWidget = sliderWidget;
57
+ //# sourceMappingURL=slider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slider.js","sourceRoot":"","sources":["../../../../../libs/widgets/src/lib/slider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ import { clearSelection, describeState, maker, wordsFor } from './kind-parts.mjs';
2
+ import { formatNumber } from './numbers.mjs';
3
+ /**
4
+ * A number picked on a slider (`integer.slider`, `float.slider`): the field's
5
+ * `min` to `max` (0 to 100 when it has none), `options.step` at a time (1),
6
+ * the value shown beside it and the ends under it, written as the page's
7
+ * readers write numbers. A native range, so the arrow keys, Home and End move
8
+ * it, a screen reader reads it, and it runs right to left on such a page.
9
+ * Until it is slid it is not answered, and says so.
10
+ */
11
+ export const sliderWidget = ({ form, name, field, node, id, document, labels, locale = 'en' }) => {
12
+ const words = wordsFor(labels, locale);
13
+ const make = maker(document);
14
+ const has = (key) => (key in field && typeof field[key] === 'number' ? field[key] : undefined);
15
+ const min = has('min') ?? 0;
16
+ const max = has('max') ?? 100;
17
+ const step = typeof node.options?.['step'] === 'number' && node.options['step'] > 0 ? node.options['step'] : 1;
18
+ const decimals = field.type === 'integer' ? 0 : field.type === 'float' && field.digits ? field.digits[1] : Math.max(0, -Math.floor(Math.log10(step)));
19
+ const written = (n) => formatNumber(n, decimals, locale);
20
+ const input = make('input', { id, type: 'range', class: 'fd-slider-input', min: String(min), max: String(max), step: String(step) });
21
+ const output = make('output', { class: 'fd-slider-value', for: id, 'aria-hidden': 'true' });
22
+ // Words under the ends' numbers, when the page has them: "Never" … "Every day".
23
+ const endWords = [node.options?.['startLabel'], node.options?.['endLabel']].map((v) => (typeof v === 'string' ? v : ''));
24
+ const end = (n, i) => make('span', { class: i ? 'fd-slider-last' : undefined }, written(n), ...(endWords[i] ? [make('span', { class: 'fd-slider-word' }, endWords[i])] : []));
25
+ const ends = make('div', { class: 'fd-slider-ends', 'aria-hidden': 'true' }, end(min, 0), end(max, 1));
26
+ const clear = clearSelection(document, words, () => {
27
+ form.setValue(name, null);
28
+ input.focus();
29
+ });
30
+ const element = make('div', { class: 'fd-slider' }, make('div', { class: 'fd-slider-track' }, input, output), ends, clear.button);
31
+ if (endWords.some(Boolean))
32
+ input.setAttribute('aria-description', endWords.filter(Boolean).join(' … '));
33
+ input.addEventListener('input', () => form.setValue(name, Number(input.value)));
34
+ return {
35
+ element,
36
+ focus: () => input.focus(),
37
+ update(state) {
38
+ const value = typeof state.value === 'number' ? state.value : null;
39
+ element.classList.toggle('fd-slider-empty', value === null);
40
+ // Not answered: the thumb waits halfway, dimmed, and says so.
41
+ const at = String(value ?? (min + max) / 2);
42
+ if (input.value !== at)
43
+ input.value = at;
44
+ output.textContent = value === null ? '–' : written(value);
45
+ input.setAttribute('aria-valuetext', value === null ? words.notAnswered : written(value));
46
+ input.disabled = state.readonly;
47
+ clear.allow(state);
48
+ clear.show(value !== null);
49
+ describeState(input, state);
50
+ },
51
+ };
52
+ };
53
+ //# sourceMappingURL=slider.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slider.mjs","sourceRoot":"","sources":["../../../../../libs/widgets/src/lib/slider.ts"],"names":[],"mappings":"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"}