@zeyos/zx 3.0.0 → 4.1.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 (106) hide show
  1. package/CHANGELOG.md +95 -0
  2. package/DESIGN-SYSTEM.md +87 -71
  3. package/README.md +16 -37
  4. package/dist/types/components/app-icon/app-icon.d.ts +88 -0
  5. package/dist/types/components/app-sidebar/app-sidebar.d.ts +106 -32
  6. package/dist/types/components/card/card.d.ts +128 -0
  7. package/dist/types/components/chart/chart.d.ts +1 -0
  8. package/dist/types/components/filter/filter-model.d.ts +87 -0
  9. package/dist/types/components/filter/filter.d.ts +331 -0
  10. package/dist/types/components/launcher/launcher.d.ts +65 -6
  11. package/dist/types/components/select/select.d.ts +97 -4
  12. package/dist/types/components/table/table.d.ts +107 -3
  13. package/dist/types/components/tag-picker/tag-picker.d.ts +16 -0
  14. package/dist/types/core/dom.d.ts +9 -1
  15. package/dist/types/core/util.d.ts +9 -0
  16. package/dist/types/index.d.ts +6 -2
  17. package/dist/types/{components/app-rail → internal}/app-rail.d.ts +34 -19
  18. package/dist/types/zeyos/icons.d.ts +24 -2
  19. package/dist/types/zeyos/index.d.ts +3 -2
  20. package/dist/types/zeyos/launcher.d.ts +147 -0
  21. package/dist/types/zeyos/select.d.ts +41 -0
  22. package/dist/zx-zeyos.esm.js +2018 -113
  23. package/dist/zx-zeyos.esm.min.js +1 -1
  24. package/dist/zx.css +815 -16
  25. package/dist/zx.esm.js +2661 -338
  26. package/dist/zx.esm.min.js +3 -3
  27. package/dist/zx.global.js +2661 -338
  28. package/dist/zx.global.min.js +3 -3
  29. package/dist/zx.min.css +1 -1
  30. package/docs/api.json +602 -110
  31. package/docs/llms.md +181 -123
  32. package/docs/llms.txt +24 -21
  33. package/package.json +8 -17
  34. package/src/components/app-icon/app-icon.css +105 -0
  35. package/src/components/app-icon/app-icon.js +134 -0
  36. package/src/components/app-sidebar/app-sidebar.css +12 -0
  37. package/src/components/app-sidebar/app-sidebar.js +310 -110
  38. package/src/components/card/card.css +149 -0
  39. package/src/components/card/card.js +285 -0
  40. package/src/components/chart/chart.js +8 -3
  41. package/src/components/filter/filter-model.js +226 -0
  42. package/src/components/filter/filter.css +147 -0
  43. package/src/components/filter/filter.js +554 -0
  44. package/src/components/grid/grid.css +1 -1
  45. package/src/components/grid/grid.js +14 -4
  46. package/src/components/launcher/launcher.css +113 -3
  47. package/src/components/launcher/launcher.js +234 -26
  48. package/src/components/message/message.css +36 -3
  49. package/src/components/select/field-adapter.js +9 -4
  50. package/src/components/select/select.css +161 -10
  51. package/src/components/select/select.js +361 -48
  52. package/src/components/table/table.css +85 -0
  53. package/src/components/table/table.js +426 -31
  54. package/src/components/tag-picker/tag-picker.css +19 -0
  55. package/src/components/tag-picker/tag-picker.js +42 -5
  56. package/src/core/dom.js +21 -1
  57. package/src/core/util.js +20 -0
  58. package/src/index.js +9 -2
  59. package/src/{components/app-rail → internal}/app-rail.js +80 -30
  60. package/src/zeyos/icons.js +38 -20
  61. package/src/zeyos/index.js +8 -2
  62. package/src/zeyos/launcher.js +338 -0
  63. package/src/zeyos/modules.js +1 -0
  64. package/src/zeyos/select.js +116 -1
  65. package/styles/tokens/global.css +1 -1
  66. package/styles/tokens/modules.css +1 -0
  67. package/styles/tokens/semantic.css +9 -0
  68. package/styles/tokens/themes.css +2 -2
  69. package/styles/zx.css +3 -0
  70. package/MIGRATION.md +0 -749
  71. package/dist/types/compat/base.d.ts +0 -156
  72. package/dist/types/compat/globals.d.ts +0 -20
  73. package/dist/types/compat/index.d.ts +0 -128
  74. package/dist/types/compat/map/basic.d.ts +0 -175
  75. package/dist/types/compat/map/data.d.ts +0 -103
  76. package/dist/types/compat/map/date-time.d.ts +0 -80
  77. package/dist/types/compat/map/factory.d.ts +0 -9
  78. package/dist/types/compat/map/form.d.ts +0 -98
  79. package/dist/types/compat/map/helpers.d.ts +0 -12
  80. package/dist/types/compat/map/http.d.ts +0 -36
  81. package/dist/types/compat/map/layout.d.ts +0 -106
  82. package/dist/types/compat/map/options.d.ts +0 -80
  83. package/dist/types/compat/map/select.d.ts +0 -95
  84. package/dist/types/compat/map/stubs.d.ts +0 -32
  85. package/dist/types/compat/map/utilities.d.ts +0 -37
  86. package/dist/types/compat-entry.d.ts +0 -5
  87. package/dist/zx-compat.esm.js +0 -17848
  88. package/dist/zx-compat.esm.min.js +0 -1
  89. package/dist/zx-compat.global.js +0 -29008
  90. package/dist/zx-compat.global.min.js +0 -3
  91. package/src/compat/base.js +0 -291
  92. package/src/compat/globals.js +0 -167
  93. package/src/compat/index.js +0 -84
  94. package/src/compat/map/basic.js +0 -464
  95. package/src/compat/map/data.js +0 -254
  96. package/src/compat/map/date-time.js +0 -177
  97. package/src/compat/map/factory.js +0 -45
  98. package/src/compat/map/form.js +0 -330
  99. package/src/compat/map/helpers.js +0 -46
  100. package/src/compat/map/http.js +0 -117
  101. package/src/compat/map/layout.js +0 -256
  102. package/src/compat/map/options.js +0 -267
  103. package/src/compat/map/select.js +0 -198
  104. package/src/compat/map/stubs.js +0 -26
  105. package/src/compat/map/utilities.js +0 -113
  106. package/src/compat-entry.js +0 -11
@@ -217,6 +217,22 @@ export type TableOptions = {
217
217
  * inert while this is `false`.
218
218
  */
219
219
  editMode?: TableEditMode;
220
+ /**
221
+ * Gesture that starts an editable cell.
222
+ */
223
+ editTrigger?: 'single' | 'double';
224
+ /**
225
+ * Whether rows expose pointer/keyboard reorder handles.
226
+ */
227
+ rowReorder?: boolean;
228
+ /**
229
+ * Whether a column visibility chooser is rendered.
230
+ */
231
+ columnVisibility?: boolean;
232
+ /**
233
+ * Initially hidden column IDs; at least one stays visible.
234
+ */
235
+ hiddenColumns?: string[];
220
236
  /**
221
237
  * Flat parent references projected as an
222
238
  * expandable treegrid. Row data and mutation APIs remain flat.
@@ -247,6 +263,11 @@ export type TableOptions = {
247
263
  oneditcancel?: (event: CustomEvent<TableEditCancelDetail>) => void;
248
264
  oneditinvalid?: (event: CustomEvent<TableEditInvalidDetail>) => void;
249
265
  onrowtoggle?: (event: CustomEvent<TableRowToggleDetail>) => void;
266
+ onrowmove?: (event: CustomEvent<TableRowMoveDetail>) => void;
267
+ oncolumnvisibilitychange?: (event: CustomEvent<{
268
+ visible: string[];
269
+ hidden: string[];
270
+ }>) => void;
250
271
  };
251
272
  export type TableRowClickDetail = {
252
273
  row: TableRow;
@@ -270,6 +291,13 @@ export type TableRowToggleDetail = {
270
291
  id: unknown;
271
292
  expanded: boolean;
272
293
  };
294
+ export type TableRowMoveDetail = {
295
+ row: TableRow;
296
+ id: unknown;
297
+ target: TableRow;
298
+ targetId: unknown;
299
+ position: 'before' | 'after';
300
+ };
273
301
  export type TableHierarchyEntry = {
274
302
  row: TableRow;
275
303
  id: unknown;
@@ -441,10 +469,13 @@ export type TableEditorEntry = {
441
469
  * @fires Table#rowtoggle
442
470
  * @fires Table#stackedchange
443
471
  * @fires Table#grow
472
+ * @fires Table#rowmove
473
+ * @fires Table#columnvisibilitychange
444
474
  * @extends {Component<TableOptions>}
445
475
  */
446
476
  export declare class Table extends Component<TableOptions> {
447
- _originalChildren: ChildNode[];
477
+ _createdRoot: boolean;
478
+ _original: import("../../core/dom.js").TargetSnapshot;
448
479
  _columns: {
449
480
  id: string;
450
481
  label: string;
@@ -479,6 +510,7 @@ export declare class Table extends Component<TableOptions> {
479
510
  _rowElements: Map<any, any>;
480
511
  _restored: boolean;
481
512
  _editMode: TableEditMode;
513
+ _editTrigger: string;
482
514
  _edit: {
483
515
  id: unknown;
484
516
  columnId: string;
@@ -501,12 +533,18 @@ export declare class Table extends Component<TableOptions> {
501
533
  _hierarchy: TableHierarchyOptions & {
502
534
  column: string;
503
535
  };
536
+ _hiddenColumns: Set<string>;
537
+ _dragId: any;
538
+ _grabbedId: any;
504
539
  _expanded: Set<unknown>;
505
540
  _table: HTMLElement;
506
541
  _colgroup: HTMLElement;
507
542
  _thead: HTMLElement;
508
543
  _tbody: HTMLElement;
509
544
  _scroll: HTMLElement;
545
+ _rowMoveMessage: HTMLElement;
546
+ _columnControls: HTMLElement;
547
+ _columnList: HTMLElement;
510
548
  _selectAll: HTMLElement;
511
549
  _headers: Map<any, any>;
512
550
  _hierarchyMeta: Map<unknown, TableHierarchyEntry>;
@@ -523,8 +561,8 @@ export declare class Table extends Component<TableOptions> {
523
561
  render(): HTMLElement;
524
562
  /**
525
563
  * Toggles a loading state. While loading, the body is dimmed, an indeterminate progress bar is
526
- * shown, and `aria-busy` is set — a lightweight take on the busy/skeleton pattern used by
527
- * enterprise tables (SAP UI5, Salesforce SLDS). Call `setLoading(false)` (or `setData`) when done.
564
+ * shown, and `aria-busy` is set — a lightweight enterprise-table busy and skeleton pattern.
565
+ * Call `setLoading(false)` (or `setData`) when done.
528
566
  * @param {boolean} [loading=true] Whether the table is loading.
529
567
  * @returns {this}
530
568
  */
@@ -574,6 +612,33 @@ export declare class Table extends Component<TableOptions> {
574
612
  * @returns {TableRow[]} Current table rows.
575
613
  */
576
614
  getData(): TableRow[];
615
+ /** Returns visible column IDs in caller order. @returns {string[]} */
616
+ getVisibleColumns(): string[];
617
+ /** Returns hidden column IDs in caller order. @returns {string[]} */
618
+ getHiddenColumns(): string[];
619
+ /**
620
+ * Shows or hides one column. The final visible column cannot be hidden.
621
+ * @param {string} id Column ID.
622
+ * @param {boolean} [visible=true] Desired visibility.
623
+ * @param {{silent?:boolean}} [options={}] Event behavior.
624
+ * @returns {this}
625
+ */
626
+ setColumnVisible(id: string, visible?: boolean, options?: {
627
+ silent?: boolean;
628
+ }): this;
629
+ /** Toggles one column. @param {string} id @param {{silent?:boolean}} [options={}] @returns {this} */
630
+ toggleColumn(id: string, options?: {
631
+ silent?: boolean;
632
+ }): this;
633
+ /**
634
+ * Reorders one row relative to another and emits a cancelable `rowmove` before committing.
635
+ * Hierarchical rows may only move among siblings; an active local sort disables manual order.
636
+ * @param {unknown} id Moving row ID.
637
+ * @param {unknown} targetId Target row ID.
638
+ * @param {'before'|'after'} [position='before'] Target edge.
639
+ * @returns {this}
640
+ */
641
+ moveRow(id: unknown, targetId: unknown, position?: 'before' | 'after'): this;
577
642
  /**
578
643
  * Removes all rows.
579
644
  * @returns {this}
@@ -785,6 +850,32 @@ export declare class Table extends Component<TableOptions> {
785
850
  isStacked(): boolean;
786
851
  /** Restores an enhanced target and releases all component listeners. @returns {void} */
787
852
  destroy(): void;
853
+ /** @returns {TableColumn[]} */
854
+ _visibleColumns(): TableColumn[];
855
+ /** @returns {HTMLElement} */
856
+ _createColumnControls(): HTMLElement;
857
+ /** @param {string|null} [focusColumn=null] Column checkbox that keeps focus. @returns {void} */
858
+ _renderColumnControls(focusColumn?: string | null): void;
859
+ /** @param {DragEvent} event @returns {void} */
860
+ _handleRowDragStart(event: DragEvent): void;
861
+ /** @param {DragEvent} event @returns {void} */
862
+ _handleRowDragOver(event: DragEvent): void;
863
+ /** @param {DragEvent} event @returns {void} */
864
+ _handleRowDrop(event: DragEvent): void;
865
+ /** @param {KeyboardEvent} event @returns {void} */
866
+ _handleRowHandleKeydown(event: KeyboardEvent): void;
867
+ /** @param {unknown} id @returns {unknown[]} */
868
+ _siblingIds(id: unknown): unknown[];
869
+ /** @param {unknown} left @param {unknown} right @returns {boolean} */
870
+ _canMoveTogether(left: unknown, right: unknown): boolean;
871
+ /** @param {unknown} id @returns {HTMLElement|null} */
872
+ _rowHandle(id: unknown): HTMLElement | null;
873
+ /** @returns {void} */
874
+ _clearDropMarkers(): void;
875
+ /** @returns {void} */
876
+ _clearRowDrag(): void;
877
+ /** @returns {string|null} */
878
+ _hierarchyColumn(): string | null;
788
879
  /** @returns {void} */
789
880
  _renderColumns(): void;
790
881
  /** @returns {void} */
@@ -1014,6 +1105,19 @@ export declare function projectHierarchyRows(rows: TableRow[], rowId: string | (
1014
1105
  * @returns {TableRow[]} Sorted flat rows.
1015
1106
  */
1016
1107
  export declare function sortHierarchyRows(rows: TableRow[], rowId: string | ((row: TableRow) => unknown), parentId: string | ((row: TableRow) => unknown), getValue: (row: TableRow) => unknown, direction: TableSortDirection): TableRow[];
1108
+ /**
1109
+ * Returns a reordered copy, or null when IDs are missing or hierarchical rows are not siblings.
1110
+ * Moving a parent changes its sibling order; hierarchy projection keeps its descendant subtree
1111
+ * attached as a unit because parent references are never rewritten.
1112
+ * @param {TableRow[]} rows
1113
+ * @param {string|((row:TableRow)=>unknown)} rowId
1114
+ * @param {unknown} id
1115
+ * @param {unknown} targetId
1116
+ * @param {'before'|'after'} [position='before']
1117
+ * @param {string|((row:TableRow)=>unknown)|null} [parentId=null]
1118
+ * @returns {TableRow[]|null}
1119
+ */
1120
+ export declare function reorderTableRows(rows: TableRow[], rowId: string | ((row: TableRow) => unknown), id: unknown, targetId: unknown, position?: 'before' | 'after', parentId?: string | ((row: TableRow) => unknown) | null): TableRow[] | null;
1017
1121
  /**
1018
1122
  * Resolves the editor type of a column for one row.
1019
1123
  *
@@ -19,6 +19,14 @@ export type TagPickerOptions = {
19
19
  * Item label property or reader.
20
20
  */
21
21
  labelKey?: TagLabelReader;
22
+ /**
23
+ * Optional item icon property or reader.
24
+ */
25
+ iconKey?: TagValueReader;
26
+ /**
27
+ * Optional item colour property or reader.
28
+ */
29
+ colorKey?: TagValueReader;
22
30
  /**
23
31
  * Fields searched by local filtering.
24
32
  */
@@ -133,6 +141,8 @@ export type TagPickerOptions = {
133
141
  * @property {unknown[]} [values=[]] Initially selected IDs.
134
142
  * @property {TagValueReader} [valueKey='ID'] Item ID property or reader.
135
143
  * @property {TagLabelReader} [labelKey='name'] Item label property or reader.
144
+ * @property {TagValueReader} [iconKey='icon'] Optional item icon property or reader.
145
+ * @property {TagValueReader} [colorKey='color'] Optional item colour property or reader.
136
146
  * @property {Array<TagValueReader>|null} [searchKeys=null] Fields searched by local filtering.
137
147
  * @property {'local'|((query: string) => Promise<TagItem[]>|TagItem[])} [filter='local'] Filtering mode.
138
148
  * @property {number} [minQuery=0] Minimum async query length.
@@ -359,6 +369,12 @@ export declare class TagPicker extends Component<TagPickerOptions> {
359
369
  _valueOf(item: unknown): unknown;
360
370
  /** @param {unknown} item @returns {string} */
361
371
  _labelOf(item: unknown): string;
372
+ /** @param {unknown} item @returns {Node|null} */
373
+ _iconOf(item: unknown): Node | null;
374
+ /** @param {unknown} item @returns {string|null} */
375
+ _colorOf(item: unknown): string | null;
376
+ /** @param {unknown} item @param {unknown} reader @returns {unknown} */
377
+ _readItem(item: unknown, reader: unknown): unknown;
362
378
  /** @returns {void} */
363
379
  _emitChange(): void;
364
380
  /** Grows the input to fit its text so the caret stays visible next to the tags. @returns {void} */
@@ -62,8 +62,16 @@ export declare function parseCompactTag(compact: string): CompactTag;
62
62
  * @returns {HTMLElement}
63
63
  */
64
64
  export declare function compactElement(compact: string, properties?: DomBuilderProperties | null, content?: unknown): HTMLElement;
65
- /** Exact migration-facing alias retained for existing ZeyOS builder calls. */
65
+ /** Public compact-builder alias for concise application DOM construction. */
66
66
  export declare const __: typeof compactElement;
67
+ /**
68
+ * Returns a trimmed native-link destination unless its parsed scheme can execute document code.
69
+ * Relative URLs, fragments, and ordinary application protocols remain valid; malformed and
70
+ * control-obfuscated script/data schemes are rejected.
71
+ * @param {unknown} value Candidate href.
72
+ * @returns {string|null}
73
+ */
74
+ export declare function safeHref(value: unknown): string | null;
67
75
  /**
68
76
  * Applies the established ZeyOS property rules to an existing element:
69
77
  * `Dname` → `data-name`, `SfontSize` → `style.fontSize`, `on*` → a legacy-compatible listener,
@@ -53,6 +53,15 @@ export declare function deepMerge<T, U>(a: T, b: U): T & U;
53
53
  * @returns {value is Element}
54
54
  */
55
55
  export declare function isElement(value: unknown): value is Element;
56
+ /**
57
+ * Accepts concrete CSS colours while rejecting image/function values that could make a colour
58
+ * descriptor trigger a network request when it is later consumed through a custom property.
59
+ * `CSS.supports()` provides the authoritative browser check; the conservative fallback covers
60
+ * ordinary named, hexadecimal, and functional colours in non-browser test environments.
61
+ * @param {unknown} value Candidate colour.
62
+ * @returns {value is string}
63
+ */
64
+ export declare function isCssColor(value: unknown): value is string;
56
65
  /**
57
66
  * Restricts a number to an inclusive range.
58
67
  * @param {number} n Value to restrict.
@@ -37,6 +37,7 @@ export { CopyInput } from './components/copy/copy-input.js';
37
37
  export { Toolbar } from './components/toolbar/toolbar.js';
38
38
  export { Toggle } from './components/toggle/toggle.js';
39
39
  export { Groupbox } from './components/groupbox/groupbox.js';
40
+ export { Card } from './components/card/card.js';
40
41
  export { Panel } from './components/panel/panel.js';
41
42
  export { MasterPanel } from './components/master-panel/master-panel.js';
42
43
  export { SplitView, clampSize, resolveSize, snapSize } from './components/split-view/split-view.js';
@@ -47,10 +48,11 @@ export { Stepper } from './components/stepper/stepper.js';
47
48
  export { Breadcrumb } from './components/breadcrumb/breadcrumb.js';
48
49
  export { Pagination, paginationRange } from './components/pagination/pagination.js';
49
50
  export { Search } from './components/search/search.js';
51
+ export { AppIcon, appIcon } from './components/app-icon/app-icon.js';
50
52
  export { Launcher, rankLauncherItems } from './components/launcher/launcher.js';
51
53
  export { Avatar, avatarInitials } from './components/avatar/avatar.js';
52
54
  export { AccountMenu } from './components/account-menu/account-menu.js';
53
- export { AppRail, normalizeAppItems } from './components/app-rail/app-rail.js';
55
+ export { normalizeAppItems } from './internal/app-rail.js';
54
56
  export { AppSidebar } from './components/app-sidebar/app-sidebar.js';
55
57
  export { Message } from './components/message/message.js';
56
58
  export { Modal } from './components/modal/modal.js';
@@ -74,12 +76,14 @@ export { Datebox, DateTimeBox } from './components/datebox/datebox.js';
74
76
  export { DateRangePicker, clampRange, defaultDateRangePresets, normalizeRange, rangeNights, rangeStateOf } from './components/date-picker/date-range-picker.js';
75
77
  export { DateRangeBox, formatRangeText, parseRangeText } from './components/datebox/date-range-box.js';
76
78
  export { Timebox, splitTime, joinTime } from './components/timebox/timebox.js';
77
- export { Table } from './components/table/table.js';
79
+ export { Table, reorderTableRows } from './components/table/table.js';
78
80
  export { Grid, billingColumns, isBillingLine } from './components/grid/grid.js';
79
81
  export { Chart, ChartJsAdapter, chartSummaryTable, cloneChartValue, isEmptyChartData } from './components/chart/chart.js';
80
82
  export { TreeView } from './components/tree/tree.js';
81
83
  export { Finder } from './components/finder/finder.js';
82
84
  export { DataFilter } from './components/data-filter/data-filter.js';
85
+ export { Filter } from './components/filter/filter.js';
86
+ export { filterOperators, emptyFilterAst, filterCondition, filterGroup, parseFilterAst, cloneFilterAst, stringifyFilterAst, validateFilterAst } from './components/filter/filter-model.js';
83
87
  export { Field } from './components/field/field.js';
84
88
  export { Fieldset } from './components/fieldset/fieldset.js';
85
89
  export { Form } from './components/form/form.js';
@@ -1,5 +1,5 @@
1
- import { Component } from '../../core/component.js';
2
- import { Dropdown } from '../dropdown/dropdown.js';
1
+ import { Component } from '../core/component.js';
2
+ import { Dropdown } from '../components/dropdown/dropdown.js';
3
3
  export type AppNavItem = {
4
4
  /**
5
5
  * Stable item identifier.
@@ -10,9 +10,11 @@ export type AppNavItem = {
10
10
  */
11
11
  label: string;
12
12
  /**
13
- * Kernel icon name.
13
+ * Icon name, node, component, or factory.
14
14
  */
15
- icon?: string;
15
+ icon?: string | Node | {
16
+ toElement: () => Node | null;
17
+ } | ((context: Record<string, any>, item: AppNavItem) => Node | null);
16
18
  /**
17
19
  * Count or status badge.
18
20
  */
@@ -22,7 +24,7 @@ export type AppNavItem = {
22
24
  */
23
25
  value?: unknown;
24
26
  /**
25
- * Native navigation target.
27
+ * Native navigation target; executable/data schemes are disabled.
26
28
  */
27
29
  href?: string;
28
30
  /**
@@ -42,7 +44,7 @@ export type AppNavItem = {
42
44
  */
43
45
  children?: AppNavItem[];
44
46
  };
45
- export type AppRailOptions = {
47
+ export type AppRailPresenterOptions = {
46
48
  /**
47
49
  * Application navigation tree.
48
50
  */
@@ -83,6 +85,10 @@ export type AppRailOptions = {
83
85
  * Pointer/focus crossing grace in milliseconds.
84
86
  */
85
87
  closeDelay?: number;
88
+ /**
89
+ * Optional host icon renderer.
90
+ */
91
+ renderIcon?: (item: AppNavItem, context: Record<string, any>) => Node | null;
86
92
  /**
87
93
  * Preventable action listener.
88
94
  */
@@ -115,17 +121,17 @@ export type RailFlyout = {
115
121
  * @typedef {Object} AppNavItem
116
122
  * @property {string|number} id Stable item identifier.
117
123
  * @property {string} label Visible/accessibility label.
118
- * @property {string} [icon] Kernel icon name.
124
+ * @property {string|Node|{toElement: () => Node|null}|((context: Record<string, any>, item: AppNavItem) => Node|null)} [icon] Icon name, node, component, or factory.
119
125
  * @property {string|number} [badge] Count or status badge.
120
126
  * @property {unknown} [value] Emitted value; defaults to `id`.
121
- * @property {string} [href] Native navigation target.
127
+ * @property {string} [href] Native navigation target; executable/data schemes are disabled.
122
128
  * @property {string} [target] Native link browsing context.
123
129
  * @property {() => void} [invoke] Application-owned non-link action.
124
130
  * @property {boolean} [disabled] Whether activation is unavailable.
125
131
  * @property {AppNavItem[]} [children] Child destinations/actions.
126
132
  */
127
133
  /**
128
- * @typedef {Object} AppRailOptions
134
+ * @typedef {Object} AppRailPresenterOptions
129
135
  * @property {AppNavItem[]} [items=[]] Application navigation tree.
130
136
  * @property {string|number|null} [active=null] Active item id.
131
137
  * @property {'vertical'|'horizontal'} [orientation='vertical'] Rail flow.
@@ -135,6 +141,7 @@ export type RailFlyout = {
135
141
  * @property {Node|string|number|{toElement: () => Node|null}|null} [footer=null] Trailing rail content.
136
142
  * @property {number} [openDelay=80] Hover-open delay in milliseconds.
137
143
  * @property {number} [closeDelay=160] Pointer/focus crossing grace in milliseconds.
144
+ * @property {(item: AppNavItem, context: Record<string, any>) => Node|null} [renderIcon] Optional host icon renderer.
138
145
  * @property {(event: CustomEvent<AppNavSelectDetail>) => void} [onselect] Preventable action listener.
139
146
  * @property {(event: CustomEvent<{item: AppNavItem, id: string|number, open: boolean}>) => void} [onflyoutchange] Flyout-state listener.
140
147
  */
@@ -142,11 +149,11 @@ export type RailFlyout = {
142
149
  /** @typedef {{key: string, parentKey: string|null, item: AppNavItem, trigger: HTMLElement, panel: HTMLElement, dropdown: Dropdown}} RailFlyout */
143
150
  /**
144
151
  * Minimized application navigation; descendants always open in hover/focus flyouts, never inline.
145
- * @fires AppRail#select
146
- * @fires AppRail#flyoutchange
147
- * @extends {Component<AppRailOptions>}
152
+ * @fires AppRailPresenter#select
153
+ * @fires AppRailPresenter#flyoutchange
154
+ * @extends {Component<AppRailPresenterOptions>}
148
155
  */
149
- export declare class AppRail extends Component<AppRailOptions> {
156
+ export declare class AppRailPresenter extends Component<AppRailPresenterOptions> {
150
157
  _createdRoot: boolean;
151
158
  _original: {
152
159
  attributes: string[][];
@@ -163,14 +170,14 @@ export declare class AppRail extends Component<AppRailOptions> {
163
170
  _pointerFocus: WeakSet<object>;
164
171
  _silenceFlyoutEvents: boolean;
165
172
  static cssName: string;
166
- /** @type {Readonly<AppRailOptions>} */
167
- static defaults: Readonly<AppRailOptions>;
173
+ /** @type {Readonly<AppRailPresenterOptions>} */
174
+ static defaults: Readonly<AppRailPresenterOptions>;
168
175
  /**
169
176
  * Creates or enhances a rail host.
170
177
  * @param {Element|string|null} target Rail target.
171
- * @param {AppRailOptions} [options={}] Rail options.
178
+ * @param {AppRailPresenterOptions} [options={}] Rail options.
172
179
  */
173
- constructor(target?: Element | string | null, options?: AppRailOptions);
180
+ constructor(target?: Element | string | null, options?: AppRailPresenterOptions);
174
181
  /** @returns {HTMLElement} */
175
182
  render(): HTMLElement;
176
183
  /** Replaces navigation items and closes removed flyouts. @param {AppNavItem[]} items @returns {this} */
@@ -245,6 +252,14 @@ declare class RailListenerScope extends Component {
245
252
  * @returns {AppNavItem[]}
246
253
  */
247
254
  export declare function normalizeAppItems(items: unknown): AppNavItem[];
255
+ /**
256
+ * Resolves a host-rendered or item-owned navigation icon without moving a mounted source node.
257
+ * @param {AppNavItem} item Navigation item.
258
+ * @param {unknown} renderer Optional component-level renderer.
259
+ * @param {Record<string, any>} context Presentation context.
260
+ * @returns {Node|null}
261
+ */
262
+ export declare function appNavIcon(item: AppNavItem, renderer: unknown, context: Record<string, any>): Node | null;
248
263
  export {};
249
- /** Fired when a destination/action is activated. @event AppRail#select @type {CustomEvent<AppNavSelectDetail>} */
250
- /** Fired when a flyout opens or closes. @event AppRail#flyoutchange @type {CustomEvent<{item: AppNavItem, id: string|number, open: boolean}>} */
264
+ /** Fired when a destination/action is activated. @event AppRailPresenter#select @type {CustomEvent<AppNavSelectDetail>} */
265
+ /** Fired when a flyout opens or closes. @event AppRailPresenter#flyoutchange @type {CustomEvent<{item: AppNavItem, id: string|number, open: boolean}>} */
@@ -64,7 +64,7 @@ export type ModuleChipOptions = {
64
64
  */
65
65
  size?: number | string;
66
66
  /**
67
- * Glyph size; `1em` is 60% of the chip edge.
67
+ * Glyph size relative to the tile edge.
68
68
  */
69
69
  iconSize?: number | string;
70
70
  /**
@@ -79,6 +79,18 @@ export type ModuleChipOptions = {
79
79
  * Use the stock Font Awesome fallback glyph.
80
80
  */
81
81
  standard?: boolean;
82
+ /**
83
+ * Explicit glyph override, useful for an offline fallback.
84
+ */
85
+ icon?: string | Node | (() => string | Node) | null;
86
+ /**
87
+ * Override the module colour for a server-defined fork or weblet.
88
+ */
89
+ color?: string;
90
+ /**
91
+ * AppIcon material treatment.
92
+ */
93
+ glass?: false | 'subtle' | 'strong';
82
94
  /**
83
95
  * Extra class names.
84
96
  */
@@ -87,10 +99,13 @@ export type ModuleChipOptions = {
87
99
  /**
88
100
  * @typedef {Object} ModuleChipOptions
89
101
  * @property {number|string} [size=24] Chip edge length.
90
- * @property {number|string} [iconSize='1em'] Glyph size; `1em` is 60% of the chip edge.
102
+ * @property {number|string} [iconSize='52%'] Glyph size relative to the tile edge.
91
103
  * @property {string|null} [label=null] Accessible label; null marks the chip decorative.
92
104
  * @property {boolean} [title=false] Adds the module's display name as a `title` tooltip.
93
105
  * @property {boolean} [standard=false] Use the stock Font Awesome fallback glyph.
106
+ * @property {string|Node|(()=>string|Node)|null} [icon] Explicit glyph override, useful for an offline fallback.
107
+ * @property {string} [color] Override the module colour for a server-defined fork or weblet.
108
+ * @property {false|'subtle'|'strong'} [glass='subtle'] AppIcon material treatment.
94
109
  * @property {string|string[]} [class] Extra class names.
95
110
  */
96
111
  /**
@@ -102,3 +117,10 @@ export type ModuleChipOptions = {
102
117
  * @returns {HTMLElement} A `<span class="zx-module-icon">` wrapping the glyph.
103
118
  */
104
119
  export declare function moduleChip(name: string, options?: ModuleChipOptions): HTMLElement;
120
+ /**
121
+ * Creates the public ZeyOS AppIcon preset for any module, entity, fork, or weblet identity.
122
+ * @param {string} name Module/entity identifier.
123
+ * @param {ModuleChipOptions} [options={}] AppIcon options.
124
+ * @returns {HTMLElement}
125
+ */
126
+ export declare function zeyosAppIcon(name: string, options?: ModuleChipOptions): HTMLElement;
@@ -6,7 +6,8 @@ export { fieldToZxField, fieldToZxColumn, resolveFields, registerFieldType } fro
6
6
  export { buildListQuery, tableSortToQuery, dataFilterStateToFilters, dateToUnixSeconds, unixSecondsToDate } from './query.js';
7
7
  export { connect } from './connect.js';
8
8
  export { zeyosModules, moduleAliases, moduleInfo, moduleColor, moduleIconName, moduleKeys, moduleGlyphColor, normalizeModuleName, registerModules } from './modules.js';
9
- export { ZEYOS_ICON_KIT, useZeyosIcons, moduleIcon, moduleChip } from './icons.js';
10
- export { zeyosSelect } from './select.js';
9
+ export { ZEYOS_ICON_KIT, useZeyosIcons, moduleIcon, moduleChip, zeyosAppIcon } from './icons.js';
10
+ export { ZEYOS_LAUNCHER_APPLICATIONS, buildZeyosLauncherConfig, zeyosLauncher, normalizeZeyosLauncherApplications, normalizeZeyosLauncherRecords, zeyosActiveIdentifier } from './launcher.js';
11
+ export { zeyosSelect, buildZeyosSelectConfig, zeyosEntitySelect, buildZeyosEntitySelectConfig } from './select.js';
11
12
  export { zeyosForm } from './form.js';
12
13
  export { zeyosTable } from './table.js';
@@ -0,0 +1,147 @@
1
+ import { Launcher } from '../components/launcher/launcher.js';
2
+ /** Static application identifiers present in the current ZeyOS shell prototype. */
3
+ export declare const ZEYOS_LAUNCHER_APPLICATIONS: readonly string[];
4
+ export type ZeyosLauncherState = {
5
+ /**
6
+ * Permitted module catalogue.
7
+ */
8
+ modules?: Record<string, string> | Array<string | Record<string, any>>;
9
+ /**
10
+ * Forks/weblets and authoritative menu entries.
11
+ */
12
+ menuApps?: Array<Array<any> | Record<string, any>>;
13
+ /**
14
+ * Application identifiers in pinned order.
15
+ */
16
+ pinned?: string[];
17
+ /**
18
+ * Recent records.
19
+ */
20
+ recent?: Array<Array<any> | Record<string, any>>;
21
+ /**
22
+ * Current module, `fork#…`, or `weblet#…` identifier.
23
+ */
24
+ activeIdentifier?: string | null;
25
+ /**
26
+ * Permission predicate.
27
+ */
28
+ canUseModule?: (module: string) => boolean;
29
+ /**
30
+ * Record search loader.
31
+ */
32
+ search?: (query: string, context: {
33
+ signal: AbortSignal;
34
+ }) => Promise<unknown> | unknown;
35
+ /**
36
+ * Recent-record loader.
37
+ */
38
+ loadRecent?: (context: {
39
+ signal: AbortSignal;
40
+ }) => Promise<unknown> | unknown;
41
+ /**
42
+ * Maps an app to href/invoke/value metadata.
43
+ */
44
+ resolveApplication?: (app: unknown) => Record<string, any> | null;
45
+ /**
46
+ * Maps a record to href/invoke/value metadata.
47
+ */
48
+ resolveRecord?: (record: unknown) => Record<string, any> | null;
49
+ /**
50
+ * Localized applications/recent/results/entity labels and hints.
51
+ */
52
+ labels?: Record<string, any>;
53
+ /**
54
+ * Host icon renderer for modules, forks, and weblets.
55
+ */
56
+ renderApplicationIcon?: (app: unknown, normalized: Record<string, any>) => Node | null;
57
+ /**
58
+ * Host record icon renderer.
59
+ */
60
+ renderRecordIcon?: (record: unknown, normalized: Record<string, any>) => Node | null;
61
+ /**
62
+ * Legacy weblet-only icon renderer.
63
+ */
64
+ renderWebletIcon?: (app: unknown, normalized: Record<string, any>) => Node | null;
65
+ };
66
+ export type ZeyosLauncherOptions = {
67
+ /**
68
+ * Use stock icon fallbacks instead of the optional ZeyOS kit.
69
+ */
70
+ standardIcons?: boolean;
71
+ /**
72
+ * Extra generic Launcher items.
73
+ */
74
+ items?: Array<Record<string, any>>;
75
+ /**
76
+ * Extra generic Launcher sources.
77
+ */
78
+ sources?: Array<Record<string, any>>;
79
+ };
80
+ /**
81
+ * @typedef {Object} ZeyosLauncherState
82
+ * @property {Record<string, string>|Array<string|Record<string, any>>} [modules={}] Permitted module catalogue.
83
+ * @property {Array<Array<any>|Record<string, any>>} [menuApps=[]] Forks/weblets and authoritative menu entries.
84
+ * @property {string[]} [pinned=[]] Application identifiers in pinned order.
85
+ * @property {Array<Array<any>|Record<string, any>>} [recent=[]] Recent records.
86
+ * @property {string|null} [activeIdentifier=null] Current module, `fork#…`, or `weblet#…` identifier.
87
+ * @property {(module: string) => boolean} [canUseModule] Permission predicate.
88
+ * @property {(query: string, context: {signal: AbortSignal}) => Promise<unknown>|unknown} [search] Record search loader.
89
+ * @property {(context: {signal: AbortSignal}) => Promise<unknown>|unknown} [loadRecent] Recent-record loader.
90
+ * @property {(app: unknown) => Record<string, any>|null} [resolveApplication] Maps an app to href/invoke/value metadata.
91
+ * @property {(record: unknown) => Record<string, any>|null} [resolveRecord] Maps a record to href/invoke/value metadata.
92
+ * @property {Record<string, any>} [labels] Localized applications/recent/results/entity labels and hints.
93
+ * @property {(app: unknown, normalized: Record<string, any>) => Node|null} [renderApplicationIcon] Host icon renderer for modules, forks, and weblets.
94
+ * @property {(record: unknown, normalized: Record<string, any>) => Node|null} [renderRecordIcon] Host record icon renderer.
95
+ * @property {(app: unknown, normalized: Record<string, any>) => Node|null} [renderWebletIcon] Legacy weblet-only icon renderer.
96
+ */
97
+ /**
98
+ * @typedef {Object} ZeyosLauncherOptions
99
+ * @property {boolean} [standardIcons=false] Use stock icon fallbacks instead of the optional ZeyOS kit.
100
+ * @property {Array<Record<string, any>>} [items] Extra generic Launcher items.
101
+ * @property {Array<Record<string, any>>} [sources] Extra generic Launcher sources.
102
+ */
103
+ /**
104
+ * Builds a generic Launcher configuration from explicitly injected ZeyOS shell state. It never
105
+ * reads PG/C globals and never resolves a route itself.
106
+ * @param {ZeyosLauncherState} [state={}] Application-owned shell state.
107
+ * @param {ZeyosLauncherOptions & Record<string, any>} [options={}] Adapter and Launcher options.
108
+ * @returns {Record<string, any>} Plain Launcher options.
109
+ */
110
+ export declare function buildZeyosLauncherConfig(state?: ZeyosLauncherState, options?: ZeyosLauncherOptions & Record<string, any>): Record<string, any>;
111
+ /**
112
+ * Creates the ZeyOS-configured Launcher. State and route resolvers remain caller-owned inputs.
113
+ * @param {ZeyosLauncherState} [state={}] Injected shell state.
114
+ * @param {ZeyosLauncherOptions & Record<string, any>} [options={}] Adapter and Launcher options.
115
+ * @returns {Launcher}
116
+ */
117
+ export declare function zeyosLauncher(state?: ZeyosLauncherState, options?: ZeyosLauncherOptions & Record<string, any>): Launcher;
118
+ /**
119
+ * Normalizes module, fork, and weblet applications while preserving menu authority and pin order.
120
+ * @param {ZeyosLauncherState} [state={}] Injected shell state.
121
+ * @param {{standardIcons?: boolean, renderApplicationIcon?: Function, renderWebletIcon?: Function}} [options={}] Icon options.
122
+ * @returns {Array<Record<string, any>>}
123
+ */
124
+ export declare function normalizeZeyosLauncherApplications(state?: ZeyosLauncherState, options?: {
125
+ standardIcons?: boolean;
126
+ renderApplicationIcon?: Function;
127
+ renderWebletIcon?: Function;
128
+ }): Array<Record<string, any>>;
129
+ /**
130
+ * Normalizes recent records or grouped search payloads without losing server/group order.
131
+ * @param {unknown} payload Recent/search payload.
132
+ * @param {{query?: string, labels?: Record<string, any>, resolveRecord?: Function, renderRecordIcon?: Function, standardIcons?: boolean}} [options={}] Mapping options.
133
+ * @returns {Array<Record<string, any>>}
134
+ */
135
+ export declare function normalizeZeyosLauncherRecords(payload: unknown, options?: {
136
+ query?: string;
137
+ labels?: Record<string, any>;
138
+ resolveRecord?: Function;
139
+ renderRecordIcon?: Function;
140
+ standardIcons?: boolean;
141
+ }): Array<Record<string, any>>;
142
+ /** @param {{module?: string, fork?: unknown, weblet?: unknown}} state @returns {string} */
143
+ export declare function zeyosActiveIdentifier(state?: {
144
+ module?: string;
145
+ fork?: unknown;
146
+ weblet?: unknown;
147
+ }): string;