@fieldia/viewer 0.10.0 → 0.12.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 (110) hide show
  1. package/README.md +126 -1
  2. package/bundle/fieldia.ar.js +2 -2
  3. package/bundle/fieldia.ar.js.map +2 -2
  4. package/bundle/fieldia.de.js +2 -2
  5. package/bundle/fieldia.de.js.map +2 -2
  6. package/bundle/fieldia.fr.js +2 -2
  7. package/bundle/fieldia.fr.js.map +2 -2
  8. package/bundle/fieldia.js +6 -4
  9. package/bundle/fieldia.js.map +4 -4
  10. package/package.json +3 -3
  11. package/src/lib/attachment-preview.d.mts +27 -0
  12. package/src/lib/attachment-preview.d.ts +27 -0
  13. package/src/lib/attachment-preview.js +89 -0
  14. package/src/lib/attachment-preview.js.map +1 -0
  15. package/src/lib/attachment-preview.mjs +86 -0
  16. package/src/lib/attachment-preview.mjs.map +1 -0
  17. package/src/lib/dialog.d.mts +31 -2
  18. package/src/lib/dialog.d.ts +31 -2
  19. package/src/lib/dialog.js +158 -30
  20. package/src/lib/dialog.js.map +1 -1
  21. package/src/lib/dialog.mjs +155 -30
  22. package/src/lib/dialog.mjs.map +1 -1
  23. package/src/lib/hotkeys.d.mts +11 -0
  24. package/src/lib/hotkeys.d.ts +11 -0
  25. package/src/lib/hotkeys.js +34 -0
  26. package/src/lib/hotkeys.js.map +1 -0
  27. package/src/lib/hotkeys.mjs +30 -0
  28. package/src/lib/hotkeys.mjs.map +1 -0
  29. package/src/lib/labels.d.mts +39 -0
  30. package/src/lib/labels.d.ts +39 -0
  31. package/src/lib/labels.js +23 -0
  32. package/src/lib/labels.js.map +1 -1
  33. package/src/lib/labels.mjs +23 -0
  34. package/src/lib/labels.mjs.map +1 -1
  35. package/src/lib/list.d.mts +5 -2
  36. package/src/lib/list.d.ts +5 -2
  37. package/src/lib/list.js +6 -6
  38. package/src/lib/list.js.map +1 -1
  39. package/src/lib/list.mjs +6 -6
  40. package/src/lib/list.mjs.map +1 -1
  41. package/src/lib/locales/ar.js +23 -0
  42. package/src/lib/locales/ar.js.map +1 -1
  43. package/src/lib/locales/ar.mjs +23 -0
  44. package/src/lib/locales/ar.mjs.map +1 -1
  45. package/src/lib/locales/de.js +23 -0
  46. package/src/lib/locales/de.js.map +1 -1
  47. package/src/lib/locales/de.mjs +23 -0
  48. package/src/lib/locales/de.mjs.map +1 -1
  49. package/src/lib/locales/fr.js +23 -0
  50. package/src/lib/locales/fr.js.map +1 -1
  51. package/src/lib/locales/fr.mjs +23 -0
  52. package/src/lib/locales/fr.mjs.map +1 -1
  53. package/src/lib/look.d.mts +7 -3
  54. package/src/lib/look.d.ts +7 -3
  55. package/src/lib/look.js +72 -15
  56. package/src/lib/look.js.map +1 -1
  57. package/src/lib/look.mjs +72 -15
  58. package/src/lib/look.mjs.map +1 -1
  59. package/src/lib/open.d.mts +30 -0
  60. package/src/lib/open.d.ts +30 -0
  61. package/src/lib/open.js +92 -0
  62. package/src/lib/open.js.map +1 -0
  63. package/src/lib/open.mjs +89 -0
  64. package/src/lib/open.mjs.map +1 -0
  65. package/src/lib/place.d.mts +2 -0
  66. package/src/lib/place.d.ts +2 -0
  67. package/src/lib/place.js.map +1 -1
  68. package/src/lib/place.mjs.map +1 -1
  69. package/src/lib/record-bar.d.mts +56 -0
  70. package/src/lib/record-bar.d.ts +56 -0
  71. package/src/lib/record-bar.js +237 -0
  72. package/src/lib/record-bar.js.map +1 -0
  73. package/src/lib/record-bar.mjs +234 -0
  74. package/src/lib/record-bar.mjs.map +1 -0
  75. package/src/lib/record-styles.d.mts +9 -0
  76. package/src/lib/record-styles.d.ts +9 -0
  77. package/src/lib/record-styles.js +83 -0
  78. package/src/lib/record-styles.js.map +1 -0
  79. package/src/lib/record-styles.mjs +79 -0
  80. package/src/lib/record-styles.mjs.map +1 -0
  81. package/src/lib/related.d.mts +26 -3
  82. package/src/lib/related.d.ts +26 -3
  83. package/src/lib/related.js +37 -10
  84. package/src/lib/related.js.map +1 -1
  85. package/src/lib/related.mjs +36 -10
  86. package/src/lib/related.mjs.map +1 -1
  87. package/src/lib/say.d.mts +11 -0
  88. package/src/lib/say.d.ts +11 -0
  89. package/src/lib/say.js +61 -0
  90. package/src/lib/say.js.map +1 -0
  91. package/src/lib/say.mjs +58 -0
  92. package/src/lib/say.mjs.map +1 -0
  93. package/src/lib/tab-strip.d.mts +17 -0
  94. package/src/lib/tab-strip.d.ts +17 -0
  95. package/src/lib/tab-strip.js +51 -0
  96. package/src/lib/tab-strip.js.map +1 -0
  97. package/src/lib/tab-strip.mjs +48 -0
  98. package/src/lib/tab-strip.mjs.map +1 -0
  99. package/src/lib/value-words.d.mts +10 -0
  100. package/src/lib/value-words.d.ts +10 -0
  101. package/src/lib/value-words.js +38 -0
  102. package/src/lib/value-words.js.map +1 -0
  103. package/src/lib/value-words.mjs +35 -0
  104. package/src/lib/value-words.mjs.map +1 -0
  105. package/src/lib/viewer.d.mts +54 -5
  106. package/src/lib/viewer.d.ts +54 -5
  107. package/src/lib/viewer.js +924 -297
  108. package/src/lib/viewer.js.map +1 -1
  109. package/src/lib/viewer.mjs +926 -299
  110. package/src/lib/viewer.mjs.map +1 -1
package/src/lib/dialog.js CHANGED
@@ -1,41 +1,75 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FIRST_FIELD = void 0;
4
+ exports.focusField = focusField;
3
5
  exports.openFormDialog = openFormDialog;
6
+ exports.openFormPanel = openFormPanel;
4
7
  exports.openSearchDialog = openSearchDialog;
5
8
  const widgets_1 = require("@fieldia/widgets");
6
9
  const labels_1 = require("./labels");
7
10
  const focus_trap_1 = require("./focus-trap");
8
11
  const look_1 = require("./look");
12
+ const hotkeys_1 = require("./hotkeys");
9
13
  const viewer_1 = require("./viewer");
10
14
  let dialogs = 0;
15
+ /** The first box to type or choose in, where a page opened takes the focus. */
16
+ exports.FIRST_FIELD = 'input:not([type="hidden"]), select, textarea, [contenteditable="true"]';
17
+ /** The box of the first field shown that takes the focus as the record opens (a node's `focus`), if there is one. */
18
+ function focusField(scope) {
19
+ const wrapper = [...scope.querySelectorAll('.fd-field[data-focus]')].find((one) => !one.closest('[hidden]'));
20
+ return wrapper?.querySelector(exports.FIRST_FIELD) ?? null;
21
+ }
22
+ /** The dialogs' way to make an element of a document: a tag, its attributes, and its words. */
23
+ const maker = (doc) => (tag, attrs = {}, text) => {
24
+ const element = doc.createElement(tag);
25
+ for (const [name, value] of Object.entries(attrs))
26
+ element.setAttribute(name, value);
27
+ if (text !== undefined)
28
+ element.textContent = text;
29
+ return element;
30
+ };
11
31
  function openFormDialog(options) {
32
+ return openForm(options, `fd-size-${options.size ?? 'medium'}`);
33
+ }
34
+ /**
35
+ * A page in a side panel: the dialog's twin, at full height along the
36
+ * inline-end edge (the left, right to left) unless it names another `side` —
37
+ * the whole width along the top or the bottom — the page behind dimmed but in
38
+ * sight; a full-screen sheet on a phone, from above for the top, from below
39
+ * for the rest. It saves, or in "values" mode hands back its values with
40
+ * Done, as the dialog does; Escape and × ask first when there are changes to
41
+ * lose. A dialog opened from it sits above it, and a panel opened from it
42
+ * stacks over it, this one stepped back from its own edge.
43
+ */
44
+ function openFormPanel(options) {
45
+ const side = options.side ?? 'end';
46
+ return openForm(options, `fd-form-panel ${side === 'top' || side === 'bottom' ? `fd-height-${options.height ?? 'medium'}` : `fd-width-${options.width ?? 'medium'}`}`, side);
47
+ }
48
+ /** A dialog or a panel (from its side): a page in a box with a head, a body that scrolls and a foot; `shape` is the box's own classes. */
49
+ function openForm(options, shape, side) {
50
+ const panel = !!side;
12
51
  const doc = options.container?.ownerDocument ?? document;
13
52
  const container = options.container ?? doc.body;
14
53
  const opener = doc.activeElement instanceof doc.defaultView.HTMLElement ? doc.activeElement : null;
15
54
  const labels = { ...viewer_1.VIEWER_LABELS[(0, labels_1.ownLocale)(options.locale)], ...options.labels };
16
55
  const id = `fd-dialog-${++dialogs}`;
17
- const make = (tag, attrs = {}, text) => {
18
- const element = doc.createElement(tag);
19
- for (const [name, value] of Object.entries(attrs))
20
- element.setAttribute(name, value);
21
- if (text !== undefined)
22
- element.textContent = text;
23
- return element;
24
- };
56
+ const make = maker(doc);
25
57
  const title = make('h2', { id: `${id}-title`, class: 'fd-form-dialog-title' }, options.title);
26
58
  const closeButton = make('button', { type: 'button', class: 'fd-dialog-close', 'aria-label': labels.close }, '×');
27
59
  const body = make('div', { class: 'fd-form-dialog-body' });
28
60
  const discard = make('button', { type: 'button', class: 'fd-button' }, labels.discard);
29
- const saveClose = make('button', { type: 'button', class: 'fd-button fd-button-primary' }, labels.saveClose);
61
+ const saveClose = make('button', { type: 'button', class: 'fd-button fd-button-primary' }, panel && options.mode === 'values' ? labels.done : labels.saveClose);
30
62
  const box = make('div', {
31
63
  // Its own tokens and skin: the dialog sits outside the page that opened it.
32
- class: `fd-theme fd-form-dialog fd-size-${options.size ?? 'medium'}`,
64
+ class: `fd-theme fd-form-dialog ${shape}`,
33
65
  'data-fd-skin': options.skin ?? 'underline',
34
66
  role: 'dialog',
35
67
  'aria-modal': 'true',
36
68
  'aria-labelledby': title.id,
37
69
  tabindex: '-1',
38
70
  });
71
+ if (side)
72
+ box.setAttribute('data-side', side);
39
73
  if (options.dir)
40
74
  box.setAttribute('dir', options.dir);
41
75
  // One look for the box and the page in it: the page's own, else the opener's.
@@ -43,16 +77,37 @@ function openFormDialog(options) {
43
77
  (0, look_1.applyLook)(box, look);
44
78
  box.append(make('div', { class: 'fd-form-dialog-head' }), body, make('div', { class: 'fd-actions fd-actions-end fd-form-dialog-foot' }));
45
79
  box.firstElementChild?.append(title, closeButton);
46
- box.lastElementChild?.append(discard, saveClose);
47
- const backdrop = make('div', { class: 'fd-dialog-backdrop fd-form-dialog-backdrop' });
80
+ // A page's own buttons at its foot, as a wizard's, stand in place of Discard and Save & Close.
81
+ const footer = options.page.layout.type === 'sections' || options.page.layout.type === 'sheet' ? (options.page.layout.footer ?? []) : [];
82
+ const own = footer.map((node) => ({ node, button: make('button', { type: 'button', class: `fd-button fd-button-${node.style ?? 'secondary'}`, 'data-node': node.id }, node.label) }));
83
+ for (const { node, button } of own)
84
+ if (node.hotkey)
85
+ (0, hotkeys_1.hotkeyOn)(button, node.hotkey, node.label);
86
+ box.lastElementChild?.append(...(own.length ? own.map((b) => b.button) : [discard, saveClose]));
87
+ const backdrop = make('div', { class: `fd-dialog-backdrop fd-form-dialog-backdrop${panel ? ' fd-form-panel-backdrop' : ''}` });
48
88
  backdrop.append(box);
89
+ // The panel this one opens over steps back while it is open.
90
+ const under = panel ? [...doc.querySelectorAll('.fd-form-panel')].pop() : undefined;
91
+ under?.setAttribute('data-behind', '');
49
92
  container.append(backdrop);
50
- const handle = (0, viewer_1.mountViewer)(body, { ...options, page: look && !options.page.look ? { ...options.page, look } : options.page, showActions: false });
93
+ // A host of its own, so its steps run here too: a `close` step closes it unsaved.
94
+ const handle = (0, viewer_1.mountViewer)(body, {
95
+ ...options,
96
+ page: look && !options.page.look ? { ...options.page, look } : options.page,
97
+ showActions: false,
98
+ // A dialog has no pager or breadcrumbs: they belong to the record under it.
99
+ records: undefined,
100
+ breadcrumbs: undefined,
101
+ host: { ...options.host, close: () => discard.click() },
102
+ });
103
+ // A panel runs the way its page does, its language's way unless told: the inline end it sits at is the left, right to left.
104
+ if (panel && handle.element.dir)
105
+ backdrop.dir = handle.element.dir;
51
106
  let done = false;
52
107
  if (options.recompute)
53
108
  recalculate(handle.form, options.page.fields, options.recompute, () => done);
54
- // Into the dialog: its first field, once the record is in, or the dialog itself meanwhile.
55
- const firstField = () => body.querySelector('input:not([type="hidden"]), select, textarea, [contenteditable="true"]');
109
+ // Into the dialog: its field that takes the focus (focus) or its first, once the record is in, or the dialog itself meanwhile.
110
+ const firstField = () => focusField(body) ?? body.querySelector(exports.FIRST_FIELD);
56
111
  (firstField() ?? box).focus();
57
112
  void handle.form.settled().then(() => {
58
113
  if (doc.activeElement === box || !box.contains(doc.activeElement))
@@ -68,9 +123,44 @@ function openFormDialog(options) {
68
123
  const result = { saved, recordId: state.recordId ?? null, values: state.values };
69
124
  handle.destroy();
70
125
  backdrop.remove();
126
+ under?.removeAttribute('data-behind');
71
127
  opener?.focus();
72
128
  resolve(result);
73
129
  };
130
+ /** "Discard your changes?" over the panel, the focus on Cancel; true for Discard. Its keys are its own. */
131
+ const ask = () => new Promise((answer) => {
132
+ const was = doc.activeElement;
133
+ const text = make('p', { id: `${id}-ask` }, labels.discardChanges);
134
+ const no = make('button', { type: 'button', class: 'fd-button' }, labels.cancel);
135
+ const yes = make('button', { type: 'button', class: 'fd-button fd-button-primary' }, labels.discard);
136
+ const buttons = make('div', { class: 'fd-actions fd-actions-end' });
137
+ const question = make('div', { class: 'fd-dialog', role: 'alertdialog', 'aria-modal': 'true', 'aria-labelledby': text.id });
138
+ const shade = make('div', { class: 'fd-dialog-backdrop' });
139
+ buttons.append(no, yes);
140
+ question.append(text, buttons);
141
+ shade.append(question);
142
+ const end = (discarding) => {
143
+ shade.remove();
144
+ was?.focus();
145
+ answer(discarding);
146
+ };
147
+ no.addEventListener('click', () => end(false));
148
+ yes.addEventListener('click', () => end(true));
149
+ shade.addEventListener('keydown', (event) => {
150
+ event.stopPropagation();
151
+ if (event.key === 'Escape')
152
+ end(false);
153
+ else
154
+ (0, focus_trap_1.keepTabIn)(question, event);
155
+ });
156
+ box.append(shade);
157
+ no.focus();
158
+ });
159
+ /** Escape and ×: a panel with changes in it asks first; a dialog closes at once, as it always has. */
160
+ const leave = async () => {
161
+ if (!panel || !handle.form.getState().dirty.length || (await ask()))
162
+ close(false);
163
+ };
74
164
  saveClose.addEventListener('click', async () => {
75
165
  saveClose.disabled = true;
76
166
  const accepted = options.mode === 'values' ? handle.check() : await handle.save();
@@ -79,8 +169,49 @@ function openFormDialog(options) {
79
169
  close(true);
80
170
  });
81
171
  discard.addEventListener('click', () => close(false));
82
- closeButton.addEventListener('click', () => close(false));
172
+ // A footer button runs its steps; once they saved or sent, the dialog closes with the answers.
173
+ let saved = false;
174
+ handle.on('save', () => (saved = true));
175
+ handle.on('send', () => (saved = true));
176
+ const shown = () => {
177
+ for (const { node, button } of own)
178
+ button.hidden = handle.form.node(node.id).invisible;
179
+ };
180
+ if (own.length) {
181
+ shown();
182
+ handle.form.subscribe(shown);
183
+ }
184
+ for (const { node, button } of own) {
185
+ button.addEventListener('click', async () => {
186
+ if (button.hasAttribute('aria-busy'))
187
+ return;
188
+ button.setAttribute('aria-busy', 'true');
189
+ saved = false;
190
+ const result = await handle.form.runAction(node.id);
191
+ button.removeAttribute('aria-busy');
192
+ if (done)
193
+ return;
194
+ if (saved)
195
+ close(true);
196
+ // A check or a save that stopped them shows its problems, as Save & Close does.
197
+ else if (result.reason === 'check' || result.reason === 'save')
198
+ handle.check();
199
+ });
200
+ }
201
+ closeButton.addEventListener('click', leave);
202
+ // A footer button's key, with Alt, and the keys shown while Alt is held.
203
+ box.addEventListener('keyup', (event) => event.key === 'Alt' && box.removeAttribute('data-hotkeys'));
83
204
  box.addEventListener('keydown', (event) => {
205
+ if (event.key === 'Alt')
206
+ box.setAttribute('data-hotkeys', '');
207
+ const key = (0, hotkeys_1.hotkeyOf)(event);
208
+ const pressed = key ? own.find(({ node, button }) => node.hotkey === key && !button.hidden && !button.disabled)?.button : undefined;
209
+ if (pressed) {
210
+ event.preventDefault();
211
+ box.removeAttribute('data-hotkeys');
212
+ pressed.click();
213
+ return;
214
+ }
84
215
  // Ctrl+Enter is Save & Close from wherever the cursor is, even after a field used the Enter
85
216
  // (a tag box adding its tag), taking what is still being typed. The grid keeps its own keys.
86
217
  if (event.key === 'Enter' && (event.ctrlKey || event.metaKey) && !event.isComposing) {
@@ -88,7 +219,11 @@ function openFormDialog(options) {
88
219
  return;
89
220
  event.preventDefault();
90
221
  doc.activeElement?.dispatchEvent(new Event('change', { bubbles: true }));
91
- saveClose.click();
222
+ // With buttons of its own, the page's primary one; else Save & Close.
223
+ if (own.length)
224
+ own.find(({ node, button }) => node.style === 'primary' && !button.hidden)?.button.click();
225
+ else
226
+ saveClose.click();
92
227
  return;
93
228
  }
94
229
  // A key a field used itself (Escape closing a list) is not the dialog's.
@@ -96,7 +231,7 @@ function openFormDialog(options) {
96
231
  return;
97
232
  if (event.key === 'Escape') {
98
233
  event.preventDefault();
99
- close(false);
234
+ void leave();
100
235
  }
101
236
  else
102
237
  (0, focus_trap_1.keepTabIn)(box, event);
@@ -117,10 +252,10 @@ function recalculate(form, fields, recompute, closed) {
117
252
  if (closed() || JSON.stringify(form.getState().values) !== now)
118
253
  return; // a newer answer is on its way
119
254
  writing = true;
120
- for (const [name, value] of Object.entries(next)) {
121
- if (name in fields && JSON.stringify(values[name] ?? null) !== JSON.stringify(value ?? null))
122
- form.setValue(name, value);
123
- }
255
+ // The answer is the app's change, not a person's: the page's change steps do not run for it.
256
+ const changed = Object.fromEntries(Object.entries(next).filter(([name, value]) => name in fields && JSON.stringify(values[name] ?? null) !== JSON.stringify(value ?? null)));
257
+ if (Object.keys(changed).length)
258
+ form.setValues(changed);
124
259
  writing = false;
125
260
  seen = JSON.stringify(form.getState().values);
126
261
  }, () => undefined);
@@ -139,14 +274,7 @@ function openSearchDialog(options) {
139
274
  const labels = viewer_1.VIEWER_LABELS[locale];
140
275
  const words = widgets_1.WIDGET_LABELS[locale];
141
276
  const id = `fd-dialog-${++dialogs}`;
142
- const make = (tag, attrs = {}, text) => {
143
- const element = doc.createElement(tag);
144
- for (const [name, value] of Object.entries(attrs))
145
- element.setAttribute(name, value);
146
- if (text !== undefined)
147
- element.textContent = text;
148
- return element;
149
- };
277
+ const make = maker(doc);
150
278
  const title = make('h2', { id: `${id}-title`, class: 'fd-form-dialog-title' }, options.title);
151
279
  const closeButton = make('button', { type: 'button', class: 'fd-dialog-close', 'aria-label': labels.close }, '×');
152
280
  const query = make('input', { type: 'search', class: 'fd-input', 'aria-label': words.search, placeholder: words.search, 'aria-controls': `${id}-list`, autocomplete: 'off' });
@@ -1 +1 @@
1
- {"version":3,"file":"dialog.js","sourceRoot":"","sources":["../../../../../libs/viewer/src/lib/dialog.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dialog.js","sourceRoot":"","sources":["../../../../../libs/viewer/src/lib/dialog.ts"],"names":[],"mappings":"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"}
@@ -2,36 +2,67 @@ import { WIDGET_LABELS } from '@fieldia/widgets';
2
2
  import { ownLocale } from './labels.mjs';
3
3
  import { keepTabIn } from './focus-trap.mjs';
4
4
  import { applyLook } from './look.mjs';
5
+ import { hotkeyOf, hotkeyOn } from './hotkeys.mjs';
5
6
  import { mountViewer, VIEWER_LABELS } from './viewer.mjs';
6
7
  let dialogs = 0;
8
+ /** The first box to type or choose in, where a page opened takes the focus. */
9
+ export const FIRST_FIELD = 'input:not([type="hidden"]), select, textarea, [contenteditable="true"]';
10
+ /** The box of the first field shown that takes the focus as the record opens (a node's `focus`), if there is one. */
11
+ export function focusField(scope) {
12
+ const wrapper = [...scope.querySelectorAll('.fd-field[data-focus]')].find((one) => !one.closest('[hidden]'));
13
+ return wrapper?.querySelector(FIRST_FIELD) ?? null;
14
+ }
15
+ /** The dialogs' way to make an element of a document: a tag, its attributes, and its words. */
16
+ const maker = (doc) => (tag, attrs = {}, text) => {
17
+ const element = doc.createElement(tag);
18
+ for (const [name, value] of Object.entries(attrs))
19
+ element.setAttribute(name, value);
20
+ if (text !== undefined)
21
+ element.textContent = text;
22
+ return element;
23
+ };
7
24
  export function openFormDialog(options) {
25
+ return openForm(options, `fd-size-${options.size ?? 'medium'}`);
26
+ }
27
+ /**
28
+ * A page in a side panel: the dialog's twin, at full height along the
29
+ * inline-end edge (the left, right to left) unless it names another `side` —
30
+ * the whole width along the top or the bottom — the page behind dimmed but in
31
+ * sight; a full-screen sheet on a phone, from above for the top, from below
32
+ * for the rest. It saves, or in "values" mode hands back its values with
33
+ * Done, as the dialog does; Escape and × ask first when there are changes to
34
+ * lose. A dialog opened from it sits above it, and a panel opened from it
35
+ * stacks over it, this one stepped back from its own edge.
36
+ */
37
+ export function openFormPanel(options) {
38
+ const side = options.side ?? 'end';
39
+ return openForm(options, `fd-form-panel ${side === 'top' || side === 'bottom' ? `fd-height-${options.height ?? 'medium'}` : `fd-width-${options.width ?? 'medium'}`}`, side);
40
+ }
41
+ /** A dialog or a panel (from its side): a page in a box with a head, a body that scrolls and a foot; `shape` is the box's own classes. */
42
+ function openForm(options, shape, side) {
43
+ const panel = !!side;
8
44
  const doc = options.container?.ownerDocument ?? document;
9
45
  const container = options.container ?? doc.body;
10
46
  const opener = doc.activeElement instanceof doc.defaultView.HTMLElement ? doc.activeElement : null;
11
47
  const labels = { ...VIEWER_LABELS[ownLocale(options.locale)], ...options.labels };
12
48
  const id = `fd-dialog-${++dialogs}`;
13
- const make = (tag, attrs = {}, text) => {
14
- const element = doc.createElement(tag);
15
- for (const [name, value] of Object.entries(attrs))
16
- element.setAttribute(name, value);
17
- if (text !== undefined)
18
- element.textContent = text;
19
- return element;
20
- };
49
+ const make = maker(doc);
21
50
  const title = make('h2', { id: `${id}-title`, class: 'fd-form-dialog-title' }, options.title);
22
51
  const closeButton = make('button', { type: 'button', class: 'fd-dialog-close', 'aria-label': labels.close }, '×');
23
52
  const body = make('div', { class: 'fd-form-dialog-body' });
24
53
  const discard = make('button', { type: 'button', class: 'fd-button' }, labels.discard);
25
- const saveClose = make('button', { type: 'button', class: 'fd-button fd-button-primary' }, labels.saveClose);
54
+ const saveClose = make('button', { type: 'button', class: 'fd-button fd-button-primary' }, panel && options.mode === 'values' ? labels.done : labels.saveClose);
26
55
  const box = make('div', {
27
56
  // Its own tokens and skin: the dialog sits outside the page that opened it.
28
- class: `fd-theme fd-form-dialog fd-size-${options.size ?? 'medium'}`,
57
+ class: `fd-theme fd-form-dialog ${shape}`,
29
58
  'data-fd-skin': options.skin ?? 'underline',
30
59
  role: 'dialog',
31
60
  'aria-modal': 'true',
32
61
  'aria-labelledby': title.id,
33
62
  tabindex: '-1',
34
63
  });
64
+ if (side)
65
+ box.setAttribute('data-side', side);
35
66
  if (options.dir)
36
67
  box.setAttribute('dir', options.dir);
37
68
  // One look for the box and the page in it: the page's own, else the opener's.
@@ -39,16 +70,37 @@ export function openFormDialog(options) {
39
70
  applyLook(box, look);
40
71
  box.append(make('div', { class: 'fd-form-dialog-head' }), body, make('div', { class: 'fd-actions fd-actions-end fd-form-dialog-foot' }));
41
72
  box.firstElementChild?.append(title, closeButton);
42
- box.lastElementChild?.append(discard, saveClose);
43
- const backdrop = make('div', { class: 'fd-dialog-backdrop fd-form-dialog-backdrop' });
73
+ // A page's own buttons at its foot, as a wizard's, stand in place of Discard and Save & Close.
74
+ const footer = options.page.layout.type === 'sections' || options.page.layout.type === 'sheet' ? (options.page.layout.footer ?? []) : [];
75
+ const own = footer.map((node) => ({ node, button: make('button', { type: 'button', class: `fd-button fd-button-${node.style ?? 'secondary'}`, 'data-node': node.id }, node.label) }));
76
+ for (const { node, button } of own)
77
+ if (node.hotkey)
78
+ hotkeyOn(button, node.hotkey, node.label);
79
+ box.lastElementChild?.append(...(own.length ? own.map((b) => b.button) : [discard, saveClose]));
80
+ const backdrop = make('div', { class: `fd-dialog-backdrop fd-form-dialog-backdrop${panel ? ' fd-form-panel-backdrop' : ''}` });
44
81
  backdrop.append(box);
82
+ // The panel this one opens over steps back while it is open.
83
+ const under = panel ? [...doc.querySelectorAll('.fd-form-panel')].pop() : undefined;
84
+ under?.setAttribute('data-behind', '');
45
85
  container.append(backdrop);
46
- const handle = mountViewer(body, { ...options, page: look && !options.page.look ? { ...options.page, look } : options.page, showActions: false });
86
+ // A host of its own, so its steps run here too: a `close` step closes it unsaved.
87
+ const handle = mountViewer(body, {
88
+ ...options,
89
+ page: look && !options.page.look ? { ...options.page, look } : options.page,
90
+ showActions: false,
91
+ // A dialog has no pager or breadcrumbs: they belong to the record under it.
92
+ records: undefined,
93
+ breadcrumbs: undefined,
94
+ host: { ...options.host, close: () => discard.click() },
95
+ });
96
+ // A panel runs the way its page does, its language's way unless told: the inline end it sits at is the left, right to left.
97
+ if (panel && handle.element.dir)
98
+ backdrop.dir = handle.element.dir;
47
99
  let done = false;
48
100
  if (options.recompute)
49
101
  recalculate(handle.form, options.page.fields, options.recompute, () => done);
50
- // Into the dialog: its first field, once the record is in, or the dialog itself meanwhile.
51
- const firstField = () => body.querySelector('input:not([type="hidden"]), select, textarea, [contenteditable="true"]');
102
+ // Into the dialog: its field that takes the focus (focus) or its first, once the record is in, or the dialog itself meanwhile.
103
+ const firstField = () => focusField(body) ?? body.querySelector(FIRST_FIELD);
52
104
  (firstField() ?? box).focus();
53
105
  void handle.form.settled().then(() => {
54
106
  if (doc.activeElement === box || !box.contains(doc.activeElement))
@@ -64,9 +116,44 @@ export function openFormDialog(options) {
64
116
  const result = { saved, recordId: state.recordId ?? null, values: state.values };
65
117
  handle.destroy();
66
118
  backdrop.remove();
119
+ under?.removeAttribute('data-behind');
67
120
  opener?.focus();
68
121
  resolve(result);
69
122
  };
123
+ /** "Discard your changes?" over the panel, the focus on Cancel; true for Discard. Its keys are its own. */
124
+ const ask = () => new Promise((answer) => {
125
+ const was = doc.activeElement;
126
+ const text = make('p', { id: `${id}-ask` }, labels.discardChanges);
127
+ const no = make('button', { type: 'button', class: 'fd-button' }, labels.cancel);
128
+ const yes = make('button', { type: 'button', class: 'fd-button fd-button-primary' }, labels.discard);
129
+ const buttons = make('div', { class: 'fd-actions fd-actions-end' });
130
+ const question = make('div', { class: 'fd-dialog', role: 'alertdialog', 'aria-modal': 'true', 'aria-labelledby': text.id });
131
+ const shade = make('div', { class: 'fd-dialog-backdrop' });
132
+ buttons.append(no, yes);
133
+ question.append(text, buttons);
134
+ shade.append(question);
135
+ const end = (discarding) => {
136
+ shade.remove();
137
+ was?.focus();
138
+ answer(discarding);
139
+ };
140
+ no.addEventListener('click', () => end(false));
141
+ yes.addEventListener('click', () => end(true));
142
+ shade.addEventListener('keydown', (event) => {
143
+ event.stopPropagation();
144
+ if (event.key === 'Escape')
145
+ end(false);
146
+ else
147
+ keepTabIn(question, event);
148
+ });
149
+ box.append(shade);
150
+ no.focus();
151
+ });
152
+ /** Escape and ×: a panel with changes in it asks first; a dialog closes at once, as it always has. */
153
+ const leave = async () => {
154
+ if (!panel || !handle.form.getState().dirty.length || (await ask()))
155
+ close(false);
156
+ };
70
157
  saveClose.addEventListener('click', async () => {
71
158
  saveClose.disabled = true;
72
159
  const accepted = options.mode === 'values' ? handle.check() : await handle.save();
@@ -75,8 +162,49 @@ export function openFormDialog(options) {
75
162
  close(true);
76
163
  });
77
164
  discard.addEventListener('click', () => close(false));
78
- closeButton.addEventListener('click', () => close(false));
165
+ // A footer button runs its steps; once they saved or sent, the dialog closes with the answers.
166
+ let saved = false;
167
+ handle.on('save', () => (saved = true));
168
+ handle.on('send', () => (saved = true));
169
+ const shown = () => {
170
+ for (const { node, button } of own)
171
+ button.hidden = handle.form.node(node.id).invisible;
172
+ };
173
+ if (own.length) {
174
+ shown();
175
+ handle.form.subscribe(shown);
176
+ }
177
+ for (const { node, button } of own) {
178
+ button.addEventListener('click', async () => {
179
+ if (button.hasAttribute('aria-busy'))
180
+ return;
181
+ button.setAttribute('aria-busy', 'true');
182
+ saved = false;
183
+ const result = await handle.form.runAction(node.id);
184
+ button.removeAttribute('aria-busy');
185
+ if (done)
186
+ return;
187
+ if (saved)
188
+ close(true);
189
+ // A check or a save that stopped them shows its problems, as Save & Close does.
190
+ else if (result.reason === 'check' || result.reason === 'save')
191
+ handle.check();
192
+ });
193
+ }
194
+ closeButton.addEventListener('click', leave);
195
+ // A footer button's key, with Alt, and the keys shown while Alt is held.
196
+ box.addEventListener('keyup', (event) => event.key === 'Alt' && box.removeAttribute('data-hotkeys'));
79
197
  box.addEventListener('keydown', (event) => {
198
+ if (event.key === 'Alt')
199
+ box.setAttribute('data-hotkeys', '');
200
+ const key = hotkeyOf(event);
201
+ const pressed = key ? own.find(({ node, button }) => node.hotkey === key && !button.hidden && !button.disabled)?.button : undefined;
202
+ if (pressed) {
203
+ event.preventDefault();
204
+ box.removeAttribute('data-hotkeys');
205
+ pressed.click();
206
+ return;
207
+ }
80
208
  // Ctrl+Enter is Save & Close from wherever the cursor is, even after a field used the Enter
81
209
  // (a tag box adding its tag), taking what is still being typed. The grid keeps its own keys.
82
210
  if (event.key === 'Enter' && (event.ctrlKey || event.metaKey) && !event.isComposing) {
@@ -84,7 +212,11 @@ export function openFormDialog(options) {
84
212
  return;
85
213
  event.preventDefault();
86
214
  doc.activeElement?.dispatchEvent(new Event('change', { bubbles: true }));
87
- saveClose.click();
215
+ // With buttons of its own, the page's primary one; else Save & Close.
216
+ if (own.length)
217
+ own.find(({ node, button }) => node.style === 'primary' && !button.hidden)?.button.click();
218
+ else
219
+ saveClose.click();
88
220
  return;
89
221
  }
90
222
  // A key a field used itself (Escape closing a list) is not the dialog's.
@@ -92,7 +224,7 @@ export function openFormDialog(options) {
92
224
  return;
93
225
  if (event.key === 'Escape') {
94
226
  event.preventDefault();
95
- close(false);
227
+ void leave();
96
228
  }
97
229
  else
98
230
  keepTabIn(box, event);
@@ -113,10 +245,10 @@ function recalculate(form, fields, recompute, closed) {
113
245
  if (closed() || JSON.stringify(form.getState().values) !== now)
114
246
  return; // a newer answer is on its way
115
247
  writing = true;
116
- for (const [name, value] of Object.entries(next)) {
117
- if (name in fields && JSON.stringify(values[name] ?? null) !== JSON.stringify(value ?? null))
118
- form.setValue(name, value);
119
- }
248
+ // The answer is the app's change, not a person's: the page's change steps do not run for it.
249
+ const changed = Object.fromEntries(Object.entries(next).filter(([name, value]) => name in fields && JSON.stringify(values[name] ?? null) !== JSON.stringify(value ?? null)));
250
+ if (Object.keys(changed).length)
251
+ form.setValues(changed);
120
252
  writing = false;
121
253
  seen = JSON.stringify(form.getState().values);
122
254
  }, () => undefined);
@@ -135,14 +267,7 @@ export function openSearchDialog(options) {
135
267
  const labels = VIEWER_LABELS[locale];
136
268
  const words = WIDGET_LABELS[locale];
137
269
  const id = `fd-dialog-${++dialogs}`;
138
- const make = (tag, attrs = {}, text) => {
139
- const element = doc.createElement(tag);
140
- for (const [name, value] of Object.entries(attrs))
141
- element.setAttribute(name, value);
142
- if (text !== undefined)
143
- element.textContent = text;
144
- return element;
145
- };
270
+ const make = maker(doc);
146
271
  const title = make('h2', { id: `${id}-title`, class: 'fd-form-dialog-title' }, options.title);
147
272
  const closeButton = make('button', { type: 'button', class: 'fd-dialog-close', 'aria-label': labels.close }, '×');
148
273
  const query = make('input', { type: 'search', class: 'fd-input', 'aria-label': words.search, placeholder: words.search, 'aria-controls': `${id}-list`, autocomplete: 'off' });