@fieldia/viewer 0.7.0 → 0.9.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 (58) hide show
  1. package/README.md +10 -1
  2. package/bundle/fieldia.js +4 -607
  3. package/bundle/fieldia.js.map +4 -4
  4. package/package.json +3 -3
  5. package/src/lib/custom-filter.d.mts +16 -0
  6. package/src/lib/custom-filter.d.ts +16 -0
  7. package/src/lib/custom-filter.js +112 -0
  8. package/src/lib/custom-filter.js.map +1 -0
  9. package/src/lib/custom-filter.mjs +109 -0
  10. package/src/lib/custom-filter.mjs.map +1 -0
  11. package/src/lib/dom.d.mts +2 -0
  12. package/src/lib/dom.d.ts +2 -0
  13. package/src/lib/dom.js +3 -0
  14. package/src/lib/dom.js.map +1 -0
  15. package/src/lib/dom.mjs +2 -0
  16. package/src/lib/dom.mjs.map +1 -0
  17. package/src/lib/favourites.d.mts +32 -0
  18. package/src/lib/favourites.d.ts +32 -0
  19. package/src/lib/favourites.js +74 -0
  20. package/src/lib/favourites.js.map +1 -0
  21. package/src/lib/favourites.mjs +69 -0
  22. package/src/lib/favourites.mjs.map +1 -0
  23. package/src/lib/labels.d.mts +46 -0
  24. package/src/lib/labels.d.ts +46 -0
  25. package/src/lib/labels.js +156 -0
  26. package/src/lib/labels.js.map +1 -1
  27. package/src/lib/labels.mjs +156 -0
  28. package/src/lib/labels.mjs.map +1 -1
  29. package/src/lib/list-groups.d.mts +29 -0
  30. package/src/lib/list-groups.d.ts +29 -0
  31. package/src/lib/list-groups.js +86 -0
  32. package/src/lib/list-groups.js.map +1 -0
  33. package/src/lib/list-groups.mjs +83 -0
  34. package/src/lib/list-groups.mjs.map +1 -0
  35. package/src/lib/list-styles.d.mts +4 -0
  36. package/src/lib/list-styles.d.ts +4 -0
  37. package/src/lib/list-styles.js +108 -0
  38. package/src/lib/list-styles.js.map +1 -0
  39. package/src/lib/list-styles.mjs +104 -0
  40. package/src/lib/list-styles.mjs.map +1 -0
  41. package/src/lib/list.d.mts +34 -0
  42. package/src/lib/list.d.ts +34 -0
  43. package/src/lib/list.js +282 -0
  44. package/src/lib/list.js.map +1 -0
  45. package/src/lib/list.mjs +279 -0
  46. package/src/lib/list.mjs.map +1 -0
  47. package/src/lib/search-bar.d.mts +30 -0
  48. package/src/lib/search-bar.d.ts +30 -0
  49. package/src/lib/search-bar.js +205 -0
  50. package/src/lib/search-bar.js.map +1 -0
  51. package/src/lib/search-bar.mjs +201 -0
  52. package/src/lib/search-bar.mjs.map +1 -0
  53. package/src/lib/viewer.d.mts +3 -1
  54. package/src/lib/viewer.d.ts +3 -1
  55. package/src/lib/viewer.js +29 -1
  56. package/src/lib/viewer.js.map +1 -1
  57. package/src/lib/viewer.mjs +29 -1
  58. package/src/lib/viewer.mjs.map +1 -1
@@ -0,0 +1,83 @@
1
+ /** A group's name as a person reads it: the choice's label, yes or no, the linked record's name, or None. */
2
+ function groupName(context, field, group) {
3
+ const def = context.page.fields[field];
4
+ if (group.value === null)
5
+ return context.labels.none;
6
+ if (def.type === 'selection')
7
+ return def.options.find((o) => o.value === group.value)?.label ?? group.label;
8
+ if (def.type === 'boolean')
9
+ return group.value ? context.labels.yes : context.labels.no;
10
+ return group.label || String(group.value);
11
+ }
12
+ /** Take away every row under a group: its records, its groups and theirs. */
13
+ function closeUnder(tr) {
14
+ const level = Number(tr.dataset['level']);
15
+ let next = tr.nextElementSibling;
16
+ while (next && Number(next.dataset['level'] ?? 0) > level) {
17
+ const after = next.nextElementSibling;
18
+ next.remove();
19
+ next = after;
20
+ }
21
+ }
22
+ /**
23
+ * A group's row: its name and how many records it holds. Opened, it shows
24
+ * the next field's groups under it, or at the last field its records, a page
25
+ * at a time; closed, everything under it goes.
26
+ */
27
+ export function groupRow(context, group, level, within, grouping) {
28
+ const { el, labels } = context;
29
+ const field = grouping[level];
30
+ const filter = [...within, group.value === null ? { field, op: 'notset', value: null } : { field, op: '=', value: group.value }];
31
+ const toggle = el('button', { type: 'button', class: 'fd-group-toggle', 'aria-expanded': 'false' }, el('span', { class: 'fd-group-label' }, groupName(context, field, group)), ' ', el('span', { class: 'fd-group-count' }, `(${group.count})`));
32
+ const tr = el('tr', { class: 'fd-list-group', 'data-level': String(level), 'aria-level': String(level + 1) }, el('td', { colspan: String(context.columns) }, toggle));
33
+ tr.style.setProperty('--fd-level', String(level));
34
+ let opening = false;
35
+ async function open() {
36
+ opening = true;
37
+ try {
38
+ const rows = level + 1 < grouping.length
39
+ ? (await context.dataSource.groups?.({ model: context.model, field: grouping[level + 1], filter }))?.map((inner) => groupRow(context, inner, level + 1, filter, grouping)) ?? []
40
+ : await recordsFrom(0);
41
+ // Closed, or the list drawn again, while the answer was on its way.
42
+ if (!tr.isConnected || toggle.getAttribute('aria-expanded') !== 'true')
43
+ return;
44
+ tr.after(...rows);
45
+ context.changed();
46
+ }
47
+ finally {
48
+ opening = false;
49
+ }
50
+ }
51
+ /** A page of the group's records, from `offset`, and a row for the rest when there are more. */
52
+ async function recordsFrom(offset) {
53
+ const answer = await context.dataSource.list({ model: context.model, fields: context.fields, filter, sort: context.sort(), offset, limit: context.pageSize });
54
+ const rows = answer.records.map((record) => context.recordRow(record, level + 1));
55
+ const left = answer.total - offset - answer.records.length;
56
+ if (left <= 0)
57
+ return rows;
58
+ const more = el('button', { type: 'button', class: 'fd-button fd-button-link' }, context.fill(labels.loadMore, { n: left }));
59
+ const moreRow = el('tr', { class: 'fd-list-more', 'data-level': String(level + 1) }, el('td', { colspan: String(context.columns) }, more));
60
+ moreRow.style.setProperty('--fd-level', String(level));
61
+ more.addEventListener('click', async () => {
62
+ more.disabled = true;
63
+ const next = await recordsFrom(offset + answer.records.length);
64
+ if (!moreRow.isConnected)
65
+ return;
66
+ moreRow.replaceWith(...next);
67
+ context.changed();
68
+ });
69
+ return [...rows, moreRow];
70
+ }
71
+ toggle.addEventListener('click', () => {
72
+ const opened = toggle.getAttribute('aria-expanded') === 'true';
73
+ toggle.setAttribute('aria-expanded', String(!opened));
74
+ if (opened) {
75
+ closeUnder(tr);
76
+ context.changed();
77
+ }
78
+ else if (!opening)
79
+ void open();
80
+ });
81
+ return tr;
82
+ }
83
+ //# sourceMappingURL=list-groups.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-groups.mjs","sourceRoot":"","sources":["../../../../../libs/viewer/src/lib/list-groups.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ /** The list's look, on the same tokens as the forms it opens. */
2
+ export declare const LIST_STYLES = "\n.fd-list { display: grid; gap: 10px; min-width: 0; }\n.fd-list [hidden] { display: none !important; }\n.fd-list-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; min-height: 34px; }\n.fd-search { position: relative; flex: 1 1 360px; max-width: 680px; min-width: 0; container: fd-search / inline-size; }\n.fd-search-field { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; min-height: 34px; box-sizing: border-box; padding: 2px 2px 2px 8px; padding-inline: 8px 2px; border: 1px solid var(--fd-border); border-radius: var(--fd-control-radius); background: var(--fd-surface); }\n.fd-search-field:focus-within { border-color: var(--fd-focus); box-shadow: var(--fd-focus-ring); }\n.fd-search-field > .fd-icon, .fd-search-field > svg { width: 16px; height: 16px; color: var(--fd-muted); flex: none; }\n.fd-facets { display: contents; }\n.fd-facet { display: inline-flex; align-items: center; gap: 4px; max-width: 100%; min-width: 0; padding-block: 2px; padding-inline: 6px 2px; border-radius: 3px; background: var(--fd-accent-soft); color: var(--fd-accent); font-size: 13px; line-height: 18px; }\n.fd-facet svg { width: 13px; height: 13px; flex: none; }\n.fd-facet[data-kind=\"groupBy\"] { background: var(--fd-success-soft); color: var(--fd-success); }\n.fd-facet-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.fd-facet-remove { all: unset; cursor: pointer; display: grid; place-items: center; width: 18px; height: 18px; border-radius: 2px; font-size: 15px; line-height: 1; opacity: 0.7; }\n.fd-facet-remove:hover, .fd-facet-remove:focus-visible { opacity: 1; background: var(--fd-surface); }\n.fd-search-input { flex: 1 1 140px; min-width: 100px; border: none; outline: none; background: none; font: inherit; font-size: 14px; color: var(--fd-text); padding: 5px 4px; }\n.fd-form .fd-search-input:focus-visible { outline: none; }\n.fd-search-toggle { all: unset; cursor: pointer; display: grid; place-items: center; width: 30px; height: 28px; border-radius: 3px; color: var(--fd-muted); }\n/* Physical sides: a down chevron points down in either direction. */\n.fd-search-toggle::before { content: ''; width: 7px; height: 7px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: translateY(-2px) rotate(45deg); }\n.fd-search-toggle[aria-expanded=\"true\"]::before { transform: translateY(2px) rotate(-135deg); }\n.fd-search-toggle:hover, .fd-search-toggle[aria-expanded=\"true\"] { background: var(--fd-page); color: var(--fd-text); }\n.fd-search-toggle:focus-visible { outline: 2px solid var(--fd-focus); }\n.fd-search-suggestions, .fd-search-panel { position: absolute; z-index: 30; inset-inline: 0; top: calc(100% + 4px); box-sizing: border-box; background: var(--fd-surface); border: 1px solid var(--fd-border); border-radius: var(--fd-radius); box-shadow: 0 10px 28px rgba(15, 23, 42, 0.14); }\n.fd-search-suggestions { list-style: none; margin: 0; padding: 4px 0; }\n.fd-search-suggestions [role=\"option\"] { padding: 7px 12px; cursor: pointer; font-size: 14px; }\n.fd-search-suggestions [role=\"option\"][aria-selected=\"true\"] { background: var(--fd-accent-soft); }\n.fd-search-panel { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); padding-block: 6px; }\n.fd-search-group { display: flex; flex-direction: column; align-items: stretch; gap: 1px; padding: 4px 10px 8px; min-width: 0; }\n.fd-search-group + .fd-search-group { border-inline-start: 1px solid var(--fd-border); }\n@container fd-search (max-width: 540px) {\n .fd-search-panel { grid-auto-flow: row; }\n .fd-search-group + .fd-search-group { border-inline-start: none; border-block-start: 1px solid var(--fd-border); padding-block-start: 8px; }\n}\n.fd-search-heading { display: flex; align-items: center; gap: 6px; font-weight: 600; font-size: 13.5px; padding: 4px 6px 6px; }\n.fd-search-heading svg { width: 15px; height: 15px; }\n.fd-search-group[data-group-kind=\"filters\"] .fd-search-heading svg { color: var(--fd-accent); }\n.fd-search-group[data-group-kind=\"groupBy\"] .fd-search-heading svg { color: var(--fd-success); }\n.fd-search-group[data-group-kind=\"favourites\"] .fd-search-heading svg { color: var(--fd-warning); }\n.fd-search-option { all: unset; box-sizing: border-box; cursor: pointer; display: flex; align-items: center; gap: 6px; padding: 5px 6px; border-radius: 4px; font-size: 14px; color: var(--fd-text); }\n.fd-search-option::before { content: ''; width: 14px; flex: none; text-align: center; color: var(--fd-accent); font-weight: 700; }\n.fd-search-option[aria-pressed=\"true\"]::before { content: '\u2713'; }\n.fd-search-option:hover, .fd-search-option:focus-visible { background: var(--fd-page); }\n.fd-search-add { color: var(--fd-muted); margin-block-start: 4px; }\n.fd-search-add::before { content: '+'; color: var(--fd-muted); font-weight: 400; }\n.fd-custom-filter, .fd-favourite-form { display: grid; gap: 6px; padding: 6px; }\n.fd-custom-filter .fd-input, .fd-favourite-form .fd-input { width: 100%; box-sizing: border-box; min-height: 30px; border: 1px solid var(--fd-border); border-radius: var(--fd-control-radius); padding: 3px 6px; font: inherit; font-size: 13.5px; background: var(--fd-surface); color: var(--fd-text); }\n.fd-favourite-default { display: flex; align-items: center; gap: 6px; font-size: 13.5px; }\n.fd-favourite-list { list-style: none; margin: 0; padding: 0; }\n.fd-favourite { display: flex; align-items: center; }\n.fd-favourite .fd-search-option { flex: 1; min-width: 0; }\n.fd-favourite .fd-search-option[data-default=\"true\"]::before { content: '\u2605'; color: var(--fd-warning); }\n.fd-favourite-remove { all: unset; cursor: pointer; width: 24px; height: 24px; display: grid; place-items: center; border-radius: 4px; color: var(--fd-muted); }\n.fd-favourite-remove:hover { background: var(--fd-page); color: var(--fd-error); }\n.fd-favourites-none { margin: 0; padding: 4px 6px; color: var(--fd-muted); font-size: 13px; }\n.fd-list-selection { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 3px 4px 3px 10px; border-radius: var(--fd-control-radius); background: var(--fd-accent-soft); }\n.fd-list-count { font-weight: 600; font-size: 13.5px; color: var(--fd-accent); font-variant-numeric: tabular-nums; }\n.fd-pager { display: flex; align-items: center; gap: 4px; margin-inline-start: auto; }\n.fd-pager-text { color: var(--fd-muted); font-size: 13.5px; font-variant-numeric: tabular-nums; margin-inline-end: 6px; white-space: nowrap; }\n.fd-pager-button { min-width: 32px; padding-inline: 0; font-size: 18px; line-height: 1; }\n.fd-list-scroll { overflow-x: auto; background: var(--fd-surface); border: 1px solid var(--fd-border); border-radius: var(--fd-radius); }\n.fd-list-table { width: 100%; border-collapse: collapse; font-size: 14px; }\n.fd-list-table th { text-align: start; font-weight: 600; font-size: 13px; color: var(--fd-text); padding: 8px 10px; border-block-end: 1px solid var(--fd-border-strong); white-space: nowrap; background: var(--fd-surface); }\n.fd-list-table td { padding: 7px 10px; border-block-end: 1px solid var(--fd-border); max-width: 28em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.fd-list-table tbody tr:last-child td { border-block-end: none; }\n.fd-list-table .fd-num { text-align: end; font-variant-numeric: tabular-nums; }\n.fd-list-table th.fd-list-check, .fd-list-table td.fd-list-check { width: 36px; padding-inline: 10px 0; }\n.fd-list-checkbox { width: 16px; height: 16px; margin: 0; vertical-align: middle; accent-color: var(--fd-accent); cursor: pointer; }\n.fd-list-sort { all: unset; box-sizing: border-box; width: 100%; cursor: pointer; display: flex; align-items: center; gap: 4px; font: inherit; color: inherit; }\n.fd-list-sort::after { content: ''; width: 0; height: 0; border-inline: 4px solid transparent; opacity: 0; }\n.fd-list-sort:hover::after { opacity: 0.35; border-block-start: 5px solid currentColor; }\n.fd-list-table th[aria-sort=\"ascending\"] .fd-list-sort::after { opacity: 1; border-block-start: none; border-block-end: 5px solid currentColor; }\n.fd-list-table th[aria-sort=\"descending\"] .fd-list-sort::after { opacity: 1; border-block-end: none; border-block-start: 5px solid currentColor; }\n.fd-list-table th.fd-num .fd-list-sort { justify-content: flex-end; }\n.fd-list-table th.fd-num .fd-list-sort::after { order: -1; }\n.fd-list-sort:focus-visible { outline: 2px solid var(--fd-focus); outline-offset: 2px; }\n.fd-list-row:hover td { background: var(--fd-page); }\n.fd-list-openable { cursor: pointer; }\n.fd-list-row[aria-selected=\"true\"] td { background: var(--fd-accent-soft); }\n.fd-list-row:focus-visible { outline: 2px solid var(--fd-focus); outline-offset: -2px; }\n.fd-list-table[aria-busy=\"true\"] tbody { opacity: 0.6; transition: opacity 0.2s 0.15s; }\n.fd-list-group td { padding: 0; background: var(--fd-page); }\n.fd-group-toggle { all: unset; box-sizing: border-box; cursor: pointer; display: flex; align-items: center; gap: 8px; width: 100%; padding: 8px 10px; padding-inline-start: calc(12px + var(--fd-level, 0) * 22px); font-weight: 600; font-size: 13.5px; color: var(--fd-text); }\n.fd-group-toggle::before { content: ''; flex: none; width: 6px; height: 6px; border-top: 1.5px solid currentColor; border-right: 1.5px solid currentColor; transform: rotate(45deg); transition: transform 0.12s; }\n.fd-group-toggle:dir(rtl)::before { transform: rotate(-135deg); }\n.fd-group-toggle[aria-expanded=\"true\"]::before { transform: rotate(135deg); }\n.fd-group-toggle:hover { background: var(--fd-accent-soft); }\n.fd-group-toggle:focus-visible { outline: 2px solid var(--fd-focus); outline-offset: -2px; }\n.fd-group-count { color: var(--fd-muted); font-weight: 400; font-variant-numeric: tabular-nums; }\n.fd-list-more td { padding: 4px 10px; padding-inline-start: calc(46px + var(--fd-level, 0) * 22px); }\n.fd-list-empty, .fd-list-failed { margin: 0; padding: 28px 12px; text-align: center; color: var(--fd-muted); }\n.fd-list-failed { color: var(--fd-error); }\n";
3
+ /** Puts the list's look in the document once. */
4
+ export declare function installListStyles(doc: Document): void;
@@ -0,0 +1,4 @@
1
+ /** The list's look, on the same tokens as the forms it opens. */
2
+ export declare const LIST_STYLES = "\n.fd-list { display: grid; gap: 10px; min-width: 0; }\n.fd-list [hidden] { display: none !important; }\n.fd-list-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; min-height: 34px; }\n.fd-search { position: relative; flex: 1 1 360px; max-width: 680px; min-width: 0; container: fd-search / inline-size; }\n.fd-search-field { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; min-height: 34px; box-sizing: border-box; padding: 2px 2px 2px 8px; padding-inline: 8px 2px; border: 1px solid var(--fd-border); border-radius: var(--fd-control-radius); background: var(--fd-surface); }\n.fd-search-field:focus-within { border-color: var(--fd-focus); box-shadow: var(--fd-focus-ring); }\n.fd-search-field > .fd-icon, .fd-search-field > svg { width: 16px; height: 16px; color: var(--fd-muted); flex: none; }\n.fd-facets { display: contents; }\n.fd-facet { display: inline-flex; align-items: center; gap: 4px; max-width: 100%; min-width: 0; padding-block: 2px; padding-inline: 6px 2px; border-radius: 3px; background: var(--fd-accent-soft); color: var(--fd-accent); font-size: 13px; line-height: 18px; }\n.fd-facet svg { width: 13px; height: 13px; flex: none; }\n.fd-facet[data-kind=\"groupBy\"] { background: var(--fd-success-soft); color: var(--fd-success); }\n.fd-facet-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.fd-facet-remove { all: unset; cursor: pointer; display: grid; place-items: center; width: 18px; height: 18px; border-radius: 2px; font-size: 15px; line-height: 1; opacity: 0.7; }\n.fd-facet-remove:hover, .fd-facet-remove:focus-visible { opacity: 1; background: var(--fd-surface); }\n.fd-search-input { flex: 1 1 140px; min-width: 100px; border: none; outline: none; background: none; font: inherit; font-size: 14px; color: var(--fd-text); padding: 5px 4px; }\n.fd-form .fd-search-input:focus-visible { outline: none; }\n.fd-search-toggle { all: unset; cursor: pointer; display: grid; place-items: center; width: 30px; height: 28px; border-radius: 3px; color: var(--fd-muted); }\n/* Physical sides: a down chevron points down in either direction. */\n.fd-search-toggle::before { content: ''; width: 7px; height: 7px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: translateY(-2px) rotate(45deg); }\n.fd-search-toggle[aria-expanded=\"true\"]::before { transform: translateY(2px) rotate(-135deg); }\n.fd-search-toggle:hover, .fd-search-toggle[aria-expanded=\"true\"] { background: var(--fd-page); color: var(--fd-text); }\n.fd-search-toggle:focus-visible { outline: 2px solid var(--fd-focus); }\n.fd-search-suggestions, .fd-search-panel { position: absolute; z-index: 30; inset-inline: 0; top: calc(100% + 4px); box-sizing: border-box; background: var(--fd-surface); border: 1px solid var(--fd-border); border-radius: var(--fd-radius); box-shadow: 0 10px 28px rgba(15, 23, 42, 0.14); }\n.fd-search-suggestions { list-style: none; margin: 0; padding: 4px 0; }\n.fd-search-suggestions [role=\"option\"] { padding: 7px 12px; cursor: pointer; font-size: 14px; }\n.fd-search-suggestions [role=\"option\"][aria-selected=\"true\"] { background: var(--fd-accent-soft); }\n.fd-search-panel { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); padding-block: 6px; }\n.fd-search-group { display: flex; flex-direction: column; align-items: stretch; gap: 1px; padding: 4px 10px 8px; min-width: 0; }\n.fd-search-group + .fd-search-group { border-inline-start: 1px solid var(--fd-border); }\n@container fd-search (max-width: 540px) {\n .fd-search-panel { grid-auto-flow: row; }\n .fd-search-group + .fd-search-group { border-inline-start: none; border-block-start: 1px solid var(--fd-border); padding-block-start: 8px; }\n}\n.fd-search-heading { display: flex; align-items: center; gap: 6px; font-weight: 600; font-size: 13.5px; padding: 4px 6px 6px; }\n.fd-search-heading svg { width: 15px; height: 15px; }\n.fd-search-group[data-group-kind=\"filters\"] .fd-search-heading svg { color: var(--fd-accent); }\n.fd-search-group[data-group-kind=\"groupBy\"] .fd-search-heading svg { color: var(--fd-success); }\n.fd-search-group[data-group-kind=\"favourites\"] .fd-search-heading svg { color: var(--fd-warning); }\n.fd-search-option { all: unset; box-sizing: border-box; cursor: pointer; display: flex; align-items: center; gap: 6px; padding: 5px 6px; border-radius: 4px; font-size: 14px; color: var(--fd-text); }\n.fd-search-option::before { content: ''; width: 14px; flex: none; text-align: center; color: var(--fd-accent); font-weight: 700; }\n.fd-search-option[aria-pressed=\"true\"]::before { content: '\u2713'; }\n.fd-search-option:hover, .fd-search-option:focus-visible { background: var(--fd-page); }\n.fd-search-add { color: var(--fd-muted); margin-block-start: 4px; }\n.fd-search-add::before { content: '+'; color: var(--fd-muted); font-weight: 400; }\n.fd-custom-filter, .fd-favourite-form { display: grid; gap: 6px; padding: 6px; }\n.fd-custom-filter .fd-input, .fd-favourite-form .fd-input { width: 100%; box-sizing: border-box; min-height: 30px; border: 1px solid var(--fd-border); border-radius: var(--fd-control-radius); padding: 3px 6px; font: inherit; font-size: 13.5px; background: var(--fd-surface); color: var(--fd-text); }\n.fd-favourite-default { display: flex; align-items: center; gap: 6px; font-size: 13.5px; }\n.fd-favourite-list { list-style: none; margin: 0; padding: 0; }\n.fd-favourite { display: flex; align-items: center; }\n.fd-favourite .fd-search-option { flex: 1; min-width: 0; }\n.fd-favourite .fd-search-option[data-default=\"true\"]::before { content: '\u2605'; color: var(--fd-warning); }\n.fd-favourite-remove { all: unset; cursor: pointer; width: 24px; height: 24px; display: grid; place-items: center; border-radius: 4px; color: var(--fd-muted); }\n.fd-favourite-remove:hover { background: var(--fd-page); color: var(--fd-error); }\n.fd-favourites-none { margin: 0; padding: 4px 6px; color: var(--fd-muted); font-size: 13px; }\n.fd-list-selection { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 3px 4px 3px 10px; border-radius: var(--fd-control-radius); background: var(--fd-accent-soft); }\n.fd-list-count { font-weight: 600; font-size: 13.5px; color: var(--fd-accent); font-variant-numeric: tabular-nums; }\n.fd-pager { display: flex; align-items: center; gap: 4px; margin-inline-start: auto; }\n.fd-pager-text { color: var(--fd-muted); font-size: 13.5px; font-variant-numeric: tabular-nums; margin-inline-end: 6px; white-space: nowrap; }\n.fd-pager-button { min-width: 32px; padding-inline: 0; font-size: 18px; line-height: 1; }\n.fd-list-scroll { overflow-x: auto; background: var(--fd-surface); border: 1px solid var(--fd-border); border-radius: var(--fd-radius); }\n.fd-list-table { width: 100%; border-collapse: collapse; font-size: 14px; }\n.fd-list-table th { text-align: start; font-weight: 600; font-size: 13px; color: var(--fd-text); padding: 8px 10px; border-block-end: 1px solid var(--fd-border-strong); white-space: nowrap; background: var(--fd-surface); }\n.fd-list-table td { padding: 7px 10px; border-block-end: 1px solid var(--fd-border); max-width: 28em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.fd-list-table tbody tr:last-child td { border-block-end: none; }\n.fd-list-table .fd-num { text-align: end; font-variant-numeric: tabular-nums; }\n.fd-list-table th.fd-list-check, .fd-list-table td.fd-list-check { width: 36px; padding-inline: 10px 0; }\n.fd-list-checkbox { width: 16px; height: 16px; margin: 0; vertical-align: middle; accent-color: var(--fd-accent); cursor: pointer; }\n.fd-list-sort { all: unset; box-sizing: border-box; width: 100%; cursor: pointer; display: flex; align-items: center; gap: 4px; font: inherit; color: inherit; }\n.fd-list-sort::after { content: ''; width: 0; height: 0; border-inline: 4px solid transparent; opacity: 0; }\n.fd-list-sort:hover::after { opacity: 0.35; border-block-start: 5px solid currentColor; }\n.fd-list-table th[aria-sort=\"ascending\"] .fd-list-sort::after { opacity: 1; border-block-start: none; border-block-end: 5px solid currentColor; }\n.fd-list-table th[aria-sort=\"descending\"] .fd-list-sort::after { opacity: 1; border-block-end: none; border-block-start: 5px solid currentColor; }\n.fd-list-table th.fd-num .fd-list-sort { justify-content: flex-end; }\n.fd-list-table th.fd-num .fd-list-sort::after { order: -1; }\n.fd-list-sort:focus-visible { outline: 2px solid var(--fd-focus); outline-offset: 2px; }\n.fd-list-row:hover td { background: var(--fd-page); }\n.fd-list-openable { cursor: pointer; }\n.fd-list-row[aria-selected=\"true\"] td { background: var(--fd-accent-soft); }\n.fd-list-row:focus-visible { outline: 2px solid var(--fd-focus); outline-offset: -2px; }\n.fd-list-table[aria-busy=\"true\"] tbody { opacity: 0.6; transition: opacity 0.2s 0.15s; }\n.fd-list-group td { padding: 0; background: var(--fd-page); }\n.fd-group-toggle { all: unset; box-sizing: border-box; cursor: pointer; display: flex; align-items: center; gap: 8px; width: 100%; padding: 8px 10px; padding-inline-start: calc(12px + var(--fd-level, 0) * 22px); font-weight: 600; font-size: 13.5px; color: var(--fd-text); }\n.fd-group-toggle::before { content: ''; flex: none; width: 6px; height: 6px; border-top: 1.5px solid currentColor; border-right: 1.5px solid currentColor; transform: rotate(45deg); transition: transform 0.12s; }\n.fd-group-toggle:dir(rtl)::before { transform: rotate(-135deg); }\n.fd-group-toggle[aria-expanded=\"true\"]::before { transform: rotate(135deg); }\n.fd-group-toggle:hover { background: var(--fd-accent-soft); }\n.fd-group-toggle:focus-visible { outline: 2px solid var(--fd-focus); outline-offset: -2px; }\n.fd-group-count { color: var(--fd-muted); font-weight: 400; font-variant-numeric: tabular-nums; }\n.fd-list-more td { padding: 4px 10px; padding-inline-start: calc(46px + var(--fd-level, 0) * 22px); }\n.fd-list-empty, .fd-list-failed { margin: 0; padding: 28px 12px; text-align: center; color: var(--fd-muted); }\n.fd-list-failed { color: var(--fd-error); }\n";
3
+ /** Puts the list's look in the document once. */
4
+ export declare function installListStyles(doc: Document): void;
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LIST_STYLES = void 0;
4
+ exports.installListStyles = installListStyles;
5
+ /** The list's look, on the same tokens as the forms it opens. */
6
+ exports.LIST_STYLES = `
7
+ .fd-list { display: grid; gap: 10px; min-width: 0; }
8
+ .fd-list [hidden] { display: none !important; }
9
+ .fd-list-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; min-height: 34px; }
10
+ .fd-search { position: relative; flex: 1 1 360px; max-width: 680px; min-width: 0; container: fd-search / inline-size; }
11
+ .fd-search-field { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; min-height: 34px; box-sizing: border-box; padding: 2px 2px 2px 8px; padding-inline: 8px 2px; border: 1px solid var(--fd-border); border-radius: var(--fd-control-radius); background: var(--fd-surface); }
12
+ .fd-search-field:focus-within { border-color: var(--fd-focus); box-shadow: var(--fd-focus-ring); }
13
+ .fd-search-field > .fd-icon, .fd-search-field > svg { width: 16px; height: 16px; color: var(--fd-muted); flex: none; }
14
+ .fd-facets { display: contents; }
15
+ .fd-facet { display: inline-flex; align-items: center; gap: 4px; max-width: 100%; min-width: 0; padding-block: 2px; padding-inline: 6px 2px; border-radius: 3px; background: var(--fd-accent-soft); color: var(--fd-accent); font-size: 13px; line-height: 18px; }
16
+ .fd-facet svg { width: 13px; height: 13px; flex: none; }
17
+ .fd-facet[data-kind="groupBy"] { background: var(--fd-success-soft); color: var(--fd-success); }
18
+ .fd-facet-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
19
+ .fd-facet-remove { all: unset; cursor: pointer; display: grid; place-items: center; width: 18px; height: 18px; border-radius: 2px; font-size: 15px; line-height: 1; opacity: 0.7; }
20
+ .fd-facet-remove:hover, .fd-facet-remove:focus-visible { opacity: 1; background: var(--fd-surface); }
21
+ .fd-search-input { flex: 1 1 140px; min-width: 100px; border: none; outline: none; background: none; font: inherit; font-size: 14px; color: var(--fd-text); padding: 5px 4px; }
22
+ .fd-form .fd-search-input:focus-visible { outline: none; }
23
+ .fd-search-toggle { all: unset; cursor: pointer; display: grid; place-items: center; width: 30px; height: 28px; border-radius: 3px; color: var(--fd-muted); }
24
+ /* Physical sides: a down chevron points down in either direction. */
25
+ .fd-search-toggle::before { content: ''; width: 7px; height: 7px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: translateY(-2px) rotate(45deg); }
26
+ .fd-search-toggle[aria-expanded="true"]::before { transform: translateY(2px) rotate(-135deg); }
27
+ .fd-search-toggle:hover, .fd-search-toggle[aria-expanded="true"] { background: var(--fd-page); color: var(--fd-text); }
28
+ .fd-search-toggle:focus-visible { outline: 2px solid var(--fd-focus); }
29
+ .fd-search-suggestions, .fd-search-panel { position: absolute; z-index: 30; inset-inline: 0; top: calc(100% + 4px); box-sizing: border-box; background: var(--fd-surface); border: 1px solid var(--fd-border); border-radius: var(--fd-radius); box-shadow: 0 10px 28px rgba(15, 23, 42, 0.14); }
30
+ .fd-search-suggestions { list-style: none; margin: 0; padding: 4px 0; }
31
+ .fd-search-suggestions [role="option"] { padding: 7px 12px; cursor: pointer; font-size: 14px; }
32
+ .fd-search-suggestions [role="option"][aria-selected="true"] { background: var(--fd-accent-soft); }
33
+ .fd-search-panel { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); padding-block: 6px; }
34
+ .fd-search-group { display: flex; flex-direction: column; align-items: stretch; gap: 1px; padding: 4px 10px 8px; min-width: 0; }
35
+ .fd-search-group + .fd-search-group { border-inline-start: 1px solid var(--fd-border); }
36
+ @container fd-search (max-width: 540px) {
37
+ .fd-search-panel { grid-auto-flow: row; }
38
+ .fd-search-group + .fd-search-group { border-inline-start: none; border-block-start: 1px solid var(--fd-border); padding-block-start: 8px; }
39
+ }
40
+ .fd-search-heading { display: flex; align-items: center; gap: 6px; font-weight: 600; font-size: 13.5px; padding: 4px 6px 6px; }
41
+ .fd-search-heading svg { width: 15px; height: 15px; }
42
+ .fd-search-group[data-group-kind="filters"] .fd-search-heading svg { color: var(--fd-accent); }
43
+ .fd-search-group[data-group-kind="groupBy"] .fd-search-heading svg { color: var(--fd-success); }
44
+ .fd-search-group[data-group-kind="favourites"] .fd-search-heading svg { color: var(--fd-warning); }
45
+ .fd-search-option { all: unset; box-sizing: border-box; cursor: pointer; display: flex; align-items: center; gap: 6px; padding: 5px 6px; border-radius: 4px; font-size: 14px; color: var(--fd-text); }
46
+ .fd-search-option::before { content: ''; width: 14px; flex: none; text-align: center; color: var(--fd-accent); font-weight: 700; }
47
+ .fd-search-option[aria-pressed="true"]::before { content: '✓'; }
48
+ .fd-search-option:hover, .fd-search-option:focus-visible { background: var(--fd-page); }
49
+ .fd-search-add { color: var(--fd-muted); margin-block-start: 4px; }
50
+ .fd-search-add::before { content: '+'; color: var(--fd-muted); font-weight: 400; }
51
+ .fd-custom-filter, .fd-favourite-form { display: grid; gap: 6px; padding: 6px; }
52
+ .fd-custom-filter .fd-input, .fd-favourite-form .fd-input { width: 100%; box-sizing: border-box; min-height: 30px; border: 1px solid var(--fd-border); border-radius: var(--fd-control-radius); padding: 3px 6px; font: inherit; font-size: 13.5px; background: var(--fd-surface); color: var(--fd-text); }
53
+ .fd-favourite-default { display: flex; align-items: center; gap: 6px; font-size: 13.5px; }
54
+ .fd-favourite-list { list-style: none; margin: 0; padding: 0; }
55
+ .fd-favourite { display: flex; align-items: center; }
56
+ .fd-favourite .fd-search-option { flex: 1; min-width: 0; }
57
+ .fd-favourite .fd-search-option[data-default="true"]::before { content: '★'; color: var(--fd-warning); }
58
+ .fd-favourite-remove { all: unset; cursor: pointer; width: 24px; height: 24px; display: grid; place-items: center; border-radius: 4px; color: var(--fd-muted); }
59
+ .fd-favourite-remove:hover { background: var(--fd-page); color: var(--fd-error); }
60
+ .fd-favourites-none { margin: 0; padding: 4px 6px; color: var(--fd-muted); font-size: 13px; }
61
+ .fd-list-selection { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 3px 4px 3px 10px; border-radius: var(--fd-control-radius); background: var(--fd-accent-soft); }
62
+ .fd-list-count { font-weight: 600; font-size: 13.5px; color: var(--fd-accent); font-variant-numeric: tabular-nums; }
63
+ .fd-pager { display: flex; align-items: center; gap: 4px; margin-inline-start: auto; }
64
+ .fd-pager-text { color: var(--fd-muted); font-size: 13.5px; font-variant-numeric: tabular-nums; margin-inline-end: 6px; white-space: nowrap; }
65
+ .fd-pager-button { min-width: 32px; padding-inline: 0; font-size: 18px; line-height: 1; }
66
+ .fd-list-scroll { overflow-x: auto; background: var(--fd-surface); border: 1px solid var(--fd-border); border-radius: var(--fd-radius); }
67
+ .fd-list-table { width: 100%; border-collapse: collapse; font-size: 14px; }
68
+ .fd-list-table th { text-align: start; font-weight: 600; font-size: 13px; color: var(--fd-text); padding: 8px 10px; border-block-end: 1px solid var(--fd-border-strong); white-space: nowrap; background: var(--fd-surface); }
69
+ .fd-list-table td { padding: 7px 10px; border-block-end: 1px solid var(--fd-border); max-width: 28em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
70
+ .fd-list-table tbody tr:last-child td { border-block-end: none; }
71
+ .fd-list-table .fd-num { text-align: end; font-variant-numeric: tabular-nums; }
72
+ .fd-list-table th.fd-list-check, .fd-list-table td.fd-list-check { width: 36px; padding-inline: 10px 0; }
73
+ .fd-list-checkbox { width: 16px; height: 16px; margin: 0; vertical-align: middle; accent-color: var(--fd-accent); cursor: pointer; }
74
+ .fd-list-sort { all: unset; box-sizing: border-box; width: 100%; cursor: pointer; display: flex; align-items: center; gap: 4px; font: inherit; color: inherit; }
75
+ .fd-list-sort::after { content: ''; width: 0; height: 0; border-inline: 4px solid transparent; opacity: 0; }
76
+ .fd-list-sort:hover::after { opacity: 0.35; border-block-start: 5px solid currentColor; }
77
+ .fd-list-table th[aria-sort="ascending"] .fd-list-sort::after { opacity: 1; border-block-start: none; border-block-end: 5px solid currentColor; }
78
+ .fd-list-table th[aria-sort="descending"] .fd-list-sort::after { opacity: 1; border-block-end: none; border-block-start: 5px solid currentColor; }
79
+ .fd-list-table th.fd-num .fd-list-sort { justify-content: flex-end; }
80
+ .fd-list-table th.fd-num .fd-list-sort::after { order: -1; }
81
+ .fd-list-sort:focus-visible { outline: 2px solid var(--fd-focus); outline-offset: 2px; }
82
+ .fd-list-row:hover td { background: var(--fd-page); }
83
+ .fd-list-openable { cursor: pointer; }
84
+ .fd-list-row[aria-selected="true"] td { background: var(--fd-accent-soft); }
85
+ .fd-list-row:focus-visible { outline: 2px solid var(--fd-focus); outline-offset: -2px; }
86
+ .fd-list-table[aria-busy="true"] tbody { opacity: 0.6; transition: opacity 0.2s 0.15s; }
87
+ .fd-list-group td { padding: 0; background: var(--fd-page); }
88
+ .fd-group-toggle { all: unset; box-sizing: border-box; cursor: pointer; display: flex; align-items: center; gap: 8px; width: 100%; padding: 8px 10px; padding-inline-start: calc(12px + var(--fd-level, 0) * 22px); font-weight: 600; font-size: 13.5px; color: var(--fd-text); }
89
+ .fd-group-toggle::before { content: ''; flex: none; width: 6px; height: 6px; border-top: 1.5px solid currentColor; border-right: 1.5px solid currentColor; transform: rotate(45deg); transition: transform 0.12s; }
90
+ .fd-group-toggle:dir(rtl)::before { transform: rotate(-135deg); }
91
+ .fd-group-toggle[aria-expanded="true"]::before { transform: rotate(135deg); }
92
+ .fd-group-toggle:hover { background: var(--fd-accent-soft); }
93
+ .fd-group-toggle:focus-visible { outline: 2px solid var(--fd-focus); outline-offset: -2px; }
94
+ .fd-group-count { color: var(--fd-muted); font-weight: 400; font-variant-numeric: tabular-nums; }
95
+ .fd-list-more td { padding: 4px 10px; padding-inline-start: calc(46px + var(--fd-level, 0) * 22px); }
96
+ .fd-list-empty, .fd-list-failed { margin: 0; padding: 28px 12px; text-align: center; color: var(--fd-muted); }
97
+ .fd-list-failed { color: var(--fd-error); }
98
+ `;
99
+ /** Puts the list's look in the document once. */
100
+ function installListStyles(doc) {
101
+ if (doc.getElementById('fd-list-styles'))
102
+ return;
103
+ const style = doc.createElement('style');
104
+ style.id = 'fd-list-styles';
105
+ style.textContent = exports.LIST_STYLES;
106
+ doc.head.append(style);
107
+ }
108
+ //# sourceMappingURL=list-styles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-styles.js","sourceRoot":"","sources":["../../../../../libs/viewer/src/lib/list-styles.ts"],"names":[],"mappings":";;;AAgGA,8CAMC;AAtGD,iEAAiE;AACpD,QAAA,WAAW,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4F1B,CAAC;AAEF,iDAAiD;AACjD,SAAgB,iBAAiB,CAAC,GAAa;IAC7C,IAAI,GAAG,CAAC,cAAc,CAAC,gBAAgB,CAAC;QAAE,OAAO;IACjD,MAAM,KAAK,GAAG,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IACzC,KAAK,CAAC,EAAE,GAAG,gBAAgB,CAAC;IAC5B,KAAK,CAAC,WAAW,GAAG,mBAAW,CAAC;IAChC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACzB,CAAC"}
@@ -0,0 +1,104 @@
1
+ /** The list's look, on the same tokens as the forms it opens. */
2
+ export const LIST_STYLES = `
3
+ .fd-list { display: grid; gap: 10px; min-width: 0; }
4
+ .fd-list [hidden] { display: none !important; }
5
+ .fd-list-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; min-height: 34px; }
6
+ .fd-search { position: relative; flex: 1 1 360px; max-width: 680px; min-width: 0; container: fd-search / inline-size; }
7
+ .fd-search-field { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; min-height: 34px; box-sizing: border-box; padding: 2px 2px 2px 8px; padding-inline: 8px 2px; border: 1px solid var(--fd-border); border-radius: var(--fd-control-radius); background: var(--fd-surface); }
8
+ .fd-search-field:focus-within { border-color: var(--fd-focus); box-shadow: var(--fd-focus-ring); }
9
+ .fd-search-field > .fd-icon, .fd-search-field > svg { width: 16px; height: 16px; color: var(--fd-muted); flex: none; }
10
+ .fd-facets { display: contents; }
11
+ .fd-facet { display: inline-flex; align-items: center; gap: 4px; max-width: 100%; min-width: 0; padding-block: 2px; padding-inline: 6px 2px; border-radius: 3px; background: var(--fd-accent-soft); color: var(--fd-accent); font-size: 13px; line-height: 18px; }
12
+ .fd-facet svg { width: 13px; height: 13px; flex: none; }
13
+ .fd-facet[data-kind="groupBy"] { background: var(--fd-success-soft); color: var(--fd-success); }
14
+ .fd-facet-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
15
+ .fd-facet-remove { all: unset; cursor: pointer; display: grid; place-items: center; width: 18px; height: 18px; border-radius: 2px; font-size: 15px; line-height: 1; opacity: 0.7; }
16
+ .fd-facet-remove:hover, .fd-facet-remove:focus-visible { opacity: 1; background: var(--fd-surface); }
17
+ .fd-search-input { flex: 1 1 140px; min-width: 100px; border: none; outline: none; background: none; font: inherit; font-size: 14px; color: var(--fd-text); padding: 5px 4px; }
18
+ .fd-form .fd-search-input:focus-visible { outline: none; }
19
+ .fd-search-toggle { all: unset; cursor: pointer; display: grid; place-items: center; width: 30px; height: 28px; border-radius: 3px; color: var(--fd-muted); }
20
+ /* Physical sides: a down chevron points down in either direction. */
21
+ .fd-search-toggle::before { content: ''; width: 7px; height: 7px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: translateY(-2px) rotate(45deg); }
22
+ .fd-search-toggle[aria-expanded="true"]::before { transform: translateY(2px) rotate(-135deg); }
23
+ .fd-search-toggle:hover, .fd-search-toggle[aria-expanded="true"] { background: var(--fd-page); color: var(--fd-text); }
24
+ .fd-search-toggle:focus-visible { outline: 2px solid var(--fd-focus); }
25
+ .fd-search-suggestions, .fd-search-panel { position: absolute; z-index: 30; inset-inline: 0; top: calc(100% + 4px); box-sizing: border-box; background: var(--fd-surface); border: 1px solid var(--fd-border); border-radius: var(--fd-radius); box-shadow: 0 10px 28px rgba(15, 23, 42, 0.14); }
26
+ .fd-search-suggestions { list-style: none; margin: 0; padding: 4px 0; }
27
+ .fd-search-suggestions [role="option"] { padding: 7px 12px; cursor: pointer; font-size: 14px; }
28
+ .fd-search-suggestions [role="option"][aria-selected="true"] { background: var(--fd-accent-soft); }
29
+ .fd-search-panel { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); padding-block: 6px; }
30
+ .fd-search-group { display: flex; flex-direction: column; align-items: stretch; gap: 1px; padding: 4px 10px 8px; min-width: 0; }
31
+ .fd-search-group + .fd-search-group { border-inline-start: 1px solid var(--fd-border); }
32
+ @container fd-search (max-width: 540px) {
33
+ .fd-search-panel { grid-auto-flow: row; }
34
+ .fd-search-group + .fd-search-group { border-inline-start: none; border-block-start: 1px solid var(--fd-border); padding-block-start: 8px; }
35
+ }
36
+ .fd-search-heading { display: flex; align-items: center; gap: 6px; font-weight: 600; font-size: 13.5px; padding: 4px 6px 6px; }
37
+ .fd-search-heading svg { width: 15px; height: 15px; }
38
+ .fd-search-group[data-group-kind="filters"] .fd-search-heading svg { color: var(--fd-accent); }
39
+ .fd-search-group[data-group-kind="groupBy"] .fd-search-heading svg { color: var(--fd-success); }
40
+ .fd-search-group[data-group-kind="favourites"] .fd-search-heading svg { color: var(--fd-warning); }
41
+ .fd-search-option { all: unset; box-sizing: border-box; cursor: pointer; display: flex; align-items: center; gap: 6px; padding: 5px 6px; border-radius: 4px; font-size: 14px; color: var(--fd-text); }
42
+ .fd-search-option::before { content: ''; width: 14px; flex: none; text-align: center; color: var(--fd-accent); font-weight: 700; }
43
+ .fd-search-option[aria-pressed="true"]::before { content: '✓'; }
44
+ .fd-search-option:hover, .fd-search-option:focus-visible { background: var(--fd-page); }
45
+ .fd-search-add { color: var(--fd-muted); margin-block-start: 4px; }
46
+ .fd-search-add::before { content: '+'; color: var(--fd-muted); font-weight: 400; }
47
+ .fd-custom-filter, .fd-favourite-form { display: grid; gap: 6px; padding: 6px; }
48
+ .fd-custom-filter .fd-input, .fd-favourite-form .fd-input { width: 100%; box-sizing: border-box; min-height: 30px; border: 1px solid var(--fd-border); border-radius: var(--fd-control-radius); padding: 3px 6px; font: inherit; font-size: 13.5px; background: var(--fd-surface); color: var(--fd-text); }
49
+ .fd-favourite-default { display: flex; align-items: center; gap: 6px; font-size: 13.5px; }
50
+ .fd-favourite-list { list-style: none; margin: 0; padding: 0; }
51
+ .fd-favourite { display: flex; align-items: center; }
52
+ .fd-favourite .fd-search-option { flex: 1; min-width: 0; }
53
+ .fd-favourite .fd-search-option[data-default="true"]::before { content: '★'; color: var(--fd-warning); }
54
+ .fd-favourite-remove { all: unset; cursor: pointer; width: 24px; height: 24px; display: grid; place-items: center; border-radius: 4px; color: var(--fd-muted); }
55
+ .fd-favourite-remove:hover { background: var(--fd-page); color: var(--fd-error); }
56
+ .fd-favourites-none { margin: 0; padding: 4px 6px; color: var(--fd-muted); font-size: 13px; }
57
+ .fd-list-selection { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 3px 4px 3px 10px; border-radius: var(--fd-control-radius); background: var(--fd-accent-soft); }
58
+ .fd-list-count { font-weight: 600; font-size: 13.5px; color: var(--fd-accent); font-variant-numeric: tabular-nums; }
59
+ .fd-pager { display: flex; align-items: center; gap: 4px; margin-inline-start: auto; }
60
+ .fd-pager-text { color: var(--fd-muted); font-size: 13.5px; font-variant-numeric: tabular-nums; margin-inline-end: 6px; white-space: nowrap; }
61
+ .fd-pager-button { min-width: 32px; padding-inline: 0; font-size: 18px; line-height: 1; }
62
+ .fd-list-scroll { overflow-x: auto; background: var(--fd-surface); border: 1px solid var(--fd-border); border-radius: var(--fd-radius); }
63
+ .fd-list-table { width: 100%; border-collapse: collapse; font-size: 14px; }
64
+ .fd-list-table th { text-align: start; font-weight: 600; font-size: 13px; color: var(--fd-text); padding: 8px 10px; border-block-end: 1px solid var(--fd-border-strong); white-space: nowrap; background: var(--fd-surface); }
65
+ .fd-list-table td { padding: 7px 10px; border-block-end: 1px solid var(--fd-border); max-width: 28em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
66
+ .fd-list-table tbody tr:last-child td { border-block-end: none; }
67
+ .fd-list-table .fd-num { text-align: end; font-variant-numeric: tabular-nums; }
68
+ .fd-list-table th.fd-list-check, .fd-list-table td.fd-list-check { width: 36px; padding-inline: 10px 0; }
69
+ .fd-list-checkbox { width: 16px; height: 16px; margin: 0; vertical-align: middle; accent-color: var(--fd-accent); cursor: pointer; }
70
+ .fd-list-sort { all: unset; box-sizing: border-box; width: 100%; cursor: pointer; display: flex; align-items: center; gap: 4px; font: inherit; color: inherit; }
71
+ .fd-list-sort::after { content: ''; width: 0; height: 0; border-inline: 4px solid transparent; opacity: 0; }
72
+ .fd-list-sort:hover::after { opacity: 0.35; border-block-start: 5px solid currentColor; }
73
+ .fd-list-table th[aria-sort="ascending"] .fd-list-sort::after { opacity: 1; border-block-start: none; border-block-end: 5px solid currentColor; }
74
+ .fd-list-table th[aria-sort="descending"] .fd-list-sort::after { opacity: 1; border-block-end: none; border-block-start: 5px solid currentColor; }
75
+ .fd-list-table th.fd-num .fd-list-sort { justify-content: flex-end; }
76
+ .fd-list-table th.fd-num .fd-list-sort::after { order: -1; }
77
+ .fd-list-sort:focus-visible { outline: 2px solid var(--fd-focus); outline-offset: 2px; }
78
+ .fd-list-row:hover td { background: var(--fd-page); }
79
+ .fd-list-openable { cursor: pointer; }
80
+ .fd-list-row[aria-selected="true"] td { background: var(--fd-accent-soft); }
81
+ .fd-list-row:focus-visible { outline: 2px solid var(--fd-focus); outline-offset: -2px; }
82
+ .fd-list-table[aria-busy="true"] tbody { opacity: 0.6; transition: opacity 0.2s 0.15s; }
83
+ .fd-list-group td { padding: 0; background: var(--fd-page); }
84
+ .fd-group-toggle { all: unset; box-sizing: border-box; cursor: pointer; display: flex; align-items: center; gap: 8px; width: 100%; padding: 8px 10px; padding-inline-start: calc(12px + var(--fd-level, 0) * 22px); font-weight: 600; font-size: 13.5px; color: var(--fd-text); }
85
+ .fd-group-toggle::before { content: ''; flex: none; width: 6px; height: 6px; border-top: 1.5px solid currentColor; border-right: 1.5px solid currentColor; transform: rotate(45deg); transition: transform 0.12s; }
86
+ .fd-group-toggle:dir(rtl)::before { transform: rotate(-135deg); }
87
+ .fd-group-toggle[aria-expanded="true"]::before { transform: rotate(135deg); }
88
+ .fd-group-toggle:hover { background: var(--fd-accent-soft); }
89
+ .fd-group-toggle:focus-visible { outline: 2px solid var(--fd-focus); outline-offset: -2px; }
90
+ .fd-group-count { color: var(--fd-muted); font-weight: 400; font-variant-numeric: tabular-nums; }
91
+ .fd-list-more td { padding: 4px 10px; padding-inline-start: calc(46px + var(--fd-level, 0) * 22px); }
92
+ .fd-list-empty, .fd-list-failed { margin: 0; padding: 28px 12px; text-align: center; color: var(--fd-muted); }
93
+ .fd-list-failed { color: var(--fd-error); }
94
+ `;
95
+ /** Puts the list's look in the document once. */
96
+ export function installListStyles(doc) {
97
+ if (doc.getElementById('fd-list-styles'))
98
+ return;
99
+ const style = doc.createElement('style');
100
+ style.id = 'fd-list-styles';
101
+ style.textContent = LIST_STYLES;
102
+ doc.head.append(style);
103
+ }
104
+ //# sourceMappingURL=list-styles.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-styles.mjs","sourceRoot":"","sources":["../../../../../libs/viewer/src/lib/list-styles.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,MAAM,CAAC,MAAM,WAAW,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4F1B,CAAC;AAEF,iDAAiD;AACjD,MAAM,UAAU,iBAAiB,CAAC,GAAa;IAC7C,IAAI,GAAG,CAAC,cAAc,CAAC,gBAAgB,CAAC;QAAE,OAAO;IACjD,MAAM,KAAK,GAAG,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IACzC,KAAK,CAAC,EAAE,GAAG,gBAAgB,CAAC;IAC5B,KAAK,CAAC,WAAW,GAAG,WAAW,CAAC;IAChC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACzB,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { type DataSource, type Form, type ListNode, type Locale, type Page, type RecordId } from '@fieldia/core';
2
+ import { type IconSet, type PreferenceStore } from '@fieldia/widgets';
3
+ import type { El } from './dom.mjs';
4
+ import type { ViewerLabels } from './labels.mjs';
5
+ export interface ListContext {
6
+ page: Page;
7
+ node: ListNode;
8
+ form: Form;
9
+ dataSource: DataSource | undefined;
10
+ doc: Document;
11
+ el: El;
12
+ labels: ViewerLabels;
13
+ locale: Locale;
14
+ fill: (template: string, values: Record<string, string | number>) => string;
15
+ confirm: (message: string) => Promise<boolean>;
16
+ withIcon: (icon: string | undefined, text: string) => (Node | string)[];
17
+ uid: (id: string) => string;
18
+ icons?: IconSet;
19
+ /** Where the list's favourite searches are kept. */
20
+ preferences: PreferenceStore;
21
+ onOpenRecord?: (id: RecordId) => void;
22
+ }
23
+ export interface ListView {
24
+ element: HTMLElement;
25
+ /** Ask for the records again, keeping the page, the order and what is chosen where it still applies. */
26
+ reload(): Promise<void>;
27
+ destroy(): void;
28
+ }
29
+ /**
30
+ * Records as a table: one page at a time, in the order a header asks for, each
31
+ * row opening its record. Chosen rows get the list's buttons, which hand the
32
+ * app their ids. A plain table, so it reads the same in every binding.
33
+ */
34
+ export declare function listView(context: ListContext): ListView;
@@ -0,0 +1,34 @@
1
+ import { type DataSource, type Form, type ListNode, type Locale, type Page, type RecordId } from '@fieldia/core';
2
+ import { type IconSet, type PreferenceStore } from '@fieldia/widgets';
3
+ import type { El } from './dom';
4
+ import type { ViewerLabels } from './labels';
5
+ export interface ListContext {
6
+ page: Page;
7
+ node: ListNode;
8
+ form: Form;
9
+ dataSource: DataSource | undefined;
10
+ doc: Document;
11
+ el: El;
12
+ labels: ViewerLabels;
13
+ locale: Locale;
14
+ fill: (template: string, values: Record<string, string | number>) => string;
15
+ confirm: (message: string) => Promise<boolean>;
16
+ withIcon: (icon: string | undefined, text: string) => (Node | string)[];
17
+ uid: (id: string) => string;
18
+ icons?: IconSet;
19
+ /** Where the list's favourite searches are kept. */
20
+ preferences: PreferenceStore;
21
+ onOpenRecord?: (id: RecordId) => void;
22
+ }
23
+ export interface ListView {
24
+ element: HTMLElement;
25
+ /** Ask for the records again, keeping the page, the order and what is chosen where it still applies. */
26
+ reload(): Promise<void>;
27
+ destroy(): void;
28
+ }
29
+ /**
30
+ * Records as a table: one page at a time, in the order a header asks for, each
31
+ * row opening its record. Chosen rows get the list's buttons, which hand the
32
+ * app their ids. A plain table, so it reads the same in every binding.
33
+ */
34
+ export declare function listView(context: ListContext): ListView;