@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
@@ -0,0 +1,260 @@
1
+ export type OverlayKind = 'modal' | 'non-modal' | 'popup' | 'tooltip' | 'toast';
2
+ export type OverlayEntryOptions = {
3
+ /**
4
+ * Layer kind.
5
+ */
6
+ kind: OverlayKind;
7
+ /**
8
+ * The overlay's own root: the panel, dialog, or region.
9
+ */
10
+ root: Element;
11
+ /**
12
+ * Component that owns the entry; informational.
13
+ */
14
+ owner?: unknown;
15
+ /**
16
+ * Element(s) the overlay was
17
+ * opened from or is anchored to. The topmost entry whose root contains one becomes the parent.
18
+ */
19
+ anchor?: Element | null | Array<Element | null | undefined>;
20
+ /**
21
+ * Further elements that count as part of the
22
+ * overlay for outside presses and focus — a dropdown's trigger, which toggles it on its own.
23
+ */
24
+ inside?: Array<Element | null | undefined>;
25
+ /**
26
+ * Handles an
27
+ * Escape routed to this entry. Return `false` to decline, which passes it to the next layer down.
28
+ * The dispatcher calls `preventDefault()` on an Escape an entry handled.
29
+ */
30
+ onEscape?: (event: KeyboardEvent, handle: OverlayHandle) => boolean | void;
31
+ /**
32
+ * Called for a press
33
+ * outside the entry's chain, while nothing above it contained the press.
34
+ */
35
+ onOutsidePointer?: (event: Event, handle: OverlayHandle) => void;
36
+ /**
37
+ * Called when focus
38
+ * moves to an element outside the entry's chain.
39
+ */
40
+ onFocusOutside?: (event: FocusEvent, handle: OverlayHandle) => void;
41
+ /**
42
+ * Called when the parent entry closes.
43
+ * An entry without it outlives its parent and is re-parented to the grandparent.
44
+ */
45
+ onParentClose?: (handle: OverlayHandle) => void;
46
+ };
47
+ export type OverlayEntry = {
48
+ /**
49
+ * Z-order; higher is on top. Unique and increasing, never reused.
50
+ */
51
+ order: number;
52
+ /**
53
+ * Layer kind.
54
+ */
55
+ kind: OverlayKind;
56
+ /**
57
+ * Overlay root.
58
+ */
59
+ root: Element;
60
+ /**
61
+ * Owning component.
62
+ */
63
+ owner: unknown;
64
+ /**
65
+ * Anchor elements.
66
+ */
67
+ anchors: Element[];
68
+ /**
69
+ * Extra elements that count as inside.
70
+ */
71
+ inside: Element[];
72
+ /**
73
+ * Overlay the anchor sat in when the entry opened.
74
+ */
75
+ parent: OverlayEntry | null;
76
+ /**
77
+ * Escape handler.
78
+ */
79
+ onEscape?: OverlayEntryOptions['onEscape'];
80
+ /**
81
+ * Outside-press handler.
82
+ */
83
+ onOutsidePointer?: OverlayEntryOptions['onOutsidePointer'];
84
+ /**
85
+ * Focus-outside handler.
86
+ */
87
+ onFocusOutside?: OverlayEntryOptions['onFocusOutside'];
88
+ /**
89
+ * Parent-close handler.
90
+ */
91
+ onParentClose?: OverlayEntryOptions['onParentClose'];
92
+ };
93
+ export type OverlayHandle = {
94
+ /**
95
+ * The registered entry.
96
+ */
97
+ entry: OverlayEntry;
98
+ /**
99
+ * The entry's z-order, for `data-zx-overlay-order`.
100
+ */
101
+ order: number;
102
+ /**
103
+ * Whether the entry is still registered.
104
+ */
105
+ isOpen: () => boolean;
106
+ /**
107
+ * Whether no other entry (toasts aside) sits above it.
108
+ */
109
+ isTopmost: () => boolean;
110
+ /**
111
+ * Whether a node is inside the entry's
112
+ * chain: its root, its `inside` elements, or any overlay opened from it.
113
+ */
114
+ contains: (node: Node | null | undefined) => boolean;
115
+ /**
116
+ * Unregisters the entry and closes the children that follow it.
117
+ * Safe to call repeatedly.
118
+ */
119
+ release: () => void;
120
+ };
121
+ /**
122
+ * Whether `node` is `root` or inside it, crossing shadow roots.
123
+ * @param {Node|null|undefined} root Container.
124
+ * @param {Node|null|undefined} node Candidate.
125
+ * @returns {boolean}
126
+ */
127
+ export declare function containsNode(root: Node | null | undefined, node: Node | null | undefined): boolean;
128
+ /**
129
+ * The entry an overlay opened from `anchors` belongs under: the topmost one whose root contains an
130
+ * anchor. Tooltips and toasts are never parents.
131
+ * @param {readonly OverlayEntry[]} entries Registered entries, bottom to top.
132
+ * @param {readonly Element[]} anchors Anchor elements of the overlay being opened.
133
+ * @returns {OverlayEntry|null}
134
+ */
135
+ export declare function findParent(entries: readonly OverlayEntry[], anchors: readonly Element[]): OverlayEntry | null;
136
+ /**
137
+ * Whether a node is inside an entry's chain: its root, its `inside` elements, or — recursively —
138
+ * any entry whose parent it is.
139
+ * @param {readonly OverlayEntry[]} entries Registered entries.
140
+ * @param {OverlayEntry} entry Entry to test.
141
+ * @param {Node|null|undefined} node Candidate.
142
+ * @returns {boolean}
143
+ */
144
+ export declare function insideChain(entries: readonly OverlayEntry[], entry: OverlayEntry, node: Node | null | undefined): boolean;
145
+ /**
146
+ * The topmost entry, toasts aside, optionally narrowed by a predicate.
147
+ * @param {readonly OverlayEntry[]} entries Registered entries, bottom to top.
148
+ * @param {(entry: OverlayEntry) => boolean} [filter] Extra condition.
149
+ * @returns {OverlayEntry|null}
150
+ */
151
+ export declare function topmostEntry(entries: readonly OverlayEntry[], filter?: (entry: OverlayEntry) => boolean): OverlayEntry | null;
152
+ /**
153
+ * The entries an Escape may be offered to, in the order they are asked: from the top down, those
154
+ * with an Escape handler, stopping at the first modal (whose Escape is the browser's).
155
+ *
156
+ * `within` is the open modal dialog the key was pressed in, when there is one. Everything outside
157
+ * it is inert, so an entry whose root lies outside it is never offered the key — which keeps a
158
+ * modal the stack does not know about (a `<dialog>` an application opened with `showModal()`)
159
+ * from losing its Escape to a popup left open behind it.
160
+ * @param {readonly OverlayEntry[]} entries Registered entries, bottom to top.
161
+ * @param {Node|null} [within=null] Open modal dialog containing the key's target.
162
+ * @returns {OverlayEntry[]}
163
+ */
164
+ export declare function escapeCandidates(entries: readonly OverlayEntry[], within?: Node | null): OverlayEntry[];
165
+ /**
166
+ * The entries a press on `node` dismisses, topmost first.
167
+ *
168
+ * A press inside a toast dismisses nothing. Tooltips go on any press outside them. For the rest,
169
+ * the walk runs from the top down and stops at the first entry whose chain contains the press — it
170
+ * landed on that layer, and the layers beneath are covered by it or own it — or at a modal, below
171
+ * which everything is inert. Every entry passed on the way that handles outside presses is
172
+ * dismissed. As for Escape, a press inside an open modal dialog dismisses nothing outside it.
173
+ * @param {readonly OverlayEntry[]} entries Registered entries, bottom to top.
174
+ * @param {Node|null|undefined} node Press target.
175
+ * @param {Node|null} [within=null] Open modal dialog containing the press.
176
+ * @returns {OverlayEntry[]}
177
+ */
178
+ export declare function outsideTargets(entries: readonly OverlayEntry[], node: Node | null | undefined, within?: Node | null): OverlayEntry[];
179
+ /**
180
+ * A registry of open overlays. The library uses the one shared instance, `overlayStack`; separate
181
+ * instances exist for tests and for documents other than the global one.
182
+ */
183
+ export declare class OverlayStack {
184
+ #private;
185
+ /**
186
+ * @param {{target?: EventTarget|null}} [options={}] Where to listen; the global document when
187
+ * omitted. Pass `null` to install no listeners and drive the dispatch methods directly.
188
+ */
189
+ constructor(options?: {
190
+ target?: EventTarget | null;
191
+ });
192
+ /**
193
+ * Registers an open overlay above every other.
194
+ * @param {OverlayEntryOptions} options Entry description.
195
+ * @returns {OverlayHandle}
196
+ */
197
+ push(options: OverlayEntryOptions): OverlayHandle;
198
+ /**
199
+ * The registered entries, bottom to top. A copy: changing it changes nothing.
200
+ * @returns {OverlayEntry[]}
201
+ */
202
+ entries(): OverlayEntry[];
203
+ /**
204
+ * The topmost entry, toasts aside.
205
+ * @param {(entry: OverlayEntry) => boolean} [filter] Extra condition.
206
+ * @returns {OverlayEntry|null}
207
+ */
208
+ topmost(filter?: (entry: OverlayEntry) => boolean): OverlayEntry | null;
209
+ /**
210
+ * Root of the topmost open modal dialog, or null when none is open. Asks the registry first and
211
+ * falls back to the document, so a `<dialog>` opened with `showModal()` outside the library still
212
+ * counts.
213
+ * @returns {Element|null}
214
+ */
215
+ topmostModal(): Element | null;
216
+ /**
217
+ * Whether a node is inside any registered overlay's root or `inside` elements.
218
+ * @param {Node|null|undefined} node Candidate.
219
+ * @returns {boolean}
220
+ */
221
+ containsNode(node: Node | null | undefined): boolean;
222
+ /**
223
+ * Subscribes to registry changes: called after every push and release.
224
+ * @param {(entries: readonly OverlayEntry[]) => void} listener Change listener.
225
+ * @returns {() => void} Unsubscribes.
226
+ */
227
+ subscribe(listener: (entries: readonly OverlayEntry[]) => void): () => void;
228
+ /**
229
+ * Routes an Escape keydown to the topmost layer that handles it. Ignores other keys and events
230
+ * already `defaultPrevented`. Installed on the document while overlays are open; public so a
231
+ * stack created without a target can be driven directly.
232
+ * @param {KeyboardEvent} event Keydown event.
233
+ * @returns {OverlayEntry|null} The entry that handled it.
234
+ */
235
+ handleKeydown(event: KeyboardEvent): OverlayEntry | null;
236
+ /**
237
+ * Dismisses the layers a press landed outside of. Installed on the document, capture phase, while
238
+ * overlays are open; public so a stack created without a target can be driven directly.
239
+ * @param {Event} event Pointerdown event.
240
+ * @returns {OverlayEntry[]} The entries asked to dismiss, topmost first.
241
+ */
242
+ handlePointerdown(event: Event): OverlayEntry[];
243
+ /**
244
+ * Tells the entries that watch focus that it moved outside them.
245
+ * @param {FocusEvent} event Focusin event.
246
+ * @returns {void}
247
+ */
248
+ handleFocusin(event: FocusEvent): void;
249
+ }
250
+ /**
251
+ * The document's overlay stack, shared by every overlay in the library.
252
+ * @type {OverlayStack}
253
+ */
254
+ export declare const overlayStack: OverlayStack;
255
+ /**
256
+ * Registers an open overlay on the shared stack. Shorthand for `overlayStack.push(options)`.
257
+ * @param {OverlayEntryOptions} options Entry description.
258
+ * @returns {OverlayHandle}
259
+ */
260
+ export declare function pushOverlay(options: OverlayEntryOptions): OverlayHandle;
@@ -13,7 +13,7 @@ export { position } from './core/position.js';
13
13
  export { breakpoints, breakpointOf, matchBreakpoint, onBreakpoint } from './core/breakpoint.js';
14
14
  export { MOTION_ATTRIBUTE, prefersReducedMotion, watchMotion } from './core/motion.js';
15
15
  export { Http, zeyosService, parseResult } from './core/http.js';
16
- export { setTranslator, setLanguage, getLanguage, translate, printf } from './core/i18n.js';
16
+ export { setTranslator, setLanguage, getLanguage, translate, printf, defaultMessages } from './core/i18n.js';
17
17
  export { focusTrap, rovingTabindex, typeahead } from './core/keyboard.js';
18
18
  export { formatDate, parseDate, clampDate, isSameDay, addDays, addMonths, getWeekStart } from './core/date.js';
19
19
  export { icon, icons, iconNames, registerIcons, configureIcons, getIconConfig, useFontAwesome, useBuiltinIcons, loadFontAwesome } from './core/icons.js';
@@ -61,8 +61,10 @@ export { FileList, normalizeFileListItems } from './components/file-list/file-li
61
61
  export { ActivityItem, resolveActivityActions, normalizeActivityAction, normalizeActivityTimestamp } from './components/activity-item/activity-item.js';
62
62
  export { ActivityList, groupActivityItems, normalizeActivityItems } from './components/activity-list/activity-list.js';
63
63
  export { AccountMenu } from './components/account-menu/account-menu.js';
64
+ export { WorkspaceSwitcher } from './components/workspace-switcher/workspace-switcher.js';
64
65
  export { normalizeAppItems } from './internal/app-rail.js';
65
- export { AppSidebar } from './components/app-sidebar/app-sidebar.js';
66
+ export { ModuleBar, partitionModules, resolveModuleColor } from './components/module-bar/module-bar.js';
67
+ export { AppSidebar, presentationGlyph } from './components/app-sidebar/app-sidebar.js';
66
68
  export { Message } from './components/message/message.js';
67
69
  export { Modal } from './components/modal/modal.js';
68
70
  export { Dialog } from './components/dialog/dialog.js';
@@ -103,6 +105,7 @@ export { DataFilter } from './components/data-filter/data-filter.js';
103
105
  export { FilterPanel, isActiveValue, pruneValue, serializeFilterValue } from './components/filter-panel/filter-panel.js';
104
106
  export { SortControl } from './components/sort-control/sort-control.js';
105
107
  export { ListToolbar } from './components/list-toolbar/list-toolbar.js';
108
+ export { ViewSettings } from './components/view-settings/view-settings.js';
106
109
  export { Filter } from './components/filter/filter.js';
107
110
  export { filterOperators, emptyFilterAst, filterCondition, filterGroup, parseFilterAst, cloneFilterAst, stringifyFilterAst, validateFilterAst } from './components/filter/filter-model.js';
108
111
  export { Field } from './components/field/field.js';
@@ -43,6 +43,17 @@ export type AppNavItem = {
43
43
  * Child destinations/actions.
44
44
  */
45
45
  children?: AppNavItem[];
46
+ /**
47
+ * Makes the item a section: a quiet heading over its `children`, which
48
+ * render at the same level. A section is never focused, selected, or collapsed, and needs no `id`.
49
+ */
50
+ section?: boolean;
51
+ /**
52
+ * A section's trailing controls, such as an add button.
53
+ */
54
+ actions?: Node | {
55
+ toElement: () => Node | null;
56
+ };
46
57
  };
47
58
  export type AppRailPresenterOptions = {
48
59
  /**
@@ -129,6 +140,9 @@ export type RailFlyout = {
129
140
  * @property {() => void} [invoke] Application-owned non-link action.
130
141
  * @property {boolean} [disabled] Whether activation is unavailable.
131
142
  * @property {AppNavItem[]} [children] Child destinations/actions.
143
+ * @property {boolean} [section] Makes the item a section: a quiet heading over its `children`, which
144
+ * render at the same level. A section is never focused, selected, or collapsed, and needs no `id`.
145
+ * @property {Node|{toElement: () => Node|null}} [actions] A section's trailing controls, such as an add button.
132
146
  */
133
147
  /**
134
148
  * @typedef {Object} AppRailPresenterOptions
@@ -170,6 +184,13 @@ export declare class AppRailPresenter extends Component<AppRailPresenterOptions>
170
184
  _pointerFocus: WeakSet<object>;
171
185
  _silenceFlyoutEvents: boolean;
172
186
  static cssName: string;
187
+ /**
188
+ * BEM block of the rail's own parts (header, list, footer, row, item). A component built on the
189
+ * presenter names its parts after itself; flyout panels keep the `zx-app-rail__` vocabulary,
190
+ * because every rail portals the same panel.
191
+ * @type {string}
192
+ */
193
+ static partBlock: string;
173
194
  /** @type {Readonly<AppRailPresenterOptions>} */
174
195
  static defaults: Readonly<AppRailPresenterOptions>;
175
196
  /**
@@ -204,6 +225,23 @@ export declare class AppRailPresenter extends Component<AppRailPresenterOptions>
204
225
  destroy(): void;
205
226
  /** @returns {void} */
206
227
  _rebuild(): void;
228
+ /** @returns {string} The BEM block of the rail's own parts. @protected */
229
+ protected _partBlock(): string;
230
+ /**
231
+ * Builds one top-level rail control. The control must carry `data-app-nav-id` and
232
+ * `data-app-nav-value-id`, which keyboard handling, flyouts, and the active state read.
233
+ * @param {AppNavItem} item Top-level item.
234
+ * @param {boolean} hasFlyout Whether the control opens a flyout of the item's children.
235
+ * @returns {HTMLElement}
236
+ * @protected
237
+ */
238
+ protected _renderControl(item: AppNavItem, hasFlyout: boolean): HTMLElement;
239
+ /** Whether an item with children presents them in a flyout. @param {AppNavItem} item @returns {boolean} @protected */
240
+ protected _flyoutsFor(item: AppNavItem): boolean;
241
+ /** Whether a top-level control gets a hover/focus tooltip naming it. @param {AppNavItem} item @returns {boolean} @protected */
242
+ protected _tooltipFor(item: AppNavItem): boolean;
243
+ /** Runs after every rebuild, before the active state is applied. @returns {void} @protected */
244
+ protected _afterRebuild(): void;
207
245
  /** @param {AppNavItem} item @param {HTMLElement} trigger @param {string} key @param {string|null} parentKey @returns {void} */
208
246
  _buildFlyout(item: AppNavItem, trigger: HTMLElement, key: string, parentKey: string | null): void;
209
247
  /** @param {AppNavItem} item @param {Event} event @returns {Event} */
@@ -80,7 +80,51 @@ export type MenuHeading = {
80
80
  export type MenuSeparator = {
81
81
  type: 'separator';
82
82
  };
83
- export type MenuEntry = MenuItem | MenuHeading | MenuSeparator | '-';
83
+ export type MenuChoiceOption = {
84
+ /**
85
+ * Value the choice takes.
86
+ */
87
+ value: unknown;
88
+ /**
89
+ * Accessible name and tooltip; the option shows its glyph or icon.
90
+ */
91
+ label: string;
92
+ /**
93
+ * Kernel icon name.
94
+ */
95
+ icon?: string;
96
+ /**
97
+ * A pictogram drawn instead of an icon.
98
+ */
99
+ glyph?: Node | (() => Node);
100
+ /**
101
+ * Whether the option is unavailable.
102
+ */
103
+ disabled?: boolean;
104
+ };
105
+ export type MenuChoice = {
106
+ /**
107
+ * Entry kind.
108
+ */
109
+ type: 'choice';
110
+ /**
111
+ * Visible row label.
112
+ */
113
+ label: string;
114
+ /**
115
+ * Value of the checked option.
116
+ */
117
+ value?: unknown;
118
+ /**
119
+ * The options, in order.
120
+ */
121
+ options: MenuChoiceOption[];
122
+ /**
123
+ * Called with the chosen option's value.
124
+ */
125
+ onselect?: (value: unknown, entry: MenuChoice, controller: MenuController) => void;
126
+ };
127
+ export type MenuEntry = MenuItem | MenuHeading | MenuSeparator | MenuChoice | '-';
84
128
  /** @typedef {'menuitem'|'menuitemcheckbox'|'menuitemradio'} MenuItemRole */
85
129
  /**
86
130
  * @typedef {Object} MenuController
@@ -111,7 +155,27 @@ export type MenuEntry = MenuItem | MenuHeading | MenuSeparator | '-';
111
155
  * @property {string} label Visible heading.
112
156
  */
113
157
  /** @typedef {{type: 'separator'}} MenuSeparator */
114
- /** @typedef {MenuItem|MenuHeading|MenuSeparator|'-'} MenuEntry */
158
+ /**
159
+ * One option of a menu choice.
160
+ * @typedef {Object} MenuChoiceOption
161
+ * @property {unknown} value Value the choice takes.
162
+ * @property {string} label Accessible name and tooltip; the option shows its glyph or icon.
163
+ * @property {string} [icon] Kernel icon name.
164
+ * @property {Node|(() => Node)} [glyph] A pictogram drawn instead of an icon.
165
+ * @property {boolean} [disabled=false] Whether the option is unavailable.
166
+ */
167
+ /**
168
+ * A setting chosen in place: a labelled row of two to a few options, one checked — a theme, a
169
+ * layout. Choosing an option keeps the menu open, so its effect shows.
170
+ * @typedef {Object} MenuChoice
171
+ * @property {'choice'} type Entry kind.
172
+ * @property {string} label Visible row label.
173
+ * @property {unknown} [value] Value of the checked option.
174
+ * @property {MenuChoiceOption[]} options The options, in order.
175
+ * @property {(value: unknown, entry: MenuChoice, controller: MenuController) => void} [onselect]
176
+ * Called with the chosen option's value.
177
+ */
178
+ /** @typedef {MenuItem|MenuHeading|MenuSeparator|MenuChoice|'-'} MenuEntry */
115
179
  export declare const MENU_ITEM_SELECTOR: string;
116
180
  /**
117
181
  * Reports whether an entry is an interactive menu action.
@@ -129,6 +193,10 @@ export declare function menuItemRole(item: MenuItem): MenuItemRole;
129
193
  * Builds one menu's entries with shared structure and link safety.
130
194
  * @param {MenuEntry[]} entries Entry definitions.
131
195
  * @param {string} block CSS block name, without the `zx-` prefix.
196
+ * @param {{choices?: boolean}} [options={}] Whether the menu handles `choice` entries; a menu that
197
+ * does not leaves them out rather than drawing a row that does nothing.
132
198
  * @returns {HTMLElement[]}
133
199
  */
134
- export declare function renderMenuEntries(entries: MenuEntry[], block: string): HTMLElement[];
200
+ export declare function renderMenuEntries(entries: MenuEntry[], block: string, { choices }?: {
201
+ choices?: boolean;
202
+ }): HTMLElement[];
@@ -8,6 +8,7 @@ export { connect } from './connect.js';
8
8
  export { zeyosModules, moduleAliases, moduleInfo, moduleColor, moduleIconName, moduleKeys, moduleGlyphColor, normalizeModuleName, registerModules } from './modules.js';
9
9
  export { ZEYOS_ICON_KIT, useZeyosIcons, moduleIcon, moduleChip, zeyosAppIcon } from './icons.js';
10
10
  export { ZEYOS_LAUNCHER_APPLICATIONS, buildZeyosLauncherConfig, zeyosLauncher, normalizeZeyosLauncherApplications, normalizeZeyosLauncherRecords, zeyosActiveIdentifier } from './launcher.js';
11
+ export { zeyosModuleItems, buildZeyosModuleBarConfig, buildZeyosAppSidebarConfig, zeyosModuleBar } from './module-bar.js';
11
12
  export { zeyosSelect, buildZeyosSelectConfig, zeyosEntitySelect, buildZeyosEntitySelectConfig } from './select.js';
12
13
  export { zeyosForm } from './form.js';
13
14
  export { zeyosTable } from './table.js';
@@ -145,3 +145,12 @@ export declare function zeyosActiveIdentifier(state?: {
145
145
  fork?: unknown;
146
146
  weblet?: unknown;
147
147
  }): string;
148
+ /**
149
+ * Normalizes one application of the ZeyOS shell catalogue: a `[module, label]` pair, a
150
+ * `[ID, name, module, color]` fork, a weblet row, or an object. Shared with the module bar.
151
+ * @param {unknown} raw @param {string|null} fallbackId @param {unknown} fallbackLabel
152
+ * @returns {Record<string, any>|null}
153
+ */
154
+ export declare function normalizeApplication(raw: unknown, fallbackId: string | null, fallbackLabel: unknown): Record<string, any> | null;
155
+ /** @param {unknown} raw @param {unknown} resolver @returns {Record<string, any>} */
156
+ export declare function mergeDestination(raw: unknown, resolver: unknown): Record<string, any>;
@@ -0,0 +1,176 @@
1
+ import { ModuleBar } from '../components/module-bar/module-bar.js';
2
+ export type ModuleItem = import('../components/module-bar/module-bar.js').ModuleItem;
3
+ export type ModuleBarOptions = import('../components/module-bar/module-bar.js').ModuleBarOptions;
4
+ export type AppSidebarOptions = import('../components/app-sidebar/app-sidebar.js').AppSidebarOptions;
5
+ export type ZeyosMenuEntry = {
6
+ /**
7
+ * Entry identifier; a section needs none.
8
+ */
9
+ id?: string | number;
10
+ /**
11
+ * Entry label.
12
+ */
13
+ label: string;
14
+ /**
15
+ * Destination.
16
+ */
17
+ href?: string;
18
+ /**
19
+ * Link browsing context.
20
+ */
21
+ target?: string;
22
+ /**
23
+ * Application-owned action.
24
+ */
25
+ invoke?: () => void;
26
+ /**
27
+ * Count.
28
+ */
29
+ badge?: string | number;
30
+ /**
31
+ * Icon name or node.
32
+ */
33
+ icon?: string | Node;
34
+ /**
35
+ * A heading over `children` rather than a destination.
36
+ */
37
+ section?: boolean;
38
+ /**
39
+ * Nested entries.
40
+ */
41
+ children?: Array<ZeyosMenuEntry | Array<any>>;
42
+ };
43
+ export type ZeyosModuleBarState = {
44
+ /**
45
+ * Permitted module catalogue.
46
+ */
47
+ modules?: Record<string, string> | Array<string | Record<string, any>>;
48
+ /**
49
+ * Forks, weblets, and authoritative menu entries.
50
+ */
51
+ menuApps?: Array<Array<any> | Record<string, any>>;
52
+ /**
53
+ * Application identifiers on the bar, in order; the rest are under "All modules".
54
+ */
55
+ pinned?: string[];
56
+ /**
57
+ * Current module, `fork#…`, or `weblet#…` identifier.
58
+ */
59
+ activeIdentifier?: string | null;
60
+ /**
61
+ * Current menu entry, when it is more precise than the module.
62
+ */
63
+ active?: string | number | null;
64
+ /**
65
+ * Permission predicate.
66
+ */
67
+ canUseModule?: (module: string) => boolean;
68
+ /**
69
+ * Maps an application to href/invoke/value metadata.
70
+ */
71
+ resolveApplication?: (app: unknown) => Record<string, any> | null;
72
+ /**
73
+ * Each application's menu, keyed by identifier.
74
+ */
75
+ menus?: Record<string, Array<ZeyosMenuEntry | Array<any>>>;
76
+ /**
77
+ * Badges keyed by application identifier or menu entry id.
78
+ */
79
+ badges?: Record<string, string | number>;
80
+ /**
81
+ * "All modules" group per application identifier.
82
+ */
83
+ groups?: Record<string, string>;
84
+ /**
85
+ * Group labels for forks and weblets.
86
+ */
87
+ labels?: {
88
+ forks?: string;
89
+ weblets?: string;
90
+ };
91
+ /**
92
+ * Host icon renderer.
93
+ */
94
+ renderApplicationIcon?: (app: unknown, normalized: Record<string, any>) => Node | null;
95
+ };
96
+ export type ZeyosModuleBarOptions = {
97
+ /**
98
+ * Use stock Font Awesome glyphs instead of the ZeyOS kit.
99
+ */
100
+ standardIcons?: boolean;
101
+ /**
102
+ * Tile treatment; ZeyOS draws its modules solid.
103
+ */
104
+ appearance?: 'solid' | 'tint' | 'plain';
105
+ };
106
+ /** @typedef {import('../components/module-bar/module-bar.js').ModuleItem} ModuleItem */
107
+ /** @typedef {import('../components/module-bar/module-bar.js').ModuleBarOptions} ModuleBarOptions */
108
+ /** @typedef {import('../components/app-sidebar/app-sidebar.js').AppSidebarOptions} AppSidebarOptions */
109
+ /**
110
+ * One entry of a module's menu, as the ZeyOS shell describes it: an object, or an
111
+ * `[id, label, href]` array.
112
+ * @typedef {Object} ZeyosMenuEntry
113
+ * @property {string|number} [id] Entry identifier; a section needs none.
114
+ * @property {string} label Entry label.
115
+ * @property {string} [href] Destination.
116
+ * @property {string} [target] Link browsing context.
117
+ * @property {() => void} [invoke] Application-owned action.
118
+ * @property {string|number} [badge] Count.
119
+ * @property {string|Node} [icon] Icon name or node.
120
+ * @property {boolean} [section] A heading over `children` rather than a destination.
121
+ * @property {Array<ZeyosMenuEntry|Array<any>>} [children] Nested entries.
122
+ */
123
+ /**
124
+ * The ZeyOS shell state a module bar is built from. The application fields are the launcher's
125
+ * (`buildZeyosLauncherConfig()`), so one state object can feed both.
126
+ * @typedef {Object} ZeyosModuleBarState
127
+ * @property {Record<string, string>|Array<string|Record<string, any>>} [modules={}] Permitted module catalogue.
128
+ * @property {Array<Array<any>|Record<string, any>>} [menuApps=[]] Forks, weblets, and authoritative menu entries.
129
+ * @property {string[]} [pinned] Application identifiers on the bar, in order; the rest are under "All modules".
130
+ * @property {string|null} [activeIdentifier=null] Current module, `fork#…`, or `weblet#…` identifier.
131
+ * @property {string|number|null} [active=null] Current menu entry, when it is more precise than the module.
132
+ * @property {(module: string) => boolean} [canUseModule] Permission predicate.
133
+ * @property {(app: unknown) => Record<string, any>|null} [resolveApplication] Maps an application to href/invoke/value metadata.
134
+ * @property {Record<string, Array<ZeyosMenuEntry|Array<any>>>} [menus={}] Each application's menu, keyed by identifier.
135
+ * @property {Record<string, string|number>} [badges={}] Badges keyed by application identifier or menu entry id.
136
+ * @property {Record<string, string>} [groups={}] "All modules" group per application identifier.
137
+ * @property {{forks?: string, weblets?: string}} [labels] Group labels for forks and weblets.
138
+ * @property {(app: unknown, normalized: Record<string, any>) => Node|null} [renderApplicationIcon] Host icon renderer.
139
+ */
140
+ /**
141
+ * @typedef {Object} ZeyosModuleBarOptions
142
+ * @property {boolean} [standardIcons=false] Use stock Font Awesome glyphs instead of the ZeyOS kit.
143
+ * @property {'solid'|'tint'|'plain'} [appearance='solid'] Tile treatment; ZeyOS draws its modules solid.
144
+ */
145
+ /**
146
+ * Maps ZeyOS shell state to module bar items: every permitted module, fork, and weblet with its
147
+ * kit icon, its identity colour (the payload's, else the registry's), its menu, and its badge.
148
+ * A module with a menu is a panel module; one without is a destination.
149
+ * @param {ZeyosModuleBarState} [state={}] Application-owned shell state.
150
+ * @param {ZeyosModuleBarOptions} [options={}] Mapping options.
151
+ * @returns {ModuleItem[]}
152
+ */
153
+ export declare function zeyosModuleItems(state?: ZeyosModuleBarState, options?: ZeyosModuleBarOptions): ModuleItem[];
154
+ /**
155
+ * Builds plain ModuleBar options from ZeyOS shell state.
156
+ * @param {ZeyosModuleBarState} [state={}] Application-owned shell state.
157
+ * @param {ZeyosModuleBarOptions & ModuleBarOptions} [options={}] Mapping and ModuleBar options.
158
+ * @returns {ModuleBarOptions}
159
+ */
160
+ export declare function buildZeyosModuleBarConfig(state?: ZeyosModuleBarState, options?: ZeyosModuleBarOptions & ModuleBarOptions): ModuleBarOptions;
161
+ /**
162
+ * Builds AppSidebar options for the modules layout from ZeyOS shell state: the module strip beside
163
+ * a panel with the current module's menu.
164
+ * @param {ZeyosModuleBarState} [state={}] Application-owned shell state.
165
+ * @param {ZeyosModuleBarOptions & AppSidebarOptions} [options={}] Mapping and AppSidebar options.
166
+ * @returns {AppSidebarOptions}
167
+ */
168
+ export declare function buildZeyosAppSidebarConfig(state?: ZeyosModuleBarState, options?: ZeyosModuleBarOptions & AppSidebarOptions): AppSidebarOptions;
169
+ /**
170
+ * Creates a ModuleBar from ZeyOS shell state.
171
+ * @param {Element|string|null} target Bar target, or null to create one.
172
+ * @param {ZeyosModuleBarState} [state={}] Application-owned shell state.
173
+ * @param {ZeyosModuleBarOptions & ModuleBarOptions} [options={}] Mapping and ModuleBar options.
174
+ * @returns {ModuleBar}
175
+ */
176
+ export declare function zeyosModuleBar(target: Element | string | null, state?: ZeyosModuleBarState, options?: ZeyosModuleBarOptions & ModuleBarOptions): ModuleBar;