@fieldia/designer 0.19.1 → 0.21.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 (305) hide show
  1. package/package.json +4 -4
  2. package/src/lib/canvas-head.d.mts +22 -0
  3. package/src/lib/canvas-head.d.ts +22 -0
  4. package/src/lib/canvas-head.js +121 -0
  5. package/src/lib/canvas-head.js.map +1 -0
  6. package/src/lib/canvas-head.mjs +118 -0
  7. package/src/lib/canvas-head.mjs.map +1 -0
  8. package/src/lib/canvas-header.js +7 -1
  9. package/src/lib/canvas-header.js.map +1 -1
  10. package/src/lib/canvas-header.mjs +7 -1
  11. package/src/lib/canvas-header.mjs.map +1 -1
  12. package/src/lib/choice-commands.d.mts +2 -1
  13. package/src/lib/choice-commands.d.ts +2 -1
  14. package/src/lib/choice-commands.js +3 -0
  15. package/src/lib/choice-commands.js.map +1 -1
  16. package/src/lib/choice-commands.mjs +3 -0
  17. package/src/lib/choice-commands.mjs.map +1 -1
  18. package/src/lib/chrome.js +11 -0
  19. package/src/lib/chrome.js.map +1 -1
  20. package/src/lib/chrome.mjs +11 -0
  21. package/src/lib/chrome.mjs.map +1 -1
  22. package/src/lib/date-setting.d.mts +49 -0
  23. package/src/lib/date-setting.d.ts +49 -0
  24. package/src/lib/date-setting.js +125 -0
  25. package/src/lib/date-setting.js.map +1 -0
  26. package/src/lib/date-setting.mjs +122 -0
  27. package/src/lib/date-setting.mjs.map +1 -0
  28. package/src/lib/designer.d.mts +16 -4
  29. package/src/lib/designer.d.ts +16 -4
  30. package/src/lib/designer.js +25 -2
  31. package/src/lib/designer.js.map +1 -1
  32. package/src/lib/designer.mjs +25 -2
  33. package/src/lib/designer.mjs.map +1 -1
  34. package/src/lib/group-fold.js +2 -0
  35. package/src/lib/group-fold.js.map +1 -1
  36. package/src/lib/group-fold.mjs +2 -0
  37. package/src/lib/group-fold.mjs.map +1 -1
  38. package/src/lib/head-commands.d.mts +116 -0
  39. package/src/lib/head-commands.d.ts +116 -0
  40. package/src/lib/head-commands.js +504 -0
  41. package/src/lib/head-commands.js.map +1 -0
  42. package/src/lib/head-commands.mjs +497 -0
  43. package/src/lib/head-commands.mjs.map +1 -0
  44. package/src/lib/head-parts.d.mts +15 -0
  45. package/src/lib/head-parts.d.ts +15 -0
  46. package/src/lib/head-parts.js +69 -0
  47. package/src/lib/head-parts.js.map +1 -0
  48. package/src/lib/head-parts.mjs +64 -0
  49. package/src/lib/head-parts.mjs.map +1 -0
  50. package/src/lib/head-properties.d.mts +25 -0
  51. package/src/lib/head-properties.d.ts +25 -0
  52. package/src/lib/head-properties.js +383 -0
  53. package/src/lib/head-properties.js.map +1 -0
  54. package/src/lib/head-properties.mjs +376 -0
  55. package/src/lib/head-properties.mjs.map +1 -0
  56. package/src/lib/header-commands.js +7 -0
  57. package/src/lib/header-commands.js.map +1 -1
  58. package/src/lib/header-commands.mjs +7 -0
  59. package/src/lib/header-commands.mjs.map +1 -1
  60. package/src/lib/header-properties.js +5 -1
  61. package/src/lib/header-properties.js.map +1 -1
  62. package/src/lib/header-properties.mjs +5 -1
  63. package/src/lib/header-properties.mjs.map +1 -1
  64. package/src/lib/inline-settings.js +19 -11
  65. package/src/lib/inline-settings.js.map +1 -1
  66. package/src/lib/inline-settings.mjs +19 -11
  67. package/src/lib/inline-settings.mjs.map +1 -1
  68. package/src/lib/input-commands.js +3 -2
  69. package/src/lib/input-commands.js.map +1 -1
  70. package/src/lib/input-commands.mjs +3 -2
  71. package/src/lib/input-commands.mjs.map +1 -1
  72. package/src/lib/kind-settings-choices.js +16 -7
  73. package/src/lib/kind-settings-choices.js.map +1 -1
  74. package/src/lib/kind-settings-choices.mjs +16 -7
  75. package/src/lib/kind-settings-choices.mjs.map +1 -1
  76. package/src/lib/kind-settings-inputs.js +116 -58
  77. package/src/lib/kind-settings-inputs.js.map +1 -1
  78. package/src/lib/kind-settings-inputs.mjs +116 -58
  79. package/src/lib/kind-settings-inputs.mjs.map +1 -1
  80. package/src/lib/kind-settings-picker.d.mts +4 -0
  81. package/src/lib/kind-settings-picker.d.ts +4 -0
  82. package/src/lib/kind-settings-picker.js +115 -0
  83. package/src/lib/kind-settings-picker.js.map +1 -0
  84. package/src/lib/kind-settings-picker.mjs +112 -0
  85. package/src/lib/kind-settings-picker.mjs.map +1 -0
  86. package/src/lib/kind-settings-structures.js +35 -16
  87. package/src/lib/kind-settings-structures.js.map +1 -1
  88. package/src/lib/kind-settings-structures.mjs +36 -17
  89. package/src/lib/kind-settings-structures.mjs.map +1 -1
  90. package/src/lib/kind-settings.js +47 -43
  91. package/src/lib/kind-settings.js.map +1 -1
  92. package/src/lib/kind-settings.mjs +47 -43
  93. package/src/lib/kind-settings.mjs.map +1 -1
  94. package/src/lib/layout-settings.d.mts +7 -0
  95. package/src/lib/layout-settings.d.ts +7 -0
  96. package/src/lib/layout-settings.js +15 -2
  97. package/src/lib/layout-settings.js.map +1 -1
  98. package/src/lib/layout-settings.mjs +15 -2
  99. package/src/lib/layout-settings.mjs.map +1 -1
  100. package/src/lib/list-canvas.js +18 -7
  101. package/src/lib/list-canvas.js.map +1 -1
  102. package/src/lib/list-canvas.mjs +18 -7
  103. package/src/lib/list-canvas.mjs.map +1 -1
  104. package/src/lib/list-commands.d.mts +24 -1
  105. package/src/lib/list-commands.d.ts +24 -1
  106. package/src/lib/list-commands.js +105 -2
  107. package/src/lib/list-commands.js.map +1 -1
  108. package/src/lib/list-commands.mjs +102 -1
  109. package/src/lib/list-commands.mjs.map +1 -1
  110. package/src/lib/list-properties.js +248 -28
  111. package/src/lib/list-properties.js.map +1 -1
  112. package/src/lib/list-properties.mjs +248 -28
  113. package/src/lib/list-properties.mjs.map +1 -1
  114. package/src/lib/locales/ar/head.d.mts +2 -0
  115. package/src/lib/locales/ar/head.d.ts +2 -0
  116. package/src/lib/locales/ar/head.js +97 -0
  117. package/src/lib/locales/ar/head.js.map +1 -0
  118. package/src/lib/locales/ar/head.mjs +94 -0
  119. package/src/lib/locales/ar/head.mjs.map +1 -0
  120. package/src/lib/locales/ar/index.js +4 -1
  121. package/src/lib/locales/ar/index.js.map +1 -1
  122. package/src/lib/locales/ar/index.mjs +4 -1
  123. package/src/lib/locales/ar/index.mjs.map +1 -1
  124. package/src/lib/locales/ar/inputs.d.mts +2 -0
  125. package/src/lib/locales/ar/inputs.d.ts +2 -0
  126. package/src/lib/locales/ar/inputs.js +20 -0
  127. package/src/lib/locales/ar/inputs.js.map +1 -0
  128. package/src/lib/locales/ar/inputs.mjs +17 -0
  129. package/src/lib/locales/ar/inputs.mjs.map +1 -0
  130. package/src/lib/locales/ar/list.js +31 -0
  131. package/src/lib/locales/ar/list.js.map +1 -1
  132. package/src/lib/locales/ar/list.mjs +31 -0
  133. package/src/lib/locales/ar/list.mjs.map +1 -1
  134. package/src/lib/locales/ar/panel.js +38 -0
  135. package/src/lib/locales/ar/panel.js.map +1 -1
  136. package/src/lib/locales/ar/panel.mjs +38 -0
  137. package/src/lib/locales/ar/panel.mjs.map +1 -1
  138. package/src/lib/locales/ar/questions.js +8 -0
  139. package/src/lib/locales/ar/questions.js.map +1 -1
  140. package/src/lib/locales/ar/questions.mjs +8 -0
  141. package/src/lib/locales/ar/questions.mjs.map +1 -1
  142. package/src/lib/locales/ar/refusals.js +11 -0
  143. package/src/lib/locales/ar/refusals.js.map +1 -1
  144. package/src/lib/locales/ar/refusals.mjs +11 -0
  145. package/src/lib/locales/ar/refusals.mjs.map +1 -1
  146. package/src/lib/locales/ar/work-text.d.mts +3 -0
  147. package/src/lib/locales/ar/work-text.d.ts +3 -0
  148. package/src/lib/locales/ar/work-text.js +58 -0
  149. package/src/lib/locales/ar/work-text.js.map +1 -0
  150. package/src/lib/locales/ar/work-text.mjs +55 -0
  151. package/src/lib/locales/ar/work-text.mjs.map +1 -0
  152. package/src/lib/locales/en/head.d.mts +101 -0
  153. package/src/lib/locales/en/head.d.ts +101 -0
  154. package/src/lib/locales/en/head.js +106 -0
  155. package/src/lib/locales/en/head.js.map +1 -0
  156. package/src/lib/locales/en/head.mjs +103 -0
  157. package/src/lib/locales/en/head.mjs.map +1 -0
  158. package/src/lib/locales/en/index.d.mts +237 -0
  159. package/src/lib/locales/en/index.d.ts +237 -0
  160. package/src/lib/locales/en/index.js +4 -1
  161. package/src/lib/locales/en/index.js.map +1 -1
  162. package/src/lib/locales/en/index.mjs +4 -1
  163. package/src/lib/locales/en/index.mjs.map +1 -1
  164. package/src/lib/locales/en/inputs.d.mts +26 -0
  165. package/src/lib/locales/en/inputs.d.ts +26 -0
  166. package/src/lib/locales/en/inputs.js +30 -0
  167. package/src/lib/locales/en/inputs.js.map +1 -0
  168. package/src/lib/locales/en/inputs.mjs +27 -0
  169. package/src/lib/locales/en/inputs.mjs.map +1 -0
  170. package/src/lib/locales/en/list.d.mts +48 -0
  171. package/src/lib/locales/en/list.d.ts +48 -0
  172. package/src/lib/locales/en/list.js +33 -0
  173. package/src/lib/locales/en/list.js.map +1 -1
  174. package/src/lib/locales/en/list.mjs +33 -0
  175. package/src/lib/locales/en/list.mjs.map +1 -1
  176. package/src/lib/locales/en/panel.d.mts +6 -0
  177. package/src/lib/locales/en/panel.d.ts +6 -0
  178. package/src/lib/locales/en/panel.js +3 -0
  179. package/src/lib/locales/en/panel.js.map +1 -1
  180. package/src/lib/locales/en/panel.mjs +3 -0
  181. package/src/lib/locales/en/panel.mjs.map +1 -1
  182. package/src/lib/locales/en/questions.d.mts +8 -0
  183. package/src/lib/locales/en/questions.d.ts +8 -0
  184. package/src/lib/locales/en/questions.js +9 -0
  185. package/src/lib/locales/en/questions.js.map +1 -1
  186. package/src/lib/locales/en/questions.mjs +9 -0
  187. package/src/lib/locales/en/questions.mjs.map +1 -1
  188. package/src/lib/locales/en/refusals.d.mts +11 -0
  189. package/src/lib/locales/en/refusals.d.ts +11 -0
  190. package/src/lib/locales/en/refusals.js +11 -0
  191. package/src/lib/locales/en/refusals.js.map +1 -1
  192. package/src/lib/locales/en/refusals.mjs +11 -0
  193. package/src/lib/locales/en/refusals.mjs.map +1 -1
  194. package/src/lib/locales/en/work-text.d.mts +58 -0
  195. package/src/lib/locales/en/work-text.d.ts +58 -0
  196. package/src/lib/locales/en/work-text.js +67 -0
  197. package/src/lib/locales/en/work-text.js.map +1 -0
  198. package/src/lib/locales/en/work-text.mjs +64 -0
  199. package/src/lib/locales/en/work-text.mjs.map +1 -0
  200. package/src/lib/number-box.d.mts +66 -0
  201. package/src/lib/number-box.d.ts +66 -0
  202. package/src/lib/number-box.js +153 -0
  203. package/src/lib/number-box.js.map +1 -0
  204. package/src/lib/number-box.mjs +149 -0
  205. package/src/lib/number-box.mjs.map +1 -0
  206. package/src/lib/page-json.d.mts +3 -1
  207. package/src/lib/page-json.d.ts +3 -1
  208. package/src/lib/page-json.js +5 -3
  209. package/src/lib/page-json.js.map +1 -1
  210. package/src/lib/page-json.mjs +5 -3
  211. package/src/lib/page-json.mjs.map +1 -1
  212. package/src/lib/page-tree.js +11 -1
  213. package/src/lib/page-tree.js.map +1 -1
  214. package/src/lib/page-tree.mjs +11 -1
  215. package/src/lib/page-tree.mjs.map +1 -1
  216. package/src/lib/panel-block.js +22 -6
  217. package/src/lib/panel-block.js.map +1 -1
  218. package/src/lib/panel-block.mjs +22 -6
  219. package/src/lib/panel-block.mjs.map +1 -1
  220. package/src/lib/panel-field.js +5 -1
  221. package/src/lib/panel-field.js.map +1 -1
  222. package/src/lib/panel-field.mjs +5 -1
  223. package/src/lib/panel-field.mjs.map +1 -1
  224. package/src/lib/panel-group.js +7 -3
  225. package/src/lib/panel-group.js.map +1 -1
  226. package/src/lib/panel-group.mjs +7 -3
  227. package/src/lib/panel-group.mjs.map +1 -1
  228. package/src/lib/panel-layout.js +20 -15
  229. package/src/lib/panel-layout.js.map +1 -1
  230. package/src/lib/panel-layout.mjs +20 -15
  231. package/src/lib/panel-layout.mjs.map +1 -1
  232. package/src/lib/panel-look.js +28 -14
  233. package/src/lib/panel-look.js.map +1 -1
  234. package/src/lib/panel-look.mjs +28 -14
  235. package/src/lib/panel-look.mjs.map +1 -1
  236. package/src/lib/panel-map.js +53 -20
  237. package/src/lib/panel-map.js.map +1 -1
  238. package/src/lib/panel-map.mjs +53 -20
  239. package/src/lib/panel-map.mjs.map +1 -1
  240. package/src/lib/panel-page.js +5 -1
  241. package/src/lib/panel-page.js.map +1 -1
  242. package/src/lib/panel-page.mjs +5 -1
  243. package/src/lib/panel-page.mjs.map +1 -1
  244. package/src/lib/panel-parts.js +5 -1
  245. package/src/lib/panel-parts.js.map +1 -1
  246. package/src/lib/panel-parts.mjs +5 -1
  247. package/src/lib/panel-parts.mjs.map +1 -1
  248. package/src/lib/picker-commands.d.mts +16 -0
  249. package/src/lib/picker-commands.d.ts +16 -0
  250. package/src/lib/picker-commands.js +61 -0
  251. package/src/lib/picker-commands.js.map +1 -0
  252. package/src/lib/picker-commands.mjs +58 -0
  253. package/src/lib/picker-commands.mjs.map +1 -0
  254. package/src/lib/rules-answers.d.mts +1 -1
  255. package/src/lib/rules-answers.d.ts +1 -1
  256. package/src/lib/rules-answers.js +45 -21
  257. package/src/lib/rules-answers.js.map +1 -1
  258. package/src/lib/rules-answers.mjs +45 -21
  259. package/src/lib/rules-answers.mjs.map +1 -1
  260. package/src/lib/rules-formula-box.d.mts +7 -3
  261. package/src/lib/rules-formula-box.d.ts +7 -3
  262. package/src/lib/rules-formula-box.js +26 -6
  263. package/src/lib/rules-formula-box.js.map +1 -1
  264. package/src/lib/rules-formula-box.mjs +26 -6
  265. package/src/lib/rules-formula-box.mjs.map +1 -1
  266. package/src/lib/rules-formula.js +7 -5
  267. package/src/lib/rules-formula.js.map +1 -1
  268. package/src/lib/rules-formula.mjs +8 -6
  269. package/src/lib/rules-formula.mjs.map +1 -1
  270. package/src/lib/rules-worked-out.js +66 -12
  271. package/src/lib/rules-worked-out.js.map +1 -1
  272. package/src/lib/rules-worked-out.mjs +66 -12
  273. package/src/lib/rules-worked-out.mjs.map +1 -1
  274. package/src/lib/screen-properties.js +9 -2
  275. package/src/lib/screen-properties.js.map +1 -1
  276. package/src/lib/screen-properties.mjs +9 -2
  277. package/src/lib/screen-properties.mjs.map +1 -1
  278. package/src/lib/setting-refusals.d.mts +3 -0
  279. package/src/lib/setting-refusals.d.ts +3 -0
  280. package/src/lib/setting-refusals.js +25 -0
  281. package/src/lib/setting-refusals.js.map +1 -0
  282. package/src/lib/setting-refusals.mjs +22 -0
  283. package/src/lib/setting-refusals.mjs.map +1 -0
  284. package/src/lib/styles-head.d.mts +7 -0
  285. package/src/lib/styles-head.d.ts +7 -0
  286. package/src/lib/styles-head.js +28 -0
  287. package/src/lib/styles-head.js.map +1 -0
  288. package/src/lib/styles-head.mjs +25 -0
  289. package/src/lib/styles-head.mjs.map +1 -0
  290. package/src/lib/styles.d.mts +1 -1
  291. package/src/lib/styles.d.ts +1 -1
  292. package/src/lib/styles.js +9 -2
  293. package/src/lib/styles.js.map +1 -1
  294. package/src/lib/styles.mjs +9 -2
  295. package/src/lib/styles.mjs.map +1 -1
  296. package/src/lib/table-panel.js +16 -5
  297. package/src/lib/table-panel.js.map +1 -1
  298. package/src/lib/table-panel.mjs +16 -5
  299. package/src/lib/table-panel.mjs.map +1 -1
  300. package/src/lib/work-text.d.mts +43 -0
  301. package/src/lib/work-text.d.ts +43 -0
  302. package/src/lib/work-text.js +235 -0
  303. package/src/lib/work-text.js.map +1 -0
  304. package/src/lib/work-text.mjs +227 -0
  305. package/src/lib/work-text.mjs.map +1 -0
@@ -0,0 +1,122 @@
1
+ import { datePart, dateOrderOf, dateShape, guard, readDateText, refusalHint, restingText, typingText, WIDGET_LABELS } from '@fieldia/widgets';
2
+ const pad = (n) => String(n).padStart(2, '0');
3
+ /** A moment read (an instant) as a page's setting writes a day and time, as the browser's box did: its local day and time, to the minute. */
4
+ const localMoment = (instant) => {
5
+ const d = new Date(instant);
6
+ return `${String(d.getFullYear()).padStart(4, '0')}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`;
7
+ };
8
+ export function settingDate(el, host, options) {
9
+ const locale = host.locale ?? 'en';
10
+ const w = host.words.inputs;
11
+ const labels = WIDGET_LABELS[locale] ?? WIDGET_LABELS.en;
12
+ const { kind } = options;
13
+ // Read as it is at each edit: the page's order, and the setting's name, may change while the box is drawn.
14
+ const reader = {
15
+ kind,
16
+ get order() {
17
+ return dateOrderOf({ page: host.getPage() });
18
+ },
19
+ locale,
20
+ get label() {
21
+ return options.label;
22
+ },
23
+ labels,
24
+ };
25
+ const input = el('input', { type: 'text', class: 'fd-input', autocomplete: 'off', spellcheck: 'false', 'aria-label': options.label, placeholder: dateShape(kind, reader.order, labels), ...options.attrs });
26
+ input.dataset['kind'] = kind;
27
+ const hint = refusalHint(input);
28
+ const focused = () => input.ownerDocument.activeElement === input;
29
+ const atRest = (value) => (value ? restingText(value, kind, locale) : '');
30
+ const typing = (value) => (value ? typingText(value, kind, reader.order, locale) : '');
31
+ // The box's input rules come with Fieldia's own date box, in the date part: at once where a date was drawn already.
32
+ let checks = null;
33
+ let gone = false;
34
+ const attach = (part) => {
35
+ if (gone || checks)
36
+ return;
37
+ checks = guard(input, part.dateRules(input, reader), hint);
38
+ if (focused())
39
+ checks.accept();
40
+ };
41
+ if (datePart.loaded)
42
+ attach(datePart.loaded);
43
+ else
44
+ datePart.load().then(attach, () => undefined);
45
+ /** The box showing `text`: what a refused edit goes back to. */
46
+ const shown = (text) => {
47
+ if (input.value !== text)
48
+ input.value = text;
49
+ checks?.accept();
50
+ };
51
+ /** The text the box was last left with, and what was said of it: change, then focusout, are one leaving. */
52
+ let left = null;
53
+ input.addEventListener('focus', () => {
54
+ left = null;
55
+ // Entered, the box shows what is saved as it is typed, all of it chosen, so typing replaces it.
56
+ const text = typing(options.saved());
57
+ if (input.value !== text) {
58
+ shown(text);
59
+ input.setSelectionRange(0, text.length);
60
+ }
61
+ });
62
+ /** The box back to what was saved, and why, said under it. */
63
+ const keep = (why) => {
64
+ const saved = options.saved();
65
+ shown(focused() ? typing(saved) : atRest(saved));
66
+ const stays = saved ? w.settingStays(atRest(saved)) : '';
67
+ const words = [why?.replace(/[.。]$/, ''), stays].filter(Boolean).join('. ') || stays;
68
+ if (words)
69
+ hint.show(words);
70
+ left = { text: input.value, said: words || null };
71
+ };
72
+ /** A value (or none) kept and shown; refused by the designer, what is saved comes back, with why under the box. */
73
+ const kept = (value) => {
74
+ const done = value === (options.saved() ?? null) || options.commit(value) !== false;
75
+ // Refused with no word of why from the designer: never in silence — that it was not taken, at least.
76
+ if (!done)
77
+ return keep(host.getState?.().issues[0] ?? w.settingDateRefused(options.label));
78
+ shown(focused() ? typing(value) : atRest(value));
79
+ hint.hide();
80
+ left = { text: input.value, said: null };
81
+ };
82
+ /** The box left, or Enter pressed: what it holds kept when it reads, else the setting as it was, and why. */
83
+ function leave() {
84
+ if (left && left.text === input.value) {
85
+ if (left.said)
86
+ hint.show(left.said);
87
+ return;
88
+ }
89
+ // Keys held after a refused one ("1x5/10/2026" where the box shows "1"): what was typed, read whole, is no date.
90
+ const held = checks?.held();
91
+ const read = readDateText(held?.text ?? input.value, reader);
92
+ if (held || !read.ok)
93
+ return keep(read.ok ? held?.words : read.words);
94
+ kept(read.value !== null && kind === 'datetime' ? localMoment(read.value) : read.value);
95
+ }
96
+ input.addEventListener('input', () => (left = null));
97
+ input.addEventListener('change', leave);
98
+ // After the guard's own blur, which takes its hint away: what was found is said last, the box at rest in words.
99
+ input.addEventListener('focusout', () => {
100
+ leave();
101
+ shown(atRest(options.saved()));
102
+ if (left)
103
+ left.text = input.value;
104
+ });
105
+ input.addEventListener('keydown', (event) => {
106
+ if (event.key === 'Enter' && !event.isComposing)
107
+ leave();
108
+ });
109
+ return {
110
+ input,
111
+ refresh: () => {
112
+ input.placeholder = dateShape(kind, reader.order, labels);
113
+ if (!focused())
114
+ shown(atRest(options.saved()));
115
+ },
116
+ destroy: () => {
117
+ gone = true;
118
+ checks?.destroy();
119
+ },
120
+ };
121
+ }
122
+ //# sourceMappingURL=date-setting.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date-setting.mjs","sourceRoot":"","sources":["../../../../../libs/designer/src/lib/date-setting.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { type AnswerRule, type ColumnCount, type ColumnsByWidth, type Field, type LabelPlace, type OptionsFrom, type PartLookKind, type HelpShown, type MapFence, type MapLayer, type MapNode, type Page, type PageLook, type SetWhen } from '@fieldia/core';
1
+ import { type AnswerRule, type ColumnCount, type ColumnsByWidth, type Field, type LabelPlace, type OptionsFrom, type PartLookKind, type HelpShown, type JsonValue, type MapFence, type MapLayer, type MapNode, type Page, type PageLook, type SetWhen } from '@fieldia/core';
2
2
  import { type Condition, type ShownWhile } from './conditions.mjs';
3
3
  import { type HeaderCommands } from './header-commands.mjs';
4
4
  import { type ListCommands } from './list-commands.mjs';
@@ -17,6 +17,7 @@ import type { BlockPatch, LookPatch, PartLookPatch, SectionLook } from './layout
17
17
  import type { EachChange } from './layout-several.mjs';
18
18
  import { type PageJsonResult } from './page-json.mjs';
19
19
  import { type AnswerRulePatch } from './rules-commands.mjs';
20
+ import { type HeadCommands } from './head-commands.mjs';
20
21
  import { type StepsCommands } from './steps-commands.mjs';
21
22
  import { type LookValues } from './look-presets.mjs';
22
23
  import { type Fold } from './group-fold.mjs';
@@ -134,7 +135,7 @@ export interface ModelField {
134
135
  name: string;
135
136
  field: Field;
136
137
  }
137
- export interface Designer extends HeaderCommands, ListCommands, ChoiceCommands, InputCommands, StructureCommands, StepsCommands, TableCommands {
138
+ export interface Designer extends HeaderCommands, ListCommands, ChoiceCommands, InputCommands, StructureCommands, StepsCommands, TableCommands, HeadCommands {
138
139
  /** The designer's own words, in its language: English unless `locale` said another it speaks. */
139
140
  readonly words: DesignerWords;
140
141
  /**
@@ -238,7 +239,9 @@ export interface Designer extends HeaderCommands, ListCommands, ChoiceCommands,
238
239
  /** An "Other" choice after the options, with a box for an answer of one's own: for multiple choice and checkboxes. */
239
240
  setOther(id: string, on: boolean): boolean;
240
241
  /** How the field's widget shows it, such as the words at a scale's ends; `null` or nothing takes a setting away. */
241
- setWidgetOptions(id: string, patch: Record<string, string | number | boolean | null>): boolean;
242
+ setWidgetOptions(id: string, patch: Record<string, JsonValue | null>): boolean;
243
+ /** The widget a field is drawn with, by name (`links` for a many2many's links box); null for its type's own. */
244
+ setFieldWidget(id: string, widget: string | null): boolean;
242
245
  /**
243
246
  * Which kinds of file a file upload takes (media types, such as image/*), and
244
247
  * the largest, in bytes; whether it, or an image, takes several files, and as
@@ -303,8 +306,17 @@ export interface Designer extends HeaderCommands, ListCommands, ChoiceCommands,
303
306
  setSeveral(id: string, on: boolean): boolean;
304
307
  undo(): void;
305
308
  redo(): void;
306
- /** Publish the draft as the next version. Returns its number. */
309
+ /**
310
+ * Publish the draft as the next version. Returns its number. A setting still typed in its box is read first, as
311
+ * leaving the box reads it (`settling`): kept when it fits, else the box shows what the setting holds and says why —
312
+ * never a version published under text the person was still typing.
313
+ */
307
314
  publish(): Promise<number>;
315
+ /**
316
+ * How the editors read a setting typed and not yet left — a number, a date, a word — now, as leaving its box would:
317
+ * `publish` runs these first, whatever asked for it (a button's key, the app's own call). Returns what stops it.
318
+ */
319
+ settling(read: () => void): () => void;
308
320
  /** What people would trip over on the page as it is, what would stop them first. */
309
321
  checks(): PageCheck[];
310
322
  /** Do a check's fix: delete an empty page, drop a rule that can never hold, or pick what it is about. */
@@ -1,4 +1,4 @@
1
- import { type AnswerRule, type ColumnCount, type ColumnsByWidth, type Field, type LabelPlace, type OptionsFrom, type PartLookKind, type HelpShown, type MapFence, type MapLayer, type MapNode, type Page, type PageLook, type SetWhen } from '@fieldia/core';
1
+ import { type AnswerRule, type ColumnCount, type ColumnsByWidth, type Field, type LabelPlace, type OptionsFrom, type PartLookKind, type HelpShown, type JsonValue, type MapFence, type MapLayer, type MapNode, type Page, type PageLook, type SetWhen } from '@fieldia/core';
2
2
  import { type Condition, type ShownWhile } from './conditions';
3
3
  import { type HeaderCommands } from './header-commands';
4
4
  import { type ListCommands } from './list-commands';
@@ -17,6 +17,7 @@ import type { BlockPatch, LookPatch, PartLookPatch, SectionLook } from './layout
17
17
  import type { EachChange } from './layout-several';
18
18
  import { type PageJsonResult } from './page-json';
19
19
  import { type AnswerRulePatch } from './rules-commands';
20
+ import { type HeadCommands } from './head-commands';
20
21
  import { type StepsCommands } from './steps-commands';
21
22
  import { type LookValues } from './look-presets';
22
23
  import { type Fold } from './group-fold';
@@ -134,7 +135,7 @@ export interface ModelField {
134
135
  name: string;
135
136
  field: Field;
136
137
  }
137
- export interface Designer extends HeaderCommands, ListCommands, ChoiceCommands, InputCommands, StructureCommands, StepsCommands, TableCommands {
138
+ export interface Designer extends HeaderCommands, ListCommands, ChoiceCommands, InputCommands, StructureCommands, StepsCommands, TableCommands, HeadCommands {
138
139
  /** The designer's own words, in its language: English unless `locale` said another it speaks. */
139
140
  readonly words: DesignerWords;
140
141
  /**
@@ -238,7 +239,9 @@ export interface Designer extends HeaderCommands, ListCommands, ChoiceCommands,
238
239
  /** An "Other" choice after the options, with a box for an answer of one's own: for multiple choice and checkboxes. */
239
240
  setOther(id: string, on: boolean): boolean;
240
241
  /** How the field's widget shows it, such as the words at a scale's ends; `null` or nothing takes a setting away. */
241
- setWidgetOptions(id: string, patch: Record<string, string | number | boolean | null>): boolean;
242
+ setWidgetOptions(id: string, patch: Record<string, JsonValue | null>): boolean;
243
+ /** The widget a field is drawn with, by name (`links` for a many2many's links box); null for its type's own. */
244
+ setFieldWidget(id: string, widget: string | null): boolean;
242
245
  /**
243
246
  * Which kinds of file a file upload takes (media types, such as image/*), and
244
247
  * the largest, in bytes; whether it, or an image, takes several files, and as
@@ -303,8 +306,17 @@ export interface Designer extends HeaderCommands, ListCommands, ChoiceCommands,
303
306
  setSeveral(id: string, on: boolean): boolean;
304
307
  undo(): void;
305
308
  redo(): void;
306
- /** Publish the draft as the next version. Returns its number. */
309
+ /**
310
+ * Publish the draft as the next version. Returns its number. A setting still typed in its box is read first, as
311
+ * leaving the box reads it (`settling`): kept when it fits, else the box shows what the setting holds and says why —
312
+ * never a version published under text the person was still typing.
313
+ */
307
314
  publish(): Promise<number>;
315
+ /**
316
+ * How the editors read a setting typed and not yet left — a number, a date, a word — now, as leaving its box would:
317
+ * `publish` runs these first, whatever asked for it (a button's key, the app's own call). Returns what stops it.
318
+ */
319
+ settling(read: () => void): () => void;
308
320
  /** What people would trip over on the page as it is, what would stop them first. */
309
321
  checks(): PageCheck[];
310
322
  /** Do a check's fix: delete an empty page, drop a rule that can never hold, or pick what it is about. */
@@ -26,6 +26,7 @@ const refusal_1 = require("./refusal");
26
26
  const translations_1 = require("./translations");
27
27
  const page_json_1 = require("./page-json");
28
28
  const rules_commands_1 = require("./rules-commands");
29
+ const head_commands_1 = require("./head-commands");
29
30
  const rules_reads_1 = require("./rules-reads");
30
31
  const steps_commands_1 = require("./steps-commands");
31
32
  const steps_places_1 = require("./steps-places");
@@ -38,6 +39,7 @@ const group_fold_1 = require("./group-fold");
38
39
  const validate_edit_1 = require("./validate-edit");
39
40
  const designer_words_1 = require("./designer-words");
40
41
  const saved_forms_1 = require("./saved-forms");
42
+ const setting_refusals_1 = require("./setting-refusals");
41
43
  /**
42
44
  * The editing model behind the designer: no DOM, so it is tested in Node.
43
45
  *
@@ -173,6 +175,8 @@ function createMemoryPageStore() {
173
175
  const clone = (value) => JSON.parse(JSON.stringify(value));
174
176
  function createDesigner(options) {
175
177
  const store = options.store;
178
+ /** How each editor reads a setting typed and not yet left (`settling`): publish runs them first. */
179
+ const readers = new Set();
176
180
  const locale = (0, designer_words_1.designerLocale)(options.locale);
177
181
  const words = designer_words_1.DESIGNER_WORDS[locale ?? 'en'];
178
182
  const appKinds = (0, kinds_1.registerKinds)(options.kinds ?? []);
@@ -284,7 +288,8 @@ function createDesigner(options) {
284
288
  (0, steps_places_1.forgetGoneTargets)(draft);
285
289
  const checked = checkEdit(page, draft);
286
290
  if (!checked.ok) {
287
- issues = checked.issues.map((issue) => words.refusals.invalid(issue.path, issue.message));
291
+ // A number setting the format refuses is said in its own words, in the designer's language: never a raw path.
292
+ issues = checked.issues.map((issue) => (0, setting_refusals_1.settingRefusal)(issue.path, words) ?? words.refusals.invalid(issue.path, issue.message));
288
293
  notify();
289
294
  return false;
290
295
  }
@@ -387,6 +392,10 @@ function createDesigner(options) {
387
392
  words,
388
393
  locale,
389
394
  getPage: () => page,
395
+ settling(read) {
396
+ readers.add(read);
397
+ return () => void readers.delete(read);
398
+ },
390
399
  modelFields() {
391
400
  const shown = (0, page_tree_1.shownFields)(page);
392
401
  return Object.keys(model)
@@ -1011,6 +1020,15 @@ function createDesigner(options) {
1011
1020
  delete node.options;
1012
1021
  }, `widget:${id}:${Object.keys(patch).join(',')}`);
1013
1022
  },
1023
+ setFieldWidget(id, widget) {
1024
+ return apply((draft) => {
1025
+ const node = fieldNode(draft, id);
1026
+ if (widget)
1027
+ node.widget = widget;
1028
+ else
1029
+ delete node.widget;
1030
+ });
1031
+ },
1014
1032
  setFileRules(id, rules) {
1015
1033
  return apply((draft) => {
1016
1034
  const field = fieldOfType(draft, id, ['binary', 'image'], (w) => w.refusals.onlyFiles, (w, label) => w.refusals.filesFromModel(label));
@@ -1140,6 +1158,9 @@ function createDesigner(options) {
1140
1158
  saveDraft();
1141
1159
  },
1142
1160
  async publish() {
1161
+ // A setting still typed is read first, as leaving its box reads it: what is published is what the boxes show.
1162
+ for (const read of [...readers])
1163
+ read();
1143
1164
  const checked = (0, core_1.validatePage)(page);
1144
1165
  if (!checked.ok)
1145
1166
  throw new Error(words.refusals.cannotPublish);
@@ -1173,7 +1194,7 @@ function createDesigner(options) {
1173
1194
  // panel lane
1174
1195
  setEach: (ids, change) => apply((draft) => several.setEach(draft, ids, change, fromModel)),
1175
1196
  // json lane
1176
- ...(0, page_json_1.pageJsonCommands)({ getPage: () => page, apply }),
1197
+ ...(0, page_json_1.pageJsonCommands)({ getPage: () => page, apply, words }),
1177
1198
  lists: () => clone(options.lists ?? []),
1178
1199
  setOptionsFrom(id, from) {
1179
1200
  const found = (0, page_tree_1.findNode)(page, id);
@@ -1226,6 +1247,8 @@ function createDesigner(options) {
1226
1247
  setWidths: (widths, options) => apply((draft) => settings.setWidths(draft, widths, options?.twelfths)),
1227
1248
  // rules lane
1228
1249
  ...(0, rules_commands_1.rulesCommands)({ apply, getPage: () => page, fromModel }),
1250
+ // A record's head, and the parts it brought: a button's icon alone, toggle and menu; a tab's count; a field's access key.
1251
+ ...(0, head_commands_1.headCommands)({ apply, select: (id) => designer.select(id), model, words }),
1229
1252
  // extend lane
1230
1253
  appKinds: () => [...appKinds],
1231
1254
  templates: () => (0, templates_1.templatesFor)(page, options.templates, locale ?? 'en'),