@fieldia/viewer 0.11.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 (103) hide show
  1. package/bundle/fieldia.ar.js +2 -2
  2. package/bundle/fieldia.ar.js.map +2 -2
  3. package/bundle/fieldia.de.js +2 -2
  4. package/bundle/fieldia.de.js.map +2 -2
  5. package/bundle/fieldia.fr.js +2 -2
  6. package/bundle/fieldia.fr.js.map +2 -2
  7. package/bundle/fieldia.js +6 -4
  8. package/bundle/fieldia.js.map +4 -4
  9. package/package.json +3 -3
  10. package/src/lib/attachment-preview.d.mts +27 -0
  11. package/src/lib/attachment-preview.d.ts +27 -0
  12. package/src/lib/attachment-preview.js +89 -0
  13. package/src/lib/attachment-preview.js.map +1 -0
  14. package/src/lib/attachment-preview.mjs +86 -0
  15. package/src/lib/attachment-preview.mjs.map +1 -0
  16. package/src/lib/dialog.d.mts +2 -0
  17. package/src/lib/dialog.d.ts +2 -0
  18. package/src/lib/dialog.js +65 -4
  19. package/src/lib/dialog.js.map +1 -1
  20. package/src/lib/dialog.mjs +64 -4
  21. package/src/lib/dialog.mjs.map +1 -1
  22. package/src/lib/hotkeys.d.mts +11 -0
  23. package/src/lib/hotkeys.d.ts +11 -0
  24. package/src/lib/hotkeys.js +34 -0
  25. package/src/lib/hotkeys.js.map +1 -0
  26. package/src/lib/hotkeys.mjs +30 -0
  27. package/src/lib/hotkeys.mjs.map +1 -0
  28. package/src/lib/labels.d.mts +25 -0
  29. package/src/lib/labels.d.ts +25 -0
  30. package/src/lib/labels.js +17 -0
  31. package/src/lib/labels.js.map +1 -1
  32. package/src/lib/labels.mjs +17 -0
  33. package/src/lib/labels.mjs.map +1 -1
  34. package/src/lib/list.d.mts +3 -1
  35. package/src/lib/list.d.ts +3 -1
  36. package/src/lib/list.js +1 -1
  37. package/src/lib/list.js.map +1 -1
  38. package/src/lib/list.mjs +1 -1
  39. package/src/lib/list.mjs.map +1 -1
  40. package/src/lib/locales/ar.js +17 -0
  41. package/src/lib/locales/ar.js.map +1 -1
  42. package/src/lib/locales/ar.mjs +17 -0
  43. package/src/lib/locales/ar.mjs.map +1 -1
  44. package/src/lib/locales/de.js +17 -0
  45. package/src/lib/locales/de.js.map +1 -1
  46. package/src/lib/locales/de.mjs +17 -0
  47. package/src/lib/locales/de.mjs.map +1 -1
  48. package/src/lib/locales/fr.js +17 -0
  49. package/src/lib/locales/fr.js.map +1 -1
  50. package/src/lib/locales/fr.mjs +17 -0
  51. package/src/lib/locales/fr.mjs.map +1 -1
  52. package/src/lib/open.d.mts +7 -1
  53. package/src/lib/open.d.ts +7 -1
  54. package/src/lib/open.js +19 -8
  55. package/src/lib/open.js.map +1 -1
  56. package/src/lib/open.mjs +20 -9
  57. package/src/lib/open.mjs.map +1 -1
  58. package/src/lib/place.d.mts +2 -0
  59. package/src/lib/place.d.ts +2 -0
  60. package/src/lib/place.js.map +1 -1
  61. package/src/lib/place.mjs.map +1 -1
  62. package/src/lib/record-bar.d.mts +56 -0
  63. package/src/lib/record-bar.d.ts +56 -0
  64. package/src/lib/record-bar.js +237 -0
  65. package/src/lib/record-bar.js.map +1 -0
  66. package/src/lib/record-bar.mjs +234 -0
  67. package/src/lib/record-bar.mjs.map +1 -0
  68. package/src/lib/record-styles.d.mts +9 -0
  69. package/src/lib/record-styles.d.ts +9 -0
  70. package/src/lib/record-styles.js +83 -0
  71. package/src/lib/record-styles.js.map +1 -0
  72. package/src/lib/record-styles.mjs +79 -0
  73. package/src/lib/record-styles.mjs.map +1 -0
  74. package/src/lib/related.d.mts +7 -3
  75. package/src/lib/related.d.ts +7 -3
  76. package/src/lib/related.js +22 -8
  77. package/src/lib/related.js.map +1 -1
  78. package/src/lib/related.mjs +22 -8
  79. package/src/lib/related.mjs.map +1 -1
  80. package/src/lib/say.d.mts +3 -1
  81. package/src/lib/say.d.ts +3 -1
  82. package/src/lib/say.js +17 -1
  83. package/src/lib/say.js.map +1 -1
  84. package/src/lib/say.mjs +17 -1
  85. package/src/lib/say.mjs.map +1 -1
  86. package/src/lib/tab-strip.d.mts +17 -0
  87. package/src/lib/tab-strip.d.ts +17 -0
  88. package/src/lib/tab-strip.js +51 -0
  89. package/src/lib/tab-strip.js.map +1 -0
  90. package/src/lib/tab-strip.mjs +48 -0
  91. package/src/lib/tab-strip.mjs.map +1 -0
  92. package/src/lib/value-words.d.mts +10 -0
  93. package/src/lib/value-words.d.ts +10 -0
  94. package/src/lib/value-words.js +38 -0
  95. package/src/lib/value-words.js.map +1 -0
  96. package/src/lib/value-words.mjs +35 -0
  97. package/src/lib/value-words.mjs.map +1 -0
  98. package/src/lib/viewer.d.mts +22 -1
  99. package/src/lib/viewer.d.ts +22 -1
  100. package/src/lib/viewer.js +488 -46
  101. package/src/lib/viewer.js.map +1 -1
  102. package/src/lib/viewer.mjs +489 -47
  103. package/src/lib/viewer.mjs.map +1 -1
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.tabStrip = tabStrip;
4
+ const dom_1 = require("./dom");
5
+ /** Room kept beside a tab brought into sight: the button over that edge and the fade beside it. */
6
+ const EDGE = 64;
7
+ /**
8
+ * A row of tabs too long for its room scrolls sideways: past an edge with more
9
+ * beyond it, the tabs fade out under a button that moves the strip a width
10
+ * along — to the left at the start of a right-to-left page. The buttons are
11
+ * for a pointer: the keyboard moves along the tabs, which come into sight.
12
+ */
13
+ function tabStrip(list, el) {
14
+ const rtl = () => list.closest('[dir]')?.getAttribute('dir') === 'rtl';
15
+ const edge = (side) => el('button', { type: 'button', class: `fd-tabs-scroll fd-tabs-${side}`, tabindex: '-1', 'aria-hidden': 'true', hidden: '' });
16
+ const before = edge('before');
17
+ const after = edge('after');
18
+ const element = el('div', { class: 'fd-tabbar' }, before, list, after);
19
+ // A strip's width along, less a tab's room, toward the button's own edge.
20
+ const move = (toward) => list.scrollBy({ left: toward * (rtl() ? -1 : 1) * Math.max(list.clientWidth - 2 * EDGE, EDGE), behavior: 'smooth' });
21
+ before.addEventListener('click', () => move(-1));
22
+ after.addEventListener('click', () => move(1));
23
+ function measure() {
24
+ // How far along from the start: right to left, scrollLeft runs from 0 down.
25
+ const along = Math.abs(list.scrollLeft);
26
+ const start = along > 1;
27
+ const end = along + list.clientWidth < list.scrollWidth - 1;
28
+ (0, dom_1.setHidden)(before, !start);
29
+ (0, dom_1.setHidden)(after, !end);
30
+ const more = [start && 'start', end && 'end'].filter(Boolean).join(' ');
31
+ (0, dom_1.setAttr)(element, 'data-more', more || null);
32
+ }
33
+ function reveal(tab) {
34
+ if (!list.clientWidth || list.scrollWidth <= list.clientWidth)
35
+ return;
36
+ const room = list.getBoundingClientRect();
37
+ const at = tab.getBoundingClientRect();
38
+ // Either way round, a larger scrollLeft shows what is further right.
39
+ if (at.left < room.left + EDGE)
40
+ list.scrollLeft += at.left - room.left - EDGE;
41
+ else if (at.right > room.right - EDGE)
42
+ list.scrollLeft += at.right - room.right + EDGE;
43
+ measure();
44
+ }
45
+ list.addEventListener('scroll', measure, { passive: true });
46
+ const view = list.ownerDocument.defaultView;
47
+ const watcher = view && 'ResizeObserver' in view ? new view.ResizeObserver(() => measure()) : null;
48
+ watcher?.observe(list);
49
+ return { element, measure, reveal, destroy: () => watcher?.disconnect() };
50
+ }
51
+ //# sourceMappingURL=tab-strip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tab-strip.js","sourceRoot":"","sources":["../../../../../libs/viewer/src/lib/tab-strip.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ import { setAttr, setHidden } from './dom.mjs';
2
+ /** Room kept beside a tab brought into sight: the button over that edge and the fade beside it. */
3
+ const EDGE = 64;
4
+ /**
5
+ * A row of tabs too long for its room scrolls sideways: past an edge with more
6
+ * beyond it, the tabs fade out under a button that moves the strip a width
7
+ * along — to the left at the start of a right-to-left page. The buttons are
8
+ * for a pointer: the keyboard moves along the tabs, which come into sight.
9
+ */
10
+ export function tabStrip(list, el) {
11
+ const rtl = () => list.closest('[dir]')?.getAttribute('dir') === 'rtl';
12
+ const edge = (side) => el('button', { type: 'button', class: `fd-tabs-scroll fd-tabs-${side}`, tabindex: '-1', 'aria-hidden': 'true', hidden: '' });
13
+ const before = edge('before');
14
+ const after = edge('after');
15
+ const element = el('div', { class: 'fd-tabbar' }, before, list, after);
16
+ // A strip's width along, less a tab's room, toward the button's own edge.
17
+ const move = (toward) => list.scrollBy({ left: toward * (rtl() ? -1 : 1) * Math.max(list.clientWidth - 2 * EDGE, EDGE), behavior: 'smooth' });
18
+ before.addEventListener('click', () => move(-1));
19
+ after.addEventListener('click', () => move(1));
20
+ function measure() {
21
+ // How far along from the start: right to left, scrollLeft runs from 0 down.
22
+ const along = Math.abs(list.scrollLeft);
23
+ const start = along > 1;
24
+ const end = along + list.clientWidth < list.scrollWidth - 1;
25
+ setHidden(before, !start);
26
+ setHidden(after, !end);
27
+ const more = [start && 'start', end && 'end'].filter(Boolean).join(' ');
28
+ setAttr(element, 'data-more', more || null);
29
+ }
30
+ function reveal(tab) {
31
+ if (!list.clientWidth || list.scrollWidth <= list.clientWidth)
32
+ return;
33
+ const room = list.getBoundingClientRect();
34
+ const at = tab.getBoundingClientRect();
35
+ // Either way round, a larger scrollLeft shows what is further right.
36
+ if (at.left < room.left + EDGE)
37
+ list.scrollLeft += at.left - room.left - EDGE;
38
+ else if (at.right > room.right - EDGE)
39
+ list.scrollLeft += at.right - room.right + EDGE;
40
+ measure();
41
+ }
42
+ list.addEventListener('scroll', measure, { passive: true });
43
+ const view = list.ownerDocument.defaultView;
44
+ const watcher = view && 'ResizeObserver' in view ? new view.ResizeObserver(() => measure()) : null;
45
+ watcher?.observe(list);
46
+ return { element, measure, reveal, destroy: () => watcher?.disconnect() };
47
+ }
48
+ //# sourceMappingURL=tab-strip.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tab-strip.mjs","sourceRoot":"","sources":["../../../../../libs/viewer/src/lib/tab-strip.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { type Fields, type Locale, type Values } from '@fieldia/core';
2
+ /**
3
+ * Words that hold fields' values — "Entries before {lock_date} cannot be
4
+ * posted." — drawn as text with each value in a span of its own, written as
5
+ * the field shows it, and brought up to date as the record changes.
6
+ */
7
+ export declare function valueWords(doc: Document, fields: Fields, text: string, locale: Locale): {
8
+ nodes: (Node | string)[];
9
+ update(values: Readonly<Values>): void;
10
+ };
@@ -0,0 +1,10 @@
1
+ import { type Fields, type Locale, type Values } from '@fieldia/core';
2
+ /**
3
+ * Words that hold fields' values — "Entries before {lock_date} cannot be
4
+ * posted." — drawn as text with each value in a span of its own, written as
5
+ * the field shows it, and brought up to date as the record changes.
6
+ */
7
+ export declare function valueWords(doc: Document, fields: Fields, text: string, locale: Locale): {
8
+ nodes: (Node | string)[];
9
+ update(values: Readonly<Values>): void;
10
+ };
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.valueWords = valueWords;
4
+ const core_1 = require("@fieldia/core");
5
+ const widgets_1 = require("@fieldia/widgets");
6
+ /**
7
+ * Words that hold fields' values — "Entries before {lock_date} cannot be
8
+ * posted." — drawn as text with each value in a span of its own, written as
9
+ * the field shows it, and brought up to date as the record changes.
10
+ */
11
+ function valueWords(doc, fields, text, locale) {
12
+ const parts = (0, core_1.splitValues)(text);
13
+ if (!parts.some((part) => part.field))
14
+ return { nodes: [text], update: () => undefined };
15
+ const values = [];
16
+ const nodes = parts.map((part) => {
17
+ if (!part.field)
18
+ return part.text;
19
+ // Set apart from the words round it, so a date or an amount keeps its own order on a page read right to left.
20
+ const span = doc.createElement('bdi');
21
+ span.className = 'fd-value';
22
+ span.dataset['field'] = part.field;
23
+ values.push({ field: part.field, span });
24
+ return span;
25
+ });
26
+ return {
27
+ nodes,
28
+ update(record) {
29
+ for (const { field, span } of values) {
30
+ const def = fields[field];
31
+ const words = def ? (0, widgets_1.displayValue)(def, record[field], record, locale) : '';
32
+ if (span.textContent !== words)
33
+ span.textContent = words;
34
+ }
35
+ },
36
+ };
37
+ }
38
+ //# sourceMappingURL=value-words.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"value-words.js","sourceRoot":"","sources":["../../../../../libs/viewer/src/lib/value-words.ts"],"names":[],"mappings":";;AAQA,gCAuBC;AA/BD,wCAA+G;AAC/G,8CAAgD;AAEhD;;;;GAIG;AACH,SAAgB,UAAU,CAAC,GAAa,EAAE,MAAc,EAAE,IAAY,EAAE,MAAc;IACpF,MAAM,KAAK,GAAG,IAAA,kBAAW,EAAC,IAAI,CAAC,CAAC;IAChC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,SAAS,EAAE,CAAC;IACzF,MAAM,MAAM,GAA2C,EAAE,CAAC;IAC1D,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QAC/B,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC,IAAI,CAAC;QAClC,8GAA8G;QAC9G,MAAM,IAAI,GAAG,GAAG,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QACtC,IAAI,CAAC,SAAS,GAAG,UAAU,CAAC;QAC5B,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC;QACnC,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;IACH,OAAO;QACL,KAAK;QACL,MAAM,CAAC,MAAM;YACX,KAAK,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,MAAM,EAAE,CAAC;gBACrC,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC1B,MAAM,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,IAAA,sBAAY,EAAC,GAAgB,EAAE,MAAM,CAAC,KAAK,CAAsB,EAAE,MAA+B,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBACrI,IAAI,IAAI,CAAC,WAAW,KAAK,KAAK;oBAAE,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;YAC3D,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,35 @@
1
+ import { splitValues } from '@fieldia/core';
2
+ import { displayValue } from '@fieldia/widgets';
3
+ /**
4
+ * Words that hold fields' values — "Entries before {lock_date} cannot be
5
+ * posted." — drawn as text with each value in a span of its own, written as
6
+ * the field shows it, and brought up to date as the record changes.
7
+ */
8
+ export function valueWords(doc, fields, text, locale) {
9
+ const parts = splitValues(text);
10
+ if (!parts.some((part) => part.field))
11
+ return { nodes: [text], update: () => undefined };
12
+ const values = [];
13
+ const nodes = parts.map((part) => {
14
+ if (!part.field)
15
+ return part.text;
16
+ // Set apart from the words round it, so a date or an amount keeps its own order on a page read right to left.
17
+ const span = doc.createElement('bdi');
18
+ span.className = 'fd-value';
19
+ span.dataset['field'] = part.field;
20
+ values.push({ field: part.field, span });
21
+ return span;
22
+ });
23
+ return {
24
+ nodes,
25
+ update(record) {
26
+ for (const { field, span } of values) {
27
+ const def = fields[field];
28
+ const words = def ? displayValue(def, record[field], record, locale) : '';
29
+ if (span.textContent !== words)
30
+ span.textContent = words;
31
+ }
32
+ },
33
+ };
34
+ }
35
+ //# sourceMappingURL=value-words.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"value-words.mjs","sourceRoot":"","sources":["../../../../../libs/viewer/src/lib/value-words.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAqE,MAAM,eAAe,CAAC;AAC/G,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEhD;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,GAAa,EAAE,MAAc,EAAE,IAAY,EAAE,MAAc;IACpF,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,SAAS,EAAE,CAAC;IACzF,MAAM,MAAM,GAA2C,EAAE,CAAC;IAC1D,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QAC/B,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC,IAAI,CAAC;QAClC,8GAA8G;QAC9G,MAAM,IAAI,GAAG,GAAG,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QACtC,IAAI,CAAC,SAAS,GAAG,UAAU,CAAC;QAC5B,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC;QACnC,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;IACH,OAAO;QACL,KAAK;QACL,MAAM,CAAC,MAAM;YACX,KAAK,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,MAAM,EAAE,CAAC;gBACrC,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC1B,MAAM,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,GAAgB,EAAE,MAAM,CAAC,KAAK,CAAsB,EAAE,MAA+B,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBACrI,IAAI,IAAI,CAAC,WAAW,KAAK,KAAK;oBAAE,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;YAC3D,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -1,6 +1,8 @@
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';
1
+ import { type ActionHost, type ActionStep, type FormEvents, type Form, type FormOptions, type Page, type RecordId, type ResolvedFilter, 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
3
  import { type PageFinder } from './related.mjs';
4
+ import { type Breadcrumb, type RecordPager } from './record-bar.mjs';
5
+ export type { Breadcrumb, RecordPager } from './record-bar.mjs';
4
6
  export type Skin = 'underline' | 'outlined';
5
7
  import { type ViewerLabels } from './labels.mjs';
6
8
  export { VIEWER_LABELS, DEFAULT_LABELS, type ViewerLabels } from './labels.mjs';
@@ -79,6 +81,8 @@ export interface ViewerOptions extends Omit<FormOptions, 'page' | 'host'> {
79
81
  translate?: (text: string) => string;
80
82
  /** A list page: a row was opened, by a click or by Enter. The app shows the record. */
81
83
  onOpenRecord?: (id: RecordId) => void;
84
+ /** A list page: only the records these conditions let through, whatever is searched — the invoices of one order, opened from it. */
85
+ listFilter?: ResolvedFilter[];
82
86
  /**
83
87
  * What the page's steps ask of the screen, the viewer does itself: a page
84
88
  * opened (in a dialog, a side panel, or this form's place, with Back), words
@@ -91,6 +95,23 @@ export interface ViewerOptions extends Omit<FormOptions, 'page' | 'host'> {
91
95
  * your router, your own dialog — or with undefined to let the viewer open it.
92
96
  */
93
97
  onOpen?: (request: OpenRequest) => Promise<OpenResult> | undefined;
98
+ /**
99
+ * The records round this one, for the pager over a record — "3 / 42",
100
+ * Previous and Next — as the list it was opened from has them: their ids in
101
+ * order, or how many there are, where this one is, and the id at a place.
102
+ * Moving saves what changed first, as Flectra does; the form then shows
103
+ * the other record (its `open` event says which). A copy joins them after
104
+ * its record; a record deleted leaves them, the pager moving to the next.
105
+ * Never in a dialog.
106
+ */
107
+ records?: readonly RecordId[] | RecordPager;
108
+ /**
109
+ * The trail to this record, for the breadcrumbs over it: each page before
110
+ * it with its words and what a press does (back to it); the record itself
111
+ * comes last, by its name. A page a step opens in this one's place adds
112
+ * this one to the trail, as the way back. Never in a dialog.
113
+ */
114
+ breadcrumbs?: readonly Breadcrumb[];
94
115
  }
95
116
  export interface ViewerHandle {
96
117
  readonly form: Form;
@@ -1,6 +1,8 @@
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';
1
+ import { type ActionHost, type ActionStep, type FormEvents, type Form, type FormOptions, type Page, type RecordId, type ResolvedFilter, 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
3
  import { type PageFinder } from './related';
4
+ import { type Breadcrumb, type RecordPager } from './record-bar';
5
+ export type { Breadcrumb, RecordPager } from './record-bar';
4
6
  export type Skin = 'underline' | 'outlined';
5
7
  import { type ViewerLabels } from './labels';
6
8
  export { VIEWER_LABELS, DEFAULT_LABELS, type ViewerLabels } from './labels';
@@ -79,6 +81,8 @@ export interface ViewerOptions extends Omit<FormOptions, 'page' | 'host'> {
79
81
  translate?: (text: string) => string;
80
82
  /** A list page: a row was opened, by a click or by Enter. The app shows the record. */
81
83
  onOpenRecord?: (id: RecordId) => void;
84
+ /** A list page: only the records these conditions let through, whatever is searched — the invoices of one order, opened from it. */
85
+ listFilter?: ResolvedFilter[];
82
86
  /**
83
87
  * What the page's steps ask of the screen, the viewer does itself: a page
84
88
  * opened (in a dialog, a side panel, or this form's place, with Back), words
@@ -91,6 +95,23 @@ export interface ViewerOptions extends Omit<FormOptions, 'page' | 'host'> {
91
95
  * your router, your own dialog — or with undefined to let the viewer open it.
92
96
  */
93
97
  onOpen?: (request: OpenRequest) => Promise<OpenResult> | undefined;
98
+ /**
99
+ * The records round this one, for the pager over a record — "3 / 42",
100
+ * Previous and Next — as the list it was opened from has them: their ids in
101
+ * order, or how many there are, where this one is, and the id at a place.
102
+ * Moving saves what changed first, as Flectra does; the form then shows
103
+ * the other record (its `open` event says which). A copy joins them after
104
+ * its record; a record deleted leaves them, the pager moving to the next.
105
+ * Never in a dialog.
106
+ */
107
+ records?: readonly RecordId[] | RecordPager;
108
+ /**
109
+ * The trail to this record, for the breadcrumbs over it: each page before
110
+ * it with its words and what a press does (back to it); the record itself
111
+ * comes last, by its name. A page a step opens in this one's place adds
112
+ * this one to the trail, as the way back. Never in a dialog.
113
+ */
114
+ breadcrumbs?: readonly Breadcrumb[];
94
115
  }
95
116
  export interface ViewerHandle {
96
117
  readonly form: Form;