@zeyos/zx 4.4.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 (252) hide show
  1. package/CHANGELOG.md +447 -0
  2. package/README.md +44 -11
  3. package/dist/types/components/account-menu/account-menu.d.ts +8 -0
  4. package/dist/types/components/activity-list/activity-list.d.ts +31 -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 +293 -17
  7. package/dist/types/components/avatar/avatar.d.ts +46 -7
  8. package/dist/types/components/badge/badge.d.ts +21 -1
  9. package/dist/types/components/button/button.d.ts +15 -0
  10. package/dist/types/components/calendar/calendar.d.ts +67 -5
  11. package/dist/types/components/card-view/card-view.d.ts +7 -4
  12. package/dist/types/components/card-view/record-card.d.ts +11 -0
  13. package/dist/types/components/chart/chart.d.ts +10 -0
  14. package/dist/types/components/checklist/checklist.d.ts +9 -0
  15. package/dist/types/components/code-editor/code-editor.d.ts +6 -17
  16. package/dist/types/components/context-menu/context-menu.d.ts +6 -2
  17. package/dist/types/components/data-filter/data-filter.d.ts +4 -4
  18. package/dist/types/components/datebox/date-range-box.d.ts +5 -1
  19. package/dist/types/components/datebox/datebox.d.ts +7 -2
  20. package/dist/types/components/dialog/dialog.d.ts +46 -6
  21. package/dist/types/components/dropdown/dropdown.d.ts +24 -9
  22. package/dist/types/components/entity-ref/entity-ref.d.ts +2 -2
  23. package/dist/types/components/field/field.d.ts +54 -2
  24. package/dist/types/components/fieldset/external-adapter.d.ts +83 -0
  25. package/dist/types/components/fieldset/fieldset.d.ts +26 -1
  26. package/dist/types/components/file-item/file-item.d.ts +34 -6
  27. package/dist/types/components/file-list/file-list.d.ts +35 -3
  28. package/dist/types/components/filter/filter.d.ts +127 -3
  29. package/dist/types/components/filter-panel/filter-panel.d.ts +36 -7
  30. package/dist/types/components/form/form.d.ts +12 -1
  31. package/dist/types/components/kanban-view/kanban-card.d.ts +8 -0
  32. package/dist/types/components/launcher/launcher.d.ts +268 -15
  33. package/dist/types/components/list-toolbar/list-toolbar.d.ts +16 -7
  34. package/dist/types/components/menu-button/menu-button.d.ts +39 -5
  35. package/dist/types/components/message/message.d.ts +132 -17
  36. package/dist/types/components/modal/modal.d.ts +43 -2
  37. package/dist/types/components/module-bar/module-bar.d.ts +395 -0
  38. package/dist/types/components/pagination/pagination.d.ts +17 -3
  39. package/dist/types/components/select/color.d.ts +12 -0
  40. package/dist/types/components/select/glyphs.d.ts +124 -0
  41. package/dist/types/components/select/select.d.ts +17 -3
  42. package/dist/types/components/sheet/sheet.d.ts +15 -0
  43. package/dist/types/components/stat-tile/stat-tile.d.ts +16 -5
  44. package/dist/types/components/tabbox/tabbox.d.ts +9 -0
  45. package/dist/types/components/table/table.d.ts +311 -18
  46. package/dist/types/components/tag-picker/tag-picker.d.ts +21 -4
  47. package/dist/types/components/tree/tree.d.ts +13 -0
  48. package/dist/types/components/view/record-view.d.ts +59 -2
  49. package/dist/types/components/view-settings/view-settings.d.ts +879 -0
  50. package/dist/types/components/workspace-switcher/workspace-switcher.d.ts +327 -0
  51. package/dist/types/core/breakpoint.d.ts +1 -1
  52. package/dist/types/core/component.d.ts +12 -2
  53. package/dist/types/core/i18n.d.ts +27 -3
  54. package/dist/types/core/icons.d.ts +23 -25
  55. package/dist/types/core/keyboard.d.ts +98 -1
  56. package/dist/types/core/messages.d.ts +382 -0
  57. package/dist/types/core/motion.d.ts +59 -0
  58. package/dist/types/core/overlay-host.d.ts +42 -1
  59. package/dist/types/core/overlay-stack.d.ts +260 -0
  60. package/dist/types/index.d.ts +10 -5
  61. package/dist/types/internal/app-rail.d.ts +38 -0
  62. package/dist/types/internal/menu-items.d.ts +71 -3
  63. package/dist/types/zeyos/connect.d.ts +6 -0
  64. package/dist/types/zeyos/form.d.ts +50 -9
  65. package/dist/types/zeyos/index.d.ts +2 -1
  66. package/dist/types/zeyos/launcher.d.ts +9 -0
  67. package/dist/types/zeyos/module-bar.d.ts +176 -0
  68. package/dist/types/zeyos/query.d.ts +110 -5
  69. package/dist/types/zeyos/schema.d.ts +24 -1
  70. package/dist/types/zeyos/table.d.ts +345 -22
  71. package/dist/types/zeyos/view.d.ts +26 -2
  72. package/dist/zx-zeyos.esm.js +6178 -1008
  73. package/dist/zx-zeyos.esm.min.js +53 -5
  74. package/dist/zx.css +2861 -827
  75. package/dist/zx.esm.js +8909 -1480
  76. package/dist/zx.esm.min.js +55 -7
  77. package/dist/zx.global.js +8911 -1482
  78. package/dist/zx.global.min.js +55 -7
  79. package/dist/zx.min.css +1 -1
  80. package/docs/api.json +1079 -117
  81. package/docs/llms.md +956 -154
  82. package/docs/llms.txt +9 -5
  83. package/package.json +1 -1
  84. package/src/components/account-menu/account-menu.css +35 -10
  85. package/src/components/account-menu/account-menu.js +12 -0
  86. package/src/components/activity-item/activity-item.css +1 -1
  87. package/src/components/activity-item/activity-item.js +3 -0
  88. package/src/components/activity-list/activity-list.css +38 -3
  89. package/src/components/activity-list/activity-list.js +61 -1
  90. package/src/components/app-icon/app-icon.css +14 -3
  91. package/src/components/app-icon/app-icon.js +11 -1
  92. package/src/components/app-rail/app-rail.css +59 -79
  93. package/src/components/app-sidebar/app-sidebar.css +304 -168
  94. package/src/components/app-sidebar/app-sidebar.js +667 -46
  95. package/src/components/aurora/aurora.css +5 -3
  96. package/src/components/avatar/avatar.css +32 -7
  97. package/src/components/avatar/avatar.js +72 -8
  98. package/src/components/badge/badge.css +54 -2
  99. package/src/components/badge/badge.js +29 -2
  100. package/src/components/breadcrumb/breadcrumb.css +1 -1
  101. package/src/components/button/button.css +67 -9
  102. package/src/components/button/button.js +38 -0
  103. package/src/components/calendar/calendar.css +47 -47
  104. package/src/components/calendar/calendar.js +26 -52
  105. package/src/components/card/card.css +4 -4
  106. package/src/components/card-view/card-view.css +14 -12
  107. package/src/components/card-view/card-view.js +13 -9
  108. package/src/components/card-view/record-card.js +14 -3
  109. package/src/components/chart/chart.css +4 -1
  110. package/src/components/chart/chart.js +12 -0
  111. package/src/components/check-button/check-button.css +10 -2
  112. package/src/components/checklist/checklist.css +9 -2
  113. package/src/components/checklist/checklist.js +11 -5
  114. package/src/components/checklist/field-adapter.js +3 -1
  115. package/src/components/code-editor/code-editor.css +7 -6
  116. package/src/components/code-editor/code-editor.js +19 -1
  117. package/src/components/code-editor/field-adapter.js +9 -2
  118. package/src/components/context-menu/context-menu.css +9 -4
  119. package/src/components/context-menu/context-menu.js +8 -2
  120. package/src/components/copy/copy-button.css +6 -0
  121. package/src/components/copy/copy-input.css +9 -4
  122. package/src/components/data-filter/data-filter.css +5 -4
  123. package/src/components/data-filter/data-filter.js +2 -2
  124. package/src/components/date-picker/date-picker.css +6 -6
  125. package/src/components/date-picker/date-range-picker.css +3 -3
  126. package/src/components/date-picker/time-picker.css +3 -3
  127. package/src/components/datebox/date-range-box.css +79 -2
  128. package/src/components/datebox/date-range-box.js +13 -2
  129. package/src/components/datebox/datebox.css +79 -2
  130. package/src/components/datebox/datebox.js +13 -2
  131. package/src/components/dialog/dialog.css +26 -0
  132. package/src/components/dialog/dialog.js +99 -17
  133. package/src/components/dock/dock.css +5 -4
  134. package/src/components/dropdown/dropdown.css +1 -1
  135. package/src/components/dropdown/dropdown.js +159 -72
  136. package/src/components/empty-state/empty-state.css +2 -2
  137. package/src/components/entity-ref/entity-ref.css +1 -1
  138. package/src/components/entity-ref/entity-ref.js +1 -1
  139. package/src/components/field/field.css +28 -9
  140. package/src/components/field/field.js +101 -29
  141. package/src/components/field-upload/field-upload.css +1 -1
  142. package/src/components/fieldset/external-adapter.js +363 -0
  143. package/src/components/fieldset/fieldset.css +5 -3
  144. package/src/components/fieldset/fieldset.js +38 -64
  145. package/src/components/file-item/file-item.js +144 -10
  146. package/src/components/file-list/file-list.js +144 -21
  147. package/src/components/filter/filter.css +86 -2
  148. package/src/components/filter/filter.js +307 -11
  149. package/src/components/filter-panel/filter-panel.css +1 -1
  150. package/src/components/filter-panel/filter-panel.js +149 -32
  151. package/src/components/finder/finder.css +16 -14
  152. package/src/components/form/form.css +5 -4
  153. package/src/components/form/form.js +11 -2
  154. package/src/components/grid/grid.css +1 -1
  155. package/src/components/groupbox/groupbox.css +1 -1
  156. package/src/components/kanban-view/kanban-card.js +11 -3
  157. package/src/components/kanban-view/kanban-view.css +42 -18
  158. package/src/components/kanban-view/kanban-view.js +9 -6
  159. package/src/components/launcher/launcher.css +108 -26
  160. package/src/components/launcher/launcher.js +530 -42
  161. package/src/components/list-toolbar/list-toolbar.css +13 -8
  162. package/src/components/list-toolbar/list-toolbar.js +40 -14
  163. package/src/components/master-panel/master-panel.css +2 -0
  164. package/src/components/master-panel/master-panel.js +0 -1
  165. package/src/components/menu-button/menu-button.css +72 -4
  166. package/src/components/menu-button/menu-button.js +160 -18
  167. package/src/components/message/message.css +33 -3
  168. package/src/components/message/message.js +264 -22
  169. package/src/components/modal/modal.css +1 -1
  170. package/src/components/modal/modal.js +83 -15
  171. package/src/components/module-bar/module-bar.css +486 -0
  172. package/src/components/module-bar/module-bar.js +1074 -0
  173. package/src/components/multi-value-editor/multi-value-editor.css +1 -1
  174. package/src/components/navigation-bar/navigation-bar.css +18 -9
  175. package/src/components/number-field/field-adapter.js +3 -1
  176. package/src/components/number-field/number-field.css +70 -0
  177. package/src/components/number-field/number-field.js +2 -0
  178. package/src/components/pagination/pagination.css +13 -11
  179. package/src/components/pagination/pagination.js +20 -4
  180. package/src/components/panel/panel.css +4 -3
  181. package/src/components/questionnaire/questionnaire.css +4 -4
  182. package/src/components/rating/field-adapter.js +2 -1
  183. package/src/components/rating/rating.css +8 -1
  184. package/src/components/search/search.css +4 -1
  185. package/src/components/select/color.js +22 -0
  186. package/src/components/select/field-adapter.js +2 -0
  187. package/src/components/select/glyphs.js +165 -0
  188. package/src/components/select/select.css +138 -45
  189. package/src/components/select/select.js +92 -47
  190. package/src/components/sheet/sheet.css +12 -9
  191. package/src/components/sheet/sheet.js +74 -32
  192. package/src/components/slider/field-adapter.js +6 -1
  193. package/src/components/slider/slider.css +18 -4
  194. package/src/components/slider/slider.js +1 -1
  195. package/src/components/sort-control/sort-control.css +4 -1
  196. package/src/components/split-view/split-view.css +1 -1
  197. package/src/components/stat-tile/stat-tile.css +42 -47
  198. package/src/components/stat-tile/stat-tile.js +17 -6
  199. package/src/components/stepper/stepper.css +1 -1
  200. package/src/components/tabbox/tabbox.css +41 -32
  201. package/src/components/tabbox/tabbox.js +5 -1
  202. package/src/components/table/table.css +187 -37
  203. package/src/components/table/table.js +718 -73
  204. package/src/components/tag-picker/field-adapter.js +2 -1
  205. package/src/components/tag-picker/tag-picker.css +83 -5
  206. package/src/components/tag-picker/tag-picker.js +25 -8
  207. package/src/components/timebox/timebox.css +22 -2
  208. package/src/components/toggle/toggle.css +12 -1
  209. package/src/components/toolbar/toolbar.js +2 -2
  210. package/src/components/tooltip/tooltip.css +4 -0
  211. package/src/components/tooltip/tooltip.js +44 -19
  212. package/src/components/tree/tree.css +26 -17
  213. package/src/components/tree/tree.js +31 -0
  214. package/src/components/value-list/value-list.css +3 -3
  215. package/src/components/view/record-view.css +1 -1
  216. package/src/components/view/record-view.js +178 -18
  217. package/src/components/view-settings/view-settings.css +285 -0
  218. package/src/components/view-settings/view-settings.js +1830 -0
  219. package/src/components/workspace-switcher/workspace-switcher.css +188 -0
  220. package/src/components/workspace-switcher/workspace-switcher.js +463 -0
  221. package/src/core/breakpoint.js +1 -1
  222. package/src/core/component.js +88 -17
  223. package/src/core/fontawesome.js +5 -1
  224. package/src/core/i18n.js +47 -4
  225. package/src/core/icons.js +204 -61
  226. package/src/core/keyboard.js +206 -11
  227. package/src/core/messages.js +427 -0
  228. package/src/core/motion.js +147 -0
  229. package/src/core/overlay-host.js +77 -3
  230. package/src/core/overlay-stack.js +487 -0
  231. package/src/core/position.js +22 -3
  232. package/src/index.js +10 -5
  233. package/src/internal/app-rail.js +135 -55
  234. package/src/internal/menu-items.js +61 -3
  235. package/src/zeyos/connect.js +6 -2
  236. package/src/zeyos/form.js +69 -27
  237. package/src/zeyos/index.js +4 -1
  238. package/src/zeyos/launcher.js +8 -3
  239. package/src/zeyos/module-bar.js +181 -0
  240. package/src/zeyos/query.js +197 -13
  241. package/src/zeyos/schema.js +144 -27
  242. package/src/zeyos/table.js +287 -84
  243. package/src/zeyos/view.js +49 -93
  244. package/styles/base.css +72 -1
  245. package/styles/icons.css +11 -1
  246. package/styles/print.css +1 -1
  247. package/styles/tokens/dark.css +117 -37
  248. package/styles/tokens/global.css +121 -27
  249. package/styles/tokens/semantic.css +140 -43
  250. package/styles/tokens/themes.css +7 -6
  251. package/styles/zx.css +3 -1
  252. package/styles/tokens/density.css +0 -9
@@ -107,6 +107,14 @@ export type FilterPanelOptions = {
107
107
  * lower bound takes the start of its day and its upper bound the end, so a one-day range matches.
108
108
  */
109
109
  serialize?: FilterPanelSerialize;
110
+ /**
111
+ * IANA zone the calendar days are counted in, such as the
112
+ * ZeyOS instance's `Europe/Vienna`. A day serializes as the first (or last) instant of that day
113
+ * in this zone, and an incoming instant shows as the day it falls on there — the same rule
114
+ * `zeyosForm()` and `zeyosTable()` apply to date-only fields. Null uses the runtime's own zone.
115
+ * An unknown zone throws a `RangeError`.
116
+ */
117
+ timeZone?: string | null;
110
118
  /**
111
119
  * Text shown when `fields` is empty; null resolves
112
120
  * `filterPanel.empty`.
@@ -175,6 +183,11 @@ export type FilterPanelOptions = {
175
183
  * applies every committed edit.
176
184
  * @property {FilterPanelSerialize} [serialize='seconds'] How a date leaves the component. A range's
177
185
  * lower bound takes the start of its day and its upper bound the end, so a one-day range matches.
186
+ * @property {string|null} [timeZone=null] IANA zone the calendar days are counted in, such as the
187
+ * ZeyOS instance's `Europe/Vienna`. A day serializes as the first (or last) instant of that day
188
+ * in this zone, and an incoming instant shows as the day it falls on there — the same rule
189
+ * `zeyosForm()` and `zeyosTable()` apply to date-only fields. Null uses the runtime's own zone.
190
+ * An unknown zone throws a `RangeError`.
178
191
  * @property {string|null} [emptyText=null] Text shown when `fields` is empty; null resolves
179
192
  * `filterPanel.empty`.
180
193
  * @property {Record<string, string>|Record<string, Record<string, string>>} [msg] Localized messages.
@@ -211,6 +224,7 @@ export declare class FilterPanel extends Component<FilterPanelOptions> {
211
224
  _draft: {};
212
225
  _applied: {};
213
226
  _appliedDraft: string;
227
+ _timeZone: string;
214
228
  _fields: {
215
229
  key: string;
216
230
  field: FilterPanelField;
@@ -402,23 +416,29 @@ export declare function isActiveValue(value: unknown): boolean;
402
416
  export declare function pruneValue(value: Record<string, unknown>): Record<string, unknown>;
403
417
  /**
404
418
  * Converts anything a calendar day can arrive as — a `YYYY-MM-DD` string, an ISO timestamp, a
405
- * `Date`, Unix seconds or milliseconds — into the local calendar day a native date input holds.
419
+ * `Date`, Unix seconds or milliseconds — into the calendar day a native date input holds.
406
420
  * Numbers below 1e11 are read as seconds, which is the boundary between the two epochs in use.
421
+ * An instant — Unix seconds or milliseconds, an ISO timestamp — names the day it falls on in
422
+ * `timeZone`. A `Date` is read as a picked day and keeps its local calendar day, matching
423
+ * `calendarDayToUnixSeconds()` in the ZeyOS binding.
407
424
  * @param {unknown} value Candidate day.
425
+ * @param {string|null} [timeZone=null] IANA zone instants are read in; null for the runtime's own.
408
426
  * @returns {string} `YYYY-MM-DD`, or an empty string when there is no day in it.
409
427
  */
410
- export declare function toDateInput(value: unknown): string;
428
+ export declare function toDateInput(value: unknown, timeZone?: string | null): string;
411
429
  /**
412
430
  * Serializes one calendar day at one edge of a range. The `from` edge takes the first instant of
413
- * its local day and the `to` edge the last, so a range whose ends name the same day still matches
414
- * everything recorded on it.
431
+ * its day and the `to` edge the last, so a range whose ends name the same day still matches
432
+ * everything recorded on it. The day is counted in `timeZone`: with `Europe/Vienna`, 2026-03-10
433
+ * starts at 23:00 UTC on the 9th whatever zone the browser is in.
415
434
  * @param {unknown} day Calendar day in any form `toDateInput()` accepts.
416
435
  * @param {FilterPanelEdge} edge Which end of the range the day is.
417
436
  * @param {FilterPanelSerialize} [serialize='seconds'] Output format, or a function receiving the
418
437
  * edge instant as a `Date`.
438
+ * @param {string|null} [timeZone=null] IANA zone the day is counted in; null for the runtime's own.
419
439
  * @returns {unknown} The serialized day, or null when there is no day.
420
440
  */
421
- export declare function serializeDate(day: unknown, edge: FilterPanelEdge, serialize?: FilterPanelSerialize): unknown;
441
+ export declare function serializeDate(day: unknown, edge: FilterPanelEdge, serialize?: FilterPanelSerialize, timeZone?: string | null): unknown;
422
442
  /**
423
443
  * Normalizes declared select options. `{value, label}`, `{ID, name}`, and bare primitives all
424
444
  * arrive from one instance or another.
@@ -435,15 +455,24 @@ export declare function normalizeOptions(options: unknown): Array<{
435
455
  * Running it on a draft returns the same draft, so it is safe on either shape.
436
456
  * @param {Record<string, unknown>|null|undefined} value Incoming values keyed by field.
437
457
  * @param {Record<string, FilterPanelField>} fields Field metadata.
458
+ * @param {string|null} [timeZone=null] IANA zone incoming instants are read in.
438
459
  * @returns {Record<string, unknown>}
439
460
  */
440
- export declare function toDraft(value: Record<string, unknown> | null | undefined, fields: Record<string, FilterPanelField>): Record<string, unknown>;
461
+ export declare function toDraft(value: Record<string, unknown> | null | undefined, fields: Record<string, FilterPanelField>, timeZone?: string | null): Record<string, unknown>;
441
462
  /**
442
463
  * Turns values into the query object a list endpoint is sent: only the constraints that are set,
443
464
  * dates serialized at the right edge, unknown field types excluded.
444
465
  * @param {Record<string, unknown>|null|undefined} value Values keyed by field, raw or drafted.
445
466
  * @param {Record<string, FilterPanelField>} fields Field metadata.
446
467
  * @param {FilterPanelSerialize} [serialize='seconds'] Date output format.
468
+ * @param {string|null} [timeZone=null] IANA zone calendar days are counted in.
447
469
  * @returns {Record<string, unknown>}
448
470
  */
449
- export declare function serializeFilterValue(value: Record<string, unknown> | null | undefined, fields: Record<string, FilterPanelField>, serialize?: FilterPanelSerialize): Record<string, unknown>;
471
+ export declare function serializeFilterValue(value: Record<string, unknown> | null | undefined, fields: Record<string, FilterPanelField>, serialize?: FilterPanelSerialize, timeZone?: string | null): Record<string, unknown>;
472
+ /**
473
+ * Validates the `timeZone` option.
474
+ * @param {unknown} timeZone IANA zone name; nullish or empty means the runtime's own zone.
475
+ * @returns {string|null} Canonical zone name, or null for the runtime's own zone.
476
+ * @throws {RangeError} When the runtime does not know the zone.
477
+ */
478
+ export declare function normalizePanelTimeZone(timeZone: unknown): string | null;
@@ -51,6 +51,12 @@ export type FormOptions = {
51
51
  * Native `novalidate` state.
52
52
  */
53
53
  novalidate?: boolean;
54
+ /**
55
+ * Prefix of the DOM ids generated for the fields of the
56
+ * fieldsets this form builds, as `<idPrefix>-<key>`. Null generates one per form instance, so a
57
+ * form mounted twice never repeats an id. A fieldset's own `idPrefix` wins.
58
+ */
59
+ idPrefix?: string | null;
54
60
  /**
55
61
  * Submit listener.
56
62
  */
@@ -88,6 +94,9 @@ export type FormOptions = {
88
94
  * @property {Array<Fieldset|import('../fieldset/fieldset.js').FieldsetOptions>} [fieldsets=[]] Initial fieldsets.
89
95
  * @property {FormAction[]} [actions=[]] Form action descriptors.
90
96
  * @property {boolean} [novalidate=true] Native `novalidate` state.
97
+ * @property {string|null} [idPrefix=null] Prefix of the DOM ids generated for the fields of the
98
+ * fieldsets this form builds, as `<idPrefix>-<key>`. Null generates one per form instance, so a
99
+ * form mounted twice never repeats an id. A fieldset's own `idPrefix` wins.
91
100
  * @property {(event: CustomEvent<{values: Record<string, unknown>}>) => void} [onsubmit] Submit listener.
92
101
  * @property {(event: CustomEvent<{errors: Record<string, string>}>) => void} [oninvalid] Invalid listener.
93
102
  * @property {(event: CustomEvent<{id: string, value: unknown}>) => void} [onchange] Field change listener.
@@ -104,6 +113,7 @@ export declare class Form extends Component<FormOptions> {
104
113
  _ownedFieldsets: Set<any>;
105
114
  _origins: Map<any, any>;
106
115
  _ownedNodes: any[];
116
+ _idPrefix: string;
107
117
  _novalidateAttribute: string;
108
118
  _body: HTMLElement;
109
119
  _actions: HTMLElement;
@@ -126,7 +136,8 @@ export declare class Form extends Component<FormOptions> {
126
136
  /** @returns {HTMLElement} */
127
137
  render(): HTMLElement;
128
138
  /**
129
- * Adds an existing fieldset or constructs one from options.
139
+ * Adds an existing fieldset or constructs one from options. A constructed fieldset generates its
140
+ * field ids from the form's `idPrefix` unless its options carry their own.
130
141
  * @param {Fieldset|import('../fieldset/fieldset.js').FieldsetOptions} fieldset Fieldset source.
131
142
  * @returns {Fieldset}
132
143
  */
@@ -52,6 +52,12 @@ export type KanbanAssignee = {
52
52
  * Fallback initials.
53
53
  */
54
54
  initials: string;
55
+ /**
56
+ * Fallback tint: a descriptor's own
57
+ * `tone` when it names one of `AVATAR_TONES`, otherwise `avatarTone(name)` — the colour the same
58
+ * person has in every Avatar.
59
+ */
60
+ tone: import('../avatar/avatar.js').AvatarTone;
55
61
  };
56
62
  /**
57
63
  * Normalizes one indicator value into the descriptor the badge is built from. A plain value
@@ -88,6 +94,8 @@ export declare function createKanbanProgress(progress: KanbanProgress, label: st
88
94
  /**
89
95
  * Normalizes one or more responsible people. Names, name lists, and descriptor objects all
90
96
  * resolve to the same shape, and an unsafe image URL degrades to initials rather than failing.
97
+ * A descriptor may name its `tone`; otherwise the tone is derived from the name exactly as Avatar
98
+ * derives it.
91
99
  * @param {unknown} value Raw field value.
92
100
  * @returns {KanbanAssignee[]} Normalized people, in the order supplied.
93
101
  */
@@ -28,6 +28,23 @@ export type LauncherItem = {
28
28
  * Compact metadata.
29
29
  */
30
30
  badge?: string | number;
31
+ /**
32
+ * Muted text at the end of the row, such as a current value or a project.
33
+ */
34
+ hint?: string | number;
35
+ /**
36
+ * Key labels drawn as
37
+ * key caps (`['⌘', 'K']`), or Button's `{label, keys}` shape. Display only: the Launcher binds nothing.
38
+ */
39
+ shortcut?: string | string[] | {
40
+ label: string | string[];
41
+ keys?: string;
42
+ };
43
+ /**
44
+ * The same shortcut in `aria-keyshortcuts` syntax (`'Meta+K'`), exposed on
45
+ * the option for assistive technology.
46
+ */
47
+ keys?: string;
31
48
  /**
32
49
  * Tile or row presentation.
33
50
  */
@@ -72,6 +89,40 @@ export type LauncherItem = {
72
89
  * Whether activation is unavailable.
73
90
  */
74
91
  disabled?: boolean;
92
+ /**
93
+ * Child items. An item with `items` opens them
94
+ * as a page instead of being selected: an array, or a loader called with the page's query.
95
+ */
96
+ items?: LauncherItem[] | LauncherPageLoader;
97
+ /**
98
+ * Search-field placeholder while this item's page is open.
99
+ */
100
+ placeholder?: string;
101
+ /**
102
+ * For a page whose `items` is a loader: whether Zx ranks
103
+ * the loaded items by the query, or keeps the loader's order.
104
+ */
105
+ order?: 'rank' | 'source';
106
+ };
107
+ export type LauncherPageLoader = (query: string, context: {
108
+ signal: AbortSignal;
109
+ }) => LauncherItem[] | Promise<LauncherItem[]>;
110
+ export type LauncherOpenOptions = {
111
+ /**
112
+ * Opens straight into a page: the id of a local item
113
+ * with `items` (at any depth of array pages, whose path becomes the back stack), or a page item.
114
+ */
115
+ page?: string | number | LauncherItem;
116
+ };
117
+ export type LauncherPageDetail = {
118
+ /**
119
+ * The page now shown; null on the root.
120
+ */
121
+ page: LauncherItem | null;
122
+ /**
123
+ * Every open page from the root down, the shown one last.
124
+ */
125
+ path: LauncherItem[];
75
126
  };
76
127
  export type LauncherSource = {
77
128
  /**
@@ -160,6 +211,7 @@ export type LauncherOptions = {
160
211
  hints?: false | {
161
212
  move?: string;
162
213
  open?: string;
214
+ back?: string;
163
215
  close?: string;
164
216
  };
165
217
  /**
@@ -176,6 +228,10 @@ export type LauncherOptions = {
176
228
  onquery?: (event: CustomEvent<{
177
229
  query: string;
178
230
  }>) => void;
231
+ /**
232
+ * Page-navigation listener.
233
+ */
234
+ onpage?: (event: CustomEvent<LauncherPageDetail>) => void;
179
235
  /**
180
236
  * Open listener.
181
237
  */
@@ -187,21 +243,49 @@ export type LauncherOptions = {
187
243
  /**
188
244
  * Source error listener.
189
245
  */
190
- onerror?: (event: CustomEvent<{
191
- source: LauncherSource;
192
- error: unknown;
193
- }>) => void;
246
+ onerror?: (event: CustomEvent<LauncherErrorDetail>) => void;
194
247
  };
195
248
  export type LauncherSelectDetail = {
196
249
  item: LauncherItem;
197
250
  value: unknown;
198
251
  source: string | null;
199
252
  query: string;
253
+ page: LauncherItem | null;
254
+ };
255
+ export type LauncherErrorDetail = {
256
+ source: LauncherSource;
257
+ error: unknown;
258
+ page: LauncherItem | null;
200
259
  };
201
260
  export type RankedLauncherItem = LauncherItem & {
202
261
  _source?: string | null;
203
262
  _score?: number;
204
263
  };
264
+ export type LevelSource = LauncherSource & {
265
+ _page?: boolean;
266
+ };
267
+ export type LauncherPageEntry = {
268
+ /**
269
+ * The page item.
270
+ */
271
+ page: LauncherItem;
272
+ /**
273
+ * Its normalized local items (an array page).
274
+ */
275
+ items: LauncherItem[];
276
+ /**
277
+ * Its loader as a source (a loader page).
278
+ */
279
+ sources: LevelSource[];
280
+ /**
281
+ * The level beneath: its query, its highlighted option, and its loaded results when they were complete.
282
+ */
283
+ parent: {
284
+ query: string;
285
+ activeId: string | null;
286
+ sourceItems: Map<string, RankedLauncherItem[]> | null;
287
+ };
288
+ };
205
289
  /**
206
290
  * @typedef {Object} LauncherItem
207
291
  * @property {string|number} id Stable item identifier.
@@ -211,6 +295,11 @@ export type RankedLauncherItem = LauncherItem & {
211
295
  * @property {string} [group] Result group.
212
296
  * @property {string|Node|((item: LauncherItem) => Node|null)} [icon] Decorative icon name, node, or factory.
213
297
  * @property {string|number} [badge] Compact metadata.
298
+ * @property {string|number} [hint] Muted text at the end of the row, such as a current value or a project.
299
+ * @property {string|string[]|{label: string|string[], keys?: string}} [shortcut] Key labels drawn as
300
+ * key caps (`['⌘', 'K']`), or Button's `{label, keys}` shape. Display only: the Launcher binds nothing.
301
+ * @property {string} [keys] The same shortcut in `aria-keyshortcuts` syntax (`'Meta+K'`), exposed on
302
+ * the option for assistive technology.
214
303
  * @property {'application'|'record'|'action'} [kind='action'] Tile or row presentation.
215
304
  * @property {boolean} [current=false] Whether this is the current application or destination.
216
305
  * @property {'always'|'empty'|'query'} [when='always'] Query state in which the item is visible.
@@ -222,6 +311,26 @@ export type RankedLauncherItem = LauncherItem & {
222
311
  * @property {() => void} [invoke] Application-owned callback for non-link actions.
223
312
  * @property {boolean|number} [pinned] Pinned state or explicit pinned order.
224
313
  * @property {boolean} [disabled] Whether activation is unavailable.
314
+ * @property {LauncherItem[]|LauncherPageLoader} [items] Child items. An item with `items` opens them
315
+ * as a page instead of being selected: an array, or a loader called with the page's query.
316
+ * @property {string} [placeholder] Search-field placeholder while this item's page is open.
317
+ * @property {'rank'|'source'} [order='rank'] For a page whose `items` is a loader: whether Zx ranks
318
+ * the loaded items by the query, or keeps the loader's order.
319
+ */
320
+ /**
321
+ * Loads a page's items for its current query. It runs when the page opens and again, debounced, as
322
+ * the query changes; a newer query aborts `signal`.
323
+ * @typedef {(query: string, context: {signal: AbortSignal}) => LauncherItem[]|Promise<LauncherItem[]>} LauncherPageLoader
324
+ */
325
+ /**
326
+ * @typedef {Object} LauncherOpenOptions
327
+ * @property {string|number|LauncherItem} [page] Opens straight into a page: the id of a local item
328
+ * with `items` (at any depth of array pages, whose path becomes the back stack), or a page item.
329
+ */
330
+ /**
331
+ * @typedef {Object} LauncherPageDetail
332
+ * @property {LauncherItem|null} page The page now shown; null on the root.
333
+ * @property {LauncherItem[]} path Every open page from the root down, the shown one last.
225
334
  */
226
335
  /**
227
336
  * @typedef {Object} LauncherSource
@@ -247,20 +356,40 @@ export type RankedLauncherItem = LauncherItem & {
247
356
  * @property {string} [emptyText] Empty-state text. Omitted resolves `launcher.empty`, English `No results`.
248
357
  * @property {string} [loadingText] Loading-state text. Omitted resolves `launcher.loading`, English `Searching…`.
249
358
  * @property {'mod+k'|false} [shortcut='mod+k'] Optional global keyboard shortcut.
250
- * @property {false|{move?: string, open?: string, close?: string}} [hints] Visible keyboard hints, or false.
359
+ * @property {false|{move?: string, open?: string, back?: string, close?: string}} [hints] Visible keyboard hints, or false.
251
360
  * @property {Element|string|null} [scope=null] Element whose nearest Zx theme scope owns an internally created launcher; defaults to the opener.
252
361
  * @property {(event: CustomEvent<LauncherSelectDetail>) => void} [onselect] Preventable selection listener.
253
362
  * @property {(event: CustomEvent<{query: string}>) => void} [onquery] Query-change listener.
363
+ * @property {(event: CustomEvent<LauncherPageDetail>) => void} [onpage] Page-navigation listener.
254
364
  * @property {(event: CustomEvent<Record<string, never>>) => void} [onopen] Open listener.
255
365
  * @property {(event: CustomEvent<Record<string, never>>) => void} [onclose] Close listener.
256
- * @property {(event: CustomEvent<{source: LauncherSource, error: unknown}>) => void} [onerror] Source error listener.
366
+ * @property {(event: CustomEvent<LauncherErrorDetail>) => void} [onerror] Source error listener.
367
+ */
368
+ /**
369
+ * A selection. `page` is the page the item was chosen on, null on the root.
370
+ * @typedef {{item: LauncherItem, value: unknown, source: string|null, query: string, page: LauncherItem|null}} LauncherSelectDetail
371
+ */
372
+ /**
373
+ * A failed load. A page loader reports as a source whose id is `page:<page id>`, with `page` set.
374
+ * @typedef {{source: LauncherSource, error: unknown, page: LauncherItem|null}} LauncherErrorDetail
257
375
  */
258
- /** @typedef {{item: LauncherItem, value: unknown, source: string|null, query: string}} LauncherSelectDetail */
259
376
  /** @typedef {LauncherItem & {_source?: string|null, _score?: number}} RankedLauncherItem */
377
+ /** @typedef {LauncherSource & {_page?: boolean}} LevelSource */
378
+ /**
379
+ * One open page and the level beneath it, kept so going back restores that level as it was.
380
+ * @typedef {Object} LauncherPageEntry
381
+ * @property {LauncherItem} page The page item.
382
+ * @property {LauncherItem[]} items Its normalized local items (an array page).
383
+ * @property {LevelSource[]} sources Its loader as a source (a loader page).
384
+ * @property {{query: string, activeId: string|null, sourceItems: Map<string, RankedLauncherItem[]>|null}} parent
385
+ * The level beneath: its query, its highlighted option, and its loaded results when they were complete.
386
+ */
260
387
  /**
261
388
  * Abortable command/search dialog that emits application-owned actions without routing itself.
389
+ * Items with `items` open nested pages: an APG combobox whose listbox shows one page at a time.
262
390
  * @fires Launcher#select
263
391
  * @fires Launcher#query
392
+ * @fires Launcher#page
264
393
  * @fires Launcher#open
265
394
  * @fires Launcher#close
266
395
  * @fires Launcher#error
@@ -268,6 +397,8 @@ export type RankedLauncherItem = LauncherItem & {
268
397
  */
269
398
  export declare class Launcher extends Component<LauncherOptions> {
270
399
  _createdRoot: boolean;
400
+ /** @type {import('../../core/overlay-stack.js').OverlayHandle|null} Entry on the overlay stack while open. */
401
+ _overlay: import('../../core/overlay-stack.js').OverlayHandle | null;
271
402
  _original: {
272
403
  attributes: string[][];
273
404
  children: ChildNode[];
@@ -283,7 +414,15 @@ export declare class Launcher extends Component<LauncherOptions> {
283
414
  _requestSequence: number;
284
415
  _queryTimer: number;
285
416
  _busy: boolean;
417
+ _settled: boolean;
418
+ /** @type {LauncherPageEntry[]} */
419
+ _pages: LauncherPageEntry[];
420
+ _restoreActiveId: string;
421
+ _announcePending: boolean;
422
+ _announceToggle: boolean;
286
423
  _destroyed: boolean;
424
+ _label: string;
425
+ _placeholder: string;
287
426
  static cssName: string;
288
427
  /** @type {Readonly<LauncherOptions>} */
289
428
  static defaults: Readonly<LauncherOptions>;
@@ -295,8 +434,24 @@ export declare class Launcher extends Component<LauncherOptions> {
295
434
  constructor(target?: HTMLDialogElement | string | null, options?: LauncherOptions);
296
435
  /** @returns {HTMLDialogElement} */
297
436
  render(): HTMLDialogElement;
298
- /** Opens the launcher and focuses/selects its query. @returns {this} @fires Launcher#open */
299
- open(): this;
437
+ /**
438
+ * Opens the launcher and focuses/selects its query. It opens on the root unless `page` names one;
439
+ * already open, `page` navigates there.
440
+ * @param {LauncherOpenOptions} [options={}] Open options.
441
+ * @returns {this}
442
+ * @fires Launcher#open
443
+ * @fires Launcher#page
444
+ */
445
+ open(options?: LauncherOpenOptions): this;
446
+ /**
447
+ * Goes back one page, restoring the level beneath with its query and highlighted option. Does
448
+ * nothing on the root.
449
+ * @returns {this}
450
+ * @fires Launcher#page
451
+ */
452
+ back(): this;
453
+ /** Returns the page shown, or null on the root. @returns {LauncherItem|null} */
454
+ getPage(): LauncherItem | null;
300
455
  /** Closes the launcher. @returns {this} */
301
456
  close(): this;
302
457
  /** Toggles the launcher. @returns {this} */
@@ -309,18 +464,86 @@ export declare class Launcher extends Component<LauncherOptions> {
309
464
  setQuery(query: string): this;
310
465
  /** Returns the untrimmed query. @returns {string} */
311
466
  getQuery(): string;
312
- /** Replaces local catalogue items. @param {LauncherItem[]} items @returns {this} */
467
+ /** Replaces the root's local catalogue items; an open page keeps its own. @param {LauncherItem[]} items @returns {this} */
313
468
  setItems(items: LauncherItem[]): this;
314
469
  /** Marks one local item as the current destination. @param {string|number|null} id Item id. @returns {this} */
315
470
  setCurrent(id: string | number | null): this;
316
- /** Replaces asynchronous sources and aborts work from the old set. @param {LauncherSource[]} sources @returns {this} */
471
+ /** Replaces the root's asynchronous sources and aborts work from the old set; on a page they load once the root is back. @param {LauncherSource[]} sources @returns {this} */
317
472
  setSources(sources: LauncherSource[]): this;
473
+ /**
474
+ * Takes the launcher off the overlay stack. Safe to call repeatedly.
475
+ * @returns {void}
476
+ * @private
477
+ */
478
+ private _releaseOverlay;
318
479
  /** Aborts sources and removes the owned dialog. @returns {void} */
319
480
  destroy(): void;
320
- /** @returns {void} */
321
- _refresh(): void;
481
+ /**
482
+ * Re-renders the current level and reloads its sources: debounced while typing, at once when a
483
+ * page opens (so its loading state shows instead of a passing "No results").
484
+ * @param {boolean} [immediate=false] Load without the debounce.
485
+ * @returns {void}
486
+ */
487
+ _refresh(immediate?: boolean): void;
322
488
  /** @returns {Promise<void>} */
323
489
  _loadSources(): Promise<void>;
490
+ /**
491
+ * The level on screen: the root's items and sources, or the open page's.
492
+ * @returns {{items: LauncherItem[], sources: LevelSource[]}}
493
+ */
494
+ _level(): {
495
+ items: LauncherItem[];
496
+ sources: LevelSource[];
497
+ };
498
+ /**
499
+ * Opens a page on top of the current level: what the user activated, or ArrowRight on its row.
500
+ * @param {LauncherItem} item Page item.
501
+ * @returns {void}
502
+ */
503
+ _openPage(item: LauncherItem): void;
504
+ /**
505
+ * Replaces the whole stack with `path` (empty for the root) and refreshes what it lands on.
506
+ * @param {LauncherItem[]} path Pages from the root down.
507
+ * @param {{emit?: boolean}} [options={}] Whether to report a change through `page`.
508
+ * @returns {void}
509
+ */
510
+ _goTo(path: LauncherItem[], { emit }?: {
511
+ emit?: boolean;
512
+ }): void;
513
+ /** Pops every page, restoring the root's query, without rendering. @returns {void} */
514
+ _unwind(): void;
515
+ /**
516
+ * Pushes a page, remembering the level beneath, and clears the query for it.
517
+ * @param {LauncherItem} item Page item.
518
+ * @returns {void}
519
+ */
520
+ _pushPage(item: LauncherItem): void;
521
+ /**
522
+ * Pops the top page and restores the level beneath.
523
+ * @returns {boolean} Whether that level's results came back complete (no reload needed).
524
+ */
525
+ _popPage(): boolean;
526
+ /** @param {string} query @returns {void} */
527
+ _setInputQuery(query: string): void;
528
+ /**
529
+ * Shows the open page in the search row: the chip, the combobox name and placeholder, and the
530
+ * footer's Back hint.
531
+ * @returns {void}
532
+ */
533
+ _syncPage(): void;
534
+ /** @returns {void} @fires Launcher#page */
535
+ _emitPage(): void;
536
+ /**
537
+ * Resolves `open({ page })`: a page item as given, or the path to a local page by id.
538
+ * @param {string|number|LauncherItem} target Page id or item.
539
+ * @returns {LauncherItem[]}
540
+ */
541
+ _pagePath(target: string | number | LauncherItem): LauncherItem[];
542
+ /**
543
+ * The polite line a page change ends on: where the user is and how much is there.
544
+ * @returns {string}
545
+ */
546
+ _pageStatus(): string;
324
547
  /** @param {boolean} busy @returns {void} */
325
548
  _setBusy(busy: boolean): void;
326
549
  /** @returns {void} */
@@ -335,6 +558,14 @@ export declare class Launcher extends Component<LauncherOptions> {
335
558
  _syncActive(): void;
336
559
  /** @param {KeyboardEvent} event @returns {void} */
337
560
  _onKeydown(event: KeyboardEvent): void;
561
+ /**
562
+ * ArrowRight on a page row opens it once the caret is at the end of the query (before that it
563
+ * moves the caret); ArrowLeft on an empty query goes back. Application tiles keep both arrows
564
+ * for moving through their grid, which the caller tries first.
565
+ * @param {string} key ArrowLeft or ArrowRight.
566
+ * @returns {boolean} Whether the key navigated.
567
+ */
568
+ _pageKey(key: string): boolean;
338
569
  /** @param {string} direction @param {number[]} enabled @returns {number|null} */
339
570
  _spatialIndex(direction: string, enabled: number[]): number | null;
340
571
  /** @param {number} index @param {Event} event @returns {void} */
@@ -345,10 +576,31 @@ export declare class Launcher extends Component<LauncherOptions> {
345
576
  * Resolves a message through the host translator, falling back to the built-in English text.
346
577
  * @param {string} key Message key.
347
578
  * @param {string} fallback English default.
579
+ * @param {...unknown} args Positional `%1`, `%2` values.
348
580
  * @returns {string}
349
581
  */
350
- _message(key: string, fallback: string): string;
582
+ _message(key: string, fallback: string, ...args: unknown[]): string;
351
583
  }
584
+ /**
585
+ * Whether an item opens a page rather than being selected.
586
+ * @param {unknown} item Candidate item.
587
+ * @returns {boolean}
588
+ */
589
+ export declare function isLauncherPage(item: unknown): boolean;
590
+ /**
591
+ * Finds a page among local items by id, descending through array pages (a loader's items are not
592
+ * known until it runs).
593
+ * @param {LauncherItem[]} items Root items.
594
+ * @param {string|number} id Page item id.
595
+ * @returns {LauncherItem[]} The pages from the root down to the match, or an empty array.
596
+ */
597
+ export declare function findLauncherPage(items: LauncherItem[], id: string | number): LauncherItem[];
598
+ /**
599
+ * Normalizes an item's `shortcut` into the key labels drawn as caps.
600
+ * @param {unknown} shortcut `['⌘', 'K']`, one label, or `{label, keys}`.
601
+ * @returns {string[]}
602
+ */
603
+ export declare function launcherShortcutCaps(shortcut: unknown): string[];
352
604
  /**
353
605
  * Ranks launcher items using the current ZeyOS application tiers.
354
606
  * @param {RankedLauncherItem[]} items Items to rank.
@@ -366,6 +618,7 @@ export declare function rankLauncherItems(items: RankedLauncherItem[], query: st
366
618
  export declare function orderedLauncherSourceItems(sources: LauncherSource[], sourceItems: Map<string, RankedLauncherItem[]>): RankedLauncherItem[];
367
619
  /** Fired when a result is activated. @event Launcher#select @type {CustomEvent<LauncherSelectDetail>} */
368
620
  /** Fired when the query changes. @event Launcher#query @type {CustomEvent<{query: string}>} */
621
+ /** Fired after a page opens or closes, or `open()` lands on a different page. @event Launcher#page @type {CustomEvent<LauncherPageDetail>} */
369
622
  /** Fired after the dialog opens. @event Launcher#open @type {CustomEvent<Record<string, never>>} */
370
623
  /** Fired after the dialog closes. @event Launcher#close @type {CustomEvent<Record<string, never>>} */
371
- /** Fired when one asynchronous source fails. @event Launcher#error @type {CustomEvent<{source: LauncherSource, error: unknown}>} */
624
+ /** Fired when one asynchronous source or page loader fails. @event Launcher#error @type {CustomEvent<LauncherErrorDetail>} */
@@ -193,7 +193,7 @@ export type ListToolbarOptions = {
193
193
  * control, rather than found separately beside it.
194
194
  * - **The count line is a live region**, and `setCount(null)` clears it. The previous number
195
195
  * describes the previous filters, and a stale count during a load is worse than none.
196
- * - **Tool buttons meet the 44 px target** in both densities. An icon button sized to its glyph is
196
+ * - **Tool buttons meet the 44 px target** at any spacing. An icon button sized to its glyph is
197
197
  * the control people miss twice before hitting once.
198
198
  *
199
199
  * `bind()` is optional sugar; the toolbar is fully functional without it.
@@ -341,8 +341,10 @@ export declare class ListToolbar extends Component<ListToolbarOptions> {
341
341
  */
342
342
  focusSearch(): this;
343
343
  /**
344
- * Optional sugar for a `TableView` or `CardView`: it wires the shape switch to the view and
345
- * mounts the view's field chooser into this bar.
344
+ * Optional sugar for a `TableView`, `CardView`, or `KanbanView`: it wires the shape switch to
345
+ * the view and mounts the view's field chooser into this bar — through the view's public
346
+ * `mountFieldControls()` when it has one, which every `RecordView` does. A `TableView` with the
347
+ * default `fieldControls: true` contributes its Table's column chooser.
346
348
  *
347
349
  * Nothing is imported and nothing is required — every capability is feature-detected, so a view
348
350
  * that offers none of them still works and still gets `viewchange`, and the host swaps the view
@@ -410,7 +412,8 @@ export declare class ListToolbar extends Component<ListToolbarOptions> {
410
412
  */
411
413
  _mountFieldControls(view: Record<string, any>): void;
412
414
  /**
413
- * Finds a view's field chooser without importing the view, newest accessor first.
415
+ * Finds a view's field chooser without importing the view: its public `getFieldControls()`,
416
+ * else — for an object that only looks like a record view — the shared chooser's class.
414
417
  * @param {Record<string, any>} view Bound view.
415
418
  * @returns {Element|null}
416
419
  */
@@ -470,6 +473,7 @@ export type AdoptedElement = {
470
473
  element: Element;
471
474
  parent: Node | null;
472
475
  next: Node | null;
476
+ viaView?: boolean;
473
477
  };
474
478
  export type RecordViewCapabilities = {
475
479
  /**
@@ -489,7 +493,8 @@ export type RecordViewCapabilities = {
489
493
  */
490
494
  events: boolean;
491
495
  /**
492
- * Whether the object offers its field chooser through a method.
496
+ * Whether the object offers its field chooser through a method
497
+ * (`getFieldControls()`, which every `RecordView` has).
493
498
  */
494
499
  fieldControls: boolean;
495
500
  };
@@ -521,14 +526,18 @@ export type RecordViewCapabilities = {
521
526
  * @property {boolean} pressed Current pressed state.
522
527
  * @property {((event: MouseEvent) => void)|null} onclick Descriptor callback.
523
528
  */
524
- /** @typedef {{element: Element, parent: Node|null, next: Node|null}} AdoptedElement */
529
+ /**
530
+ * @typedef {{element: Element, parent: Node|null, next: Node|null, viaView?: boolean}} AdoptedElement
531
+ * `viaView` marks a field chooser the bound view moved here itself and takes back on `unbind()`.
532
+ */
525
533
  /**
526
534
  * @typedef {Object} RecordViewCapabilities
527
535
  * @property {boolean} isRecordView Whether the object publishes the record-view state surface.
528
536
  * @property {string|null} setShape Method that changes the view shape, if any.
529
537
  * @property {string|null} getShape Method that reads the view shape, if any.
530
538
  * @property {boolean} events Whether the object emits component events.
531
- * @property {boolean} fieldControls Whether the object offers its field chooser through a method.
539
+ * @property {boolean} fieldControls Whether the object offers its field chooser through a method
540
+ * (`getFieldControls()`, which every `RecordView` has).
532
541
  */
533
542
  /**
534
543
  * Describes what `bind()` can wire on an object, by feature rather than by class.