@zeyos/zx 5.0.0 → 5.2.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 (154) hide show
  1. package/CHANGELOG.md +164 -0
  2. package/README.md +2 -1
  3. package/dist/types/components/account-menu/account-menu.d.ts +8 -0
  4. package/dist/types/components/activity-list/activity-list.d.ts +9 -1
  5. package/dist/types/components/app-icon/app-icon.d.ts +14 -2
  6. package/dist/types/components/app-sidebar/app-sidebar.d.ts +288 -14
  7. package/dist/types/components/calendar/calendar.d.ts +67 -5
  8. package/dist/types/components/card-view/card-view.d.ts +7 -4
  9. package/dist/types/components/card-view/record-card.d.ts +11 -0
  10. package/dist/types/components/context-menu/context-menu.d.ts +6 -2
  11. package/dist/types/components/data-filter/data-filter.d.ts +4 -4
  12. package/dist/types/components/dropdown/dropdown.d.ts +22 -7
  13. package/dist/types/components/field/field.d.ts +30 -0
  14. package/dist/types/components/fieldset/external-adapter.d.ts +83 -0
  15. package/dist/types/components/fieldset/fieldset.d.ts +7 -0
  16. package/dist/types/components/file-list/file-list.d.ts +35 -3
  17. package/dist/types/components/filter/filter.d.ts +127 -3
  18. package/dist/types/components/filter-panel/filter-panel.d.ts +36 -7
  19. package/dist/types/components/launcher/launcher.d.ts +8 -0
  20. package/dist/types/components/list-toolbar/list-toolbar.d.ts +15 -6
  21. package/dist/types/components/menu-button/menu-button.d.ts +6 -0
  22. package/dist/types/components/message/message.d.ts +14 -1
  23. package/dist/types/components/modal/modal.d.ts +30 -0
  24. package/dist/types/components/module-bar/module-bar.d.ts +395 -0
  25. package/dist/types/components/pagination/pagination.d.ts +17 -3
  26. package/dist/types/components/select/select.d.ts +6 -0
  27. package/dist/types/components/sheet/sheet.d.ts +15 -0
  28. package/dist/types/components/table/table.d.ts +265 -17
  29. package/dist/types/components/view/record-view.d.ts +59 -2
  30. package/dist/types/components/view-settings/view-settings.d.ts +879 -0
  31. package/dist/types/components/workspace-switcher/workspace-switcher.d.ts +327 -0
  32. package/dist/types/core/component.d.ts +12 -2
  33. package/dist/types/core/i18n.d.ts +27 -3
  34. package/dist/types/core/keyboard.d.ts +98 -1
  35. package/dist/types/core/messages.d.ts +382 -0
  36. package/dist/types/core/overlay-host.d.ts +28 -1
  37. package/dist/types/core/overlay-stack.d.ts +260 -0
  38. package/dist/types/index.d.ts +5 -2
  39. package/dist/types/internal/app-rail.d.ts +38 -0
  40. package/dist/types/internal/menu-items.d.ts +71 -3
  41. package/dist/types/zeyos/index.d.ts +1 -0
  42. package/dist/types/zeyos/launcher.d.ts +9 -0
  43. package/dist/types/zeyos/module-bar.d.ts +176 -0
  44. package/dist/types/zeyos/query.d.ts +31 -5
  45. package/dist/types/zeyos/table.d.ts +245 -8
  46. package/dist/types/zeyos/view.d.ts +16 -2
  47. package/dist/zx-zeyos.esm.js +4422 -430
  48. package/dist/zx-zeyos.esm.min.js +5 -5
  49. package/dist/zx.css +1417 -134
  50. package/dist/zx.esm.js +6986 -830
  51. package/dist/zx.esm.min.js +8 -8
  52. package/dist/zx.global.js +6986 -830
  53. package/dist/zx.global.min.js +8 -8
  54. package/dist/zx.min.css +1 -1
  55. package/docs/api.json +794 -17
  56. package/docs/llms.md +503 -63
  57. package/docs/llms.txt +6 -2
  58. package/package.json +1 -1
  59. package/src/components/account-menu/account-menu.js +12 -0
  60. package/src/components/activity-list/activity-list.js +27 -1
  61. package/src/components/app-icon/app-icon.css +13 -2
  62. package/src/components/app-icon/app-icon.js +11 -1
  63. package/src/components/app-rail/app-rail.css +19 -0
  64. package/src/components/app-sidebar/app-sidebar.css +204 -3
  65. package/src/components/app-sidebar/app-sidebar.js +646 -40
  66. package/src/components/breadcrumb/breadcrumb.css +1 -1
  67. package/src/components/calendar/calendar.css +1 -1
  68. package/src/components/calendar/calendar.js +26 -52
  69. package/src/components/card/card.css +2 -2
  70. package/src/components/card-view/card-view.css +5 -5
  71. package/src/components/card-view/card-view.js +13 -9
  72. package/src/components/card-view/record-card.js +14 -3
  73. package/src/components/code-editor/code-editor.css +1 -1
  74. package/src/components/code-editor/field-adapter.js +9 -2
  75. package/src/components/context-menu/context-menu.js +8 -2
  76. package/src/components/copy/copy-input.css +1 -1
  77. package/src/components/data-filter/data-filter.js +2 -2
  78. package/src/components/date-picker/time-picker.css +2 -2
  79. package/src/components/dock/dock.css +5 -4
  80. package/src/components/dropdown/dropdown.js +157 -72
  81. package/src/components/field/field.js +33 -3
  82. package/src/components/fieldset/external-adapter.js +363 -0
  83. package/src/components/fieldset/fieldset.js +10 -59
  84. package/src/components/file-list/file-list.js +144 -21
  85. package/src/components/filter/filter.css +86 -2
  86. package/src/components/filter/filter.js +300 -8
  87. package/src/components/filter-panel/filter-panel.js +149 -32
  88. package/src/components/finder/finder.css +1 -1
  89. package/src/components/kanban-view/kanban-view.css +3 -3
  90. package/src/components/kanban-view/kanban-view.js +5 -2
  91. package/src/components/launcher/launcher.css +1 -1
  92. package/src/components/launcher/launcher.js +29 -3
  93. package/src/components/list-toolbar/list-toolbar.js +39 -13
  94. package/src/components/master-panel/master-panel.js +0 -1
  95. package/src/components/menu-button/menu-button.css +63 -0
  96. package/src/components/menu-button/menu-button.js +97 -11
  97. package/src/components/message/message.js +60 -20
  98. package/src/components/modal/modal.css +1 -1
  99. package/src/components/modal/modal.js +66 -13
  100. package/src/components/module-bar/module-bar.css +486 -0
  101. package/src/components/module-bar/module-bar.js +1074 -0
  102. package/src/components/multi-value-editor/multi-value-editor.css +1 -1
  103. package/src/components/number-field/field-adapter.js +2 -1
  104. package/src/components/pagination/pagination.css +5 -5
  105. package/src/components/pagination/pagination.js +20 -4
  106. package/src/components/panel/panel.css +3 -2
  107. package/src/components/questionnaire/questionnaire.css +4 -4
  108. package/src/components/rating/field-adapter.js +2 -1
  109. package/src/components/rating/rating.css +1 -1
  110. package/src/components/search/search.css +4 -1
  111. package/src/components/select/select.js +9 -0
  112. package/src/components/sheet/sheet.css +1 -1
  113. package/src/components/sheet/sheet.js +74 -32
  114. package/src/components/slider/field-adapter.js +6 -1
  115. package/src/components/slider/slider.css +2 -2
  116. package/src/components/split-view/split-view.css +1 -1
  117. package/src/components/stat-tile/stat-tile.css +1 -1
  118. package/src/components/stepper/stepper.css +1 -1
  119. package/src/components/tabbox/tabbox.css +9 -5
  120. package/src/components/table/table.css +86 -11
  121. package/src/components/table/table.js +628 -57
  122. package/src/components/tag-picker/field-adapter.js +2 -1
  123. package/src/components/tooltip/tooltip.js +35 -17
  124. package/src/components/tree/tree.css +1 -1
  125. package/src/components/view/record-view.css +1 -1
  126. package/src/components/view/record-view.js +178 -18
  127. package/src/components/view-settings/view-settings.css +285 -0
  128. package/src/components/view-settings/view-settings.js +1830 -0
  129. package/src/components/workspace-switcher/workspace-switcher.css +188 -0
  130. package/src/components/workspace-switcher/workspace-switcher.js +463 -0
  131. package/src/core/component.js +88 -17
  132. package/src/core/fontawesome.js +5 -1
  133. package/src/core/i18n.js +47 -4
  134. package/src/core/icons.js +12 -2
  135. package/src/core/keyboard.js +206 -11
  136. package/src/core/messages.js +427 -0
  137. package/src/core/overlay-host.js +64 -9
  138. package/src/core/overlay-stack.js +487 -0
  139. package/src/core/position.js +22 -3
  140. package/src/index.js +5 -2
  141. package/src/internal/app-rail.js +134 -53
  142. package/src/internal/menu-items.js +61 -3
  143. package/src/zeyos/form.js +5 -3
  144. package/src/zeyos/index.js +3 -0
  145. package/src/zeyos/launcher.js +8 -3
  146. package/src/zeyos/module-bar.js +181 -0
  147. package/src/zeyos/query.js +44 -13
  148. package/src/zeyos/table.js +220 -80
  149. package/src/zeyos/view.js +43 -93
  150. package/styles/base.css +16 -1
  151. package/styles/print.css +1 -1
  152. package/styles/tokens/dark.css +4 -0
  153. package/styles/tokens/semantic.css +56 -28
  154. package/styles/zx.css +3 -0
@@ -295,6 +295,24 @@ export type TableOptions = {
295
295
  * expandable treegrid. Row data and mutation APIs remain flat.
296
296
  */
297
297
  hierarchy?: false | TableHierarchyOptions;
298
+ /**
299
+ * Makes the table an APG grid — row focus, Enter firing
300
+ * `rowclick` — even without selection, editing, or hierarchy, which already imply it. Attaching a
301
+ * `rowclick` or `rowdblclick` listener through `on()` or an `on…` option sets it too; pass it when
302
+ * the host listens for the bubbling `zx-rowclick` DOM event instead.
303
+ */
304
+ interactive?: boolean;
305
+ /**
306
+ * Accessible name of the table. A grid must have one; null
307
+ * resolves the `table.label` message (English "Table") for a grid and leaves a plain table unnamed,
308
+ * so name it after what it lists.
309
+ */
310
+ label?: string | null;
311
+ /**
312
+ * Id of an element that names the grid — the heading
313
+ * above it, say. Wins over `label`.
314
+ */
315
+ labelledBy?: string | null;
298
316
  onrowclick?: (event: CustomEvent<TableRowClickDetail>) => void;
299
317
  onrowdblclick?: (event: CustomEvent<TableRowClickDetail>) => void;
300
318
  onsort?: (event: CustomEvent<TableSortDetail>) => void;
@@ -517,6 +535,20 @@ export type TableEditorEntry = {
517
535
  /**
518
536
  * Semantic, sortable data table with optional single or checkbox-based multi-selection and
519
537
  * opt-in inline cell or row editing.
538
+ *
539
+ * An interactive table — one that is `selectable`, has `editMode` or `hierarchy`, sets
540
+ * `interactive: true`, or has a `rowclick`/`rowdblclick` listener attached through `on()` or an
541
+ * `on…` option — follows the WAI-ARIA APG Grid pattern (`role="grid"`), or the Treegrid pattern
542
+ * (`role="treegrid"`) with `hierarchy`. Any other table keeps plain `<table>` semantics and no
543
+ * keyboard model of its own. In a grid the rows are one Tab stop with a roving `tabindex`. Rows
544
+ * take focus by default; a table with `editMode` moves focus between cells instead, which the root
545
+ * reflects as `data-focus="row"|"cell"`. ArrowUp/ArrowDown move between rows, ArrowLeft/ArrowRight
546
+ * between cells (cell focus) or expand, collapse, and walk the tree (treegrid), Home/End and
547
+ * Ctrl+Home/End jump to the ends, PageUp/PageDown move by a visible page (10 rows when the table
548
+ * does not scroll). Enter activates the row exactly as a click does (`rowclick`), Space toggles the
549
+ * row's selection when `selectable` (and activates otherwise), Shift+Arrow extends a `multi`
550
+ * selection, and Ctrl/Cmd+A selects every rendered row. The focused row survives `setData`, sorting,
551
+ * expansion, and `updateRow`. Column headers keep their sort buttons in the Tab order.
520
552
  * @fires Table#rowclick
521
553
  * @fires Table#rowdblclick
522
554
  * @fires Table#sort
@@ -543,10 +575,11 @@ export declare class Table extends Component<TableOptions> {
543
575
  _rowKinds: Record<string, TableRowKind>;
544
576
  _spanning: boolean;
545
577
  _sortWarned: boolean;
546
- _selected: Set<any>;
547
- _selectionAnchorId: any;
578
+ _selected: Set<any> | Set<unknown>;
579
+ _selectionAnchorId: unknown;
548
580
  _sort: any;
549
581
  _rowMeta: WeakMap<object, any>;
582
+ _rowNames: WeakMap<object, any>;
550
583
  _rowElements: Map<any, any>;
551
584
  _restored: boolean;
552
585
  _editMode: TableEditMode;
@@ -564,12 +597,11 @@ export declare class Table extends Component<TableOptions> {
564
597
  _growStep: number;
565
598
  _rendered: number;
566
599
  _more: HTMLElement;
567
- _rovingKey: {
568
- id: unknown;
569
- columnId: string;
570
- };
571
- _rovingCell: any;
572
- _rovingMatched: boolean;
600
+ _focusMode: string;
601
+ _interactive: boolean;
602
+ _current: any;
603
+ _rovingEl: any;
604
+ _extendBase: Set<any>;
573
605
  _hierarchy: TableHierarchyOptions & {
574
606
  column: string;
575
607
  };
@@ -586,6 +618,7 @@ export declare class Table extends Component<TableOptions> {
586
618
  _scroll: HTMLElement;
587
619
  _rowMoveMessage: HTMLElement;
588
620
  _columnControls: HTMLElement;
621
+ _clickListened: boolean;
589
622
  _columnList: HTMLElement;
590
623
  _selectAll: HTMLElement;
591
624
  _headers: Map<any, any>;
@@ -938,12 +971,26 @@ export declare class Table extends Component<TableOptions> {
938
971
  * @fires Table#stackedchange
939
972
  */
940
973
  _setStacked(stacked: boolean): void;
974
+ /**
975
+ * Registers a listener, and turns the table into a grid when the listener is for a row click:
976
+ * a host that reacts to the row needs the row reachable by keyboard.
977
+ * @param {string} type Event name.
978
+ * @param {EventListenerOrEventListenerObject|null} listener Listener.
979
+ * @param {boolean|AddEventListenerOptions} [options] Listener options.
980
+ * @returns {void}
981
+ */
982
+ addEventListener(type: string, listener: EventListenerOrEventListenerObject | null, options?: boolean | AddEventListenerOptions): void;
983
+ /** @returns {'grid'|'treegrid'|null} Role of the `<table>`, or null for plain table semantics. */
984
+ _gridRole(): 'grid' | 'treegrid' | null;
985
+ /** Writes the grid role, name, and focus mode — or their absence — onto the table. @returns {void} */
986
+ _syncGridRole(): void;
941
987
  /**
942
988
  * States the table roles explicitly while stacked, and removes them again on the way out.
943
989
  *
944
990
  * Stacking works by changing `display` on the table elements, and a table whose display is not
945
991
  * `table` loses its implicit ARIA roles — leaving a screen reader with a pile of generic blocks
946
- * where a table used to be. The roles are only asserted while the layout has taken them away.
992
+ * where a table used to be. The roles are only asserted while the layout has taken them away;
993
+ * a grid keeps its explicit grid or treegrid role in either mode.
947
994
  * @param {boolean} stacked Whether the roles should be present.
948
995
  * @returns {void}
949
996
  */
@@ -1048,6 +1095,14 @@ export declare class Table extends Component<TableOptions> {
1048
1095
  _createRow(row: TableRow, index: number, tree: TableHierarchyEntry & {
1049
1096
  visibleIndex: number;
1050
1097
  }): HTMLTableRowElement;
1098
+ /**
1099
+ * Names a row's own controls after the row's content rather than its position: "Select Acme
1100
+ * GmbH", not "Select row 3", which tells a screen reader user nothing and changes on every sort.
1101
+ * The position is the fallback for a row without any text.
1102
+ * @param {HTMLTableRowElement} tr Rendered row.
1103
+ * @returns {void}
1104
+ */
1105
+ _labelRowControls(tr: HTMLTableRowElement): void;
1051
1106
  /**
1052
1107
  * Fills a cell with the column's rendered value, replacing anything already in it.
1053
1108
  * @param {HTMLTableCellElement} cell Target cell.
@@ -1060,6 +1115,20 @@ export declare class Table extends Component<TableOptions> {
1060
1115
  _renderCellContent(cell: HTMLTableCellElement, column: TableColumn, row: TableRow, index: number, tree?: TableHierarchyEntry): void;
1061
1116
  /** @param {MouseEvent} event @returns {void} */
1062
1117
  _handleBodyClick(event: MouseEvent): void;
1118
+ /**
1119
+ * Activates a row: the click path, shared by Enter on a focused row or cell.
1120
+ * @param {{row: TableRow, id: unknown, index: number, visibleIndex?: number}} meta Row metadata.
1121
+ * @param {Event} event Originating click or keydown.
1122
+ * @returns {void}
1123
+ * @fires Table#rowclick
1124
+ * @fires Table#selectionchange
1125
+ */
1126
+ _activateRow(meta: {
1127
+ row: TableRow;
1128
+ id: unknown;
1129
+ index: number;
1130
+ visibleIndex?: number;
1131
+ }, event: Event): void;
1063
1132
  /** @param {MouseEvent} event @returns {void} @fires Table#editstart */
1064
1133
  _handleBodyDoubleClick(event: MouseEvent): void;
1065
1134
  /**
@@ -1130,20 +1199,127 @@ export declare class Table extends Component<TableOptions> {
1130
1199
  columnId: string;
1131
1200
  index: number;
1132
1201
  } | null;
1133
- /** @param {Event} event @returns {void} */
1134
- _handleEditFocusIn(event: Event): void;
1135
1202
  /** @param {Event} event @returns {void} @fires Table#editcommit */
1136
1203
  _handleDocumentPointerDown(event: Event): void;
1204
+ /** @returns {HTMLTableRowElement[]} Rendered body rows in display order, section rows included. */
1205
+ _navRows(): HTMLTableRowElement[];
1137
1206
  /**
1138
- * Keeps exactly one editable cell in the tab order, preferring the last focused one.
1139
- * @param {HTMLTableCellElement} cell Newly rendered editable cell.
1207
+ * Cells that take focus while the table moves focus by cell: the data cells, or the single cell of
1208
+ * a section row. The selection and reorder cells are not among them; their controls have keys of
1209
+ * their own on the row.
1210
+ * @param {HTMLTableRowElement} tr Body row.
1211
+ * @returns {HTMLTableCellElement[]}
1212
+ */
1213
+ _navCells(tr: HTMLTableRowElement): HTMLTableCellElement[];
1214
+ /**
1215
+ * The cell of a row that matches the current column: by id, else by position, so a section row
1216
+ * (one cell) or a hidden column still lands somewhere sensible.
1217
+ * @param {HTMLTableRowElement} tr Body row.
1218
+ * @returns {HTMLElement}
1219
+ */
1220
+ _cellFor(tr: HTMLTableRowElement): HTMLElement;
1221
+ /** @param {HTMLTableRowElement} tr @returns {HTMLElement} Element of a row that holds the Tab stop. */
1222
+ _rovingTarget(tr: HTMLTableRowElement): HTMLElement;
1223
+ /** @param {HTMLElement} element New roving Tab stop. @returns {void} */
1224
+ _setRoving(element: HTMLElement): void;
1225
+ /**
1226
+ * Records which part of a row holds focus before the body is rebuilt.
1227
+ * @returns {{part: 'row'|'cell'|'checkbox'|'toggle'|'handle'}|null} Null when focus is elsewhere.
1228
+ */
1229
+ _captureFocus(): {
1230
+ part: 'row' | 'cell' | 'checkbox' | 'toggle' | 'handle';
1231
+ } | null;
1232
+ /**
1233
+ * Puts the Tab stop back on the current row after a render — the same row by id; else, when a
1234
+ * collapsed ancestor hid it, that ancestor; else the row now at its old position — and gives it
1235
+ * focus again only when the body had focus before. The focus is restored without scrolling: a
1236
+ * table refreshed by polling must not pull the page back to itself.
1237
+ * @param {{part: string}|null} focus What `_captureFocus()` found before the render.
1238
+ * @returns {void}
1239
+ */
1240
+ _syncRoving(focus: {
1241
+ part: string;
1242
+ } | null): void;
1243
+ /**
1244
+ * The nearest ancestor of a row that is rendered — where focus goes when collapsing a branch
1245
+ * hid the focused row.
1140
1246
  * @param {unknown} id Row id.
1141
- * @param {string} columnId Column id.
1247
+ * @returns {HTMLTableRowElement|undefined}
1248
+ */
1249
+ _renderedAncestor(id: unknown): HTMLTableRowElement | undefined;
1250
+ /**
1251
+ * While the table has no rows to focus, its frame takes focus instead of letting it fall to the
1252
+ * document — and gives the Tab order its old shape back once rows return.
1253
+ * @param {boolean} hold Whether focus was in the body and there is now no row for it.
1254
+ * @returns {void}
1255
+ */
1256
+ _syncEmptyFocus(hold: boolean): void;
1257
+ /** @param {Event} event @returns {void} */
1258
+ _handleFocusIn(event: Event): void;
1259
+ /**
1260
+ * The APG grid and treegrid keyboard model on the focused row or cell. The row's own checkbox and
1261
+ * disclosure answer the navigation keys too, so a pointer user who clicked one can carry on by
1262
+ * keyboard; anything else inside a cell — a link, a button, an open editor — keeps its keys.
1263
+ * @param {KeyboardEvent} event Keydown event.
1264
+ * @returns {void}
1265
+ * @fires Table#rowclick
1266
+ * @fires Table#selectionchange
1267
+ * @fires Table#rowtoggle
1268
+ */
1269
+ _handleGridKeydown(event: KeyboardEvent): void;
1270
+ /**
1271
+ * Carries out one treegrid arrow-key action on a row.
1272
+ * @param {{action: string, column?: number}} action What `treegridArrowAction()` decided.
1273
+ * @param {HTMLTableRowElement} tr Focused row.
1274
+ * @param {{id: unknown}} meta Row metadata.
1275
+ * @param {unknown} parentId Parent row id, or null at the root.
1276
+ * @returns {void}
1277
+ * @fires Table#rowtoggle
1278
+ */
1279
+ _applyTreeAction(action: {
1280
+ action: string;
1281
+ column?: number;
1282
+ }, tr: HTMLTableRowElement, meta: {
1283
+ id: unknown;
1284
+ }, parentId: unknown): void;
1285
+ /**
1286
+ * How many rows PageUp and PageDown move: what fits in the scroll region when the table scrolls
1287
+ * on its own, else ten.
1288
+ * @param {HTMLTableRowElement[]} rows Rendered rows.
1289
+ * @returns {number}
1290
+ */
1291
+ _pageSize(rows: HTMLTableRowElement[]): number;
1292
+ /**
1293
+ * Space on a row: toggles it in `multi`, and in `single` selects it or clears the selection.
1294
+ * @param {{row: TableRow, id: unknown, index: number, visibleIndex?: number}} meta Row metadata.
1142
1295
  * @returns {void}
1296
+ * @fires Table#selectionchange
1143
1297
  */
1144
- _offerRovingCell(cell: HTMLTableCellElement, id: unknown, columnId: string): void;
1145
- /** @param {HTMLTableCellElement} cell @param {unknown} id @param {string} columnId @returns {void} */
1146
- _setRovingCell(cell: HTMLTableCellElement, id: unknown, columnId: string): void;
1298
+ _toggleRowSelection(meta: {
1299
+ row: TableRow;
1300
+ id: unknown;
1301
+ index: number;
1302
+ visibleIndex?: number;
1303
+ }): void;
1304
+ /**
1305
+ * Ctrl/Cmd+A: selects every rendered row that can hold a selection, as the header checkbox does.
1306
+ * @returns {void}
1307
+ * @fires Table#selectionchange
1308
+ */
1309
+ _selectAllRendered(): void;
1310
+ /**
1311
+ * Shift+Arrow: selects the rows between the anchor and the row focus moved to, on top of what was
1312
+ * selected before the extension began — moving back shrinks the range again.
1313
+ * @param {{id: unknown}} from Row focus moved from.
1314
+ * @param {{id: unknown}|undefined} to Row focus moved to.
1315
+ * @returns {void}
1316
+ * @fires Table#selectionchange
1317
+ */
1318
+ _extendSelection(from: {
1319
+ id: unknown;
1320
+ }, to: {
1321
+ id: unknown;
1322
+ } | undefined): void;
1147
1323
  /**
1148
1324
  * Resolves a message key with an English fallback for hosts without a translator.
1149
1325
  * @param {string} key Message key.
@@ -1226,6 +1402,78 @@ export declare class Table extends Component<TableOptions> {
1226
1402
  * @event Table#editinvalid
1227
1403
  * @type {CustomEvent<TableEditInvalidDetail>}
1228
1404
  */
1405
+ /**
1406
+ * Where a navigation key moves focus in the table body: the arithmetic of the APG grid keyboard
1407
+ * model, kept apart from the DOM. Positions are zero-based and every move is clamped — focus never
1408
+ * wraps, as the APG asks of a grid.
1409
+ *
1410
+ * With `cells` false (row focus) only the vertical keys move: ArrowUp/ArrowDown by one row,
1411
+ * PageUp/PageDown by `page`, Home/End (with or without Ctrl) to the first or last row. With `cells`
1412
+ * true ArrowLeft/ArrowRight move one cell, Home/End go to the first or last cell of the row, and
1413
+ * Ctrl+Home/Ctrl+End to the first cell of the first row or the last cell of the last row.
1414
+ * @param {{row: number, column?: number}} position Current position.
1415
+ * @param {string} key `KeyboardEvent.key`.
1416
+ * @param {{rows: number, columns?: number, page?: number, ctrl?: boolean, cells?: boolean}} grid
1417
+ * Row and column counts, the page size, whether Ctrl/Cmd is held, and whether focus is on cells.
1418
+ * @returns {{row: number, column: number}|null} New position, or null when the key is not a move.
1419
+ */
1420
+ export declare function tableGridTarget(position: {
1421
+ row: number;
1422
+ column?: number;
1423
+ }, key: string, grid: {
1424
+ rows: number;
1425
+ columns?: number;
1426
+ page?: number;
1427
+ ctrl?: boolean;
1428
+ cells?: boolean;
1429
+ }): {
1430
+ row: number;
1431
+ column: number;
1432
+ } | null;
1433
+ /**
1434
+ * How many rows a PageUp or PageDown moves: the rows that fit in the visible height, less one so
1435
+ * the row focus leaves stays in view as context. Falls back when either height is unknown.
1436
+ * @param {number} viewport Visible height of the scroll region, below any sticky header.
1437
+ * @param {number} rowHeight Height of one row.
1438
+ * @param {number} [fallback=10] Rows to move when the heights are unusable.
1439
+ * @returns {number} At least 1.
1440
+ */
1441
+ export declare function tablePageSize(viewport: number, rowHeight: number, fallback?: number): number;
1442
+ /**
1443
+ * ArrowLeft and ArrowRight in a treegrid, after the APG Treegrid pattern.
1444
+ *
1445
+ * Row focus (`focus: 'row'`): ArrowRight expands a collapsed branch; on an expanded branch it moves
1446
+ * into the first child — or, when cells take focus too (`cells`), onto the row's first cell, which
1447
+ * is also where it goes from a leaf. ArrowLeft collapses an expanded branch and otherwise moves to
1448
+ * the parent row. Cell focus: ArrowRight moves one cell right; ArrowLeft one cell left, and from the
1449
+ * first cell onto the row itself, where the branch can be expanded or collapsed.
1450
+ * @param {'ArrowLeft'|'ArrowRight'|string} key `KeyboardEvent.key`.
1451
+ * @param {{focus: 'row'|'cell', cells?: boolean, column?: number, columns?: number,
1452
+ * hasChildren?: boolean, expanded?: boolean, hasParent?: boolean}} state Focused row and cell.
1453
+ * @returns {{action: 'expand'|'collapse'|'child'|'parent'|'row'|'cell', column?: number}|null}
1454
+ * What to do, or null when focus stays where it is.
1455
+ */
1456
+ export declare function treegridArrowAction(key: 'ArrowLeft' | 'ArrowRight' | string, state: {
1457
+ focus: 'row' | 'cell';
1458
+ cells?: boolean;
1459
+ column?: number;
1460
+ columns?: number;
1461
+ hasChildren?: boolean;
1462
+ expanded?: boolean;
1463
+ hasParent?: boolean;
1464
+ }): {
1465
+ action: 'expand' | 'collapse' | 'child' | 'parent' | 'row' | 'cell';
1466
+ column?: number;
1467
+ } | null;
1468
+ /**
1469
+ * The name a row goes by in the labels of its own controls ("Select …", "Expand …"): the text of
1470
+ * its first cell that has any, whitespace collapsed and long text cut short. Null when no cell has
1471
+ * text, which is when the caller falls back to the row's position.
1472
+ * @param {Array<string|null|undefined>} texts Text of the row's cells, in display order.
1473
+ * @param {number} [max=80] Longest name returned before it is cut with an ellipsis.
1474
+ * @returns {string|null}
1475
+ */
1476
+ export declare function tableRowLabel(texts: Array<string | null | undefined>, max?: number): string | null;
1229
1477
  /**
1230
1478
  * Resolves a row's kind through the `rowKind` accessor and coerces it to the string `rowKinds` is
1231
1479
  * keyed by.
@@ -274,8 +274,20 @@ export declare class RecordView extends Component<RecordViewOptions> {
274
274
  _viewSort: ViewSort;
275
275
  _viewSelected: any;
276
276
  _viewSelectionAnchor: unknown;
277
- _viewFieldControls: HTMLElement;
277
+ _viewFieldControls: HTMLDetailsElement;
278
278
  _viewFieldList: HTMLElement;
279
+ _viewFieldStatus: HTMLElement;
280
+ _viewFieldHome: {
281
+ parent: ParentNode;
282
+ next: ChildNode;
283
+ mounted: string;
284
+ };
285
+ _viewNativeMounted: HTMLElement;
286
+ /** @type {{id: string, action: 'toggle'|'up'|'down'}|null} */
287
+ _viewFieldFocus: {
288
+ id: string;
289
+ action: 'toggle' | 'up' | 'down';
290
+ } | null;
279
291
  _viewFieldSettings: ViewFieldControlsSettings;
280
292
  _viewFieldControlsTarget: Element;
281
293
  _viewInitialized: boolean;
@@ -343,6 +355,26 @@ export declare class RecordView extends Component<RecordViewOptions> {
343
355
  getHiddenFields(): string[];
344
356
  /** Returns the complete field id order. @returns {string[]} */
345
357
  getFieldOrder(): string[];
358
+ /**
359
+ * Returns the element that lets a reader show, hide, and reorder this view's fields: the shared
360
+ * field chooser, or — for a `TableView` with `fieldControls: true` — the column chooser of its
361
+ * composed `Table`. Null when the view renders none (`fieldControls: false`).
362
+ *
363
+ * The element stays owned by the view: move it with {@link RecordView#mountFieldControls}
364
+ * rather than appending it elsewhere yourself, so `destroy()` can still find and remove it.
365
+ * @returns {HTMLElement|null}
366
+ */
367
+ getFieldControls(): HTMLElement | null;
368
+ /**
369
+ * Moves the view's field chooser into a host element — a list toolbar, a pane header — or, with
370
+ * `null`, back to where the view first rendered it. It keeps driving this view wherever it
371
+ * sits, and `destroy()` removes it from the host. `ListToolbar.bind()` calls this for every
372
+ * record view, which is how its field chooser ends up in the bar.
373
+ * @param {Element|string|null} target Host element or selector; null returns the chooser home.
374
+ * @returns {HTMLElement|null} The chooser, or null when the view renders none or the target
375
+ * does not resolve.
376
+ */
377
+ mountFieldControls(target: Element | string | null): HTMLElement | null;
346
378
  /**
347
379
  * Shows or hides one field. The final visible field cannot be hidden.
348
380
  * @param {string} id Field id.
@@ -457,6 +489,24 @@ export declare class RecordView extends Component<RecordViewOptions> {
457
489
  * @returns {void}
458
490
  */
459
491
  protected _removeViewFieldControls(): void;
492
+ /**
493
+ * A field chooser the concrete view renders natively instead of the shared one. The base class
494
+ * recognises a composed `Table` exposed through `getTable()` — `TableView` with
495
+ * `fieldControls: true` keeps Table's own column chooser — and any other subclass may override
496
+ * this to publish its own.
497
+ * @protected
498
+ * @returns {HTMLElement|null}
499
+ */
500
+ protected _nativeFieldControls(): HTMLElement | null;
501
+ /**
502
+ * Moves a field one place through the chooser's buttons, keeps focus on that field's control
503
+ * across the re-render, and announces where it landed.
504
+ * @private
505
+ * @param {string} id Field id.
506
+ * @param {-1|1} delta Direction.
507
+ * @returns {void}
508
+ */
509
+ private _moveViewFieldFromChooser;
460
510
  /**
461
511
  * Resolves the field-chooser trigger label: the configured one, else the translated message.
462
512
  * @protected
@@ -488,7 +538,14 @@ export declare class RecordView extends Component<RecordViewOptions> {
488
538
  private _emitViewSelection;
489
539
  /** @private @param {string} reason @returns {void} */
490
540
  private _emitViewState;
491
- /** @private @param {string|null} [focusId=null] @returns {void} */
541
+ /**
542
+ * Re-renders the chooser list. A focus request names the field and the control that should
543
+ * hold focus afterwards — a bare id means its checkbox — and falls back to the field's other
544
+ * enabled control when the requested one became disabled (a move button at either end).
545
+ * @private
546
+ * @param {string|{id:string,action:'toggle'|'up'|'down'}|null} [focus=null] Control to focus.
547
+ * @returns {void}
548
+ */
492
549
  private _renderViewFieldControls;
493
550
  }
494
551
  /**