@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.
- package/bundle/fieldia.ar.js +2 -2
- package/bundle/fieldia.ar.js.map +2 -2
- package/bundle/fieldia.de.js +2 -2
- package/bundle/fieldia.de.js.map +2 -2
- package/bundle/fieldia.fr.js +2 -2
- package/bundle/fieldia.fr.js.map +2 -2
- package/bundle/fieldia.js +6 -4
- package/bundle/fieldia.js.map +4 -4
- package/package.json +3 -3
- package/src/lib/attachment-preview.d.mts +27 -0
- package/src/lib/attachment-preview.d.ts +27 -0
- package/src/lib/attachment-preview.js +89 -0
- package/src/lib/attachment-preview.js.map +1 -0
- package/src/lib/attachment-preview.mjs +86 -0
- package/src/lib/attachment-preview.mjs.map +1 -0
- package/src/lib/dialog.d.mts +2 -0
- package/src/lib/dialog.d.ts +2 -0
- package/src/lib/dialog.js +65 -4
- package/src/lib/dialog.js.map +1 -1
- package/src/lib/dialog.mjs +64 -4
- package/src/lib/dialog.mjs.map +1 -1
- package/src/lib/hotkeys.d.mts +11 -0
- package/src/lib/hotkeys.d.ts +11 -0
- package/src/lib/hotkeys.js +34 -0
- package/src/lib/hotkeys.js.map +1 -0
- package/src/lib/hotkeys.mjs +30 -0
- package/src/lib/hotkeys.mjs.map +1 -0
- package/src/lib/labels.d.mts +25 -0
- package/src/lib/labels.d.ts +25 -0
- package/src/lib/labels.js +17 -0
- package/src/lib/labels.js.map +1 -1
- package/src/lib/labels.mjs +17 -0
- package/src/lib/labels.mjs.map +1 -1
- package/src/lib/list.d.mts +3 -1
- package/src/lib/list.d.ts +3 -1
- package/src/lib/list.js +1 -1
- package/src/lib/list.js.map +1 -1
- package/src/lib/list.mjs +1 -1
- package/src/lib/list.mjs.map +1 -1
- package/src/lib/locales/ar.js +17 -0
- package/src/lib/locales/ar.js.map +1 -1
- package/src/lib/locales/ar.mjs +17 -0
- package/src/lib/locales/ar.mjs.map +1 -1
- package/src/lib/locales/de.js +17 -0
- package/src/lib/locales/de.js.map +1 -1
- package/src/lib/locales/de.mjs +17 -0
- package/src/lib/locales/de.mjs.map +1 -1
- package/src/lib/locales/fr.js +17 -0
- package/src/lib/locales/fr.js.map +1 -1
- package/src/lib/locales/fr.mjs +17 -0
- package/src/lib/locales/fr.mjs.map +1 -1
- package/src/lib/open.d.mts +7 -1
- package/src/lib/open.d.ts +7 -1
- package/src/lib/open.js +19 -8
- package/src/lib/open.js.map +1 -1
- package/src/lib/open.mjs +20 -9
- package/src/lib/open.mjs.map +1 -1
- package/src/lib/place.d.mts +2 -0
- package/src/lib/place.d.ts +2 -0
- package/src/lib/place.js.map +1 -1
- package/src/lib/place.mjs.map +1 -1
- package/src/lib/record-bar.d.mts +56 -0
- package/src/lib/record-bar.d.ts +56 -0
- package/src/lib/record-bar.js +237 -0
- package/src/lib/record-bar.js.map +1 -0
- package/src/lib/record-bar.mjs +234 -0
- package/src/lib/record-bar.mjs.map +1 -0
- package/src/lib/record-styles.d.mts +9 -0
- package/src/lib/record-styles.d.ts +9 -0
- package/src/lib/record-styles.js +83 -0
- package/src/lib/record-styles.js.map +1 -0
- package/src/lib/record-styles.mjs +79 -0
- package/src/lib/record-styles.mjs.map +1 -0
- package/src/lib/related.d.mts +7 -3
- package/src/lib/related.d.ts +7 -3
- package/src/lib/related.js +22 -8
- package/src/lib/related.js.map +1 -1
- package/src/lib/related.mjs +22 -8
- package/src/lib/related.mjs.map +1 -1
- package/src/lib/say.d.mts +3 -1
- package/src/lib/say.d.ts +3 -1
- package/src/lib/say.js +17 -1
- package/src/lib/say.js.map +1 -1
- package/src/lib/say.mjs +17 -1
- package/src/lib/say.mjs.map +1 -1
- package/src/lib/tab-strip.d.mts +17 -0
- package/src/lib/tab-strip.d.ts +17 -0
- package/src/lib/tab-strip.js +51 -0
- package/src/lib/tab-strip.js.map +1 -0
- package/src/lib/tab-strip.mjs +48 -0
- package/src/lib/tab-strip.mjs.map +1 -0
- package/src/lib/value-words.d.mts +10 -0
- package/src/lib/value-words.d.ts +10 -0
- package/src/lib/value-words.js +38 -0
- package/src/lib/value-words.js.map +1 -0
- package/src/lib/value-words.mjs +35 -0
- package/src/lib/value-words.mjs.map +1 -0
- package/src/lib/viewer.d.mts +22 -1
- package/src/lib/viewer.d.ts +22 -1
- package/src/lib/viewer.js +488 -46
- package/src/lib/viewer.js.map +1 -1
- package/src/lib/viewer.mjs +489 -47
- package/src/lib/viewer.mjs.map +1 -1
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.recordBar = recordBar;
|
|
4
|
+
const widgets_1 = require("@fieldia/widgets");
|
|
5
|
+
const dom_1 = require("./dom");
|
|
6
|
+
const hotkeys_1 = require("./hotkeys");
|
|
7
|
+
const GEAR = {
|
|
8
|
+
gear: '<circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.7 1.7 0 0 0 .3 1.8l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.7 1.7 0 0 0-1.8-.3 1.7 1.7 0 0 0-1 1.5V21a2 2 0 1 1-4 0v-.1a1.7 1.7 0 0 0-1.1-1.5 1.7 1.7 0 0 0-1.8.3l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1a1.7 1.7 0 0 0 .3-1.8 1.7 1.7 0 0 0-1.5-1H3a2 2 0 1 1 0-4h.1a1.7 1.7 0 0 0 1.5-1.1 1.7 1.7 0 0 0-.3-1.8l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1a1.7 1.7 0 0 0 1.8.3H9a1.7 1.7 0 0 0 1-1.5V3a2 2 0 1 1 4 0v.1a1.7 1.7 0 0 0 1 1.5 1.7 1.7 0 0 0 1.8-.3l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1a1.7 1.7 0 0 0-.3 1.8V9a1.7 1.7 0 0 0 1.5 1H21a2 2 0 1 1 0 4h-.1a1.7 1.7 0 0 0-1.5 1z"/>',
|
|
9
|
+
};
|
|
10
|
+
const same = (a, b) => a != null && b != null && String(a) === String(b);
|
|
11
|
+
/**
|
|
12
|
+
* The bar over a record, as Flectra's control panel: the breadcrumbs the app
|
|
13
|
+
* gives, the gear menu the page fills (its Print group, then its actions),
|
|
14
|
+
* and the pager over the records the app gives. Null when it would hold
|
|
15
|
+
* nothing. A dialog is given neither breadcrumbs nor records, so there only
|
|
16
|
+
* the menu shows; on a phone the trail folds to the page before this one.
|
|
17
|
+
*/
|
|
18
|
+
function recordBar(context) {
|
|
19
|
+
const { el, labels, toolbar } = context;
|
|
20
|
+
const menuItems = toolbar?.menu ?? [];
|
|
21
|
+
const trail = toolbar?.breadcrumbs === false ? undefined : context.breadcrumbs;
|
|
22
|
+
const given = toolbar?.pager === false ? undefined : context.records;
|
|
23
|
+
if (!menuItems.length && !trail?.length && !given)
|
|
24
|
+
return null;
|
|
25
|
+
const updaters = [];
|
|
26
|
+
const cleanups = [];
|
|
27
|
+
const bar = el('div', { class: 'fd-record-bar' });
|
|
28
|
+
// ---- the trail ----
|
|
29
|
+
if (trail?.length) {
|
|
30
|
+
const current = el('span', { class: 'fd-crumb-current', 'aria-current': 'page' });
|
|
31
|
+
const list = el('ol', {}, ...trail.map((crumb) => {
|
|
32
|
+
const link = crumb.href !== undefined ? el('a', { class: 'fd-crumb', href: crumb.href }, crumb.label) : el('button', { type: 'button', class: 'fd-crumb' }, crumb.label);
|
|
33
|
+
if (crumb.open) {
|
|
34
|
+
link.addEventListener('click', (event) => {
|
|
35
|
+
event.preventDefault();
|
|
36
|
+
crumb.open?.();
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
return el('li', {}, link);
|
|
40
|
+
}), el('li', {}, current));
|
|
41
|
+
bar.append(el('nav', { class: 'fd-breadcrumbs', 'aria-label': labels.breadcrumbs }, list));
|
|
42
|
+
updaters.push(() => (0, dom_1.setText)(current, context.name() || labels.newRecord));
|
|
43
|
+
}
|
|
44
|
+
// ---- the gear menu ----
|
|
45
|
+
if (menuItems.length)
|
|
46
|
+
bar.append(gearMenu(context, menuItems, updaters, cleanups));
|
|
47
|
+
// ---- the pager ----
|
|
48
|
+
if (given)
|
|
49
|
+
bar.append(pager(context, given, trail, updaters, cleanups));
|
|
50
|
+
return {
|
|
51
|
+
element: bar,
|
|
52
|
+
update: () => {
|
|
53
|
+
for (const update of updaters)
|
|
54
|
+
update();
|
|
55
|
+
},
|
|
56
|
+
destroy: () => {
|
|
57
|
+
for (const cleanup of cleanups)
|
|
58
|
+
cleanup();
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/** The gear and its menu: a real menu, opened with Enter, Space or the arrows, its items reached with the arrows, gone with Escape. */
|
|
63
|
+
function gearMenu(context, items, updaters, cleanups) {
|
|
64
|
+
const { doc, el, form, labels } = context;
|
|
65
|
+
const id = context.uid('record-menu');
|
|
66
|
+
const gear = el('button', { type: 'button', class: 'fd-button fd-record-gear', id: `${id}-button`, 'aria-haspopup': 'menu', 'aria-expanded': 'false', 'aria-controls': id, title: labels.actions });
|
|
67
|
+
const icon = (0, widgets_1.drawIcon)(doc, 'gear', GEAR);
|
|
68
|
+
if (icon)
|
|
69
|
+
gear.append(icon);
|
|
70
|
+
gear.append(el('span', { class: 'fd-record-gear-words' }, labels.actions));
|
|
71
|
+
const menu = el('div', { class: 'fd-record-menu', role: 'menu', id, 'aria-labelledby': gear.id, hidden: '' });
|
|
72
|
+
const drawn = items.map((item) => {
|
|
73
|
+
const words = item.label ?? (item.builtin ? labels[item.builtin] : item.id);
|
|
74
|
+
const button = el('button', { type: 'button', role: 'menuitem', tabindex: '-1', class: 'fd-record-menu-item', 'data-node': item.id }, ...context.withIcon(item.icon, words));
|
|
75
|
+
if (item.builtin === 'delete')
|
|
76
|
+
button.classList.add('fd-record-menu-danger');
|
|
77
|
+
button.addEventListener('click', () => {
|
|
78
|
+
close(true);
|
|
79
|
+
void context.press(gear, () => form.runAction(item.id));
|
|
80
|
+
});
|
|
81
|
+
return { item, button };
|
|
82
|
+
});
|
|
83
|
+
const printed = drawn.filter((d) => d.item.group === 'print');
|
|
84
|
+
const acted = drawn.filter((d) => d.item.group !== 'print');
|
|
85
|
+
const heading = el('div', { class: 'fd-record-menu-heading', role: 'presentation' }, labels.print);
|
|
86
|
+
const printGroup = el('div', { role: 'group', 'aria-label': labels.print }, heading, ...printed.map((d) => d.button));
|
|
87
|
+
const rule = el('div', { class: 'fd-record-menu-rule', role: 'separator' });
|
|
88
|
+
menu.append(...(printed.length ? [printGroup] : []), ...(printed.length && acted.length ? [rule] : []), ...acted.map((d) => d.button));
|
|
89
|
+
const wrap = el('div', { class: 'fd-record-actions' }, gear, menu);
|
|
90
|
+
const shown = () => drawn.filter((d) => !d.button.hidden).map((d) => d.button);
|
|
91
|
+
const onOutside = (event) => {
|
|
92
|
+
if (!wrap.contains(event.target))
|
|
93
|
+
close(false);
|
|
94
|
+
};
|
|
95
|
+
function open(at) {
|
|
96
|
+
if (!menu.hidden)
|
|
97
|
+
return;
|
|
98
|
+
menu.hidden = false;
|
|
99
|
+
// From the gear's start, unless that runs past the screen's edge: then from its end.
|
|
100
|
+
menu.removeAttribute('data-end');
|
|
101
|
+
const box = menu.getBoundingClientRect();
|
|
102
|
+
if (box.right > doc.documentElement.clientWidth - 4 || box.left < 4)
|
|
103
|
+
menu.setAttribute('data-end', '');
|
|
104
|
+
gear.setAttribute('aria-expanded', 'true');
|
|
105
|
+
doc.addEventListener('pointerdown', onOutside, true);
|
|
106
|
+
const items = shown();
|
|
107
|
+
(at === 'first' ? items[0] : items[items.length - 1])?.focus();
|
|
108
|
+
}
|
|
109
|
+
function close(refocus) {
|
|
110
|
+
if (menu.hidden)
|
|
111
|
+
return;
|
|
112
|
+
menu.hidden = true;
|
|
113
|
+
gear.setAttribute('aria-expanded', 'false');
|
|
114
|
+
doc.removeEventListener('pointerdown', onOutside, true);
|
|
115
|
+
if (refocus)
|
|
116
|
+
gear.focus();
|
|
117
|
+
}
|
|
118
|
+
cleanups.push(() => doc.removeEventListener('pointerdown', onOutside, true));
|
|
119
|
+
gear.addEventListener('click', () => (menu.hidden ? open('first') : close(false)));
|
|
120
|
+
gear.addEventListener('keydown', (event) => {
|
|
121
|
+
if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
|
|
122
|
+
event.preventDefault();
|
|
123
|
+
open(event.key === 'ArrowDown' ? 'first' : 'last');
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
menu.addEventListener('keydown', (event) => {
|
|
127
|
+
const items = shown();
|
|
128
|
+
const at = items.indexOf(doc.activeElement);
|
|
129
|
+
const to = { ArrowDown: at + 1, ArrowUp: at - 1, Home: 0, End: items.length - 1 }[event.key];
|
|
130
|
+
if (to !== undefined) {
|
|
131
|
+
event.preventDefault();
|
|
132
|
+
items[(to + items.length) % items.length]?.focus();
|
|
133
|
+
}
|
|
134
|
+
else if (event.key === 'Escape') {
|
|
135
|
+
// Escape closes the menu, not the dialog round the form.
|
|
136
|
+
event.preventDefault();
|
|
137
|
+
event.stopPropagation();
|
|
138
|
+
close(true);
|
|
139
|
+
}
|
|
140
|
+
else if (event.key === 'Tab')
|
|
141
|
+
close(false);
|
|
142
|
+
});
|
|
143
|
+
updaters.push(() => {
|
|
144
|
+
for (const { item, button } of drawn)
|
|
145
|
+
(0, dom_1.setHidden)(button, form.node(item.id).invisible);
|
|
146
|
+
(0, dom_1.setHidden)(printGroup, !printed.some((d) => !d.button.hidden));
|
|
147
|
+
(0, dom_1.setHidden)(rule, printGroup.hidden || !acted.some((d) => !d.button.hidden));
|
|
148
|
+
(0, dom_1.setHidden)(wrap, !drawn.some((d) => !d.button.hidden));
|
|
149
|
+
});
|
|
150
|
+
return wrap;
|
|
151
|
+
}
|
|
152
|
+
/** "3 / 42" with Previous and Next, round from the last to the first as Flectra's; Alt+P and Alt+N press them. */
|
|
153
|
+
function pager(context, given, trail, updaters, cleanups) {
|
|
154
|
+
const { el, form, labels } = context;
|
|
155
|
+
/** The ids, when the app gave them; else the app's count and its place, followed as the pager moves. */
|
|
156
|
+
const ids = Array.isArray(given) ? [...given] : null;
|
|
157
|
+
const asked = Array.isArray(given) ? null : given;
|
|
158
|
+
let total = ids ? ids.length : asked.total;
|
|
159
|
+
let at = ids ? -1 : asked.at;
|
|
160
|
+
/** The record the app's place stands for: once the form shows another, its place is unknown. */
|
|
161
|
+
let placed = ids ? null : form.getState().recordId;
|
|
162
|
+
let moving = false;
|
|
163
|
+
const here = () => {
|
|
164
|
+
const id = form.getState().recordId;
|
|
165
|
+
if (ids)
|
|
166
|
+
return ids.findIndex((other) => same(other, id));
|
|
167
|
+
return same(placed, id) ? at : -1;
|
|
168
|
+
};
|
|
169
|
+
// "3 / 42" reads left to right in every language, as numbers do.
|
|
170
|
+
const text = el('span', { class: 'fd-record-pager-text', dir: 'ltr' });
|
|
171
|
+
const previous = el('button', { type: 'button', class: 'fd-button fd-record-step', 'aria-label': labels.previousRecord }, el('span', { 'aria-hidden': 'true', class: 'fd-record-arrow' }, '‹'));
|
|
172
|
+
const next = el('button', { type: 'button', class: 'fd-button fd-record-step', 'aria-label': labels.nextRecord }, el('span', { 'aria-hidden': 'true', class: 'fd-record-arrow' }, '›'));
|
|
173
|
+
(0, hotkeys_1.hotkeyOn)(previous, 'p', labels.previousRecord);
|
|
174
|
+
(0, hotkeys_1.hotkeyOn)(next, 'n', labels.nextRecord);
|
|
175
|
+
const box = el('div', { class: 'fd-record-pager', role: 'group', 'aria-label': labels.records }, text, previous, next);
|
|
176
|
+
const idAt = async (place) => (ids ? ids[place] : asked.id(place));
|
|
177
|
+
async function move(by) {
|
|
178
|
+
const from = here();
|
|
179
|
+
if (moving || from === -1 || total < 2)
|
|
180
|
+
return;
|
|
181
|
+
moving = true;
|
|
182
|
+
try {
|
|
183
|
+
const to = (from + by + total) % total;
|
|
184
|
+
if (!(await context.leave()))
|
|
185
|
+
return;
|
|
186
|
+
const id = await idAt(to);
|
|
187
|
+
at = to;
|
|
188
|
+
placed = id;
|
|
189
|
+
await form.openRecord(id);
|
|
190
|
+
}
|
|
191
|
+
finally {
|
|
192
|
+
moving = false;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
previous.addEventListener('click', () => void move(-1));
|
|
196
|
+
next.addEventListener('click', () => void move(1));
|
|
197
|
+
// A copy joins the records after the one it was made from; a record deleted leaves them, the pager moving to the next.
|
|
198
|
+
cleanups.push(form.on('duplicate', ({ from, recordId }) => {
|
|
199
|
+
if (!ids)
|
|
200
|
+
return;
|
|
201
|
+
const place = ids.findIndex((id) => same(id, from));
|
|
202
|
+
ids.splice(place + 1, 0, recordId);
|
|
203
|
+
total = ids.length;
|
|
204
|
+
// Told once the copy shows: the pager counts it now.
|
|
205
|
+
context.render();
|
|
206
|
+
}), form.on('delete', ({ recordId }) => {
|
|
207
|
+
const place = ids ? ids.findIndex((id) => same(id, recordId)) : same(placed, recordId) ? at : -1;
|
|
208
|
+
if (place === -1)
|
|
209
|
+
return;
|
|
210
|
+
if (ids)
|
|
211
|
+
ids.splice(place, 1);
|
|
212
|
+
total = ids ? ids.length : total - 1;
|
|
213
|
+
if (total < 1)
|
|
214
|
+
return void trail?.[trail.length - 1]?.open?.();
|
|
215
|
+
at = Math.min(place, total - 1);
|
|
216
|
+
// At once when the id is at hand, so the form never starts a new record meanwhile.
|
|
217
|
+
const go = (id) => {
|
|
218
|
+
placed = id;
|
|
219
|
+
void form.openRecord(id);
|
|
220
|
+
};
|
|
221
|
+
const id = ids ? ids[at] : asked.id(at);
|
|
222
|
+
if (id instanceof Promise)
|
|
223
|
+
void id.then(go);
|
|
224
|
+
else
|
|
225
|
+
go(id);
|
|
226
|
+
}));
|
|
227
|
+
updaters.push(() => {
|
|
228
|
+
const place = here();
|
|
229
|
+
(0, dom_1.setHidden)(box, place === -1);
|
|
230
|
+
(0, dom_1.setText)(text, context.fill(labels.recordAt, { n: place + 1, total }));
|
|
231
|
+
const alone = total < 2;
|
|
232
|
+
(0, dom_1.setAttr)(previous, 'aria-disabled', alone ? 'true' : null);
|
|
233
|
+
(0, dom_1.setAttr)(next, 'aria-disabled', alone ? 'true' : null);
|
|
234
|
+
});
|
|
235
|
+
return box;
|
|
236
|
+
}
|
|
237
|
+
//# sourceMappingURL=record-bar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"record-bar.js","sourceRoot":"","sources":["../../../../../libs/viewer/src/lib/record-bar.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import { drawIcon } from '@fieldia/widgets';
|
|
2
|
+
import { setAttr, setHidden, setText } from './dom.mjs';
|
|
3
|
+
import { hotkeyOn } from './hotkeys.mjs';
|
|
4
|
+
const GEAR = {
|
|
5
|
+
gear: '<circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.7 1.7 0 0 0 .3 1.8l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.7 1.7 0 0 0-1.8-.3 1.7 1.7 0 0 0-1 1.5V21a2 2 0 1 1-4 0v-.1a1.7 1.7 0 0 0-1.1-1.5 1.7 1.7 0 0 0-1.8.3l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1a1.7 1.7 0 0 0 .3-1.8 1.7 1.7 0 0 0-1.5-1H3a2 2 0 1 1 0-4h.1a1.7 1.7 0 0 0 1.5-1.1 1.7 1.7 0 0 0-.3-1.8l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1a1.7 1.7 0 0 0 1.8.3H9a1.7 1.7 0 0 0 1-1.5V3a2 2 0 1 1 4 0v.1a1.7 1.7 0 0 0 1 1.5 1.7 1.7 0 0 0 1.8-.3l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1a1.7 1.7 0 0 0-.3 1.8V9a1.7 1.7 0 0 0 1.5 1H21a2 2 0 1 1 0 4h-.1a1.7 1.7 0 0 0-1.5 1z"/>',
|
|
6
|
+
};
|
|
7
|
+
const same = (a, b) => a != null && b != null && String(a) === String(b);
|
|
8
|
+
/**
|
|
9
|
+
* The bar over a record, as Flectra's control panel: the breadcrumbs the app
|
|
10
|
+
* gives, the gear menu the page fills (its Print group, then its actions),
|
|
11
|
+
* and the pager over the records the app gives. Null when it would hold
|
|
12
|
+
* nothing. A dialog is given neither breadcrumbs nor records, so there only
|
|
13
|
+
* the menu shows; on a phone the trail folds to the page before this one.
|
|
14
|
+
*/
|
|
15
|
+
export function recordBar(context) {
|
|
16
|
+
const { el, labels, toolbar } = context;
|
|
17
|
+
const menuItems = toolbar?.menu ?? [];
|
|
18
|
+
const trail = toolbar?.breadcrumbs === false ? undefined : context.breadcrumbs;
|
|
19
|
+
const given = toolbar?.pager === false ? undefined : context.records;
|
|
20
|
+
if (!menuItems.length && !trail?.length && !given)
|
|
21
|
+
return null;
|
|
22
|
+
const updaters = [];
|
|
23
|
+
const cleanups = [];
|
|
24
|
+
const bar = el('div', { class: 'fd-record-bar' });
|
|
25
|
+
// ---- the trail ----
|
|
26
|
+
if (trail?.length) {
|
|
27
|
+
const current = el('span', { class: 'fd-crumb-current', 'aria-current': 'page' });
|
|
28
|
+
const list = el('ol', {}, ...trail.map((crumb) => {
|
|
29
|
+
const link = crumb.href !== undefined ? el('a', { class: 'fd-crumb', href: crumb.href }, crumb.label) : el('button', { type: 'button', class: 'fd-crumb' }, crumb.label);
|
|
30
|
+
if (crumb.open) {
|
|
31
|
+
link.addEventListener('click', (event) => {
|
|
32
|
+
event.preventDefault();
|
|
33
|
+
crumb.open?.();
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
return el('li', {}, link);
|
|
37
|
+
}), el('li', {}, current));
|
|
38
|
+
bar.append(el('nav', { class: 'fd-breadcrumbs', 'aria-label': labels.breadcrumbs }, list));
|
|
39
|
+
updaters.push(() => setText(current, context.name() || labels.newRecord));
|
|
40
|
+
}
|
|
41
|
+
// ---- the gear menu ----
|
|
42
|
+
if (menuItems.length)
|
|
43
|
+
bar.append(gearMenu(context, menuItems, updaters, cleanups));
|
|
44
|
+
// ---- the pager ----
|
|
45
|
+
if (given)
|
|
46
|
+
bar.append(pager(context, given, trail, updaters, cleanups));
|
|
47
|
+
return {
|
|
48
|
+
element: bar,
|
|
49
|
+
update: () => {
|
|
50
|
+
for (const update of updaters)
|
|
51
|
+
update();
|
|
52
|
+
},
|
|
53
|
+
destroy: () => {
|
|
54
|
+
for (const cleanup of cleanups)
|
|
55
|
+
cleanup();
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/** The gear and its menu: a real menu, opened with Enter, Space or the arrows, its items reached with the arrows, gone with Escape. */
|
|
60
|
+
function gearMenu(context, items, updaters, cleanups) {
|
|
61
|
+
const { doc, el, form, labels } = context;
|
|
62
|
+
const id = context.uid('record-menu');
|
|
63
|
+
const gear = el('button', { type: 'button', class: 'fd-button fd-record-gear', id: `${id}-button`, 'aria-haspopup': 'menu', 'aria-expanded': 'false', 'aria-controls': id, title: labels.actions });
|
|
64
|
+
const icon = drawIcon(doc, 'gear', GEAR);
|
|
65
|
+
if (icon)
|
|
66
|
+
gear.append(icon);
|
|
67
|
+
gear.append(el('span', { class: 'fd-record-gear-words' }, labels.actions));
|
|
68
|
+
const menu = el('div', { class: 'fd-record-menu', role: 'menu', id, 'aria-labelledby': gear.id, hidden: '' });
|
|
69
|
+
const drawn = items.map((item) => {
|
|
70
|
+
const words = item.label ?? (item.builtin ? labels[item.builtin] : item.id);
|
|
71
|
+
const button = el('button', { type: 'button', role: 'menuitem', tabindex: '-1', class: 'fd-record-menu-item', 'data-node': item.id }, ...context.withIcon(item.icon, words));
|
|
72
|
+
if (item.builtin === 'delete')
|
|
73
|
+
button.classList.add('fd-record-menu-danger');
|
|
74
|
+
button.addEventListener('click', () => {
|
|
75
|
+
close(true);
|
|
76
|
+
void context.press(gear, () => form.runAction(item.id));
|
|
77
|
+
});
|
|
78
|
+
return { item, button };
|
|
79
|
+
});
|
|
80
|
+
const printed = drawn.filter((d) => d.item.group === 'print');
|
|
81
|
+
const acted = drawn.filter((d) => d.item.group !== 'print');
|
|
82
|
+
const heading = el('div', { class: 'fd-record-menu-heading', role: 'presentation' }, labels.print);
|
|
83
|
+
const printGroup = el('div', { role: 'group', 'aria-label': labels.print }, heading, ...printed.map((d) => d.button));
|
|
84
|
+
const rule = el('div', { class: 'fd-record-menu-rule', role: 'separator' });
|
|
85
|
+
menu.append(...(printed.length ? [printGroup] : []), ...(printed.length && acted.length ? [rule] : []), ...acted.map((d) => d.button));
|
|
86
|
+
const wrap = el('div', { class: 'fd-record-actions' }, gear, menu);
|
|
87
|
+
const shown = () => drawn.filter((d) => !d.button.hidden).map((d) => d.button);
|
|
88
|
+
const onOutside = (event) => {
|
|
89
|
+
if (!wrap.contains(event.target))
|
|
90
|
+
close(false);
|
|
91
|
+
};
|
|
92
|
+
function open(at) {
|
|
93
|
+
if (!menu.hidden)
|
|
94
|
+
return;
|
|
95
|
+
menu.hidden = false;
|
|
96
|
+
// From the gear's start, unless that runs past the screen's edge: then from its end.
|
|
97
|
+
menu.removeAttribute('data-end');
|
|
98
|
+
const box = menu.getBoundingClientRect();
|
|
99
|
+
if (box.right > doc.documentElement.clientWidth - 4 || box.left < 4)
|
|
100
|
+
menu.setAttribute('data-end', '');
|
|
101
|
+
gear.setAttribute('aria-expanded', 'true');
|
|
102
|
+
doc.addEventListener('pointerdown', onOutside, true);
|
|
103
|
+
const items = shown();
|
|
104
|
+
(at === 'first' ? items[0] : items[items.length - 1])?.focus();
|
|
105
|
+
}
|
|
106
|
+
function close(refocus) {
|
|
107
|
+
if (menu.hidden)
|
|
108
|
+
return;
|
|
109
|
+
menu.hidden = true;
|
|
110
|
+
gear.setAttribute('aria-expanded', 'false');
|
|
111
|
+
doc.removeEventListener('pointerdown', onOutside, true);
|
|
112
|
+
if (refocus)
|
|
113
|
+
gear.focus();
|
|
114
|
+
}
|
|
115
|
+
cleanups.push(() => doc.removeEventListener('pointerdown', onOutside, true));
|
|
116
|
+
gear.addEventListener('click', () => (menu.hidden ? open('first') : close(false)));
|
|
117
|
+
gear.addEventListener('keydown', (event) => {
|
|
118
|
+
if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
|
|
119
|
+
event.preventDefault();
|
|
120
|
+
open(event.key === 'ArrowDown' ? 'first' : 'last');
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
menu.addEventListener('keydown', (event) => {
|
|
124
|
+
const items = shown();
|
|
125
|
+
const at = items.indexOf(doc.activeElement);
|
|
126
|
+
const to = { ArrowDown: at + 1, ArrowUp: at - 1, Home: 0, End: items.length - 1 }[event.key];
|
|
127
|
+
if (to !== undefined) {
|
|
128
|
+
event.preventDefault();
|
|
129
|
+
items[(to + items.length) % items.length]?.focus();
|
|
130
|
+
}
|
|
131
|
+
else if (event.key === 'Escape') {
|
|
132
|
+
// Escape closes the menu, not the dialog round the form.
|
|
133
|
+
event.preventDefault();
|
|
134
|
+
event.stopPropagation();
|
|
135
|
+
close(true);
|
|
136
|
+
}
|
|
137
|
+
else if (event.key === 'Tab')
|
|
138
|
+
close(false);
|
|
139
|
+
});
|
|
140
|
+
updaters.push(() => {
|
|
141
|
+
for (const { item, button } of drawn)
|
|
142
|
+
setHidden(button, form.node(item.id).invisible);
|
|
143
|
+
setHidden(printGroup, !printed.some((d) => !d.button.hidden));
|
|
144
|
+
setHidden(rule, printGroup.hidden || !acted.some((d) => !d.button.hidden));
|
|
145
|
+
setHidden(wrap, !drawn.some((d) => !d.button.hidden));
|
|
146
|
+
});
|
|
147
|
+
return wrap;
|
|
148
|
+
}
|
|
149
|
+
/** "3 / 42" with Previous and Next, round from the last to the first as Flectra's; Alt+P and Alt+N press them. */
|
|
150
|
+
function pager(context, given, trail, updaters, cleanups) {
|
|
151
|
+
const { el, form, labels } = context;
|
|
152
|
+
/** The ids, when the app gave them; else the app's count and its place, followed as the pager moves. */
|
|
153
|
+
const ids = Array.isArray(given) ? [...given] : null;
|
|
154
|
+
const asked = Array.isArray(given) ? null : given;
|
|
155
|
+
let total = ids ? ids.length : asked.total;
|
|
156
|
+
let at = ids ? -1 : asked.at;
|
|
157
|
+
/** The record the app's place stands for: once the form shows another, its place is unknown. */
|
|
158
|
+
let placed = ids ? null : form.getState().recordId;
|
|
159
|
+
let moving = false;
|
|
160
|
+
const here = () => {
|
|
161
|
+
const id = form.getState().recordId;
|
|
162
|
+
if (ids)
|
|
163
|
+
return ids.findIndex((other) => same(other, id));
|
|
164
|
+
return same(placed, id) ? at : -1;
|
|
165
|
+
};
|
|
166
|
+
// "3 / 42" reads left to right in every language, as numbers do.
|
|
167
|
+
const text = el('span', { class: 'fd-record-pager-text', dir: 'ltr' });
|
|
168
|
+
const previous = el('button', { type: 'button', class: 'fd-button fd-record-step', 'aria-label': labels.previousRecord }, el('span', { 'aria-hidden': 'true', class: 'fd-record-arrow' }, '‹'));
|
|
169
|
+
const next = el('button', { type: 'button', class: 'fd-button fd-record-step', 'aria-label': labels.nextRecord }, el('span', { 'aria-hidden': 'true', class: 'fd-record-arrow' }, '›'));
|
|
170
|
+
hotkeyOn(previous, 'p', labels.previousRecord);
|
|
171
|
+
hotkeyOn(next, 'n', labels.nextRecord);
|
|
172
|
+
const box = el('div', { class: 'fd-record-pager', role: 'group', 'aria-label': labels.records }, text, previous, next);
|
|
173
|
+
const idAt = async (place) => (ids ? ids[place] : asked.id(place));
|
|
174
|
+
async function move(by) {
|
|
175
|
+
const from = here();
|
|
176
|
+
if (moving || from === -1 || total < 2)
|
|
177
|
+
return;
|
|
178
|
+
moving = true;
|
|
179
|
+
try {
|
|
180
|
+
const to = (from + by + total) % total;
|
|
181
|
+
if (!(await context.leave()))
|
|
182
|
+
return;
|
|
183
|
+
const id = await idAt(to);
|
|
184
|
+
at = to;
|
|
185
|
+
placed = id;
|
|
186
|
+
await form.openRecord(id);
|
|
187
|
+
}
|
|
188
|
+
finally {
|
|
189
|
+
moving = false;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
previous.addEventListener('click', () => void move(-1));
|
|
193
|
+
next.addEventListener('click', () => void move(1));
|
|
194
|
+
// A copy joins the records after the one it was made from; a record deleted leaves them, the pager moving to the next.
|
|
195
|
+
cleanups.push(form.on('duplicate', ({ from, recordId }) => {
|
|
196
|
+
if (!ids)
|
|
197
|
+
return;
|
|
198
|
+
const place = ids.findIndex((id) => same(id, from));
|
|
199
|
+
ids.splice(place + 1, 0, recordId);
|
|
200
|
+
total = ids.length;
|
|
201
|
+
// Told once the copy shows: the pager counts it now.
|
|
202
|
+
context.render();
|
|
203
|
+
}), form.on('delete', ({ recordId }) => {
|
|
204
|
+
const place = ids ? ids.findIndex((id) => same(id, recordId)) : same(placed, recordId) ? at : -1;
|
|
205
|
+
if (place === -1)
|
|
206
|
+
return;
|
|
207
|
+
if (ids)
|
|
208
|
+
ids.splice(place, 1);
|
|
209
|
+
total = ids ? ids.length : total - 1;
|
|
210
|
+
if (total < 1)
|
|
211
|
+
return void trail?.[trail.length - 1]?.open?.();
|
|
212
|
+
at = Math.min(place, total - 1);
|
|
213
|
+
// At once when the id is at hand, so the form never starts a new record meanwhile.
|
|
214
|
+
const go = (id) => {
|
|
215
|
+
placed = id;
|
|
216
|
+
void form.openRecord(id);
|
|
217
|
+
};
|
|
218
|
+
const id = ids ? ids[at] : asked.id(at);
|
|
219
|
+
if (id instanceof Promise)
|
|
220
|
+
void id.then(go);
|
|
221
|
+
else
|
|
222
|
+
go(id);
|
|
223
|
+
}));
|
|
224
|
+
updaters.push(() => {
|
|
225
|
+
const place = here();
|
|
226
|
+
setHidden(box, place === -1);
|
|
227
|
+
setText(text, context.fill(labels.recordAt, { n: place + 1, total }));
|
|
228
|
+
const alone = total < 2;
|
|
229
|
+
setAttr(previous, 'aria-disabled', alone ? 'true' : null);
|
|
230
|
+
setAttr(next, 'aria-disabled', alone ? 'true' : null);
|
|
231
|
+
});
|
|
232
|
+
return box;
|
|
233
|
+
}
|
|
234
|
+
//# sourceMappingURL=record-bar.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"record-bar.mjs","sourceRoot":"","sources":["../../../../../libs/viewer/src/lib/record-bar.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What sits around a record, on the same tokens as the form: the bar over it
|
|
3
|
+
* (breadcrumbs, the gear menu, the pager), the attachment preview beside its
|
|
4
|
+
* sheet, and where the side panel goes. Put in the document after Fieldia's
|
|
5
|
+
* own stylesheet, so its rules on the sheet's layout come after those.
|
|
6
|
+
*/
|
|
7
|
+
export declare const RECORD_STYLES = "\n.fd-record-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; min-height: 46px; box-sizing: border-box; padding: 6px 16px; background: var(--fd-surface); border-block-end: 1px solid var(--fd-border); }\n.fd-form > .fd-content > .fd-record-bar { margin: -4px 0 12px; border-radius: var(--fd-radius); border: 1px solid var(--fd-border); }\n.fd-breadcrumbs { min-width: 0; }\n.fd-breadcrumbs ol { display: flex; flex-wrap: wrap; align-items: center; list-style: none; margin: 0; padding: 0; font-size: 17px; line-height: 1.3; }\n.fd-breadcrumbs li { display: flex; align-items: center; min-width: 0; }\n.fd-breadcrumbs li + li::before { content: \"/\"; color: var(--fd-muted); padding-inline: 8px; }\n.fd-crumb { all: unset; cursor: pointer; color: var(--fd-accent); border-radius: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.fd-crumb:hover { text-decoration: underline; }\n.fd-crumb:focus-visible { outline: 2px solid var(--fd-focus); outline-offset: 2px; }\n.fd-crumb-current { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.fd-record-actions { position: relative; }\n.fd-record-actions[hidden] { display: none; }\n.fd-record-gear { display: inline-flex; align-items: center; gap: 6px; }\n.fd-record-gear svg { width: 16px; height: 16px; flex: none; }\n.fd-record-menu { position: absolute; z-index: 40; inset-block-start: calc(100% + 4px); inset-inline-start: 0; display: grid; min-width: 220px; max-width: min(320px, 90vw); padding: 4px; box-sizing: border-box; background: var(--fd-surface); color: var(--fd-text); border: 1px solid var(--fd-border); border-radius: max(var(--fd-control-radius), 4px); box-shadow: 0 8px 24px rgba(0, 0, 0, 0.16); }\n.fd-record-menu[data-end] { inset-inline-start: auto; inset-inline-end: 0; }\n.fd-record-menu[hidden], .fd-record-menu [hidden] { display: none; }\n.fd-record-menu [role=\"group\"] { display: grid; }\n.fd-record-menu-heading { padding: 6px 12px 2px; font-size: 12px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--fd-muted); }\n.fd-record-menu-rule { margin: 4px 0; border-block-start: 1px solid var(--fd-border); }\n.fd-record-menu-item { all: unset; box-sizing: border-box; display: flex; align-items: center; gap: 8px; min-height: 34px; padding: 6px 12px; border-radius: 3px; cursor: pointer; color: var(--fd-text); }\n.fd-record-menu-item svg { width: 16px; height: 16px; flex: none; color: var(--fd-muted); }\n.fd-record-menu-item:hover, .fd-record-menu-item:focus { background: var(--fd-accent-soft); }\n.fd-record-menu-item:focus-visible { outline: 2px solid var(--fd-focus); outline-offset: -2px; }\n.fd-record-menu-danger { color: var(--fd-error); }\n.fd-record-pager { display: flex; align-items: center; gap: 4px; margin-inline-start: auto; }\n.fd-record-pager[hidden] { display: none; }\n.fd-record-pager-text { padding-inline-end: 6px; font-variant-numeric: tabular-nums; color: var(--fd-muted); white-space: nowrap; }\n.fd-record-step { min-width: 34px; padding-inline: 8px; font-size: 18px; line-height: 1; }\n.fd-record-step[aria-disabled=\"true\"] { opacity: 0.5; cursor: default; }\n/* \u2039 and \u203A are mirrored by the browser itself in a page read right to left: they point the way it reads. */\n@container fd-form (max-width: 520px) {\n .fd-record-bar { padding-inline: 12px; gap: 6px 8px; }\n /* On a phone the gear says nothing more than its picture, and the trail folds to the page before this one, a way back. */\n .fd-record-gear-words { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }\n .fd-breadcrumbs ol { flex-wrap: nowrap; font-size: 15px; }\n .fd-breadcrumbs li:not(:nth-last-child(-n + 2)) { display: none; }\n .fd-breadcrumbs li:nth-last-child(2)::before { content: \"\u2039\"; padding-inline: 0 6px; font-size: 20px; color: var(--fd-accent); }\n}\n\n/* The attachment beside the sheet: the sheet and its side panel in the first column, the file in the second. */\n.fd-attachment-preview { display: grid; grid-template-rows: auto minmax(0, 1fr); min-width: 0; background: var(--fd-surface); border: 1px solid var(--fd-border); border-radius: var(--fd-radius); overflow: hidden; }\n.fd-attachment-preview[hidden] { display: none; }\n.fd-attachment-head { display: flex; align-items: center; gap: 6px; padding: 6px 8px 6px 12px; padding-inline: 12px 8px; border-block-end: 1px solid var(--fd-border); min-width: 0; }\n.fd-attachment-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }\n.fd-attachment-count { color: var(--fd-muted); font-variant-numeric: tabular-nums; white-space: nowrap; }\n.fd-attachment-head [hidden] { display: none; }\n.fd-attachment-body { display: grid; min-height: 0; background: var(--fd-page); }\n.fd-attachment-body > iframe { width: 100%; height: 100%; min-height: 70vh; border: 0; background: #fff; }\n.fd-attachment-body > img { display: block; max-width: 100%; max-height: 80vh; margin: auto; object-fit: contain; }\n.fd-sheet-layout.fd-has-preview:has(> .fd-attachment-preview:not([hidden])) { max-width: none; grid-template-columns: minmax(0, 3fr) minmax(320px, 2fr); grid-template-rows: auto 1fr; }\n.fd-sheet-layout.fd-has-preview:has(> .fd-attachment-preview:not([hidden])) > :is(.fd-card, .fd-side) { grid-column: 1; }\n.fd-sheet-layout.fd-has-preview > .fd-attachment-preview { grid-column: 2; grid-row: 1 / span 2; position: sticky; top: 8px; height: calc(100vh - 16px); max-height: 1200px; }\n@container (max-width: 1000px) {\n .fd-sheet-layout.fd-has-preview:has(> .fd-attachment-preview:not([hidden])) { grid-template-columns: minmax(0, 1fr); }\n .fd-sheet-layout.fd-has-preview > .fd-attachment-preview { grid-column: 1; grid-row: auto; position: static; height: auto; }\n .fd-attachment-body > iframe { min-height: 60vh; }\n}\n/* A side panel kept beside the sheet: narrower under 1000px, under the sheet only once the form is too narrow for both. */\n@container (max-width: 1000px) { .fd-sheet-layout.fd-has-side[data-side-beside=\"always\"]:not(:has(> .fd-attachment-preview:not([hidden]))) { grid-template-columns: minmax(0, 1fr) minmax(240px, 300px); } }\n@container (max-width: 600px) { .fd-sheet-layout.fd-has-side[data-side-beside=\"always\"]:not(:has(> .fd-attachment-preview:not([hidden]))) { grid-template-columns: minmax(0, 1fr); } }\n";
|
|
8
|
+
/** Puts the record's surroundings' look in the document once. */
|
|
9
|
+
export declare function installRecordStyles(doc: Document): void;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What sits around a record, on the same tokens as the form: the bar over it
|
|
3
|
+
* (breadcrumbs, the gear menu, the pager), the attachment preview beside its
|
|
4
|
+
* sheet, and where the side panel goes. Put in the document after Fieldia's
|
|
5
|
+
* own stylesheet, so its rules on the sheet's layout come after those.
|
|
6
|
+
*/
|
|
7
|
+
export declare const RECORD_STYLES = "\n.fd-record-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; min-height: 46px; box-sizing: border-box; padding: 6px 16px; background: var(--fd-surface); border-block-end: 1px solid var(--fd-border); }\n.fd-form > .fd-content > .fd-record-bar { margin: -4px 0 12px; border-radius: var(--fd-radius); border: 1px solid var(--fd-border); }\n.fd-breadcrumbs { min-width: 0; }\n.fd-breadcrumbs ol { display: flex; flex-wrap: wrap; align-items: center; list-style: none; margin: 0; padding: 0; font-size: 17px; line-height: 1.3; }\n.fd-breadcrumbs li { display: flex; align-items: center; min-width: 0; }\n.fd-breadcrumbs li + li::before { content: \"/\"; color: var(--fd-muted); padding-inline: 8px; }\n.fd-crumb { all: unset; cursor: pointer; color: var(--fd-accent); border-radius: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.fd-crumb:hover { text-decoration: underline; }\n.fd-crumb:focus-visible { outline: 2px solid var(--fd-focus); outline-offset: 2px; }\n.fd-crumb-current { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.fd-record-actions { position: relative; }\n.fd-record-actions[hidden] { display: none; }\n.fd-record-gear { display: inline-flex; align-items: center; gap: 6px; }\n.fd-record-gear svg { width: 16px; height: 16px; flex: none; }\n.fd-record-menu { position: absolute; z-index: 40; inset-block-start: calc(100% + 4px); inset-inline-start: 0; display: grid; min-width: 220px; max-width: min(320px, 90vw); padding: 4px; box-sizing: border-box; background: var(--fd-surface); color: var(--fd-text); border: 1px solid var(--fd-border); border-radius: max(var(--fd-control-radius), 4px); box-shadow: 0 8px 24px rgba(0, 0, 0, 0.16); }\n.fd-record-menu[data-end] { inset-inline-start: auto; inset-inline-end: 0; }\n.fd-record-menu[hidden], .fd-record-menu [hidden] { display: none; }\n.fd-record-menu [role=\"group\"] { display: grid; }\n.fd-record-menu-heading { padding: 6px 12px 2px; font-size: 12px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--fd-muted); }\n.fd-record-menu-rule { margin: 4px 0; border-block-start: 1px solid var(--fd-border); }\n.fd-record-menu-item { all: unset; box-sizing: border-box; display: flex; align-items: center; gap: 8px; min-height: 34px; padding: 6px 12px; border-radius: 3px; cursor: pointer; color: var(--fd-text); }\n.fd-record-menu-item svg { width: 16px; height: 16px; flex: none; color: var(--fd-muted); }\n.fd-record-menu-item:hover, .fd-record-menu-item:focus { background: var(--fd-accent-soft); }\n.fd-record-menu-item:focus-visible { outline: 2px solid var(--fd-focus); outline-offset: -2px; }\n.fd-record-menu-danger { color: var(--fd-error); }\n.fd-record-pager { display: flex; align-items: center; gap: 4px; margin-inline-start: auto; }\n.fd-record-pager[hidden] { display: none; }\n.fd-record-pager-text { padding-inline-end: 6px; font-variant-numeric: tabular-nums; color: var(--fd-muted); white-space: nowrap; }\n.fd-record-step { min-width: 34px; padding-inline: 8px; font-size: 18px; line-height: 1; }\n.fd-record-step[aria-disabled=\"true\"] { opacity: 0.5; cursor: default; }\n/* \u2039 and \u203A are mirrored by the browser itself in a page read right to left: they point the way it reads. */\n@container fd-form (max-width: 520px) {\n .fd-record-bar { padding-inline: 12px; gap: 6px 8px; }\n /* On a phone the gear says nothing more than its picture, and the trail folds to the page before this one, a way back. */\n .fd-record-gear-words { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }\n .fd-breadcrumbs ol { flex-wrap: nowrap; font-size: 15px; }\n .fd-breadcrumbs li:not(:nth-last-child(-n + 2)) { display: none; }\n .fd-breadcrumbs li:nth-last-child(2)::before { content: \"\u2039\"; padding-inline: 0 6px; font-size: 20px; color: var(--fd-accent); }\n}\n\n/* The attachment beside the sheet: the sheet and its side panel in the first column, the file in the second. */\n.fd-attachment-preview { display: grid; grid-template-rows: auto minmax(0, 1fr); min-width: 0; background: var(--fd-surface); border: 1px solid var(--fd-border); border-radius: var(--fd-radius); overflow: hidden; }\n.fd-attachment-preview[hidden] { display: none; }\n.fd-attachment-head { display: flex; align-items: center; gap: 6px; padding: 6px 8px 6px 12px; padding-inline: 12px 8px; border-block-end: 1px solid var(--fd-border); min-width: 0; }\n.fd-attachment-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }\n.fd-attachment-count { color: var(--fd-muted); font-variant-numeric: tabular-nums; white-space: nowrap; }\n.fd-attachment-head [hidden] { display: none; }\n.fd-attachment-body { display: grid; min-height: 0; background: var(--fd-page); }\n.fd-attachment-body > iframe { width: 100%; height: 100%; min-height: 70vh; border: 0; background: #fff; }\n.fd-attachment-body > img { display: block; max-width: 100%; max-height: 80vh; margin: auto; object-fit: contain; }\n.fd-sheet-layout.fd-has-preview:has(> .fd-attachment-preview:not([hidden])) { max-width: none; grid-template-columns: minmax(0, 3fr) minmax(320px, 2fr); grid-template-rows: auto 1fr; }\n.fd-sheet-layout.fd-has-preview:has(> .fd-attachment-preview:not([hidden])) > :is(.fd-card, .fd-side) { grid-column: 1; }\n.fd-sheet-layout.fd-has-preview > .fd-attachment-preview { grid-column: 2; grid-row: 1 / span 2; position: sticky; top: 8px; height: calc(100vh - 16px); max-height: 1200px; }\n@container (max-width: 1000px) {\n .fd-sheet-layout.fd-has-preview:has(> .fd-attachment-preview:not([hidden])) { grid-template-columns: minmax(0, 1fr); }\n .fd-sheet-layout.fd-has-preview > .fd-attachment-preview { grid-column: 1; grid-row: auto; position: static; height: auto; }\n .fd-attachment-body > iframe { min-height: 60vh; }\n}\n/* A side panel kept beside the sheet: narrower under 1000px, under the sheet only once the form is too narrow for both. */\n@container (max-width: 1000px) { .fd-sheet-layout.fd-has-side[data-side-beside=\"always\"]:not(:has(> .fd-attachment-preview:not([hidden]))) { grid-template-columns: minmax(0, 1fr) minmax(240px, 300px); } }\n@container (max-width: 600px) { .fd-sheet-layout.fd-has-side[data-side-beside=\"always\"]:not(:has(> .fd-attachment-preview:not([hidden]))) { grid-template-columns: minmax(0, 1fr); } }\n";
|
|
8
|
+
/** Puts the record's surroundings' look in the document once. */
|
|
9
|
+
export declare function installRecordStyles(doc: Document): void;
|