@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
@@ -3,6 +3,7 @@ export type ActivityItemOptions = import('../activity-item/activity-item.js').Ac
3
3
  export type ActivityListContent = string | number | Node | Component | null;
4
4
  export type ActivityGroupReader = string | ((item: ActivityItemOptions, index: number) => unknown) | null;
5
5
  export type ActivityGroupLabel = (group: unknown, items: ActivityItemOptions[]) => ActivityListContent;
6
+ export type ActivityListVariant = 'default' | 'compact';
6
7
  export type ActivityGroup = {
7
8
  /**
8
9
  * Group identity returned by the configured reader.
@@ -30,6 +31,11 @@ export type ActivityListOptions = {
30
31
  * Accessible collection name.
31
32
  */
32
33
  label?: string;
34
+ /**
35
+ * Entry layout, reflected as `data-variant` on
36
+ * the root. `'compact'` also makes an avatar descriptor without a `size` small.
37
+ */
38
+ variant?: ActivityListVariant;
33
39
  /**
34
40
  * Whether initial or incremental activity is loading.
35
41
  */
@@ -62,6 +68,13 @@ export type ActivityListOptions = {
62
68
  /** @typedef {string|number|Node|Component|null} ActivityListContent */
63
69
  /** @typedef {string|((item:ActivityItemOptions,index:number)=>unknown)|null} ActivityGroupReader */
64
70
  /** @typedef {(group:unknown,items:ActivityItemOptions[])=>ActivityListContent} ActivityGroupLabel */
71
+ /**
72
+ * Entry layout. `'default'` gives each entry its avatar, a heading row, and room for content;
73
+ * below 30rem the time moves under the heading. `'compact'` is one line per entry at any width —
74
+ * actor and summary reading as one sentence, the time at the trailing end, a small avatar, and
75
+ * metadata as a muted second line — for a summary card narrower than 30rem.
76
+ * @typedef {'default'|'compact'} ActivityListVariant
77
+ */
65
78
  /**
66
79
  * @typedef {Object} ActivityGroup
67
80
  * @property {unknown} id Group identity returned by the configured reader.
@@ -73,6 +86,8 @@ export type ActivityListOptions = {
73
86
  * @property {ActivityGroupReader} [groupBy=null] Property or resolver used for stable grouping.
74
87
  * @property {ActivityGroupLabel|null} [groupLabel=null] Group-heading renderer.
75
88
  * @property {string} [label='Activity'] Accessible collection name.
89
+ * @property {ActivityListVariant} [variant='default'] Entry layout, reflected as `data-variant` on
90
+ * the root. `'compact'` also makes an avatar descriptor without a `size` small.
76
91
  * @property {boolean} [loading=false] Whether initial or incremental activity is loading.
77
92
  * @property {number} [loadingCount=3] Placeholder rows shown for an empty loading list.
78
93
  * @property {string} [loadingText='Loading activity'] Loading status text.
@@ -97,6 +112,7 @@ export declare class ActivityList extends Component<ActivityListOptions> {
97
112
  _loading: any;
98
113
  _itemComponents: any[];
99
114
  _groupSequence: number;
115
+ _variant: ActivityListVariant;
100
116
  static cssName: string;
101
117
  /** @type {Readonly<ActivityListOptions>} */
102
118
  static defaults: Readonly<ActivityListOptions>;
@@ -162,8 +178,16 @@ export declare class ActivityList extends Component<ActivityListOptions> {
162
178
  setLoading(loading: boolean): this;
163
179
  /** Restores an enhanced target exactly, or removes an owned list. @returns {void} */
164
180
  destroy(): void;
165
- /** @private @returns {void} */
181
+ /**
182
+ * Rebuilds the list. Items are regrouped on every mutation, so the rows are new; focus that sat
183
+ * on an item's control is put back on the same control of the same activity (matched by `id`,
184
+ * else by position), so a live feed prepending entries does not throw the reader to `<body>`.
185
+ * @private
186
+ * @returns {void}
187
+ */
166
188
  private _renderList;
189
+ /** @private @returns {void} */
190
+ private _renderItems;
167
191
  /** @private @param {ActivityGroup} group @param {boolean} grouped @returns {HTMLElement} */
168
192
  private _createGroup;
169
193
  /** @private @param {boolean} placeholders @returns {HTMLElement} */
@@ -188,6 +212,12 @@ export declare function groupActivityItems(items: ActivityItemOptions[], groupBy
188
212
  * @returns {ActivityItemOptions[]}
189
213
  */
190
214
  export declare function normalizeActivityItems(value: unknown): ActivityItemOptions[];
215
+ /**
216
+ * Resolves the entry layout; anything but `'compact'` is the default layout.
217
+ * @param {unknown} value Requested variant.
218
+ * @returns {ActivityListVariant}
219
+ */
220
+ export declare function normalizeActivityListVariant(value: unknown): ActivityListVariant;
191
221
  /**
192
222
  * Activity descriptors changed through a list mutation method.
193
223
  * @event ActivityList#datachange
@@ -1,13 +1,22 @@
1
1
  import { Component } from '../../core/component.js';
2
+ export type AppIconTone = 'blue' | 'teal' | 'green' | 'amber' | 'orange' | 'red' | 'pink' | 'violet' | 'slate';
3
+ /** @typedef {'blue'|'teal'|'green'|'amber'|'orange'|'red'|'pink'|'violet'|'slate'} AppIconTone */
4
+ /** The categorical tones a `tone` option accepts. @type {ReadonlyArray<AppIconTone>} */
5
+ export declare const APP_ICON_TONES: ReadonlyArray<AppIconTone>;
2
6
  export type AppIconOptions = {
3
7
  /**
4
8
  * Icon name, node, or lazy renderer.
5
9
  */
6
10
  icon?: string | Node | (() => string | Node) | null;
7
11
  /**
8
- * Identity colour; falls back to the accent colour.
12
+ * Identity colour, any CSS colour; takes precedence over `tone`.
9
13
  */
10
14
  color?: string | null;
15
+ /**
16
+ * Categorical identity colour from the theme's tone palette,
17
+ * drawn with its `--zx-color-tone-<tone>-solid` fill. Without `color` or `tone` the icon takes the accent.
18
+ */
19
+ tone?: AppIconTone | null;
11
20
  /**
12
21
  * Edge length in pixels or any CSS length.
13
22
  */
@@ -44,7 +53,9 @@ export type AppIconOptions = {
44
53
  /**
45
54
  * @typedef {Object} AppIconOptions
46
55
  * @property {string|Node|(()=>string|Node)|null} [icon=null] Icon name, node, or lazy renderer.
47
- * @property {string|null} [color=null] Identity colour; falls back to the accent colour.
56
+ * @property {string|null} [color=null] Identity colour, any CSS colour; takes precedence over `tone`.
57
+ * @property {AppIconTone|null} [tone=null] Categorical identity colour from the theme's tone palette,
58
+ * drawn with its `--zx-color-tone-<tone>-solid` fill. Without `color` or `tone` the icon takes the accent.
48
59
  * @property {number|string} [size=36] Edge length in pixels or any CSS length.
49
60
  * @property {number|string} [iconSize='52%'] Glyph size.
50
61
  * @property {string|null} [label=null] Accessible image label; null makes the icon decorative.
@@ -65,6 +76,7 @@ export declare class AppIcon extends Component<AppIconOptions> {
65
76
  _state: {
66
77
  icon?: string | Node | (() => string | Node) | null;
67
78
  color?: string | null;
79
+ tone?: AppIconTone | null;
68
80
  size?: number | string;
69
81
  iconSize?: number | string;
70
82
  label?: string | null;
@@ -1,12 +1,43 @@
1
1
  import { Component } from '../../core/component.js';
2
2
  import { AppRailPresenter as MinimizedPresenter } from '../../internal/app-rail.js';
3
+ import { ModuleBar } from '../module-bar/module-bar.js';
3
4
  export type AppNavItem = import('../../internal/app-rail.js').AppNavItem;
4
5
  export type AppNavSelectDetail = import('../../internal/app-rail.js').AppNavSelectDetail;
6
+ export type ModuleItem = import('../module-bar/module-bar.js').ModuleItem;
7
+ export type AppSidebarModule = ModuleItem & {
8
+ header?: Node | {
9
+ toElement: () => Node | null;
10
+ };
11
+ content?: Node | {
12
+ toElement: () => Node | null;
13
+ };
14
+ };
15
+ export type AppSidebarModuleBarOptions = {
16
+ /**
17
+ * Tile treatment.
18
+ */
19
+ appearance?: 'tint' | 'solid' | 'plain';
20
+ /**
21
+ * Module names on the strip: `'auto'`
22
+ * prints them beside the tiles while expanded and leaves the icons alone while collapsed;
23
+ * `'hidden'` keeps the icon strip beside the panel; `'below'` prints them under the tiles.
24
+ */
25
+ labels?: 'auto' | 'beside' | 'below' | 'hidden';
26
+ /**
27
+ * The "All modules" button.
28
+ */
29
+ allModules?: 'auto' | 'always' | 'never';
30
+ /**
31
+ * Strip accessible label; omitted resolves `moduleBar.label`.
32
+ */
33
+ label?: string | null;
34
+ };
5
35
  export type AppSidebarOptions = {
6
36
  /**
7
- * Application navigation tree.
37
+ * Application navigation tree; in the
38
+ * modules layout its top level is the modules.
8
39
  */
9
- items?: AppNavItem[];
40
+ items?: AppNavItem[] | AppSidebarModule[];
10
41
  /**
11
42
  * Active item id.
12
43
  */
@@ -31,12 +62,44 @@ export type AppSidebarOptions = {
31
62
  * Workspace edge occupied by navigation.
32
63
  */
33
64
  side?: 'left' | 'right' | 'top' | 'bottom';
65
+ /**
66
+ * `'modules'` draws the top level as a module strip
67
+ * beside a panel showing one module's menu; minimized, the strip remains and menus open as flyouts.
68
+ */
69
+ layout?: 'tree' | 'modules';
70
+ /**
71
+ * Modules layout: the module the panel shows first.
72
+ * Defaults to the module containing `active`, else the first module with a panel.
73
+ */
74
+ module?: string | number | null;
75
+ /**
76
+ * Modules layout: strip presentation.
77
+ */
78
+ moduleBar?: AppSidebarModuleBarOptions;
79
+ /**
80
+ * Modules layout: how much
81
+ * of the navigation shows — both menus expanded (module names beside the side menu), the module
82
+ * menu collapsed to icons beside the side menu, or both collapsed to the icon strip. Defaults
83
+ * to `collapsed` ? `'collapsed'` : `'expanded'`.
84
+ */
85
+ presentation?: 'expanded' | 'compact' | 'collapsed' | null;
86
+ /**
87
+ * Modules layout: the presentations offered, widest first.
88
+ */
89
+ presentations?: Array<'expanded' | 'compact' | 'collapsed'>;
90
+ /**
91
+ * Modules layout: whether the strip's foot carries the
92
+ * switch between presentations. Turn it off when the choice lives elsewhere — an account menu,
93
+ * through `presentationChoice()`.
94
+ */
95
+ presentationSwitch?: boolean;
34
96
  /**
35
97
  * Navigation accessible label.
36
98
  */
37
99
  label?: string;
38
100
  /**
39
- * Expanded header content.
101
+ * Expanded header content;
102
+ * in the modules layout, content above every module's menu.
40
103
  */
41
104
  header?: Node | string | number | {
42
105
  toElement: () => Node | null;
@@ -48,13 +111,15 @@ export type AppSidebarOptions = {
48
111
  toElement: () => Node | null;
49
112
  } | null;
50
113
  /**
51
- * Minimized leading content.
114
+ * Minimized leading content;
115
+ * in the modules layout, the strip's leading content in both states.
52
116
  */
53
117
  railHeader?: Node | string | number | {
54
118
  toElement: () => Node | null;
55
119
  } | null;
56
120
  /**
57
- * Minimized trailing content.
121
+ * Minimized trailing content;
122
+ * in the modules layout, the strip's trailing content in both states.
58
123
  */
59
124
  railFooter?: Node | string | number | {
60
125
  toElement: () => Node | null;
@@ -98,23 +163,71 @@ export type AppSidebarOptions = {
98
163
  id: string | number;
99
164
  open: boolean;
100
165
  }>) => void;
166
+ /**
167
+ * Preventable module-switch listener.
168
+ */
169
+ onmodulechange?: (event: CustomEvent<{
170
+ item: AppNavItem;
171
+ id: string | number;
172
+ previous: string | number | null;
173
+ }>) => void;
174
+ /**
175
+ * Presentation listener.
176
+ */
177
+ onpresentationchange?: (event: CustomEvent<{
178
+ presentation: 'expanded' | 'compact' | 'collapsed';
179
+ previous: 'expanded' | 'compact' | 'collapsed';
180
+ }>) => void;
101
181
  };
102
182
  /** @typedef {import('../../internal/app-rail.js').AppNavItem} AppNavItem */
103
183
  /** @typedef {import('../../internal/app-rail.js').AppNavSelectDetail} AppNavSelectDetail */
184
+ /** @typedef {import('../module-bar/module-bar.js').ModuleItem} ModuleItem */
185
+ /**
186
+ * A module in the modules layout: a `ModuleItem` whose panel may carry content of its own.
187
+ * @typedef {ModuleItem & {header?: Node|{toElement: () => Node|null}, content?: Node|{toElement: () => Node|null}}} AppSidebarModule
188
+ */
189
+ /**
190
+ * Presentation of the module strip in the modules layout.
191
+ * @typedef {Object} AppSidebarModuleBarOptions
192
+ * @property {'tint'|'solid'|'plain'} [appearance='tint'] Tile treatment.
193
+ * @property {'auto'|'beside'|'below'|'hidden'} [labels='auto'] Module names on the strip: `'auto'`
194
+ * prints them beside the tiles while expanded and leaves the icons alone while collapsed;
195
+ * `'hidden'` keeps the icon strip beside the panel; `'below'` prints them under the tiles.
196
+ * @property {'auto'|'always'|'never'} [allModules='auto'] The "All modules" button.
197
+ * @property {string|null} [label=null] Strip accessible label; omitted resolves `moduleBar.label`.
198
+ */
104
199
  /**
105
200
  * @typedef {Object} AppSidebarOptions
106
- * @property {AppNavItem[]} [items=[]] Application navigation tree.
201
+ * @property {AppNavItem[]|AppSidebarModule[]} [items=[]] Application navigation tree; in the
202
+ * modules layout its top level is the modules.
107
203
  * @property {string|number|null} [active=null] Active item id.
108
204
  * @property {Array<string|number>} [expanded=[]] Initially expanded branch ids.
109
205
  * @property {boolean} [collapsed=false] Whether the minimized presentation is shown.
110
206
  * @property {boolean} [collapsible=true] Whether vertical navigation exposes a mode toggle.
111
207
  * @property {'vertical'|'horizontal'} [orientation='vertical'] Navigation flow; horizontal is always minimized.
112
208
  * @property {'left'|'right'|'top'|'bottom'} [side='left'] Workspace edge occupied by navigation.
209
+ * @property {'tree'|'modules'} [layout='tree'] `'modules'` draws the top level as a module strip
210
+ * beside a panel showing one module's menu; minimized, the strip remains and menus open as flyouts.
211
+ * @property {string|number|null} [module=null] Modules layout: the module the panel shows first.
212
+ * Defaults to the module containing `active`, else the first module with a panel.
213
+ * @property {AppSidebarModuleBarOptions} [moduleBar={}] Modules layout: strip presentation.
214
+ * @property {'expanded'|'compact'|'collapsed'|null} [presentation=null] Modules layout: how much
215
+ * of the navigation shows — both menus expanded (module names beside the side menu), the module
216
+ * menu collapsed to icons beside the side menu, or both collapsed to the icon strip. Defaults
217
+ * to `collapsed` ? `'collapsed'` : `'expanded'`.
218
+ * @property {Array<'expanded'|'compact'|'collapsed'>} [presentations=['expanded','compact','collapsed']]
219
+ * Modules layout: the presentations offered, widest first.
220
+ * @property {boolean} [presentationSwitch=true] Modules layout: whether the strip's foot carries the
221
+ * switch between presentations. Turn it off when the choice lives elsewhere — an account menu,
222
+ * through `presentationChoice()`.
113
223
  * @property {string} [label='Applications'] Navigation accessible label.
114
- * @property {Node|string|number|{toElement: () => Node|null}|null} [header=null] Expanded header content.
224
+ * @property {Node|string|number|{toElement: () => Node|null}|null} [header=null] Expanded header content;
225
+ * in the modules layout, content above every module's menu.
115
226
  * @property {Node|string|number|{toElement: () => Node|null}|null} [footer=null] Expanded sticky footer content.
116
- * @property {Node|string|number|{toElement: () => Node|null}|null} [railHeader=null] Minimized leading content.
117
- * @property {Node|string|number|{toElement: () => Node|null}|null} [railFooter=null] Minimized trailing content.
227
+ * @property {Node|string|number|{toElement: () => Node|null}|null} [railHeader=null] Minimized leading content;
228
+ * in the modules layout, the strip's leading content in both states.
229
+ * @property {Node|string|number|{toElement: () => Node|null}|null} [railFooter=null] Minimized trailing content;
230
+ * in the modules layout, the strip's trailing content in both states.
118
231
  * @property {number} [openDelay=80] Minimized flyout hover-open delay.
119
232
  * @property {number} [closeDelay=160] Minimized flyout crossing grace.
120
233
  * @property {(item: AppNavItem, context: Record<string, any>) => Node|null} [renderIcon] Optional host icon renderer.
@@ -122,19 +235,24 @@ export type AppSidebarOptions = {
122
235
  * @property {(event: CustomEvent<{item: AppNavItem|null, id: string|number|null, expanded: boolean|null, ids: Array<string|number>}>) => void} [onbranchchange] Branch-state listener.
123
236
  * @property {(event: CustomEvent<{collapsed: boolean}>) => void} [oncollapsechange] Presentation-state listener.
124
237
  * @property {(event: CustomEvent<{item: AppNavItem, id: string|number, open: boolean}>) => void} [onflyoutchange] Minimized flyout-state listener.
238
+ * @property {(event: CustomEvent<{item: AppNavItem, id: string|number, previous: string|number|null}>) => void} [onmodulechange] Preventable module-switch listener.
239
+ * @property {(event: CustomEvent<{presentation: 'expanded'|'compact'|'collapsed', previous: 'expanded'|'compact'|'collapsed'}>) => void} [onpresentationchange] Presentation listener.
125
240
  */
126
241
  /**
127
242
  * One application navigation component. Vertical expanded descendants render inline; minimized
128
- * vertical and horizontal descendants use pointer-, focus-, and keyboard-accessible flyouts.
243
+ * vertical and horizontal descendants use pointer-, focus-, and keyboard-accessible flyouts. The
244
+ * modules layout puts a `ModuleBar` of the top level beside a panel with the current module's menu.
129
245
  * @fires AppSidebar#select
130
246
  * @fires AppSidebar#branchchange
131
247
  * @fires AppSidebar#collapsechange
132
248
  * @fires AppSidebar#flyoutchange
249
+ * @fires AppSidebar#modulechange
250
+ * @fires AppSidebar#presentationchange
133
251
  * @extends {Component<AppSidebarOptions>}
134
252
  */
135
253
  export declare class AppSidebar extends Component<AppSidebarOptions> {
136
- _rail: MinimizedPresenter;
137
- _railExpandButton: HTMLElement;
254
+ _rail: MinimizedPresenter | ModuleBar;
255
+ _railExpandButton: HTMLButtonElement | HTMLElement;
138
256
  _createdRoot: boolean;
139
257
  _original: {
140
258
  attributes: string[][];
@@ -146,6 +264,12 @@ export declare class AppSidebar extends Component<AppSidebarOptions> {
146
264
  _collapsed: boolean;
147
265
  _orientation: any;
148
266
  _side: "bottom" | "left" | "right" | "top";
267
+ _modules: boolean;
268
+ _moduleLabels: "auto" | "below" | "beside" | "hidden";
269
+ _compact: boolean;
270
+ _presentationGroup: HTMLElement;
271
+ _stripTooltips: any[];
272
+ _shownId: string | number;
149
273
  _modeAbort: AbortController;
150
274
  static cssName: string;
151
275
  /** @type {Readonly<AppSidebarOptions>} */
@@ -160,10 +284,62 @@ export declare class AppSidebar extends Component<AppSidebarOptions> {
160
284
  render(): HTMLElement;
161
285
  /** Replaces the navigation tree in the active presentation. @param {AppNavItem[]} items @returns {this} */
162
286
  setItems(items: AppNavItem[]): this;
163
- /** Returns a shallow copy of normalized items. @returns {AppNavItem[]} */
287
+ /**
288
+ * Returns a copy of the normalized items. A leaf has no `children` property, as it was written,
289
+ * rather than the empty list normalization gives it.
290
+ * @returns {AppNavItem[]}
291
+ */
164
292
  getItems(): AppNavItem[];
165
- /** Sets the active id without routing. @param {string|number|null} id @returns {this} */
293
+ /**
294
+ * Sets the active id without routing. In the modules layout the panel follows the active route
295
+ * into its module.
296
+ * @param {string|number|null} id
297
+ * @returns {this}
298
+ */
166
299
  setActive(id: string | number | null): this;
300
+ /**
301
+ * Updates one badge — a module's, or any destination's — without rebuilding the navigation.
302
+ * @param {string|number} id Item id.
303
+ * @param {string|number|null} badge New badge; null removes it.
304
+ * @returns {this}
305
+ */
306
+ setBadge(id: string | number, badge: string | number | null): this;
307
+ /**
308
+ * Modules layout: shows a module's menu in the panel. Fires a preventable `modulechange` unless silent.
309
+ * @param {string|number} id Module id.
310
+ * @param {{silent?: boolean}} [options={}]
311
+ * @returns {this}
312
+ */
313
+ setModule(id: string | number, { silent }?: {
314
+ silent?: boolean;
315
+ }): this;
316
+ /** Modules layout: the module whose menu the panel shows. @returns {string|number|null} */
317
+ getModule(): string | number | null;
318
+ /**
319
+ * Modules layout: whether the strip prints module names — `'auto'` (beside the tiles while
320
+ * expanded, none while collapsed), `'beside'`, `'below'`, or `'hidden'`. A narrow drawer that
321
+ * has no room for a labelled strip beside the panel sets `'hidden'`.
322
+ * @param {'auto'|'beside'|'below'|'hidden'} labels
323
+ * @returns {this}
324
+ */
325
+ setModuleLabels(labels: 'auto' | 'beside' | 'below' | 'hidden'): this;
326
+ /**
327
+ * How much of the navigation shows: `'expanded'` (in the modules layout, both menus),
328
+ * `'compact'` (the module menu collapsed to icons beside the side menu), or `'collapsed'`.
329
+ * @returns {'expanded'|'compact'|'collapsed'}
330
+ */
331
+ getPresentation(): 'expanded' | 'compact' | 'collapsed';
332
+ /**
333
+ * Shows the navigation as `'expanded'`, `'compact'` (modules layout), or `'collapsed'`.
334
+ * @param {'expanded'|'compact'|'collapsed'} presentation
335
+ * @param {{silent?: boolean}} [options={}]
336
+ * @returns {this}
337
+ */
338
+ setPresentation(presentation: 'expanded' | 'compact' | 'collapsed', { silent }?: {
339
+ silent?: boolean;
340
+ }): this;
341
+ /** Moves to the next presentation the strip's switch offers, wrapping (Mod+B in an application). @returns {this} */
342
+ togglePresentation(): this;
167
343
  /** Replaces expanded branch ids. @param {Array<string|number>} ids @param {{silent?: boolean}} [options={}] @returns {this} */
168
344
  setExpanded(ids: Array<string | number>, { silent }?: {
169
345
  silent?: boolean;
@@ -186,6 +362,17 @@ export declare class AppSidebar extends Component<AppSidebarOptions> {
186
362
  setCollapsed(collapsed: boolean, { silent }?: {
187
363
  silent?: boolean;
188
364
  }): this;
365
+ /**
366
+ * Applies a collapsed state and, in the modules layout, whether the module menu is collapsed
367
+ * beside an expanded side menu; reports what changed.
368
+ * @param {boolean} collapsed
369
+ * @param {boolean} compact
370
+ * @param {{silent?: boolean}} options
371
+ * @returns {this}
372
+ */
373
+ _present(collapsed: boolean, compact: boolean, { silent }: {
374
+ silent?: boolean;
375
+ }): this;
189
376
  /** Reports the effective presentation state; horizontal navigation is always minimized. @returns {boolean} */
190
377
  isCollapsed(): boolean;
191
378
  /**
@@ -210,7 +397,7 @@ export declare class AppSidebar extends Component<AppSidebarOptions> {
210
397
  closeAllFlyouts(): this;
211
398
  /** Reports whether a minimized flyout is open. @param {string|number} id @returns {boolean} */
212
399
  isFlyoutOpen(id: string | number): boolean;
213
- /** Focuses the first navigation action. @returns {this} */
400
+ /** Focuses the first navigation action: the module strip's Tab stop in the modules layout. @returns {this} */
214
401
  focus(): this;
215
402
  /** Destroys flyouts and restores/removes the host. @returns {void} */
216
403
  destroy(): void;
@@ -218,8 +405,81 @@ export declare class AppSidebar extends Component<AppSidebarOptions> {
218
405
  _renderMode(): void;
219
406
  /** @returns {void} */
220
407
  _renderExpanded(): void;
408
+ /** @returns {HTMLButtonElement} The minimize control of an expanded presentation. */
409
+ _collapseButton(): HTMLButtonElement;
410
+ /** @returns {HTMLButtonElement} The expand control at the head of a minimized vertical rail. */
411
+ _expandButton(): HTMLButtonElement;
412
+ /** @param {HTMLElement} list @returns {void} */
413
+ _listenTree(list: HTMLElement): void;
221
414
  /** @returns {void} */
222
415
  _renderRail(): void;
416
+ /**
417
+ * The modules layout. Expanded, the strip leaves module menus to the panel beside it; minimized
418
+ * or horizontal, the strip is the whole navigation and menus open as flyouts.
419
+ * @returns {void}
420
+ */
421
+ _renderModules(): void;
422
+ /**
423
+ * The modules layout's switch between its presentations: an APG radio group of one small
424
+ * pictogram per presentation — both menus, the side menu beside module icons, the icons alone.
425
+ * Its checked option is also the collapse control while expanded and the expand control while
426
+ * collapsed, so focus lands on the checked option of its successor across a re-render.
427
+ * @param {boolean} expanded Whether the side menu shows.
428
+ * @returns {HTMLElement}
429
+ */
430
+ _presentationSwitch(expanded: boolean): HTMLElement;
431
+ /**
432
+ * The choice between presentations as a menu entry, for an account or settings menu that holds
433
+ * it instead of the strip: `account.setItems([sidebar.presentationChoice(), …])`. It reads the
434
+ * current presentation when called, so rebuild it after `presentationchange`.
435
+ * @param {{label?: string}} [options={}] Row label; omitted resolves `appSidebar.presentation`.
436
+ * @returns {import('../../internal/menu-items.js').MenuChoice}
437
+ */
438
+ presentationChoice({ label }?: {
439
+ label?: string;
440
+ }): import('../../internal/menu-items.js').MenuChoice;
441
+ /** @returns {Record<'expanded'|'compact'|'collapsed', string>} */
442
+ _presentationLabels(): Record<'expanded' | 'compact' | 'collapsed', string>;
443
+ /** Arrow keys move through the presentations and choose as they go, as in any radio group. @param {KeyboardEvent} event @returns {void} */
444
+ _onPresentationKeydown(event: KeyboardEvent): void;
445
+ /** Checks the current presentation's option and makes it the group's one Tab stop. @returns {void} */
446
+ _syncPresentationSwitch(): void;
447
+ /** @returns {Array<'expanded'|'compact'|'collapsed'>} The presentations the switch offers, widest first. */
448
+ _presentationCycle(): Array<'expanded' | 'compact' | 'collapsed'>;
449
+ /** @returns {'expanded'|'compact'|'collapsed'} */
450
+ _nextPresentation(): 'expanded' | 'compact' | 'collapsed';
451
+ /**
452
+ * What the strip prints for the current state: `'auto'` names the modules beside their tiles
453
+ * while expanded and leaves the icons alone while collapsed.
454
+ * @returns {'hidden'|'below'|'beside'}
455
+ */
456
+ _stripLabels(): 'hidden' | 'below' | 'beside';
457
+ /** @returns {AppSidebarModule[]} The modules, read through any sections that group them. */
458
+ _moduleList(): AppSidebarModule[];
459
+ /** @param {string} panelId @returns {HTMLElement} */
460
+ _renderPanel(panelId: string): HTMLElement;
461
+ /** Puts the shown module's title, header, menu, and content into the panel. @returns {void} */
462
+ _renderPanelContent(): void;
463
+ /**
464
+ * Shows a module's panel. Returns false when there is no such panel module or a listener
465
+ * prevented the switch.
466
+ * @param {string|number} id Module id.
467
+ * @param {{silent?: boolean}} [options={}]
468
+ * @returns {boolean}
469
+ */
470
+ _showModule(id: string | number, { silent }?: {
471
+ silent?: boolean;
472
+ }): boolean;
473
+ /** @param {CustomEvent<AppNavSelectDetail>} event @param {boolean} expanded @returns {void} */
474
+ _onModuleSelect(event: CustomEvent<AppNavSelectDetail>, expanded: boolean): void;
475
+ /** The arrow toward the panel shows a module's menu and moves into it. @param {KeyboardEvent} event @returns {void} */
476
+ _onStripKeydown(event: KeyboardEvent): void;
477
+ /** @returns {AppSidebarModule|null} */
478
+ _shownModule(): AppSidebarModule | null;
479
+ /** @param {string|number|null|undefined} preferred @returns {string|number|null} */
480
+ _resolveShown(preferred: string | number | null | undefined): string | number | null;
481
+ /** @returns {AppNavItem[]} The items the tree draws: the shown module's menu in the modules layout. */
482
+ _treeItems(): AppNavItem[];
223
483
  /**
224
484
  * Keeps a minimized rail's counts readable and audible.
225
485
  *
@@ -236,6 +496,14 @@ export declare class AppSidebar extends Component<AppSidebarOptions> {
236
496
  _renderTree(): void;
237
497
  /** @param {AppNavItem} item @param {number} level @returns {HTMLElement} */
238
498
  _treeRow(item: AppNavItem, level: number): HTMLElement;
499
+ /**
500
+ * A section: a heading over rows that stay at its own level. It names its list, so a screen
501
+ * reader hears "Records, list, 3 items" rather than a heading floating above unrelated rows.
502
+ * @param {AppNavItem} item Section.
503
+ * @param {number} level Level its rows take.
504
+ * @returns {HTMLElement}
505
+ */
506
+ _sectionRow(item: AppNavItem, level: number): HTMLElement;
239
507
  /** @param {Event} event @returns {void} */
240
508
  _onTreeClick(event: Event): void;
241
509
  /** @param {KeyboardEvent} event @returns {void} */
@@ -265,7 +533,15 @@ export declare class AppSidebar extends Component<AppSidebarOptions> {
265
533
  /** @returns {void} */
266
534
  _reconcileExpanded(): void;
267
535
  }
268
- /** Fired when a destination/action is activated. @event AppSidebar#select @type {CustomEvent<AppNavSelectDetail>} */
269
- /** Fired when an inline branch changes. @event AppSidebar#branchchange @type {CustomEvent<{item: AppNavItem|null, id: string|number|null, expanded: boolean|null, ids: Array<string|number>}>} */
536
+ /**
537
+ * The pictogram of a presentation: a small window with its navigation drawn in it — the module
538
+ * strip, wide when it is named, and the side menu when it shows. Built from boxes in the text
539
+ * colour, so it follows the theme and forced colours and needs no icon set. Decorative.
540
+ * @param {'expanded'|'compact'|'collapsed'} presentation
541
+ * @returns {HTMLElement}
542
+ */
543
+ export declare function presentationGlyph(presentation: 'expanded' | 'compact' | 'collapsed'): HTMLElement;
270
544
  /** Fired when expanded/minimized presentation changes. @event AppSidebar#collapsechange @type {CustomEvent<{collapsed: boolean}>} */
271
545
  /** Fired when a minimized flyout changes. @event AppSidebar#flyoutchange @type {CustomEvent<{item: AppNavItem, id: string|number, open: boolean}>} */
546
+ /** Fired when how much of the navigation shows changes. @event AppSidebar#presentationchange @type {CustomEvent<{presentation: 'expanded'|'compact'|'collapsed', previous: 'expanded'|'compact'|'collapsed'}>} */
547
+ /** Fired before the modules layout's panel switches to another module; preventable. @event AppSidebar#modulechange @type {CustomEvent<{item: AppNavItem, id: string|number, previous: string|number|null}>} */
@@ -1,11 +1,12 @@
1
1
  import { Component } from '../../core/component.js';
2
+ export type AvatarTone = 'blue' | 'teal' | 'green' | 'amber' | 'orange' | 'red' | 'pink' | 'violet' | 'slate';
2
3
  export type AvatarOptions = {
3
4
  /**
4
5
  * Image URL.
5
6
  */
6
7
  src?: string | null;
7
8
  /**
8
- * Name used to derive fallback initials.
9
+ * Name used to derive the fallback initials and tone.
9
10
  */
10
11
  name?: string;
11
12
  /**
@@ -17,13 +18,20 @@ export type AvatarOptions = {
17
18
  */
18
19
  label?: string | null;
19
20
  /**
20
- * Preset (`sm`, `md`, `lg`) or pixel size.
21
+ * Preset — `sm` 24px, `md` 32px, `lg` 40px at the default
22
+ * spacing unit — or a pixel size. Below 24px the fallback shows a single initial.
21
23
  */
22
24
  size?: string | number;
23
25
  /**
24
26
  * Avatar shape.
25
27
  */
26
28
  shape?: 'circle' | 'rounded' | 'square';
29
+ /**
30
+ * Fallback colour from the tone palette. `null` derives a
31
+ * stable tone from the name (or the initials when there is no name), so the same person gets the
32
+ * same colour on every screen; see {@link avatarTone}.
33
+ */
34
+ tone?: AvatarTone | null;
27
35
  /**
28
36
  * Optional presence state.
29
37
  */
@@ -33,19 +41,35 @@ export type AvatarOptions = {
33
41
  */
34
42
  statusLabel?: string | null;
35
43
  };
44
+ /**
45
+ * A categorical tone from the design system's tone palette (`--zx-color-tone-*`).
46
+ * @typedef {'blue'|'teal'|'green'|'amber'|'orange'|'red'|'pink'|'violet'|'slate'} AvatarTone
47
+ */
36
48
  /**
37
49
  * @typedef {Object} AvatarOptions
38
50
  * @property {string|null} [src=null] Image URL.
39
- * @property {string} [name=''] Name used to derive fallback initials.
51
+ * @property {string} [name=''] Name used to derive the fallback initials and tone.
40
52
  * @property {string|null} [initials=null] Explicit fallback initials.
41
53
  * @property {string|null} [label=null] Accessible label; null makes the avatar decorative.
42
- * @property {string|number} [size='md'] Preset (`sm`, `md`, `lg`) or pixel size.
54
+ * @property {string|number} [size='md'] Preset — `sm` 24px, `md` 32px, `lg` 40px at the default
55
+ * spacing unit — or a pixel size. Below 24px the fallback shows a single initial.
43
56
  * @property {'circle'|'rounded'|'square'} [shape='circle'] Avatar shape.
57
+ * @property {AvatarTone|null} [tone=null] Fallback colour from the tone palette. `null` derives a
58
+ * stable tone from the name (or the initials when there is no name), so the same person gets the
59
+ * same colour on every screen; see {@link avatarTone}.
44
60
  * @property {'online'|'away'|'busy'|'offline'|null} [status=null] Optional presence state.
45
61
  * @property {string|null} [statusLabel=null] Text alternative for the presence state.
46
62
  */
47
63
  /**
48
- * Stable-size user image with deterministic initials fallback and optional presence state.
64
+ * The tone palette, in hash order. Every entry is a valid `tone`; the hash picks among the
65
+ * chromatic ones and keeps `slate`, the neutral, for a fallback with no name behind it. Order is
66
+ * part of the contract: changing it moves every derived avatar to a different colour.
67
+ * @type {ReadonlyArray<AvatarTone>}
68
+ */
69
+ export declare const AVATAR_TONES: ReadonlyArray<AvatarTone>;
70
+ /**
71
+ * Stable-size user image with a deterministic fallback — initials on a tone picked from the name —
72
+ * and an optional presence state.
49
73
  * @extends {Component<AvatarOptions>}
50
74
  */
51
75
  export declare class Avatar extends Component<AvatarOptions> {
@@ -61,6 +85,7 @@ export declare class Avatar extends Component<AvatarOptions> {
61
85
  label: string;
62
86
  size: string | number;
63
87
  shape: "circle" | "rounded" | "square";
88
+ tone: AvatarTone;
64
89
  status: "away" | "busy" | "offline" | "online";
65
90
  statusLabel: string;
66
91
  };
@@ -93,8 +118,22 @@ export declare class Avatar extends Component<AvatarOptions> {
93
118
  _syncStatus(): void;
94
119
  }
95
120
  /**
96
- * Derives at most two uppercase initials from the first and last words of a name.
121
+ * Derives uppercase initials from the first and last words of a name.
97
122
  * @param {unknown} name Name-like value.
123
+ * @param {1|2} [limit=2] How many initials to return: two by default, one for an avatar too small
124
+ * to hold two legibly.
98
125
  * @returns {string}
99
126
  */
100
- export declare function avatarInitials(name: unknown): string;
127
+ export declare function avatarInitials(name: unknown, limit?: 1 | 2): string;
128
+ /**
129
+ * Picks a stable fallback tone for a name.
130
+ *
131
+ * The name is trimmed, NFC-normalised and lower-cased, then hashed with 32-bit FNV-1a over its
132
+ * UTF-16 code units, and the hash picks one of the eight chromatic tones of {@link AVATAR_TONES}.
133
+ * The result depends on nothing but the name — not the locale, the page, or the order avatars
134
+ * render in — so a person keeps their colour everywhere. An empty name is `slate`, the neutral
135
+ * tone, which no name hashes to.
136
+ * @param {unknown} name Name-like value.
137
+ * @returns {AvatarTone}
138
+ */
139
+ export declare function avatarTone(name: unknown): AvatarTone;