@zeyos/zx 4.3.4 → 4.4.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 (128) hide show
  1. package/CHANGELOG.md +155 -0
  2. package/README.md +7 -0
  3. package/dist/types/components/activity-item/activity-item.d.ts +351 -0
  4. package/dist/types/components/activity-list/activity-list.d.ts +195 -0
  5. package/dist/types/components/app-sidebar/app-sidebar.d.ts +28 -0
  6. package/dist/types/components/button/button.d.ts +8 -0
  7. package/dist/types/components/calendar/calendar.d.ts +19 -0
  8. package/dist/types/components/card/card.d.ts +7 -0
  9. package/dist/types/components/card-view/card-view.d.ts +11 -3
  10. package/dist/types/components/card-view/record-card.d.ts +7 -1
  11. package/dist/types/components/code-editor/code-editor.d.ts +160 -0
  12. package/dist/types/components/code-editor/field-adapter.d.ts +5 -0
  13. package/dist/types/components/context-menu/context-menu.d.ts +18 -2
  14. package/dist/types/components/date-picker/date-picker.d.ts +8 -0
  15. package/dist/types/components/date-picker/time-picker.d.ts +7 -0
  16. package/dist/types/components/dialog/dialog.d.ts +29 -0
  17. package/dist/types/components/entity-ref/entity-ref.d.ts +331 -0
  18. package/dist/types/components/file-item/file-item.d.ts +234 -0
  19. package/dist/types/components/file-list/file-list.d.ts +171 -0
  20. package/dist/types/components/filter/filter.d.ts +91 -36
  21. package/dist/types/components/filter-panel/filter-panel.d.ts +449 -0
  22. package/dist/types/components/kanban-view/kanban-card.d.ts +138 -0
  23. package/dist/types/components/kanban-view/kanban-view.d.ts +170 -4
  24. package/dist/types/components/launcher/launcher.d.ts +19 -12
  25. package/dist/types/components/list-toolbar/list-toolbar.d.ts +599 -0
  26. package/dist/types/components/menu-button/menu-button.d.ts +4 -37
  27. package/dist/types/components/message/message.d.ts +7 -0
  28. package/dist/types/components/modal/modal.d.ts +48 -0
  29. package/dist/types/components/navigation-bar/navigation-bar.d.ts +105 -21
  30. package/dist/types/components/panel/panel.d.ts +7 -0
  31. package/dist/types/components/search/search.d.ts +7 -0
  32. package/dist/types/components/select/select.d.ts +4 -0
  33. package/dist/types/components/sort-control/sort-control.d.ts +105 -0
  34. package/dist/types/components/stat-tile/stat-tile.d.ts +277 -0
  35. package/dist/types/components/tabbox/tabbox.d.ts +7 -0
  36. package/dist/types/components/table/table.d.ts +144 -0
  37. package/dist/types/components/table-view/table-view.d.ts +11 -5
  38. package/dist/types/components/timebox/timebox.d.ts +7 -0
  39. package/dist/types/components/value-list/value-list.d.ts +8 -0
  40. package/dist/types/components/view/record-view.d.ts +96 -5
  41. package/dist/types/core/icons.d.ts +17 -0
  42. package/dist/types/index.d.ts +11 -0
  43. package/dist/types/internal/app-rail.d.ts +10 -0
  44. package/dist/types/internal/menu-items.d.ts +134 -0
  45. package/dist/zx-zeyos.esm.js +616 -77
  46. package/dist/zx-zeyos.esm.min.js +8 -1
  47. package/dist/zx.css +2085 -238
  48. package/dist/zx.esm.js +6704 -1542
  49. package/dist/zx.esm.min.js +10 -3
  50. package/dist/zx.global.js +6704 -1542
  51. package/dist/zx.global.min.js +10 -3
  52. package/dist/zx.min.css +1 -1
  53. package/docs/api.json +1479 -127
  54. package/docs/llms.md +315 -10
  55. package/docs/llms.txt +11 -5
  56. package/package.json +1 -1
  57. package/src/components/activity-item/activity-item.css +137 -0
  58. package/src/components/activity-item/activity-item.js +599 -0
  59. package/src/components/activity-list/activity-list.css +64 -0
  60. package/src/components/activity-list/activity-list.js +375 -0
  61. package/src/components/app-rail/app-rail.css +227 -19
  62. package/src/components/app-sidebar/app-sidebar.css +414 -24
  63. package/src/components/app-sidebar/app-sidebar.js +65 -5
  64. package/src/components/button/button.css +8 -0
  65. package/src/components/button/button.js +6 -1
  66. package/src/components/calendar/calendar.js +33 -3
  67. package/src/components/card/card.js +12 -1
  68. package/src/components/card-view/card-view.css +1 -0
  69. package/src/components/card-view/card-view.js +25 -9
  70. package/src/components/card-view/record-card.js +7 -3
  71. package/src/components/code-editor/code-editor.css +67 -0
  72. package/src/components/code-editor/code-editor.js +288 -0
  73. package/src/components/code-editor/field-adapter.js +34 -0
  74. package/src/components/context-menu/context-menu.css +80 -3
  75. package/src/components/context-menu/context-menu.js +22 -30
  76. package/src/components/date-picker/date-picker.js +22 -8
  77. package/src/components/date-picker/month-picker.js +3 -3
  78. package/src/components/date-picker/time-picker.js +20 -8
  79. package/src/components/dialog/dialog.js +88 -66
  80. package/src/components/dropdown/dropdown.js +2 -2
  81. package/src/components/entity-ref/entity-ref.css +182 -0
  82. package/src/components/entity-ref/entity-ref.js +496 -0
  83. package/src/components/file-item/file-item.css +88 -0
  84. package/src/components/file-item/file-item.js +371 -0
  85. package/src/components/file-list/file-list.css +51 -0
  86. package/src/components/file-list/file-list.js +320 -0
  87. package/src/components/filter/filter.css +27 -1
  88. package/src/components/filter/filter.js +199 -45
  89. package/src/components/filter-panel/filter-panel.css +104 -0
  90. package/src/components/filter-panel/filter-panel.js +964 -0
  91. package/src/components/kanban-view/kanban-card.js +239 -0
  92. package/src/components/kanban-view/kanban-view.css +194 -0
  93. package/src/components/kanban-view/kanban-view.js +251 -8
  94. package/src/components/launcher/launcher.js +59 -27
  95. package/src/components/list-toolbar/list-toolbar.css +189 -0
  96. package/src/components/list-toolbar/list-toolbar.js +851 -0
  97. package/src/components/menu-button/menu-button.css +80 -3
  98. package/src/components/menu-button/menu-button.js +21 -37
  99. package/src/components/message/message.css +5 -2
  100. package/src/components/message/message.js +13 -2
  101. package/src/components/modal/modal.css +15 -0
  102. package/src/components/modal/modal.js +141 -0
  103. package/src/components/navigation-bar/navigation-bar.css +77 -2
  104. package/src/components/navigation-bar/navigation-bar.js +171 -4
  105. package/src/components/panel/panel.js +13 -2
  106. package/src/components/search/search.js +17 -5
  107. package/src/components/select/field-adapter.js +4 -1
  108. package/src/components/select/select.js +3 -0
  109. package/src/components/sort-control/sort-control.css +17 -0
  110. package/src/components/sort-control/sort-control.js +140 -0
  111. package/src/components/stat-tile/stat-tile.css +213 -0
  112. package/src/components/stat-tile/stat-tile.js +590 -0
  113. package/src/components/tabbox/tabbox.js +12 -1
  114. package/src/components/table/table.css +51 -2
  115. package/src/components/table/table.js +298 -19
  116. package/src/components/table-view/table-view.css +8 -2
  117. package/src/components/table-view/table-view.js +21 -6
  118. package/src/components/tag-picker/tag-picker.css +3 -1
  119. package/src/components/timebox/timebox.js +18 -5
  120. package/src/components/value-list/value-list.js +22 -6
  121. package/src/components/view/record-view.css +5 -0
  122. package/src/components/view/record-view.js +100 -7
  123. package/src/core/icons.js +74 -5
  124. package/src/index.js +25 -0
  125. package/src/internal/app-rail.js +19 -1
  126. package/src/internal/menu-items.js +142 -0
  127. package/styles/print.css +192 -0
  128. package/styles/zx.css +11 -0
@@ -25,6 +25,29 @@ export type TableHierarchyOptions = {
25
25
  */
26
26
  expanded?: boolean | unknown[];
27
27
  };
28
+ export type TableRowKind = {
29
+ /**
30
+ * Draw the row as a single cell across every rendered column — a
31
+ * section heading rather than a record. The cell is a `<th scope="colgroup">`, not a `<td>`,
32
+ * because it labels the columns of the rows beneath it and a screen reader walking the table
33
+ * should meet it as a heading rather than as a value. A spanning row carries no selection
34
+ * checkbox, is never editable, and is skipped by `rowReorder`; it still emits `rowclick` and still
35
+ * participates in `getData()` and `updateRow()`.
36
+ */
37
+ span?: boolean;
38
+ /**
39
+ * Content
40
+ * of the spanning cell. Omitted, the cell falls back to the row's raw value for the first visible
41
+ * column, which is what a host otherwise writes by hand.
42
+ */
43
+ render?: (row: TableRow, index: number) => Node | string | number | null | undefined;
44
+ /**
45
+ * Space-separated classes added to the row, on top of `rowClass`. Zx
46
+ * ships no section look: a billing section is not a kanban swimlane, so the tint, the weight and
47
+ * the rule above it are the host's to decide.
48
+ */
49
+ class?: string;
50
+ };
28
51
  export type TableEditorApi = {
29
52
  /**
30
53
  * Value the cell holds when the editor opens.
@@ -207,6 +230,21 @@ export type TableOptions = {
207
230
  * Additional row class callback.
208
231
  */
209
232
  rowClass?: ((row: TableRow) => string) | null;
233
+ /**
234
+ * Row property or callback
235
+ * naming each row's kind — the `type` on a ZeyOS transaction line, where one value is a position
236
+ * carrying quantities and amounts and another is a section heading that groups the positions under
237
+ * it. `null`, the default, renders every row exactly as before.
238
+ */
239
+ rowKind?: string | ((row: TableRow) => unknown) | null;
240
+ /**
241
+ * Presentation per kind, keyed by the
242
+ * resolved kind coerced to a string. A kind with no entry here renders as an ordinary row. While
243
+ * any row in the current data resolves to a `span` kind the header sort controls are withheld and
244
+ * `setSort()` is inert: sorting a grouped table scatters the positions out of their sections, and
245
+ * doing that silently is worse than not offering it. `sortMode: 'server'` still owns its own order.
246
+ */
247
+ rowKinds?: Record<string, TableRowKind> | null;
210
248
  /**
211
249
  * Whether alternate rows use the zebra background.
212
250
  */
@@ -487,6 +525,10 @@ export declare class Table extends Component<TableOptions> {
487
525
  _original: import("../../core/dom.js").TargetSnapshot;
488
526
  _columns: any[] | TableColumn[];
489
527
  _data: any[] | TableRow[];
528
+ _rowKind: string | ((row: TableRow) => unknown);
529
+ _rowKinds: Record<string, TableRowKind>;
530
+ _spanning: boolean;
531
+ _sortWarned: boolean;
490
532
  _selected: Set<any>;
491
533
  _selectionAnchorId: any;
492
534
  _sort: any;
@@ -533,6 +575,7 @@ export declare class Table extends Component<TableOptions> {
533
575
  _columnList: HTMLElement;
534
576
  _selectAll: HTMLElement;
535
577
  _headers: Map<any, any>;
578
+ _headerSpanning: boolean;
536
579
  _hierarchyMeta: Map<unknown, TableHierarchyEntry>;
537
580
  static cssName: string;
538
581
  /** @type {TableOptions} */
@@ -678,6 +721,10 @@ export declare class Table extends Component<TableOptions> {
678
721
  /**
679
722
  * Activates a column sort. Local mode stably reorders data; server mode only updates the
680
723
  * header state and emits the request event.
724
+ *
725
+ * Inert while the data holds a spanning row: a sort would scatter the positions out of the
726
+ * sections that group them, in either sort mode. The header withholds its controls for the same
727
+ * reason, so nothing on screen invites the call.
681
728
  * @param {string} id Column id.
682
729
  * @param {TableSortDirection} [dir] Direction; omitted toggles the current column.
683
730
  * @param {{silent?: boolean}} [options={}] Event options.
@@ -896,6 +943,28 @@ export declare class Table extends Component<TableOptions> {
896
943
  destroy(): void;
897
944
  /** @returns {TableColumn[]} */
898
945
  _visibleColumns(): TableColumn[];
946
+ /**
947
+ * Whether a row draws as one cell across the table instead of as a record.
948
+ * @param {TableRow} row Row to classify.
949
+ * @returns {boolean}
950
+ */
951
+ _isSpanningRow(row: TableRow): boolean;
952
+ /**
953
+ * Whether any row in the current data — not only the rendered prefix — spans. This is what
954
+ * withholds the sort controls, and the reader must not be offered a control that the next
955
+ * `growBy()` would have to take away again.
956
+ * @returns {boolean}
957
+ */
958
+ _hasSpanningRow(): boolean;
959
+ /**
960
+ * How many cells one row occupies: every visible column plus the structural columns the table
961
+ * renders beside them. Shared by the spanning cell and the empty-state cell so the two can never
962
+ * disagree about the table's width.
963
+ * @returns {number}
964
+ */
965
+ _spanColspan(): number;
966
+ /** @returns {TableRow[]} Rendered rows that can carry a selection; spanning rows cannot. */
967
+ _selectableData(): TableRow[];
899
968
  /** @returns {HTMLElement} */
900
969
  _createColumnControls(): HTMLElement;
901
970
  /**
@@ -1091,6 +1160,8 @@ export declare class Table extends Component<TableOptions> {
1091
1160
  _emitRowToggle(id: unknown, expanded: boolean): void;
1092
1161
  /** Keeps the reader's current expansion state limited to branches still present in the data. */
1093
1162
  _reconcileExpanded(): void;
1163
+ /** @returns {Set<unknown>} Ids of every row in the data that may hold a selection. */
1164
+ _selectableIds(): Set<unknown>;
1094
1165
  /** @returns {boolean} Whether selection changed. */
1095
1166
  _pruneSelection(): boolean;
1096
1167
  /** @param {TableRow} row @returns {unknown} */
@@ -1141,6 +1212,79 @@ export declare class Table extends Component<TableOptions> {
1141
1212
  * @event Table#editinvalid
1142
1213
  * @type {CustomEvent<TableEditInvalidDetail>}
1143
1214
  */
1215
+ /**
1216
+ * Resolves a row's kind through the `rowKind` accessor and coerces it to the string `rowKinds` is
1217
+ * keyed by.
1218
+ *
1219
+ * Only `null` and `undefined` mean "no kind". `0` and `''` are kinds like any other: a ZeyOS
1220
+ * transaction line uses `0` for a position and `1` for a section, so a falsy test here would render
1221
+ * every position as though the table had never been told about kinds at all.
1222
+ * @param {TableRow} row Row to classify.
1223
+ * @param {string|((row: TableRow) => unknown)|null|undefined} rowKind Field name or accessor.
1224
+ * @returns {string|null} The kind as a string, or null when there is none.
1225
+ */
1226
+ export declare function resolveRowKind(row: TableRow, rowKind: string | ((row: TableRow) => unknown) | null | undefined): string | null;
1227
+ /**
1228
+ * Looks one resolved kind up in the `rowKinds` map.
1229
+ *
1230
+ * Own properties only: a kind read out of server data could just as easily be `toString` or
1231
+ * `constructor`, and inherited members of `Object.prototype` are not configuration.
1232
+ * @param {Record<string, TableRowKind>|null|undefined} rowKinds Kind map.
1233
+ * @param {string|null} kind Resolved kind.
1234
+ * @returns {TableRowKind|null} Matching entry, or null.
1235
+ */
1236
+ export declare function resolveRowKindSpec(rowKinds: Record<string, TableRowKind> | null | undefined, kind: string | null): TableRowKind | null;
1237
+ /**
1238
+ * Whether a row draws as one spanning cell under the given configuration.
1239
+ * @param {TableRow} row Row to classify.
1240
+ * @param {string|((row: TableRow) => unknown)|null|undefined} rowKind Field name or accessor.
1241
+ * @param {Record<string, TableRowKind>|null|undefined} rowKinds Kind map.
1242
+ * @returns {boolean}
1243
+ */
1244
+ export declare function isSpanningRow(row: TableRow, rowKind: string | ((row: TableRow) => unknown) | null | undefined, rowKinds: Record<string, TableRowKind> | null | undefined): boolean;
1245
+ /**
1246
+ * Whether a data set holds a row that spans — the question that decides whether `Table` offers its
1247
+ * sort controls at all.
1248
+ *
1249
+ * Asked of the whole data rather than of the rendered prefix: with `growing` on, a sort control
1250
+ * that disappeared the moment the reader pressed "show 20 more" would be worse than one that was
1251
+ * never there. Asked again on every data change, so a filter that removes the last section gives
1252
+ * the sort back.
1253
+ * @param {TableRow[]} rows Rows to scan.
1254
+ * @param {string|((row: TableRow) => unknown)|null|undefined} rowKind Field name or accessor.
1255
+ * @param {Record<string, TableRowKind>|null|undefined} rowKinds Kind map.
1256
+ * @returns {boolean}
1257
+ */
1258
+ export declare function hasSpanningRow(rows: TableRow[], rowKind: string | ((row: TableRow) => unknown) | null | undefined, rowKinds: Record<string, TableRowKind> | null | undefined): boolean;
1259
+ /**
1260
+ * How many cells one table row occupies.
1261
+ *
1262
+ * `selectable: 'multi'` and `rowReorder` each render a `<col>` and a leading cell of their own, and
1263
+ * a spanning cell that ignored them would leave the row one or two columns short — the table would
1264
+ * still lay out, silently and wrongly. `selectable: 'single'` adds no column: the whole row is the
1265
+ * control there.
1266
+ * @param {number} columnCount Number of visible data columns.
1267
+ * @param {{selectable?: TableSelectionMode, rowReorder?: boolean}} [structure={}] Structural columns.
1268
+ * @returns {number} Colspan covering every rendered cell, never below 1.
1269
+ */
1270
+ export declare function tableSpanColspan(columnCount: number, structure?: {
1271
+ selectable?: TableSelectionMode;
1272
+ rowReorder?: boolean;
1273
+ }): number;
1274
+ /**
1275
+ * Content for a spanning row's single cell.
1276
+ *
1277
+ * Without a `render` the cell shows the row's raw value for the first visible column — the same
1278
+ * thing a host writes by hand today. Deliberately raw rather than routed through the column's own
1279
+ * renderer or display type: that renderer was written for a record, and running it against a
1280
+ * heading that carries no quantities or amounts is how a section row ends up showing `0,00 €`.
1281
+ * @param {TableRow} row Row being rendered.
1282
+ * @param {TableRowKind|null|undefined} spec Resolved kind presentation.
1283
+ * @param {TableColumn[]} visibleColumns Columns currently rendered, in display order.
1284
+ * @param {number} [index=0] Flat row index.
1285
+ * @returns {Node|string|number|null|undefined} Cell content.
1286
+ */
1287
+ export declare function spanRowContent(row: TableRow, spec: TableRowKind | null | undefined, visibleColumns: TableColumn[], index?: number): Node | string | number | null | undefined;
1144
1288
  /**
1145
1289
  * Applies a column's built-in display type. A custom renderer always wins and may still return a
1146
1290
  * Node; all built-in results are strings so `_renderCellContent` can insert them as text.
@@ -43,9 +43,11 @@ export type TableViewOptions = {
43
43
  */
44
44
  hiddenFields?: string[];
45
45
  /**
46
- * Show the accessible visibility and reorder disclosure.
46
+ * Show the accessible visibility and reorder disclosure. `true` keeps the composed Table's own
47
+ * column chooser and `false` omits it; an object renders the shared record-view chooser instead,
48
+ * with a translated `label` and, with `target`, mounted into a host element.
47
49
  */
48
- fieldControls?: boolean;
50
+ fieldControls?: boolean | import('../view/record-view.js').ViewFieldControlsConfig;
49
51
  /**
50
52
  * Empty-result content.
51
53
  */
@@ -93,7 +95,10 @@ export type TableViewOptions = {
93
95
  * @property {unknown[]} [selection=[]] Initially selected record ids.
94
96
  * @property {string[]} [fieldOrder=[]] Preferred stable field order.
95
97
  * @property {string[]} [hiddenFields=[]] Initially hidden field ids.
96
- * @property {boolean} [fieldControls=true] Show the accessible visibility and reorder disclosure.
98
+ * @property {boolean|import('../view/record-view.js').ViewFieldControlsConfig} [fieldControls=true]
99
+ * Show the accessible visibility and reorder disclosure. `true` keeps the composed Table's own
100
+ * column chooser and `false` omits it; an object renders the shared record-view chooser instead,
101
+ * with a translated `label` and, with `target`, mounted into a host element.
97
102
  * @property {string|Node|(()=>string|Node)|null} [emptyText=null] Empty-result content.
98
103
  * @property {TableOptions} [table={}] Advanced low-level Table options. Shared options win where
99
104
  * their contracts overlap; all other options and callbacks are forwarded unchanged.
@@ -126,6 +131,7 @@ export declare class TableView extends RecordView {
126
131
  _tableSyncDepth: number;
127
132
  _tableViewDestroyed: boolean;
128
133
  _tableHost: HTMLElement;
134
+ _tableViewToolbar: HTMLElement;
129
135
  table: Table;
130
136
  static cssName: string;
131
137
  /** @type {Readonly<TableViewOptions>} */
@@ -176,7 +182,7 @@ export declare function fieldsToTableColumns(fields: ViewField[]): TableColumn[]
176
182
  * Builds the composed Table configuration. Shared options deliberately overwrite overlapping
177
183
  * low-level options; every advanced option remains untouched.
178
184
  * @param {TableOptions|undefined} table Advanced Table options.
179
- * @param {{fields:ViewField[],data:TableViewRecord[],recordId:string|((record:TableViewRecord)=>unknown),sort:ViewSort|null,sortMode:'local'|'server',selectable:false|'single'|'multi',hiddenFields:string[],fieldControls:boolean,emptyText:string|Node|(()=>string|Node)|null}} shared Shared state.
185
+ * @param {{fields:ViewField[],data:TableViewRecord[],recordId:string|((record:TableViewRecord)=>unknown),sort:ViewSort|null,sortMode:'local'|'server',selectable:false|'single'|'multi',hiddenFields:string[],fieldControls:boolean|import('../view/record-view.js').ViewFieldControlsConfig,emptyText:string|Node|(()=>string|Node)|null}} shared Shared state.
180
186
  * @returns {TableOptions} Table configuration.
181
187
  */
182
188
  export declare function tableOptionsForView(table: TableOptions | undefined, shared: {
@@ -187,6 +193,6 @@ export declare function tableOptionsForView(table: TableOptions | undefined, sha
187
193
  sortMode: 'local' | 'server';
188
194
  selectable: false | 'single' | 'multi';
189
195
  hiddenFields: string[];
190
- fieldControls: boolean;
196
+ fieldControls: boolean | import('../view/record-view.js').ViewFieldControlsConfig;
191
197
  emptyText: string | Node | (() => string | Node) | null;
192
198
  }): TableOptions;
@@ -118,4 +118,11 @@ export declare class Timebox extends Component<TimeboxOptions> {
118
118
  _syncDisabled(): void;
119
119
  /** @returns {void} */
120
120
  _emitChange(): void;
121
+ /**
122
+ * Resolves a message through the host translator, falling back to the built-in English text.
123
+ * @param {string} key Message key.
124
+ * @param {string} fallback English default.
125
+ * @returns {string}
126
+ */
127
+ _message(key: string, fallback: string): string;
121
128
  }
@@ -144,6 +144,14 @@ export declare class ValueList extends Component<ValueListOptions> {
144
144
  _removeAt(index: number, focusIndex?: number): void;
145
145
  /** @param {string} message @returns {void} */
146
146
  _showError(message: string): void;
147
+ /**
148
+ * Resolves a message through the host translator, falling back to the built-in English text.
149
+ * @param {string} key Message key.
150
+ * @param {string} fallback Built-in text, with `%1`-style placeholders.
151
+ * @param {...unknown} args Interpolation values.
152
+ * @returns {string}
153
+ */
154
+ _message(key: string, fallback: string, ...args: unknown[]): string;
147
155
  /** @returns {void} */
148
156
  destroy(): void;
149
157
  }
@@ -62,6 +62,35 @@ export type ViewSort = {
62
62
  */
63
63
  dir: ViewSortDirection;
64
64
  };
65
+ export type ViewFieldControlsConfig = {
66
+ /**
67
+ * Trigger label. Omitted resolves `recordView.fields`, English `Fields`.
68
+ */
69
+ label?: string;
70
+ /**
71
+ * Element or selector the disclosure is mounted into
72
+ * instead of the view's own toolbar. An unresolvable target falls back to the view.
73
+ */
74
+ target?: Element | string | null;
75
+ };
76
+ export type ViewFieldControlsSettings = {
77
+ /**
78
+ * Whether a concrete view renders the chooser at all.
79
+ */
80
+ enabled: boolean;
81
+ /**
82
+ * Whether the option was given as a `ViewFieldControlsConfig` object.
83
+ */
84
+ custom: boolean;
85
+ /**
86
+ * Configured trigger label, or null to resolve the message.
87
+ */
88
+ label: string | null;
89
+ /**
90
+ * Configured mount point, before resolution.
91
+ */
92
+ target: Element | string | null;
93
+ };
65
94
  export type RecordViewState = {
66
95
  /**
67
96
  * State schema version.
@@ -118,9 +147,12 @@ export type RecordViewOptions = {
118
147
  */
119
148
  hiddenFields?: string[];
120
149
  /**
121
- * Whether concrete views show the shared field chooser.
150
+ * Whether concrete views show the
151
+ * shared field chooser. `true` renders it in the view's own toolbar and `false` omits it; a
152
+ * `ViewFieldControlsConfig` object renders the same control with a translated `label` and, with
153
+ * `target`, mounts it into a host element such as a list toolbar.
122
154
  */
123
- fieldControls?: boolean;
155
+ fieldControls?: boolean | ViewFieldControlsConfig;
124
156
  /**
125
157
  * Empty-result content.
126
158
  */
@@ -174,6 +206,21 @@ export type RecordViewOptions = {
174
206
  * @property {string} id Field id.
175
207
  * @property {ViewSortDirection} dir Sort direction.
176
208
  */
209
+ /**
210
+ * Trigger customisation for the shared field chooser. Passing this object in place of `true` keeps
211
+ * the control and its state model exactly as they are; only its wording and mount point change.
212
+ * @typedef {Object} ViewFieldControlsConfig
213
+ * @property {string} [label] Trigger label. Omitted resolves `recordView.fields`, English `Fields`.
214
+ * @property {Element|string|null} [target=null] Element or selector the disclosure is mounted into
215
+ * instead of the view's own toolbar. An unresolvable target falls back to the view.
216
+ */
217
+ /**
218
+ * @typedef {Object} ViewFieldControlsSettings
219
+ * @property {boolean} enabled Whether a concrete view renders the chooser at all.
220
+ * @property {boolean} custom Whether the option was given as a `ViewFieldControlsConfig` object.
221
+ * @property {string|null} label Configured trigger label, or null to resolve the message.
222
+ * @property {Element|string|null} target Configured mount point, before resolution.
223
+ */
177
224
  /**
178
225
  * @typedef {Object} RecordViewState
179
226
  * @property {1} version State schema version.
@@ -192,7 +239,10 @@ export type RecordViewOptions = {
192
239
  * @property {unknown[]} [selection=[]] Initially selected record ids.
193
240
  * @property {string[]} [fieldOrder=[]] Field ids in preferred order.
194
241
  * @property {string[]} [hiddenFields=[]] Initially hidden field ids.
195
- * @property {boolean} [fieldControls=true] Whether concrete views show the shared field chooser.
242
+ * @property {boolean|ViewFieldControlsConfig} [fieldControls=true] Whether concrete views show the
243
+ * shared field chooser. `true` renders it in the view's own toolbar and `false` omits it; a
244
+ * `ViewFieldControlsConfig` object renders the same control with a translated `label` and, with
245
+ * `target`, mounts it into a host element such as a list toolbar.
196
246
  * @property {string|Node|(() => string|Node)|null} [emptyText=null] Empty-result content.
197
247
  * @property {(event: CustomEvent<Record<string, unknown>>) => void} [onrecordclick]
198
248
  * @property {(event: CustomEvent<Record<string, unknown>>) => void} [onrecorddblclick]
@@ -226,6 +276,8 @@ export declare class RecordView extends Component<RecordViewOptions> {
226
276
  _viewSelectionAnchor: unknown;
227
277
  _viewFieldControls: HTMLElement;
228
278
  _viewFieldList: HTMLElement;
279
+ _viewFieldSettings: ViewFieldControlsSettings;
280
+ _viewFieldControlsTarget: Element;
229
281
  _viewInitialized: boolean;
230
282
  static cssName: string;
231
283
  /** @type {Readonly<RecordViewOptions>} */
@@ -384,10 +436,42 @@ export declare class RecordView extends Component<RecordViewOptions> {
384
436
  /**
385
437
  * Builds the shared show/hide and ordering disclosure for a concrete view toolbar.
386
438
  * @protected
387
- * @param {string} [label='Fields'] Trigger label.
439
+ * @param {string|null} [label=null] Explicit trigger label. Omitted resolves the configured
440
+ * `fieldControls.label` and then the `recordView.fields` message.
388
441
  * @returns {HTMLElement} Disclosure element.
389
442
  */
390
- protected _createViewFieldControls(label?: string): HTMLElement;
443
+ protected _createViewFieldControls(label?: string | null): HTMLElement;
444
+ /**
445
+ * Builds the shared field disclosure and mounts it where `fieldControls` asks for it: the host
446
+ * element named by `target`, or the view's own toolbar when no target resolves.
447
+ * @protected
448
+ * @param {Element} toolbar The view's own toolbar.
449
+ * @param {string|null} [label=null] Explicit trigger label, for views that own their wording.
450
+ * @returns {HTMLElement} The mounted disclosure.
451
+ */
452
+ protected _mountViewFieldControls(toolbar: Element, label?: string | null): HTMLElement;
453
+ /**
454
+ * Removes the shared field disclosure from wherever it was mounted. An external `target` keeps
455
+ * every node it had before the view was created.
456
+ * @protected
457
+ * @returns {void}
458
+ */
459
+ protected _removeViewFieldControls(): void;
460
+ /**
461
+ * Resolves the field-chooser trigger label: the configured one, else the translated message.
462
+ * @protected
463
+ * @returns {string} Trigger label.
464
+ */
465
+ protected _viewFieldControlsLabel(): string;
466
+ /**
467
+ * Resolves a message through the host translator, falling back to the built-in English text.
468
+ * @protected
469
+ * @param {string} key Message key.
470
+ * @param {string} fallback Built-in text, with `%1`-style placeholders.
471
+ * @param {...unknown} args Interpolation values.
472
+ * @returns {string} Translated or built-in text.
473
+ */
474
+ protected _message(key: string, fallback: string, ...args: unknown[]): string;
391
475
  /** Concrete renderers override this hook. @protected @param {string} _reason Refresh reason. @returns {void} */
392
476
  protected _refreshView(_reason: string): void;
393
477
  /** Reads one record's stable id. @protected @param {ViewRecord} record Record. @returns {unknown} */
@@ -407,6 +491,13 @@ export declare class RecordView extends Component<RecordViewOptions> {
407
491
  /** @private @param {string|null} [focusId=null] @returns {void} */
408
492
  private _renderViewFieldControls;
409
493
  }
494
+ /**
495
+ * Reads the `fieldControls` option in its three shapes. `true` and `false` keep their exact
496
+ * meaning; an object additionally carries the trigger label and the host element to mount into.
497
+ * @param {boolean|ViewFieldControlsConfig|null|undefined} value Raw option value.
498
+ * @returns {ViewFieldControlsSettings} Normalized settings.
499
+ */
500
+ export declare function normalizeViewFieldControls(value: boolean | ViewFieldControlsConfig | null | undefined): ViewFieldControlsSettings;
410
501
  /**
411
502
  * Validates and clones field descriptors.
412
503
  * @param {ViewField[]} fields Fields.
@@ -33,6 +33,12 @@ export type IconOptions = {
33
33
  * Adds Font Awesome's `fa-fw` for column-aligned glyphs.
34
34
  */
35
35
  fixedWidth?: boolean;
36
+ /**
37
+ * Throws `RangeError` on a name the bundled glyph set does not
38
+ * carry, instead of returning the placeholder. For call sites that can afford to fail — a test,
39
+ * a build-time check — rather than a screen rendering server data.
40
+ */
41
+ strict?: boolean;
36
42
  };
37
43
  /**
38
44
  * @typedef {Object} IconOptions
@@ -42,6 +48,9 @@ export type IconOptions = {
42
48
  * @property {string} [style] Font Awesome style for this icon only (`'solid'`, `'duotone'`, …).
43
49
  * @property {string} [family] Font Awesome family for this icon only (`'classic'`, `'sharp'`, …).
44
50
  * @property {boolean} [fixedWidth] Adds Font Awesome's `fa-fw` for column-aligned glyphs.
51
+ * @property {boolean} [strict=false] Throws `RangeError` on a name the bundled glyph set does not
52
+ * carry, instead of returning the placeholder. For call sites that can afford to fail — a test,
53
+ * a build-time check — rather than a screen rendering server data.
45
54
  */
46
55
  /**
47
56
  * Icon glyphs from Font Awesome Free 6 (solid, plus `square` from regular), fontawesome.com,
@@ -130,8 +139,16 @@ export declare function iconNames(): string[];
130
139
  * its renderer itself — `'fa:user'`, `'duotone:user'`, `'kit:zeyos-notes'`, `'builtin:check'`, or
131
140
  * a literal Font Awesome class list such as `'fa-solid fa-user'`.
132
141
  *
142
+ * **A name this cannot resolve never throws.** Icon names routinely arrive from a server, and one
143
+ * unconfigured name must not take down the screen it appears on. An inline glyph the bundled set
144
+ * does not carry renders as the placeholder described in `missingIcon()` and is reported once per
145
+ * distinct name through `console.warn`; pass `{ strict: true }` to get a `RangeError` instead.
146
+ * Only the inline-SVG path can fail this way: Font Awesome resolves names in the browser at render
147
+ * time, so a name under a loaded kit or stylesheet is never "unknown" here and never warns.
148
+ *
133
149
  * @param {string} name Icon name or spec.
134
150
  * @param {IconOptions} [options={}] Display and accessibility options.
135
151
  * @returns {SVGSVGElement|HTMLElement} An `<svg>` for inline glyphs, an `<i>` for Font Awesome.
152
+ * @throws {RangeError} With `{ strict: true }` only, when the bundled set has no such glyph.
136
153
  */
137
154
  export declare function icon(name: string, options?: IconOptions): SVGSVGElement | HTMLElement;
@@ -34,10 +34,12 @@ export { stack, grid, aspect } from './components/layout/layout.js';
34
34
  export { truncate, isTruncated } from './components/truncate/truncate.js';
35
35
  export { copyButton } from './components/copy/copy-button.js';
36
36
  export { CopyInput } from './components/copy/copy-input.js';
37
+ export { CodeEditor, indentSelection, editorPosition } from './components/code-editor/code-editor.js';
37
38
  export { Toolbar } from './components/toolbar/toolbar.js';
38
39
  export { Toggle } from './components/toggle/toggle.js';
39
40
  export { Groupbox } from './components/groupbox/groupbox.js';
40
41
  export { Card } from './components/card/card.js';
42
+ export { StatTile, statTile } from './components/stat-tile/stat-tile.js';
41
43
  export { Aurora } from './components/aurora/aurora.js';
42
44
  export { Panel } from './components/panel/panel.js';
43
45
  export { MasterPanel } from './components/master-panel/master-panel.js';
@@ -52,6 +54,11 @@ export { Search } from './components/search/search.js';
52
54
  export { AppIcon, appIcon } from './components/app-icon/app-icon.js';
53
55
  export { Launcher, rankLauncherItems } from './components/launcher/launcher.js';
54
56
  export { Avatar, avatarInitials } from './components/avatar/avatar.js';
57
+ export { EntityRef, normalizeEntityRef, normalizeEntityRefLink, normalizeEntityRefMetadata, normalizeEntityRefActions } from './components/entity-ref/entity-ref.js';
58
+ export { FileItem, normalizeFileItem } from './components/file-item/file-item.js';
59
+ export { FileList, normalizeFileListItems } from './components/file-list/file-list.js';
60
+ export { ActivityItem, resolveActivityActions, normalizeActivityAction, normalizeActivityTimestamp } from './components/activity-item/activity-item.js';
61
+ export { ActivityList, groupActivityItems, normalizeActivityItems } from './components/activity-list/activity-list.js';
55
62
  export { AccountMenu } from './components/account-menu/account-menu.js';
56
63
  export { normalizeAppItems } from './internal/app-rail.js';
57
64
  export { AppSidebar } from './components/app-sidebar/app-sidebar.js';
@@ -85,11 +92,15 @@ export { TableView } from './components/table-view/table-view.js';
85
92
  export { CardView } from './components/card-view/card-view.js';
86
93
  export { KanbanView } from './components/kanban-view/kanban-view.js';
87
94
  export { absoluteKanbanIndex, allowsKanbanTransition, createKanbanHistory, evaluateKanbanMove, kanbanSearchTerms, locateKanbanRecord, matchesKanbanSearch, normalizeKanbanRules, reorderKanbanRecords, resolveKanbanRules } from './components/kanban-view/kanban-policy.js';
95
+ export { createKanbanAvatars, createKanbanCardHead, createKanbanIndicator, createKanbanProgress, kanbanAvatarLimit, resolveKanbanAssignees, resolveKanbanIndicator, resolveKanbanProgress } from './components/kanban-view/kanban-card.js';
88
96
  export { Grid, billingColumns, isBillingLine } from './components/grid/grid.js';
89
97
  export { Chart, ChartJsAdapter, chartSummaryTable, cloneChartValue, isEmptyChartData } from './components/chart/chart.js';
90
98
  export { TreeView } from './components/tree/tree.js';
91
99
  export { Finder } from './components/finder/finder.js';
92
100
  export { DataFilter } from './components/data-filter/data-filter.js';
101
+ export { FilterPanel, isActiveValue, pruneValue, serializeFilterValue } from './components/filter-panel/filter-panel.js';
102
+ export { SortControl } from './components/sort-control/sort-control.js';
103
+ export { ListToolbar } from './components/list-toolbar/list-toolbar.js';
93
104
  export { Filter } from './components/filter/filter.js';
94
105
  export { filterOperators, emptyFilterAst, filterCondition, filterGroup, parseFilterAst, cloneFilterAst, stringifyFilterAst, validateFilterAst } from './components/filter/filter-model.js';
95
106
  export { Field } from './components/field/field.js';
@@ -238,6 +238,16 @@ export declare class AppRailPresenter extends Component<AppRailPresenterOptions>
238
238
  _syncActive(): void;
239
239
  /** @returns {void} */
240
240
  _clearArtifacts(): void;
241
+ /**
242
+ * Resolves one message through `msg()`, which falls back to the host translator. Copied from
243
+ * `Pagination` rather than invented: the rail's flyout label was the last user-visible string
244
+ * in the navigation stack with no way to change it.
245
+ * @param {string} key Message key.
246
+ * @param {string} fallback English default.
247
+ * @param {...unknown} args Interpolation arguments.
248
+ * @returns {string}
249
+ */
250
+ _message(key: string, fallback: string, ...args: unknown[]): string;
241
251
  }
242
252
  /** Owns listeners attached to one dynamic rail render so `setItems()` can release them immediately. */
243
253
  declare class RailListenerScope extends Component {
@@ -0,0 +1,134 @@
1
+ export type MenuItemRole = 'menuitem' | 'menuitemcheckbox' | 'menuitemradio';
2
+ export type MenuController = {
3
+ /**
4
+ * Close the owning menu.
5
+ */
6
+ close: () => unknown;
7
+ };
8
+ export type MenuItem = {
9
+ /**
10
+ * Item label.
11
+ */
12
+ label: string;
13
+ /**
14
+ * Kernel icon name.
15
+ */
16
+ icon?: string;
17
+ /**
18
+ * Value emitted on selection.
19
+ */
20
+ value?: unknown;
21
+ /**
22
+ * Whether selection is disabled.
23
+ */
24
+ disabled?: boolean;
25
+ /**
26
+ * Whether the action is dangerous.
27
+ */
28
+ danger?: boolean;
29
+ /**
30
+ * Native-link destination.
31
+ */
32
+ href?: string;
33
+ /**
34
+ * Native-link target.
35
+ */
36
+ target?: string;
37
+ /**
38
+ * Native-link relationship.
39
+ */
40
+ rel?: string;
41
+ /**
42
+ * Supporting text under the label.
43
+ */
44
+ description?: string;
45
+ /**
46
+ * Compact trailing metadata.
47
+ */
48
+ badge?: string | number;
49
+ /**
50
+ * Keyboard shortcut label.
51
+ */
52
+ shortcut?: string;
53
+ /**
54
+ * Additional trailing content.
55
+ */
56
+ adornment?: string | number | Node;
57
+ /**
58
+ * APG role.
59
+ */
60
+ role?: MenuItemRole;
61
+ /**
62
+ * Checked state for checkbox/radio roles.
63
+ */
64
+ checked?: boolean;
65
+ /**
66
+ * Selection callback.
67
+ */
68
+ onselect?: (value: unknown, item: MenuItem, controller: MenuController) => void;
69
+ };
70
+ export type MenuHeading = {
71
+ /**
72
+ * Entry kind.
73
+ */
74
+ type: 'heading';
75
+ /**
76
+ * Visible heading.
77
+ */
78
+ label: string;
79
+ };
80
+ export type MenuSeparator = {
81
+ type: 'separator';
82
+ };
83
+ export type MenuEntry = MenuItem | MenuHeading | MenuSeparator | '-';
84
+ /** @typedef {'menuitem'|'menuitemcheckbox'|'menuitemradio'} MenuItemRole */
85
+ /**
86
+ * @typedef {Object} MenuController
87
+ * @property {() => unknown} close Close the owning menu.
88
+ */
89
+ /**
90
+ * @typedef {Object} MenuItem
91
+ * @property {string} label Item label.
92
+ * @property {string} [icon] Kernel icon name.
93
+ * @property {unknown} [value] Value emitted on selection.
94
+ * @property {boolean} [disabled=false] Whether selection is disabled.
95
+ * @property {boolean} [danger=false] Whether the action is dangerous.
96
+ * @property {string} [href] Native-link destination.
97
+ * @property {string} [target] Native-link target.
98
+ * @property {string} [rel] Native-link relationship.
99
+ * @property {string} [description] Supporting text under the label.
100
+ * @property {string|number} [badge] Compact trailing metadata.
101
+ * @property {string} [shortcut] Keyboard shortcut label.
102
+ * @property {string|number|Node} [adornment] Additional trailing content.
103
+ * @property {MenuItemRole} [role='menuitem'] APG role.
104
+ * @property {boolean} [checked=false] Checked state for checkbox/radio roles.
105
+ * @property {(value: unknown, item: MenuItem, controller: MenuController) => void} [onselect]
106
+ * Selection callback.
107
+ */
108
+ /**
109
+ * @typedef {Object} MenuHeading
110
+ * @property {'heading'} type Entry kind.
111
+ * @property {string} label Visible heading.
112
+ */
113
+ /** @typedef {{type: 'separator'}} MenuSeparator */
114
+ /** @typedef {MenuItem|MenuHeading|MenuSeparator|'-'} MenuEntry */
115
+ export declare const MENU_ITEM_SELECTOR: string;
116
+ /**
117
+ * Reports whether an entry is an interactive menu action.
118
+ * @param {MenuEntry|unknown} entry Candidate entry.
119
+ * @returns {entry is MenuItem}
120
+ */
121
+ export declare function isMenuItem(entry: MenuEntry | unknown): entry is MenuItem;
122
+ /**
123
+ * Resolves the only APG roles accepted by the shared action model.
124
+ * @param {MenuItem} item Item definition.
125
+ * @returns {MenuItemRole}
126
+ */
127
+ export declare function menuItemRole(item: MenuItem): MenuItemRole;
128
+ /**
129
+ * Builds one menu's entries with shared structure and link safety.
130
+ * @param {MenuEntry[]} entries Entry definitions.
131
+ * @param {string} block CSS block name, without the `zx-` prefix.
132
+ * @returns {HTMLElement[]}
133
+ */
134
+ export declare function renderMenuEntries(entries: MenuEntry[], block: string): HTMLElement[];