@fieldia/viewer 0.10.0 → 0.11.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 (70) 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 +4 -4
  9. package/bundle/fieldia.js.map +4 -4
  10. package/package.json +3 -3
  11. package/src/lib/dialog.d.mts +29 -2
  12. package/src/lib/dialog.d.ts +29 -2
  13. package/src/lib/dialog.js +94 -27
  14. package/src/lib/dialog.js.map +1 -1
  15. package/src/lib/dialog.mjs +92 -27
  16. package/src/lib/dialog.mjs.map +1 -1
  17. package/src/lib/labels.d.mts +14 -0
  18. package/src/lib/labels.d.ts +14 -0
  19. package/src/lib/labels.js +6 -0
  20. package/src/lib/labels.js.map +1 -1
  21. package/src/lib/labels.mjs +6 -0
  22. package/src/lib/labels.mjs.map +1 -1
  23. package/src/lib/list.d.mts +3 -2
  24. package/src/lib/list.d.ts +3 -2
  25. package/src/lib/list.js +5 -5
  26. package/src/lib/list.js.map +1 -1
  27. package/src/lib/list.mjs +5 -5
  28. package/src/lib/list.mjs.map +1 -1
  29. package/src/lib/locales/ar.js +6 -0
  30. package/src/lib/locales/ar.js.map +1 -1
  31. package/src/lib/locales/ar.mjs +6 -0
  32. package/src/lib/locales/ar.mjs.map +1 -1
  33. package/src/lib/locales/de.js +6 -0
  34. package/src/lib/locales/de.js.map +1 -1
  35. package/src/lib/locales/de.mjs +6 -0
  36. package/src/lib/locales/de.mjs.map +1 -1
  37. package/src/lib/locales/fr.js +6 -0
  38. package/src/lib/locales/fr.js.map +1 -1
  39. package/src/lib/locales/fr.mjs +6 -0
  40. package/src/lib/locales/fr.mjs.map +1 -1
  41. package/src/lib/look.d.mts +7 -3
  42. package/src/lib/look.d.ts +7 -3
  43. package/src/lib/look.js +72 -15
  44. package/src/lib/look.js.map +1 -1
  45. package/src/lib/look.mjs +72 -15
  46. package/src/lib/look.mjs.map +1 -1
  47. package/src/lib/open.d.mts +24 -0
  48. package/src/lib/open.d.ts +24 -0
  49. package/src/lib/open.js +81 -0
  50. package/src/lib/open.js.map +1 -0
  51. package/src/lib/open.mjs +78 -0
  52. package/src/lib/open.mjs.map +1 -0
  53. package/src/lib/related.d.mts +19 -0
  54. package/src/lib/related.d.ts +19 -0
  55. package/src/lib/related.js +15 -2
  56. package/src/lib/related.js.map +1 -1
  57. package/src/lib/related.mjs +14 -2
  58. package/src/lib/related.mjs.map +1 -1
  59. package/src/lib/say.d.mts +9 -0
  60. package/src/lib/say.d.ts +9 -0
  61. package/src/lib/say.js +45 -0
  62. package/src/lib/say.js.map +1 -0
  63. package/src/lib/say.mjs +42 -0
  64. package/src/lib/say.mjs.map +1 -0
  65. package/src/lib/viewer.d.mts +33 -5
  66. package/src/lib/viewer.d.ts +33 -5
  67. package/src/lib/viewer.js +464 -279
  68. package/src/lib/viewer.js.map +1 -1
  69. package/src/lib/viewer.mjs +465 -280
  70. package/src/lib/viewer.mjs.map +1 -1
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.nameFieldOf = nameFieldOf;
4
+ exports.findPage = findPage;
4
5
  exports.pageDialogs = pageDialogs;
5
6
  const dialog_1 = require("./dialog");
6
7
  /** The field a page's records are named by: its title, or "name", or its first line of text. */
@@ -27,6 +28,17 @@ function valuesPage(fields, title, readonly) {
27
28
  },
28
29
  };
29
30
  }
31
+ /** The page the app gives for a request: from `pages`, and for a model from `relatedPages` after it. A promise when it answers later. */
32
+ function findPage(options, request) {
33
+ const { pages, relatedPages } = options;
34
+ const key = 'model' in request ? request.model : request.version === undefined ? request.id : `${request.id}@${request.version}`;
35
+ const found = typeof pages === 'function' ? pages(request) : pages && Object.prototype.hasOwnProperty.call(pages, key) ? pages[key] : null;
36
+ if (found instanceof Promise)
37
+ return found.then((page) => page ?? null);
38
+ if (found || !('model' in request))
39
+ return found ?? null;
40
+ return (typeof relatedPages === 'function' ? relatedPages(request.model) : relatedPages?.[request.model]) ?? null;
41
+ }
30
42
  /** Only finding and making linked records: values edited in a dialog are no record of the source's to load, save or recalculate. */
31
43
  function lookupsOf(source) {
32
44
  if (!source)
@@ -38,7 +50,7 @@ function lookupsOf(source) {
38
50
  }
39
51
  /** The dialogs a page's widgets may open, made from the viewer's own options. */
40
52
  function pageDialogs(options) {
41
- const pageFor = (model) => (typeof options.relatedPages === 'function' ? options.relatedPages(model) : options.relatedPages?.[model]) ?? null;
53
+ const pageFor = (model) => findPage(options, { model });
42
54
  // A dialog's page looks and reads like the page that opened it, and can open dialogs of its own.
43
55
  const shared = {
44
56
  locale: options.locale,
@@ -46,6 +58,7 @@ function pageDialogs(options) {
46
58
  dir: options.dir,
47
59
  widgets: options.widgets,
48
60
  preferences: options.preferences,
61
+ pages: options.pages,
49
62
  relatedPages: options.relatedPages,
50
63
  translate: options.translate,
51
64
  look: options.page.look,
@@ -53,7 +66,7 @@ function pageDialogs(options) {
53
66
  return {
54
67
  canOpen: (model) => pageFor(model) !== null,
55
68
  async openRecord(model, request) {
56
- const related = pageFor(model);
69
+ const related = await pageFor(model);
57
70
  if (!related)
58
71
  return null;
59
72
  const nameField = nameFieldOf(related);
@@ -1 +1 @@
1
- {"version":3,"file":"related.js","sourceRoot":"","sources":["../../../../../libs/viewer/src/lib/related.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"related.js","sourceRoot":"","sources":["../../../../../libs/viewer/src/lib/related.ts"],"names":[],"mappings":"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"}
@@ -23,6 +23,17 @@ function valuesPage(fields, title, readonly) {
23
23
  },
24
24
  };
25
25
  }
26
+ /** The page the app gives for a request: from `pages`, and for a model from `relatedPages` after it. A promise when it answers later. */
27
+ export function findPage(options, request) {
28
+ const { pages, relatedPages } = options;
29
+ const key = 'model' in request ? request.model : request.version === undefined ? request.id : `${request.id}@${request.version}`;
30
+ const found = typeof pages === 'function' ? pages(request) : pages && Object.prototype.hasOwnProperty.call(pages, key) ? pages[key] : null;
31
+ if (found instanceof Promise)
32
+ return found.then((page) => page ?? null);
33
+ if (found || !('model' in request))
34
+ return found ?? null;
35
+ return (typeof relatedPages === 'function' ? relatedPages(request.model) : relatedPages?.[request.model]) ?? null;
36
+ }
26
37
  /** Only finding and making linked records: values edited in a dialog are no record of the source's to load, save or recalculate. */
27
38
  function lookupsOf(source) {
28
39
  if (!source)
@@ -34,7 +45,7 @@ function lookupsOf(source) {
34
45
  }
35
46
  /** The dialogs a page's widgets may open, made from the viewer's own options. */
36
47
  export function pageDialogs(options) {
37
- const pageFor = (model) => (typeof options.relatedPages === 'function' ? options.relatedPages(model) : options.relatedPages?.[model]) ?? null;
48
+ const pageFor = (model) => findPage(options, { model });
38
49
  // A dialog's page looks and reads like the page that opened it, and can open dialogs of its own.
39
50
  const shared = {
40
51
  locale: options.locale,
@@ -42,6 +53,7 @@ export function pageDialogs(options) {
42
53
  dir: options.dir,
43
54
  widgets: options.widgets,
44
55
  preferences: options.preferences,
56
+ pages: options.pages,
45
57
  relatedPages: options.relatedPages,
46
58
  translate: options.translate,
47
59
  look: options.page.look,
@@ -49,7 +61,7 @@ export function pageDialogs(options) {
49
61
  return {
50
62
  canOpen: (model) => pageFor(model) !== null,
51
63
  async openRecord(model, request) {
52
- const related = pageFor(model);
64
+ const related = await pageFor(model);
53
65
  if (!related)
54
66
  return null;
55
67
  const nameField = nameFieldOf(related);
@@ -1 +1 @@
1
- {"version":3,"file":"related.mjs","sourceRoot":"","sources":["../../../../../libs/viewer/src/lib/related.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"related.mjs","sourceRoot":"","sources":["../../../../../libs/viewer/src/lib/related.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAG5D,gGAAgG;AAChG,MAAM,UAAU,WAAW,CAAC,IAAU;IACpC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK;QAAE,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC;IAC7F,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC;IACvC,OAAO,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;AACzF,CAAC;AAID,8EAA8E;AAC9E,SAAS,UAAU,CAAC,MAA6B,EAAE,KAAa,EAAE,QAAiB;IACjF,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAmB,CAAC;IACrJ,OAAO;QACL,OAAO,EAAE,KAAK;QACd,EAAE,EAAE,QAAQ;QACZ,KAAK;QACL,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE;QACzC,MAAM,EAAE,KAAK;QACb,MAAM,EAAE;YACN,IAAI,EAAE,UAAU;YAChB,EAAE,EAAE,QAAQ;YACZ,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,OAAgB,EAAE,EAAE,EAAE,UAAU,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;SAC/K;KACF,CAAC;AACJ,CAAC;AAgBD,yIAAyI;AACzI,MAAM,UAAU,QAAQ,CAAC,OAAsD,EAAE,OAAoB;IACnG,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC;IACxC,MAAM,GAAG,GAAG,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,EAAE,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IACjI,MAAM,KAAK,GAAG,OAAO,KAAK,KAAK,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3I,IAAI,KAAK,YAAY,OAAO;QAAE,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC;IACxE,IAAI,KAAK,IAAI,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC;QAAE,OAAO,KAAK,IAAI,IAAI,CAAC;IACzD,OAAO,CAAC,OAAO,YAAY,KAAK,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC;AACpH,CAAC;AAED,oIAAoI;AACpI,SAAS,SAAS,CAAC,MAA8B;IAC/C,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IAC9B,OAAO;QACL,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,OAAsB,EAAE,EAAE,CAAC,MAAM,CAAC,MAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzF,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,OAAsB,EAAE,EAAE,CAAC,MAAM,CAAC,MAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC1F,CAAC;AACJ,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,WAAW,CAAC,OAAsB;IAChD,MAAM,OAAO,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IAChE,iGAAiG;IACjG,MAAM,MAAM,GAAG;QACb,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI;KACxB,CAAC;IACF,OAAO;QACL,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI;QAC3C,KAAK,CAAC,UAAU,CAAC,KAAK,EAAE,OAAO;YAC7B,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,CAAC;YACrC,IAAI,CAAC,OAAO;gBAAE,OAAO,IAAI,CAAC;YAC1B,MAAM,SAAS,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;YACvC,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC;gBAClC,GAAG,MAAM;gBACT,IAAI,EAAE,OAAO;gBACb,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,IAAI;gBAClC,MAAM,EAAE,OAAO,CAAC,IAAI,IAAI,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS;gBAC7E,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,IAAI,EAAE,OAAO;aACd,CAAC,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,QAAQ,KAAK,IAAI;gBAAE,OAAO,IAAI,CAAC;YAC3D,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACzD,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,QAAQ,EAAE,KAAK,EAAE,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QACjH,CAAC;QACD,UAAU,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,gBAAgB,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAClL,KAAK,CAAC,UAAU,CAAC,OAAO;YACtB,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC;gBAClC,GAAG,MAAM;gBACT,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,QAAQ,KAAK,IAAI,CAAC;gBAC1E,UAAU,EAAE,SAAS,CAAC,OAAO,CAAC,UAAU,CAAC;gBACzC,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,IAAI,EAAE,QAAQ;gBACd,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC/D,CAAC,CAAC;YACH,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;QAC7C,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { Tone } from '@fieldia/core';
2
+ import type { El } from './dom.mjs';
3
+ /**
4
+ * Words a step says, as toasts at the foot of the screen: each in its tone,
5
+ * one over another, in a polite live region inside the form — so they wear its
6
+ * skin, scheme and direction. Each goes by itself after a moment, but not
7
+ * while the pointer or the focus is on it, and at once with its ×.
8
+ */
9
+ export declare function sayer(root: HTMLElement, el: El, dismiss: string): (message: string, tone: Tone) => void;
@@ -0,0 +1,9 @@
1
+ import type { Tone } from '@fieldia/core';
2
+ import type { El } from './dom';
3
+ /**
4
+ * Words a step says, as toasts at the foot of the screen: each in its tone,
5
+ * one over another, in a polite live region inside the form — so they wear its
6
+ * skin, scheme and direction. Each goes by itself after a moment, but not
7
+ * while the pointer or the focus is on it, and at once with its ×.
8
+ */
9
+ export declare function sayer(root: HTMLElement, el: El, dismiss: string): (message: string, tone: Tone) => void;
package/src/lib/say.js ADDED
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sayer = sayer;
4
+ /** How long words stay before they go by themselves: a warning or a danger stays longer. */
5
+ const STAY_MS = 6000;
6
+ const STAY_LONG_MS = 10000;
7
+ /** The most toasts on screen at once: the oldest give way. */
8
+ const MOST = 4;
9
+ /**
10
+ * Words a step says, as toasts at the foot of the screen: each in its tone,
11
+ * one over another, in a polite live region inside the form — so they wear its
12
+ * skin, scheme and direction. Each goes by itself after a moment, but not
13
+ * while the pointer or the focus is on it, and at once with its ×.
14
+ */
15
+ function sayer(root, el, dismiss) {
16
+ // There before anything is said, so a screen reader hears what comes into it.
17
+ const region = el('div', { class: 'fd-says', role: 'status', 'aria-live': 'polite' });
18
+ root.append(region);
19
+ return (message, tone) => {
20
+ const close = el('button', { type: 'button', class: 'fd-alert-close', 'aria-label': dismiss }, '×');
21
+ const toast = el('div', { class: 'fd-say', 'data-tone': tone }, el('span', {}, message), close);
22
+ // Its edge in its tone's colour, from the scheme's own: a danger is the error colour.
23
+ toast.style.setProperty('--fd-tone', `var(--fd-${tone === 'danger' ? 'error' : tone})`);
24
+ let timer;
25
+ const hold = () => clearTimeout(timer);
26
+ const go = () => {
27
+ hold();
28
+ toast.remove();
29
+ };
30
+ const wait = () => {
31
+ hold();
32
+ timer = setTimeout(go, tone === 'warning' || tone === 'danger' ? STAY_LONG_MS : STAY_MS);
33
+ };
34
+ close.addEventListener('click', go);
35
+ toast.addEventListener('mouseenter', hold);
36
+ toast.addEventListener('focusin', hold);
37
+ toast.addEventListener('mouseleave', wait);
38
+ toast.addEventListener('focusout', wait);
39
+ region.append(toast);
40
+ while (region.children.length > MOST)
41
+ region.firstElementChild?.remove();
42
+ wait();
43
+ };
44
+ }
45
+ //# sourceMappingURL=say.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"say.js","sourceRoot":"","sources":["../../../../../libs/viewer/src/lib/say.ts"],"names":[],"mappings":";;AAeA,sBA4BC;AAxCD,4FAA4F;AAC5F,MAAM,OAAO,GAAG,IAAI,CAAC;AACrB,MAAM,YAAY,GAAG,KAAK,CAAC;AAC3B,8DAA8D;AAC9D,MAAM,IAAI,GAAG,CAAC,CAAC;AAEf;;;;;GAKG;AACH,SAAgB,KAAK,CAAC,IAAiB,EAAE,EAAM,EAAE,OAAe;IAC9D,8EAA8E;IAC9E,MAAM,MAAM,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,CAAC;IACtF,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACpB,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE;QACvB,MAAM,KAAK,GAAG,EAAE,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,OAAO,EAAE,EAAE,GAAG,CAAC,CAAC;QACpG,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,MAAM,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,KAAK,CAAC,CAAC;QAChG,sFAAsF;QACtF,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,WAAW,EAAE,YAAY,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;QACxF,IAAI,KAAgD,CAAC;QACrD,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QACvC,MAAM,EAAE,GAAG,GAAG,EAAE;YACd,IAAI,EAAE,CAAC;YACP,KAAK,CAAC,MAAM,EAAE,CAAC;QACjB,CAAC,CAAC;QACF,MAAM,IAAI,GAAG,GAAG,EAAE;YAChB,IAAI,EAAE,CAAC;YACP,KAAK,GAAG,UAAU,CAAC,EAAE,EAAE,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAC3F,CAAC,CAAC;QACF,KAAK,CAAC,gBAAgB,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACpC,KAAK,CAAC,gBAAgB,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;QAC3C,KAAK,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QACxC,KAAK,CAAC,gBAAgB,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;QAC3C,KAAK,CAAC,gBAAgB,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QACzC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACrB,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,IAAI;YAAE,MAAM,CAAC,iBAAiB,EAAE,MAAM,EAAE,CAAC;QACzE,IAAI,EAAE,CAAC;IACT,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,42 @@
1
+ /** How long words stay before they go by themselves: a warning or a danger stays longer. */
2
+ const STAY_MS = 6000;
3
+ const STAY_LONG_MS = 10000;
4
+ /** The most toasts on screen at once: the oldest give way. */
5
+ const MOST = 4;
6
+ /**
7
+ * Words a step says, as toasts at the foot of the screen: each in its tone,
8
+ * one over another, in a polite live region inside the form — so they wear its
9
+ * skin, scheme and direction. Each goes by itself after a moment, but not
10
+ * while the pointer or the focus is on it, and at once with its ×.
11
+ */
12
+ export function sayer(root, el, dismiss) {
13
+ // There before anything is said, so a screen reader hears what comes into it.
14
+ const region = el('div', { class: 'fd-says', role: 'status', 'aria-live': 'polite' });
15
+ root.append(region);
16
+ return (message, tone) => {
17
+ const close = el('button', { type: 'button', class: 'fd-alert-close', 'aria-label': dismiss }, '×');
18
+ const toast = el('div', { class: 'fd-say', 'data-tone': tone }, el('span', {}, message), close);
19
+ // Its edge in its tone's colour, from the scheme's own: a danger is the error colour.
20
+ toast.style.setProperty('--fd-tone', `var(--fd-${tone === 'danger' ? 'error' : tone})`);
21
+ let timer;
22
+ const hold = () => clearTimeout(timer);
23
+ const go = () => {
24
+ hold();
25
+ toast.remove();
26
+ };
27
+ const wait = () => {
28
+ hold();
29
+ timer = setTimeout(go, tone === 'warning' || tone === 'danger' ? STAY_LONG_MS : STAY_MS);
30
+ };
31
+ close.addEventListener('click', go);
32
+ toast.addEventListener('mouseenter', hold);
33
+ toast.addEventListener('focusin', hold);
34
+ toast.addEventListener('mouseleave', wait);
35
+ toast.addEventListener('focusout', wait);
36
+ region.append(toast);
37
+ while (region.children.length > MOST)
38
+ region.firstElementChild?.remove();
39
+ wait();
40
+ };
41
+ }
42
+ //# sourceMappingURL=say.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"say.mjs","sourceRoot":"","sources":["../../../../../libs/viewer/src/lib/say.ts"],"names":[],"mappings":"AAGA,4FAA4F;AAC5F,MAAM,OAAO,GAAG,IAAI,CAAC;AACrB,MAAM,YAAY,GAAG,KAAK,CAAC;AAC3B,8DAA8D;AAC9D,MAAM,IAAI,GAAG,CAAC,CAAC;AAEf;;;;;GAKG;AACH,MAAM,UAAU,KAAK,CAAC,IAAiB,EAAE,EAAM,EAAE,OAAe;IAC9D,8EAA8E;IAC9E,MAAM,MAAM,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,CAAC;IACtF,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACpB,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE;QACvB,MAAM,KAAK,GAAG,EAAE,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,OAAO,EAAE,EAAE,GAAG,CAAC,CAAC;QACpG,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,MAAM,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,KAAK,CAAC,CAAC;QAChG,sFAAsF;QACtF,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,WAAW,EAAE,YAAY,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;QACxF,IAAI,KAAgD,CAAC;QACrD,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QACvC,MAAM,EAAE,GAAG,GAAG,EAAE;YACd,IAAI,EAAE,CAAC;YACP,KAAK,CAAC,MAAM,EAAE,CAAC;QACjB,CAAC,CAAC;QACF,MAAM,IAAI,GAAG,GAAG,EAAE;YAChB,IAAI,EAAE,CAAC;YACP,KAAK,GAAG,UAAU,CAAC,EAAE,EAAE,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAC3F,CAAC,CAAC;QACF,KAAK,CAAC,gBAAgB,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACpC,KAAK,CAAC,gBAAgB,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;QAC3C,KAAK,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QACxC,KAAK,CAAC,gBAAgB,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;QAC3C,KAAK,CAAC,gBAAgB,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QACzC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACrB,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,IAAI;YAAE,MAAM,CAAC,iBAAiB,EAAE,MAAM,EAAE,CAAC;QACzE,IAAI,EAAE,CAAC;IACT,CAAC,CAAC;AACJ,CAAC"}
@@ -1,14 +1,16 @@
1
- import { type Form, type FormOptions, type Page, type RecordId, type Locale } from '@fieldia/core';
1
+ import { type ActionHost, type ActionStep, type FormEvents, type Form, type FormOptions, type Page, type RecordId, type Locale, type OpenRequest, type OpenResult, type RunContext, type RunResult, type Values } from '@fieldia/core';
2
2
  import { type IconSet, type PreferenceStore, type WidgetFactory } from '@fieldia/widgets';
3
+ import { type PageFinder } from './related.mjs';
3
4
  export type Skin = 'underline' | 'outlined';
4
5
  import { type ViewerLabels } from './labels.mjs';
5
6
  export { VIEWER_LABELS, DEFAULT_LABELS, type ViewerLabels } from './labels.mjs';
7
+ export type { PageFinder, PageRequest } from './related.mjs';
6
8
  /** Fill a slot with the app's own content. Return a function to clean up. */
7
9
  export type SlotRenderer = (element: HTMLElement, context: {
8
10
  form: Form;
9
11
  name: string;
10
12
  }) => void | (() => void);
11
- export interface ViewerOptions extends Omit<FormOptions, 'page'> {
13
+ export interface ViewerOptions extends Omit<FormOptions, 'page' | 'host'> {
12
14
  page: Page;
13
15
  /** A form made elsewhere, to share one record between two views. */
14
16
  form?: Form;
@@ -29,16 +31,24 @@ export interface ViewerOptions extends Omit<FormOptions, 'page'> {
29
31
  /** Labels that win over the language's defaults. */
30
32
  labels?: Partial<ViewerLabels>;
31
33
  dir?: 'ltr' | 'rtl';
32
- /** How to ask before a button with `confirm` runs. Defaults to a small dialog. */
34
+ /** How a question is asked: a button's `confirm`, and an `ask` step. Defaults to the viewer's own small box. */
33
35
  confirm?: (message: string) => Promise<boolean>;
34
36
  /** Where a person's choices about the page's look are kept, such as a table's columns. The browser's storage by default. */
35
37
  preferences?: PreferenceStore;
36
38
  /** False when something around the page saves it, such as a dialog: the page's own Save, Discard and Submit stay hidden. */
37
39
  showActions?: boolean;
38
40
  /**
39
- * Pages for the models links point to, so a link can show its record in a
40
- * dialog: Create and edit…, and the button that opens the linked record.
41
+ * The app's pages, for the parts that show another page. A saved form placed
42
+ * in this one (a `form` part) is drawn from the page asked for by its id —
43
+ * `{ id, version }` when it keeps to a version; and a link shows its record
44
+ * in a dialog (Create and edit…, and the button that opens the linked
45
+ * record) with the page asked for by the model it points to, `{ model }`.
46
+ * Either a record of pages by key — a model, a page's id, or `id@version`
47
+ * for a version kept to — or a function asked for each, which may answer
48
+ * with a promise: a saved form shows a quiet placeholder until it does.
41
49
  */
50
+ pages?: PageFinder;
51
+ /** Pages by the models links point to: what `pages` gives by model, as earlier versions had it. Still read. */
42
52
  relatedPages?: Record<string, Page> | ((model: string) => Page | null | undefined);
43
53
  /**
44
54
  * The app's own icons, or replacements for Fieldia's, by the name a page
@@ -69,6 +79,18 @@ export interface ViewerOptions extends Omit<FormOptions, 'page'> {
69
79
  translate?: (text: string) => string;
70
80
  /** A list page: a row was opened, by a click or by Enter. The app shows the record. */
71
81
  onOpenRecord?: (id: RecordId) => void;
82
+ /**
83
+ * What the page's steps ask of the screen, the viewer does itself: a page
84
+ * opened (in a dialog, a side panel, or this form's place, with Back), words
85
+ * said (a toast), a question asked (its own box, or `confirm`), a tab shown.
86
+ * Give any of these to do it your own way; the rest stay the viewer's.
87
+ */
88
+ host?: Partial<ActionHost>;
89
+ /**
90
+ * A page a step opens: answer with how it ended to open it your own way —
91
+ * your router, your own dialog — or with undefined to let the viewer open it.
92
+ */
93
+ onOpen?: (request: OpenRequest) => Promise<OpenResult> | undefined;
72
94
  }
73
95
  export interface ViewerHandle {
74
96
  readonly form: Form;
@@ -81,6 +103,12 @@ export interface ViewerHandle {
81
103
  /** Lock or unlock the whole form. */
82
104
  setReadonly(readonly: boolean): void;
83
105
  isReadonly(): boolean;
106
+ /** Listen to one of the form's events — change, save, send, action, run, step, open; returns what stops listening. */
107
+ on<E extends keyof FormEvents>(event: E, listener: (event: FormEvents[E]) => void): () => void;
108
+ /** Write several fields at once, as the app: the page's change steps do not run for it. */
109
+ setValues(values: Values): void;
110
+ /** Run steps on the form, as a button would. */
111
+ run(steps: readonly ActionStep[], context?: RunContext): Promise<RunResult>;
84
112
  destroy(): void;
85
113
  }
86
114
  /**
@@ -1,14 +1,16 @@
1
- import { type Form, type FormOptions, type Page, type RecordId, type Locale } from '@fieldia/core';
1
+ import { type ActionHost, type ActionStep, type FormEvents, type Form, type FormOptions, type Page, type RecordId, type Locale, type OpenRequest, type OpenResult, type RunContext, type RunResult, type Values } from '@fieldia/core';
2
2
  import { type IconSet, type PreferenceStore, type WidgetFactory } from '@fieldia/widgets';
3
+ import { type PageFinder } from './related';
3
4
  export type Skin = 'underline' | 'outlined';
4
5
  import { type ViewerLabels } from './labels';
5
6
  export { VIEWER_LABELS, DEFAULT_LABELS, type ViewerLabels } from './labels';
7
+ export type { PageFinder, PageRequest } from './related';
6
8
  /** Fill a slot with the app's own content. Return a function to clean up. */
7
9
  export type SlotRenderer = (element: HTMLElement, context: {
8
10
  form: Form;
9
11
  name: string;
10
12
  }) => void | (() => void);
11
- export interface ViewerOptions extends Omit<FormOptions, 'page'> {
13
+ export interface ViewerOptions extends Omit<FormOptions, 'page' | 'host'> {
12
14
  page: Page;
13
15
  /** A form made elsewhere, to share one record between two views. */
14
16
  form?: Form;
@@ -29,16 +31,24 @@ export interface ViewerOptions extends Omit<FormOptions, 'page'> {
29
31
  /** Labels that win over the language's defaults. */
30
32
  labels?: Partial<ViewerLabels>;
31
33
  dir?: 'ltr' | 'rtl';
32
- /** How to ask before a button with `confirm` runs. Defaults to a small dialog. */
34
+ /** How a question is asked: a button's `confirm`, and an `ask` step. Defaults to the viewer's own small box. */
33
35
  confirm?: (message: string) => Promise<boolean>;
34
36
  /** Where a person's choices about the page's look are kept, such as a table's columns. The browser's storage by default. */
35
37
  preferences?: PreferenceStore;
36
38
  /** False when something around the page saves it, such as a dialog: the page's own Save, Discard and Submit stay hidden. */
37
39
  showActions?: boolean;
38
40
  /**
39
- * Pages for the models links point to, so a link can show its record in a
40
- * dialog: Create and edit…, and the button that opens the linked record.
41
+ * The app's pages, for the parts that show another page. A saved form placed
42
+ * in this one (a `form` part) is drawn from the page asked for by its id —
43
+ * `{ id, version }` when it keeps to a version; and a link shows its record
44
+ * in a dialog (Create and edit…, and the button that opens the linked
45
+ * record) with the page asked for by the model it points to, `{ model }`.
46
+ * Either a record of pages by key — a model, a page's id, or `id@version`
47
+ * for a version kept to — or a function asked for each, which may answer
48
+ * with a promise: a saved form shows a quiet placeholder until it does.
41
49
  */
50
+ pages?: PageFinder;
51
+ /** Pages by the models links point to: what `pages` gives by model, as earlier versions had it. Still read. */
42
52
  relatedPages?: Record<string, Page> | ((model: string) => Page | null | undefined);
43
53
  /**
44
54
  * The app's own icons, or replacements for Fieldia's, by the name a page
@@ -69,6 +79,18 @@ export interface ViewerOptions extends Omit<FormOptions, 'page'> {
69
79
  translate?: (text: string) => string;
70
80
  /** A list page: a row was opened, by a click or by Enter. The app shows the record. */
71
81
  onOpenRecord?: (id: RecordId) => void;
82
+ /**
83
+ * What the page's steps ask of the screen, the viewer does itself: a page
84
+ * opened (in a dialog, a side panel, or this form's place, with Back), words
85
+ * said (a toast), a question asked (its own box, or `confirm`), a tab shown.
86
+ * Give any of these to do it your own way; the rest stay the viewer's.
87
+ */
88
+ host?: Partial<ActionHost>;
89
+ /**
90
+ * A page a step opens: answer with how it ended to open it your own way —
91
+ * your router, your own dialog — or with undefined to let the viewer open it.
92
+ */
93
+ onOpen?: (request: OpenRequest) => Promise<OpenResult> | undefined;
72
94
  }
73
95
  export interface ViewerHandle {
74
96
  readonly form: Form;
@@ -81,6 +103,12 @@ export interface ViewerHandle {
81
103
  /** Lock or unlock the whole form. */
82
104
  setReadonly(readonly: boolean): void;
83
105
  isReadonly(): boolean;
106
+ /** Listen to one of the form's events — change, save, send, action, run, step, open; returns what stops listening. */
107
+ on<E extends keyof FormEvents>(event: E, listener: (event: FormEvents[E]) => void): () => void;
108
+ /** Write several fields at once, as the app: the page's change steps do not run for it. */
109
+ setValues(values: Values): void;
110
+ /** Run steps on the form, as a button would. */
111
+ run(steps: readonly ActionStep[], context?: RunContext): Promise<RunResult>;
84
112
  destroy(): void;
85
113
  }
86
114
  /**