@meshmakers/shared-ui 3.4.1480 → 3.5.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 (56) hide show
  1. package/README.md +48 -0
  2. package/assets/octobot/lg/octo_blink.webp +0 -0
  3. package/assets/octobot/lg/octo_blink_still.png +0 -0
  4. package/assets/octobot/lg/octo_idle.webp +0 -0
  5. package/assets/octobot/lg/octo_idle_still.png +0 -0
  6. package/assets/octobot/lg/octo_look.webp +0 -0
  7. package/assets/octobot/lg/octo_look_still.png +0 -0
  8. package/assets/octobot/lg/octo_swim.webp +0 -0
  9. package/assets/octobot/lg/octo_swim_still.png +0 -0
  10. package/assets/octobot/lg/octo_thinking.webp +0 -0
  11. package/assets/octobot/lg/octo_thinking_still.png +0 -0
  12. package/assets/octobot/lg/octo_wave.webp +0 -0
  13. package/assets/octobot/lg/octo_wave_still.png +0 -0
  14. package/assets/octobot/md/octo_blink.webp +0 -0
  15. package/assets/octobot/md/octo_blink_still.png +0 -0
  16. package/assets/octobot/md/octo_idle.webp +0 -0
  17. package/assets/octobot/md/octo_idle_still.png +0 -0
  18. package/assets/octobot/md/octo_look.webp +0 -0
  19. package/assets/octobot/md/octo_look_still.png +0 -0
  20. package/assets/octobot/md/octo_swim.webp +0 -0
  21. package/assets/octobot/md/octo_swim_still.png +0 -0
  22. package/assets/octobot/md/octo_thinking.webp +0 -0
  23. package/assets/octobot/md/octo_thinking_still.png +0 -0
  24. package/assets/octobot/md/octo_wave.webp +0 -0
  25. package/assets/octobot/md/octo_wave_still.png +0 -0
  26. package/assets/octobot/sm/octo_blink.webp +0 -0
  27. package/assets/octobot/sm/octo_blink_still.png +0 -0
  28. package/assets/octobot/sm/octo_idle.webp +0 -0
  29. package/assets/octobot/sm/octo_idle_still.png +0 -0
  30. package/assets/octobot/sm/octo_look.webp +0 -0
  31. package/assets/octobot/sm/octo_look_still.png +0 -0
  32. package/assets/octobot/sm/octo_swim.webp +0 -0
  33. package/assets/octobot/sm/octo_swim_still.png +0 -0
  34. package/assets/octobot/sm/octo_thinking.webp +0 -0
  35. package/assets/octobot/sm/octo_thinking_still.png +0 -0
  36. package/assets/octobot/sm/octo_wave.webp +0 -0
  37. package/assets/octobot/sm/octo_wave_still.png +0 -0
  38. package/fesm2022/meshmakers-shared-ui-assistant-core.mjs +940 -0
  39. package/fesm2022/meshmakers-shared-ui-assistant-core.mjs.map +1 -0
  40. package/fesm2022/meshmakers-shared-ui-assistant.mjs +819 -0
  41. package/fesm2022/meshmakers-shared-ui-assistant.mjs.map +1 -0
  42. package/fesm2022/meshmakers-shared-ui-command-palette.mjs +817 -0
  43. package/fesm2022/meshmakers-shared-ui-command-palette.mjs.map +1 -0
  44. package/fesm2022/meshmakers-shared-ui-shell.mjs +1738 -0
  45. package/fesm2022/meshmakers-shared-ui-shell.mjs.map +1 -0
  46. package/fesm2022/meshmakers-shared-ui-testing.mjs +92 -0
  47. package/fesm2022/meshmakers-shared-ui-testing.mjs.map +1 -0
  48. package/fesm2022/meshmakers-shared-ui.mjs +1550 -203
  49. package/fesm2022/meshmakers-shared-ui.mjs.map +1 -1
  50. package/package.json +28 -2
  51. package/types/meshmakers-shared-ui-assistant-core.d.ts +732 -0
  52. package/types/meshmakers-shared-ui-assistant.d.ts +258 -0
  53. package/types/meshmakers-shared-ui-command-palette.d.ts +398 -0
  54. package/types/meshmakers-shared-ui-shell.d.ts +939 -0
  55. package/types/meshmakers-shared-ui-testing.d.ts +41 -0
  56. package/types/meshmakers-shared-ui.d.ts +1004 -154
@@ -0,0 +1,939 @@
1
+ import * as _angular_core from '@angular/core';
2
+ import { InjectionToken, TemplateRef } from '@angular/core';
3
+ import { ActivatedRouteSnapshot } from '@angular/router';
4
+ import { DrawerItem } from '@progress/kendo-angular-layout';
5
+ import { SVGIcon } from '@progress/kendo-svg-icons';
6
+ import { Observable } from 'rxjs';
7
+ import { BreadCrumbData } from '@meshmakers/shared-services';
8
+ import { NotificationDisplayOptions } from '@meshmakers/shared-ui';
9
+
10
+ /**
11
+ * UI strings of the shell building blocks (`mm-shell-rail`, `mm-space-shell`,
12
+ * `mm-settings-side-nav`, `mm-shell-top-bar`, `mm-shell-user-menu`) and of the
13
+ * pure helpers (greeting, environment chip).
14
+ *
15
+ * Hosts translate them in two ways, which can be combined:
16
+ * - app wide: `{ provide: SHELL_MESSAGES, useValue: { signIn: 'Anmelden', … } }`;
17
+ * - per component: the `messages` input (wins over the token).
18
+ *
19
+ * Missing, `undefined` or `null` members keep the English default of
20
+ * {@link DEFAULT_SHELL_MESSAGES}. Strings with `{name}` placeholders are filled with
21
+ * {@link formatShellMessage}.
22
+ */
23
+ interface ShellMessages {
24
+ /** Screen-reader text after an external link marker (↗). */
25
+ opensInNewTab: string;
26
+ /** `aria-label` of the rail navigation. */
27
+ railLabel: string;
28
+ /** Accessible text of a navigation badge without its own label; `{count}` = the count. */
29
+ navBadge: string;
30
+ /** `aria-label` of a rail icon with a badge; `{label}` = area name, `{badge}` = badge text. */
31
+ navItemWithBadge: string;
32
+ /** `aria-label` of the back link on object detail pages; `{target}` = list name. */
33
+ backTo: string;
34
+ /** `aria-label` of the status chip list. */
35
+ statusChips: string;
36
+ /** `aria-label` of the tab strip; `{area}` = area name. */
37
+ areaPages: string;
38
+ /** `aria-label` of the side navigation; `{area}` = area name. */
39
+ areaCategories: string;
40
+ /** The "home" entry of the side navigation; `{area}` = area name as given (not re-cased, AB#5621). */
41
+ allOfArea: string;
42
+ /** `aria-label` of the mode switch group. */
43
+ modeSwitch: string;
44
+ /** `aria-label` of the search trigger. */
45
+ searchAriaLabel: string;
46
+ /** Visible text of the search trigger. */
47
+ search: string;
48
+ /** Visible text of the assistant toggle. */
49
+ assistant: string;
50
+ signIn: string;
51
+ signOut: string;
52
+ /** Title (`aria-label`) of the account panel. */
53
+ accountAndPreferences: string;
54
+ /** `aria-label` of the avatar button for a known user; `{name}` = display name. */
55
+ accountAndPreferencesOf: string;
56
+ theme: string;
57
+ themeSystem: string;
58
+ themeLight: string;
59
+ themeDark: string;
60
+ density: string;
61
+ language: string;
62
+ manageProfile: string;
63
+ /** Version line; `{version}` = version string. */
64
+ version: string;
65
+ environmentProduction: string;
66
+ environmentProductionShort: string;
67
+ environmentStaging: string;
68
+ environmentStagingShort: string;
69
+ environmentDevelopment: string;
70
+ environmentDevelopmentShort: string;
71
+ environmentTesting: string;
72
+ environmentTestingShort: string;
73
+ environmentUnknown: string;
74
+ environmentUnknownShort: string;
75
+ greetingMorning: string;
76
+ greetingAfternoon: string;
77
+ greetingEvening: string;
78
+ /** Greeting with a name; `{greeting}` = phrase, `{name}` = first name. */
79
+ greetingWithName: string;
80
+ /** Meta line label of the tenant. */
81
+ tenant: string;
82
+ }
83
+ /** English defaults of {@link ShellMessages}. */
84
+ declare const DEFAULT_SHELL_MESSAGES: ShellMessages;
85
+ /**
86
+ * App-wide translations of the shell. Partial: members left out keep their English default.
87
+ */
88
+ declare const SHELL_MESSAGES: InjectionToken<Partial<ShellMessages>>;
89
+ /**
90
+ * Merges message overrides over {@link DEFAULT_SHELL_MESSAGES}, later sources winning.
91
+ * Members that are missing, `undefined` or `null` keep the earlier value, so a host compiled
92
+ * against an older `ShellMessages` shape never renders an empty label.
93
+ */
94
+ declare function resolveShellMessages(...overrides: (Partial<ShellMessages> | null | undefined)[]): ShellMessages;
95
+ /** Replaces `{name}` placeholders; unknown placeholders stay as they are. */
96
+ declare function formatShellMessage(message: string, values: Record<string, string | number>): string;
97
+
98
+ /** Id of the separator in front of the rail's bottom block (Settings). */
99
+ declare const RAIL_BOTTOM_SEPARATOR_ID = "rail-bottom";
100
+ declare function areaId(space: string): string;
101
+ /** The space of an area id (`area-data` → `data`), or null for any other id. */
102
+ declare function spaceOfAreaId(id: string): string | null;
103
+ declare function tabId(space: string, tab: string): string;
104
+ /**
105
+ * The space whose pages use the settings side navigation (`mm-settings-side-nav`) instead
106
+ * of the tab strip. Default `'settings'` (area id `area-settings`); provide `null` for a
107
+ * host without a settings space.
108
+ */
109
+ declare const SHELL_SETTINGS_SPACE: InjectionToken<string | null>;
110
+
111
+ /**
112
+ * One entry of the shell navigation: a rail area, a tab, or an entry nested
113
+ * below a tab (flyout only). Built from the CommandService's visible items.
114
+ */
115
+ interface ShellNavNode {
116
+ id: string;
117
+ text: string;
118
+ svgIcon?: SVGIcon;
119
+ tooltip?: string;
120
+ separator: boolean;
121
+ /** The CommandService highlights exactly this entry (longest link match on the URL). */
122
+ selected: boolean;
123
+ /** This entry or one below it is selected. */
124
+ active: boolean;
125
+ /** Opening it navigates (router link or external href); otherwise it only groups entries. */
126
+ navigable: boolean;
127
+ /** Opens in a new browser tab. */
128
+ external: boolean;
129
+ children: ShellNavNode[];
130
+ /**
131
+ * Optional count shown as a badge on the rail icon / flyout entry (AB#5621); 0 or none shows
132
+ * nothing. The rail's `badges` input wins over it. Not set by {@link ShellNavigationService}.
133
+ */
134
+ badgeCount?: number;
135
+ }
136
+ /** `space` / `tab` / `objectDetail` route data, merged from the root to the deepest active route. */
137
+ interface ShellRouteData {
138
+ space?: string;
139
+ tab?: string;
140
+ /**
141
+ * The page is the detail page of one object (AB#5547): its own object header (name, chips,
142
+ * actions, object tabs) replaces the area title and tab strip of the space header. Set by
143
+ * `data: { objectDetail: true }` on any route of the chain.
144
+ */
145
+ objectDetail?: boolean;
146
+ /**
147
+ * `data: { spaceTabs: false }`: the page brings its own navigation for the area's entries, so
148
+ * the space header leaves its tab strip out instead of showing the same entries twice.
149
+ * (Settings needs no flag: its side navigation replaces the tab strip on every page.)
150
+ */
151
+ spaceTabs?: boolean;
152
+ }
153
+ /** Navigation traits of one command item, keyed by id (see {@link ShellNavigationService.buildTree}). */
154
+ interface ShellNavItemKind {
155
+ navigable: boolean;
156
+ external: boolean;
157
+ tooltip?: string;
158
+ }
159
+ /**
160
+ * The shell's view of the navigation: turns the flat, visibility-filtered
161
+ * item list of the CommandService into a tree (rail areas → tabs → nested
162
+ * entries) and works out which area and tab are active.
163
+ *
164
+ * The active area comes from the route's `data.space` when it names an area
165
+ * of the current mode, otherwise from the area that holds the selected
166
+ * entry. The active tab likewise comes from `data.tab` (matched as
167
+ * `<space>-<tab>`) or from the selection. URLs never change for the shell.
168
+ */
169
+ declare class ShellNavigationService {
170
+ private readonly commandService;
171
+ private readonly commandSettings;
172
+ private readonly router;
173
+ private readonly settingsSpace;
174
+ private readonly items;
175
+ private readonly _routeData;
176
+ readonly routeData: _angular_core.Signal<ShellRouteData>;
177
+ private readonly tree;
178
+ /** Rail areas above the bottom separator. */
179
+ readonly topAreas: _angular_core.Signal<ShellNavNode[]>;
180
+ /** Rail areas pinned to the bottom (Settings). */
181
+ readonly bottomAreas: _angular_core.Signal<ShellNavNode[]>;
182
+ readonly activeArea: _angular_core.Signal<ShellNavNode | null>;
183
+ readonly activeTab: _angular_core.Signal<ShellNavNode | null>;
184
+ /**
185
+ * Settings has one navigation (concept §5.6, AB#5523; the space comes from {@link SHELL_SETTINGS_SPACE}): the category list on the left of every
186
+ * Settings page, never the tab strip — so opening a category cannot switch between two layouts.
187
+ * Off on object detail pages, whose object header owns the navigation.
188
+ */
189
+ readonly settingsSideNav: _angular_core.Signal<boolean>;
190
+ /** The Settings home is open: Settings side navigation without an active category. */
191
+ readonly settingsHomeActive: _angular_core.Signal<boolean>;
192
+ /**
193
+ * Whether the space header shows the area's tab strip: not in Settings (side navigation), not
194
+ * when the route says `spaceTabs: false`; default true.
195
+ */
196
+ readonly showTabs: _angular_core.Signal<boolean>;
197
+ /** The current page is an object detail page (route data `objectDetail`). */
198
+ readonly objectDetail: _angular_core.Signal<boolean>;
199
+ /**
200
+ * Where "back" leads from an object detail page: the selected entry of the active area
201
+ * (the list the object belongs to, e.g. Integration › Adapters), else the active tab.
202
+ */
203
+ readonly backTarget: _angular_core.Signal<ShellNavNode | null>;
204
+ constructor();
205
+ /**
206
+ * Opens an entry: navigable entries navigate (or open their href), grouping
207
+ * entries open their first navigable descendant.
208
+ */
209
+ open(node: ShellNavNode): Promise<void>;
210
+ /**
211
+ * Opens an area from the rail. An area with its own in-app link (e.g. Home without tabs, or a
212
+ * Settings overview) opens that page (AB#5621); any other area opens its first page. Nothing
213
+ * happens when the current page already lives in the area (re-clicking the active area must
214
+ * not throw the person out of the page they are on). External entries are skipped; an area
215
+ * click never pops up a browser tab.
216
+ */
217
+ openArea(area: ShellNavNode): Promise<void>;
218
+ /** Opens the first page of the first area (used after a mode switch). */
219
+ openFirstPage(): Promise<void>;
220
+ /**
221
+ * Where a rail click on an area leads: the area itself when it has its own in-app link,
222
+ * else its first navigable, in-app entry; `null` when there is none.
223
+ */
224
+ static areaTarget(area: ShellNavNode): ShellNavNode | null;
225
+ /** The selected entry at or below a node, deepest first; `null` when none is selected. */
226
+ static deepestSelected(node: ShellNavNode): ShellNavNode | null;
227
+ /** The first navigable, in-app entry below a node (depth first). */
228
+ static firstPage(node: ShellNavNode, allowExternal: boolean): ShellNavNode | null;
229
+ /**
230
+ * Link / href / target per item id, read from the command item tree. The
231
+ * CommandService's items carry neither, but the rail must know whether an
232
+ * entry navigates and whether it leaves the app.
233
+ */
234
+ private collectKinds;
235
+ static buildTree(items: DrawerItem[], kinds: Map<string, ShellNavItemKind>): {
236
+ top: ShellNavNode[];
237
+ bottom: ShellNavNode[];
238
+ };
239
+ /** Drops leading, trailing and repeated separators (left over when entries around them are hidden). */
240
+ static tidySeparators(nodes: ShellNavNode[]): ShellNavNode[];
241
+ static readRouteData(root: ActivatedRouteSnapshot | null | undefined): ShellRouteData;
242
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<ShellNavigationService, never>;
243
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<ShellNavigationService>;
244
+ }
245
+
246
+ /**
247
+ * A count next to a navigation entry (AB#5621): pending work such as open inbox items or ToDos.
248
+ * Hosts pass either the plain count or this object. A count of 0 (or none) shows no badge.
249
+ */
250
+ interface ShellNavBadge {
251
+ count: number;
252
+ /** Needs attention: rendered in the warning colour. */
253
+ attention?: boolean;
254
+ /**
255
+ * Accessible text of the badge (e.g. "3 open ToDos"); without one the shell reads
256
+ * {@link ShellMessages.navBadge} (`'{count} open'`).
257
+ */
258
+ label?: string;
259
+ }
260
+ /** Badge input of the rail: keyed by node id (area id `area-<space>` or a tab id). */
261
+ type ShellNavBadges = Readonly<Record<string, number | ShellNavBadge | null | undefined>>;
262
+ /** Highest count shown as a number; larger counts read `99+`. */
263
+ declare const SHELL_BADGE_MAX = 99;
264
+ /**
265
+ * The badge of one entry: the `badges` input wins over the node's own `badgeCount`;
266
+ * `null` when there is nothing to show (missing, 0, negative or not a number).
267
+ */
268
+ declare function resolveShellBadge(badges: ShellNavBadges | null | undefined, id: string, ownCount?: number | null): ShellNavBadge | null;
269
+ /** Visible text of a badge count: the number, or `99+` above {@link SHELL_BADGE_MAX}. */
270
+ declare function shellBadgeText(count: number): string;
271
+
272
+ /** A status chip in the space header: dot + label, never colour alone. */
273
+ interface SpaceStatusChip {
274
+ label: string;
275
+ status: 'success' | 'warning' | 'error' | 'info' | 'neutral';
276
+ }
277
+ /**
278
+ * Lets the page shown inside a space contribute to the space header: status
279
+ * chips next to the title and a template for the primary actions.
280
+ *
281
+ * A page sets them in its constructor or `ngOnInit` and never cleans up: the
282
+ * shell calls {@link mark} when a navigation starts and
283
+ * {@link clearOlderThan} when it ends with a different page component, which
284
+ * drops only what the previous page contributed. A cancelled navigation or a
285
+ * param-only change (same component) keeps the chips.
286
+ */
287
+ declare class SpaceHeaderService {
288
+ private readonly _chips;
289
+ private readonly _actions;
290
+ private stamp;
291
+ private chipsStamp;
292
+ private actionsStamp;
293
+ readonly chips: _angular_core.Signal<SpaceStatusChip[]>;
294
+ readonly actions: _angular_core.Signal<TemplateRef<unknown> | null>;
295
+ setChips(chips: SpaceStatusChip[]): void;
296
+ setActions(actions: TemplateRef<unknown> | null): void;
297
+ /** A marker for "now"; contributions made after it count as newer. */
298
+ mark(): number;
299
+ /** Drops every contribution made at or before the marker. */
300
+ clearOlderThan(marker: number): void;
301
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<SpaceHeaderService, never>;
302
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<SpaceHeaderService>;
303
+ }
304
+
305
+ /**
306
+ * Hook between the top bar's search button and the command palette (AB#5520).
307
+ *
308
+ * The shell only announces that the person asked for search; it does not
309
+ * know the palette. The host (or the palette) subscribes once and opens it:
310
+ *
311
+ * ```ts
312
+ * inject(ShellSearchTriggerService).requested$
313
+ * .pipe(takeUntilDestroyed())
314
+ * .subscribe(() => commandPalette.open());
315
+ * ```
316
+ *
317
+ * Until something subscribes, a click is a no-op. The keyboard shortcut
318
+ * (Cmd/Ctrl+K) is not bound here — it belongs to the palette, which can call
319
+ * {@link request} or open itself directly.
320
+ */
321
+ declare class ShellSearchTriggerService {
322
+ private readonly requests;
323
+ /** Emits every time search was requested from the shell. */
324
+ readonly requested$: Observable<void>;
325
+ request(): void;
326
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<ShellSearchTriggerService, never>;
327
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<ShellSearchTriggerService>;
328
+ }
329
+
330
+ /**
331
+ * Host-specific crumb rewriting of {@link shellBreadcrumbs}. Hosts that migrated from a
332
+ * section-based navigation use it to replace the old section crumb with the rail area.
333
+ */
334
+ interface ShellBreadcrumbOptions {
335
+ /**
336
+ * Lower-case labels of old section crumbs that routes still start with (e.g. `'identity'`).
337
+ * Such a first crumb is replaced by the rail area the page lives in.
338
+ */
339
+ legacySectionCrumbs?: ReadonlySet<string>;
340
+ /**
341
+ * Area names of old section crumbs (lower-case key → area name), used when the page has no
342
+ * active area: `{ communication: 'Integration' }` turns "Communication › Data Flows" into
343
+ * "Integration › Data Flows".
344
+ */
345
+ legacySectionAreaNames?: Readonly<Record<string, string>>;
346
+ }
347
+ /** A breadcrumb the shell added for the rail area; clicking it opens the area. */
348
+ interface ShellAreaCrumb extends BreadCrumbData {
349
+ areaId: string;
350
+ }
351
+ declare function isAreaCrumb(item: unknown): item is ShellAreaCrumb;
352
+ /**
353
+ * Breadcrumbs as the shell shows them (AB#5516): the first crumb names the rail area of the
354
+ * page (route `data.space`), never a section of an old drawer navigation.
355
+ *
356
+ * - a legacy section crumb ({@link ShellBreadcrumbOptions.legacySectionCrumbs}) is replaced by the area crumb;
357
+ * - a first crumb that already is the area ("Settings") stays as it is;
358
+ * - otherwise the area crumb is put in front ("Data Explorer" → "Data › Data Explorer");
359
+ * - the area crumb is dropped again when the next crumb carries the same label
360
+ * ("General › Settings" → "Settings", not "Settings › Settings").
361
+ *
362
+ * - crumbs without text are dropped (no empty segments).
363
+ *
364
+ * Pure: returns a new array and never mutates the items (the BreadCrumbService re-emits the
365
+ * same objects after resolving `{{placeholders}}`).
366
+ */
367
+ declare function shellBreadcrumbs(allItems: readonly BreadCrumbData[], area: ShellNavNode | null, options?: ShellBreadcrumbOptions): BreadCrumbData[];
368
+ /** "Integration › Adapters" — the description stored with a recent page. */
369
+ declare function crumbPath(items: readonly BreadCrumbData[]): string | undefined;
370
+
371
+ /**
372
+ * The Home space header (wireframe screen 1, AB#5558): instead of the area name "Home" it greets
373
+ * the user — "Good morning, Gerald" — with a short meta line naming the tenant. Pass the results
374
+ * to `mm-space-shell` as `heading` and `meta`.
375
+ *
376
+ * Every helper takes optional {@link ShellMessages} overrides (translations).
377
+ */
378
+ /** A label/value pair of the space header meta line (the value is set in mono). */
379
+ interface SpaceMetaItem {
380
+ label: string;
381
+ value: string;
382
+ }
383
+ /** The parts of the signed-in user the greeting reads. */
384
+ interface GreetingUser {
385
+ given_name?: string | null;
386
+ }
387
+ /** Morning 05–11, afternoon 12–17, evening otherwise (local time of the browser). */
388
+ declare function greetingPhrase(now: Date, messages?: Partial<ShellMessages> | null): string;
389
+ /** The first name: the `given_name` claim, else the first word of the display name, else null. */
390
+ declare function firstNameOf(user: GreetingUser | null | undefined, displayName: string | null | undefined): string | null;
391
+ /** "Good morning, Gerald", or just "Good morning" when the name is unknown. */
392
+ declare function homeGreeting(user: GreetingUser | null | undefined, displayName: string | null | undefined, now: Date, messages?: Partial<ShellMessages> | null): string;
393
+ /** The meta line of the Home header: the tenant (nothing without one). */
394
+ declare function homeMeta(tenantId: string | null | undefined, messages?: Partial<ShellMessages> | null): SpaceMetaItem[];
395
+
396
+ /** Status colour of a chip; the label always carries the meaning as well (never colour alone). */
397
+ type ShellStatus = 'success' | 'warning' | 'error' | 'info' | 'neutral';
398
+ /** The environment chip next to the tenant switcher in `mm-shell-top-bar`. */
399
+ interface ShellEnvironmentChip {
400
+ label: string;
401
+ /** Shown on narrow screens, so the environment never becomes colour-only. */
402
+ short: string;
403
+ status: ShellStatus;
404
+ /** Marks the whole top bar as production (accent line). */
405
+ production?: boolean;
406
+ }
407
+ /** Tenant environment modes of the OctoMesh tenant mode configuration. */
408
+ type ShellEnvironmentMode = 'PRODUCTION' | 'STAGING' | 'DEVELOPMENT' | 'TESTING' | 'unknown';
409
+ /**
410
+ * The environment chip of a tenant mode, in sentence case with its status colour:
411
+ * Production (error, marks the bar), Staging (warning), Development (success),
412
+ * Testing (info), anything else "Environment unknown" (neutral).
413
+ */
414
+ declare function shellEnvironmentChip(mode: ShellEnvironmentMode | string | null | undefined, messages?: Partial<ShellMessages> | null): ShellEnvironmentChip;
415
+
416
+ /**
417
+ * Toast stacking for a shell host (AB#5516 visual check: six identical "not found" errors
418
+ * covered the top bar): identical messages once; errors leave after 10 s and warnings after
419
+ * 8 s (paused while hovered or focused), except those with details, which wait for the user;
420
+ * at most three toasts, a success/info is dropped before any error. Errors that must stay
421
+ * pass `hideAfter: 0`.
422
+ *
423
+ * Use: `{ provide: NOTIFICATION_DISPLAY_OPTIONS, useValue: SHELL_NOTIFICATION_OPTIONS }`.
424
+ * Placing `.k-notification-group` below the top bar is the host's global style.
425
+ */
426
+ declare const SHELL_NOTIFICATION_OPTIONS: NotificationDisplayOptions;
427
+
428
+ /**
429
+ * The rail: one icon per area of the navigation tree, Settings pinned to the
430
+ * bottom. Enter/Space or a click on an icon navigates to the area. The
431
+ * flyout with the area's entries is a disclosure: it opens on hover or with
432
+ * Arrow Right (`aria-expanded` / `aria-controls` on the icon); it never opens
433
+ * on focus alone. On phones (≤ 640 px) the rail is a bottom bar without
434
+ * flyouts — the space shell's tab strip takes over.
435
+ *
436
+ * Pointer: hovering opens the flyout after a short intent delay (at once when
437
+ * another flyout is already showing). It stays open while the pointer is over
438
+ * the icon or the flyout — the flyout host spans the gap between them, so
439
+ * crossing it never counts as leaving — and closes only after a grace delay
440
+ * once the pointer has left both. A mouse click on an icon with a flyout
441
+ * still navigates, and additionally pins the flyout open (as does Arrow
442
+ * Right): a pinned flyout ignores the pointer leaving and closes on an
443
+ * outside click, Escape, choosing an entry, focus leaving the entry, a
444
+ * second click on the same icon, or a navigation (AB#5621).
445
+ *
446
+ * Navigation (AB#5621): every open flyout — pinned or hovered — closes when a
447
+ * router navigation ends or the active area changes, so a click on an icon
448
+ * that navigates does not leave the flyout over the new page. A click that
449
+ * does not navigate (the area's page is already open) keeps the pin. Closing
450
+ * on navigation moves focus only when it was inside the flyout (back to its
451
+ * area icon); focus the new page took is left alone.
452
+ *
453
+ * Keyboard: the rail is one tab stop (roving tabindex). Arrow Up/Down (Left/
454
+ * Right on the bottom bar) move between areas, Home/End jump, Arrow Right
455
+ * opens the flyout and focuses its first entry; inside the flyout Arrow
456
+ * Up/Down move, Escape or Arrow Left return to the icon. After choosing a
457
+ * flyout entry focus returns to the area icon instead of falling to <body>.
458
+ *
459
+ * Badges (AB#5621): `badges` maps node ids (areas and flyout entries) to a count or a
460
+ * {@link ShellNavBadge}; a node's own `badgeCount` is the fallback. 0 or no count shows nothing.
461
+ * The count joins the icon's accessible name ("Inbox, 3 open") and is read after a flyout entry.
462
+ *
463
+ * Every activation of an area icon emits `areaSelected` — also for areas without entries
464
+ * (Home, a Settings overview), which have no flyout; `ShellNavigationService.openArea` opens
465
+ * the area's own link then.
466
+ *
467
+ * Pure presentation: the host feeds the areas (`ShellNavigationService.topAreas()` /
468
+ * `bottomAreas()`) and handles the outputs (`openArea` / `open`).
469
+ */
470
+ /** Hover intent before a flyout opens when none is showing (ms). */
471
+ declare const RAIL_FLYOUT_OPEN_DELAY = 120;
472
+ /** Grace period after the pointer left both icon and flyout (ms). */
473
+ declare const RAIL_FLYOUT_CLOSE_DELAY = 300;
474
+ declare class ShellRailComponent {
475
+ private readonly host;
476
+ private readonly changeDetector;
477
+ readonly areas: _angular_core.InputSignal<ShellNavNode[]>;
478
+ readonly bottomAreas: _angular_core.InputSignal<ShellNavNode[]>;
479
+ readonly activeAreaId: _angular_core.InputSignal<string | null>;
480
+ /** Counts per node id (area or flyout entry); wins over `ShellNavNode.badgeCount`. */
481
+ readonly badges: _angular_core.InputSignal<Readonly<Record<string, number | ShellNavBadge | null | undefined>>>;
482
+ /** Translations; members left out fall back to {@link SHELL_MESSAGES}, then English. */
483
+ readonly messages: _angular_core.InputSignal<Partial<ShellMessages> | null>;
484
+ protected readonly m: _angular_core.Signal<ShellMessages>;
485
+ /** An area icon was activated. */
486
+ readonly areaSelected: _angular_core.OutputEmitterRef<ShellNavNode>;
487
+ /** An entry in a flyout was activated. */
488
+ readonly itemSelected: _angular_core.OutputEmitterRef<ShellNavNode>;
489
+ /** The area whose flyout is shown. */
490
+ protected readonly openId: _angular_core.WritableSignal<string | null>;
491
+ /** Opened by click or keyboard: the pointer leaving does not close it. */
492
+ protected readonly pinned: _angular_core.WritableSignal<boolean>;
493
+ private readonly focusedId;
494
+ private openTimer;
495
+ private closeTimer;
496
+ constructor();
497
+ private readonly allAreas;
498
+ /** The one area button in the tab order: the focused one, else the active one, else the first. */
499
+ protected readonly tabStopId: _angular_core.Signal<string>;
500
+ protected hasFlyout(area: ShellNavNode): boolean;
501
+ /** The badge of a node, or null when it shows none. */
502
+ protected badgeOf(node: ShellNavNode): ShellNavBadge | null;
503
+ protected badgeText(badge: ShellNavBadge): string;
504
+ /** Accessible text of a badge: its own label, else "{count} open". */
505
+ protected badgeLabel(badge: ShellNavBadge): string;
506
+ /** Accessible name of an area icon, with its badge when it has one. */
507
+ protected areaLabel(area: ShellNavNode): string;
508
+ protected flyoutId(area: ShellNavNode): string;
509
+ protected onAreaClick(area: ShellNavNode, event?: MouseEvent): void;
510
+ protected onItemClick(area: ShellNavNode, item: ShellNavNode): void;
511
+ protected onAreaFocus(area: ShellNavNode): void;
512
+ protected onPointerEnter(area: ShellNavNode): void;
513
+ protected onPointerLeave(area: ShellNavNode): void;
514
+ protected onEntryFocusOut(area: ShellNavNode, event: FocusEvent): void;
515
+ protected onDocumentPointerDown(event: Event): void;
516
+ protected onDocumentEscape(): void;
517
+ protected onAreaKeydown(area: ShellNavNode, event: KeyboardEvent): void;
518
+ protected onFlyoutKeydown(area: ShellNavNode, event: KeyboardEvent): void;
519
+ /** A navigation happened: close the flyout without taking focus from the new page. */
520
+ private closeOnNavigation;
521
+ private openNow;
522
+ private close;
523
+ private cancelOpen;
524
+ private cancelClose;
525
+ private clearTimers;
526
+ private focusArea;
527
+ private entryOf;
528
+ private flyoutItems;
529
+ /** Attribute lookup without building a selector from ids (no escaping needed). */
530
+ private findByAttribute;
531
+ /** Below 640 px the rail is laid out horizontally at the bottom. */
532
+ private isBottomBar;
533
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<ShellRailComponent, never>;
534
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<ShellRailComponent, "mm-shell-rail", never, { "areas": { "alias": "areas"; "required": false; "isSignal": true; }; "bottomAreas": { "alias": "bottomAreas"; "required": false; "isSignal": true; }; "activeAreaId": { "alias": "activeAreaId"; "required": false; "isSignal": true; }; "badges": { "alias": "badges"; "required": false; "isSignal": true; }; "messages": { "alias": "messages"; "required": false; "isSignal": true; }; }, { "areaSelected": "areaSelected"; "itemSelected": "itemSelected"; }, never, never, true, never>;
535
+ }
536
+
537
+ interface MenuPosition {
538
+ top: number;
539
+ left: number;
540
+ }
541
+ /**
542
+ * The header of a space (concept §3.3): breadcrumbs, the area title with
543
+ * optional status chips and a primary-action slot, and the tab strip built
544
+ * from the area's children — the same entries the rail flyout lists.
545
+ *
546
+ * Content projection:
547
+ * - `[spaceCrumbs]` — the breadcrumb line above the title
548
+ * - `[spaceActions]` — primary actions, right of the title
549
+ *
550
+ * Tabs are navigation, not ARIA tabs (there is no tab panel): a `nav` with
551
+ * buttons and `aria-current="page"` on the active one. A grouping tab
552
+ * without its own page (e.g. Swagger) is a menu button: opening moves focus
553
+ * into the menu, Arrow Up/Down/Home/End move, Escape (on the button or in the
554
+ * menu) closes and returns focus to the button, Tab / focus leaving / a click
555
+ * outside / scrolling or resizing closes it. The menu is positioned `fixed`
556
+ * from the button's bounding box, so the scrollable tab strip cannot clip it.
557
+ * Without an area (a page outside the current mode's navigation) only the
558
+ * breadcrumbs and actions are shown. A `heading` replaces the area name and a `meta` line
559
+ * follows it (Home greets the user and names the tenant, wireframe screen 1).
560
+ *
561
+ * On an object detail page (`objectDetail`, AB#5547) the page's own object header
562
+ * (name, chips, actions, object tabs) replaces the area title, the status chips and
563
+ * the tab strip: the space header shrinks to one line with a back link to the list
564
+ * the object belongs to (`backTarget`, e.g. "Adapters"), the breadcrumbs and the
565
+ * actions slot.
566
+ *
567
+ * An empty breadcrumb line (AB#5621) takes no height: when the `[spaceCrumbs]` content shows
568
+ * nothing (no text, no list item, link, button or image — e.g. a Kendo breadcrumb without
569
+ * items) and there is no back link, the line collapses. It stays in the DOM with its width, so
570
+ * a breadcrumb that measures its width (Kendo's collapse mode) is laid out right once items arrive.
571
+ */
572
+ declare class SpaceShellComponent {
573
+ private readonly host;
574
+ readonly area: _angular_core.InputSignal<ShellNavNode | null>;
575
+ readonly activeTabId: _angular_core.InputSignal<string | null>;
576
+ readonly chips: _angular_core.InputSignal<SpaceStatusChip[]>;
577
+ /** Replaces the area name as the title (Home: the greeting, AB#5558). */
578
+ readonly heading: _angular_core.InputSignal<string | null>;
579
+ /** A short meta line right of the title (Home: the tenant), hidden on phones. */
580
+ readonly meta: _angular_core.InputSignal<SpaceMetaItem[]>;
581
+ /** The page renders its own object header; area title, chips and tabs are left out. */
582
+ readonly objectDetail: _angular_core.InputSignal<boolean>;
583
+ /** Show the area's tab strip; false when the page lists the same entries itself (Settings home). */
584
+ readonly showTabs: _angular_core.InputSignal<boolean>;
585
+ /** Target of the back link on an object detail page (the list of the object). */
586
+ readonly backTarget: _angular_core.InputSignal<ShellNavNode | null>;
587
+ /** Translations; members left out fall back to {@link SHELL_MESSAGES}, then English. */
588
+ readonly messages: _angular_core.InputSignal<Partial<ShellMessages> | null>;
589
+ protected readonly m: _angular_core.Signal<ShellMessages>;
590
+ readonly tabSelected: _angular_core.OutputEmitterRef<ShellNavNode>;
591
+ /** The grouping tab whose menu is open. */
592
+ protected readonly openMenuId: _angular_core.WritableSignal<string | null>;
593
+ protected readonly menuPosition: _angular_core.WritableSignal<MenuPosition>;
594
+ protected readonly tabs: _angular_core.Signal<ShellNavNode[]>;
595
+ /** The breadcrumb line shows something (projected crumbs or the back link). */
596
+ protected readonly hasCrumbs: _angular_core.WritableSignal<boolean>;
597
+ constructor();
598
+ /** Scrolls the tab strip (only it, never the page) so the tab is fully visible. */
599
+ revealTab(id: string): void;
600
+ private crumbsElement;
601
+ private updateHasCrumbs;
602
+ protected format(message: string, values: Record<string, string>): string;
603
+ protected onBackClick(target: ShellNavNode): void;
604
+ protected isGroup(tab: ShellNavNode): boolean;
605
+ protected menuId(tab: ShellNavNode): string;
606
+ protected onTabClick(tab: ShellNavNode, button: HTMLElement): void;
607
+ protected onTabKeydown(tab: ShellNavNode, button: HTMLElement, event: KeyboardEvent): void;
608
+ protected onMenuItemClick(item: ShellNavNode): void;
609
+ protected onMenuKeydown(event: KeyboardEvent): void;
610
+ protected onWrapperFocusOut(tab: ShellNavNode, event: FocusEvent): void;
611
+ protected onDocumentClick(target: EventTarget | null): void;
612
+ protected onViewportChange(): void;
613
+ private openMenu;
614
+ private closeMenu;
615
+ private openWrapper;
616
+ private menuItems;
617
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<SpaceShellComponent, never>;
618
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<SpaceShellComponent, "mm-space-shell", never, { "area": { "alias": "area"; "required": false; "isSignal": true; }; "activeTabId": { "alias": "activeTabId"; "required": false; "isSignal": true; }; "chips": { "alias": "chips"; "required": false; "isSignal": true; }; "heading": { "alias": "heading"; "required": false; "isSignal": true; }; "meta": { "alias": "meta"; "required": false; "isSignal": true; }; "objectDetail": { "alias": "objectDetail"; "required": false; "isSignal": true; }; "showTabs": { "alias": "showTabs"; "required": false; "isSignal": true; }; "backTarget": { "alias": "backTarget"; "required": false; "isSignal": true; }; "messages": { "alias": "messages"; "required": false; "isSignal": true; }; }, { "tabSelected": "tabSelected"; }, never, ["[spaceCrumbs]", "[spaceActions]"], true, never>;
619
+ }
620
+
621
+ /** Badge of one Settings category in the side navigation. */
622
+ interface SettingsSideNavBadge {
623
+ count: number;
624
+ /** Needs attention (open re-entry tasks): rendered as a warning badge. */
625
+ attention?: boolean;
626
+ /** Accessible label of the badge; without one the count is read as is. */
627
+ label?: string;
628
+ }
629
+ /**
630
+ * Counts and badges of the Settings side navigation, keyed by shell tab id
631
+ * (`settings-<category>`). The Settings home fills them when it has loaded its
632
+ * categories (forms + custom pages) and the secrets inventory; until then, and on a
633
+ * deep link to another Settings page, the categories are shown without counts.
634
+ */
635
+ declare class SettingsSideNavBadgesService {
636
+ private readonly _badges;
637
+ readonly badges: _angular_core.Signal<Record<string, SettingsSideNavBadge>>;
638
+ set(badges: Record<string, SettingsSideNavBadge>): void;
639
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<SettingsSideNavBadgesService, never>;
640
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<SettingsSideNavBadgesService>;
641
+ }
642
+
643
+ /**
644
+ * A heading over some categories of the Settings side navigation (AB#5621).
645
+ */
646
+ interface SettingsSideNavGroup {
647
+ id: string;
648
+ /** Visible heading (already translated by the host). */
649
+ label: string;
650
+ /** Tab ids of the categories under the heading, in display order. */
651
+ tabIds: readonly string[];
652
+ }
653
+ /** One block of the side navigation: a group with its categories, or the ungrouped ones. */
654
+ interface SideNavSection {
655
+ id: string;
656
+ label: string | null;
657
+ categories: ShellNavNode[];
658
+ }
659
+ /**
660
+ * The one navigation of the Settings space (concept §5.6, AB#5523): "All settings" plus the
661
+ * categories of the Settings area on the left, on every Settings page — the home, the category
662
+ * pages, the generated forms and the hand-written pages (secrets, identity providers, …). The
663
+ * space header shows no tab strip in Settings, so opening a category never switches between two
664
+ * navigation layouts.
665
+ *
666
+ * The entries are the area's children from the command tree (the same entries as the rail
667
+ * flyout); counts and the re-entry badge come from {@link SettingsSideNavBadgesService}.
668
+ * Navigation, not ARIA tabs: a `nav` with buttons and `aria-current="page"` on the active one.
669
+ *
670
+ * Groups (AB#5621, optional): `groups` puts headings over the categories they list (in the
671
+ * group's order); categories in no group follow without a heading, groups without a visible
672
+ * category are left out. Without groups the list is flat, as before.
673
+ *
674
+ * Labels are shown exactly as given (AB#5621): the area name, the categories and the group
675
+ * headings keep the host's case — no lower-casing, no CSS `text-transform`. A language that
676
+ * needs a different case in "All {area}" sets `allOfArea` to the whole text.
677
+ */
678
+ declare class SettingsSideNavComponent {
679
+ readonly area: _angular_core.InputSignal<ShellNavNode>;
680
+ readonly activeTabId: _angular_core.InputSignal<string | null>;
681
+ /** The Settings home is open ("All settings" is the current entry). */
682
+ readonly homeActive: _angular_core.InputSignal<boolean>;
683
+ readonly badges: _angular_core.InputSignal<Record<string, SettingsSideNavBadge>>;
684
+ /** Optional headings over the categories; empty keeps the flat list. */
685
+ readonly groups: _angular_core.InputSignal<readonly SettingsSideNavGroup[]>;
686
+ /** Translations; members left out fall back to {@link SHELL_MESSAGES}, then English. */
687
+ readonly messages: _angular_core.InputSignal<Partial<ShellMessages> | null>;
688
+ protected readonly m: _angular_core.Signal<ShellMessages>;
689
+ readonly homeSelected: _angular_core.OutputEmitterRef<void>;
690
+ readonly tabSelected: _angular_core.OutputEmitterRef<ShellNavNode>;
691
+ protected readonly categories: _angular_core.Signal<ShellNavNode[]>;
692
+ protected readonly sections: _angular_core.Signal<SideNavSection[]>;
693
+ /** Unique per instance, so two side navs on one page never share heading ids. */
694
+ private readonly instanceId;
695
+ protected groupHeadingId(section: SideNavSection): string;
696
+ protected readonly navLabel: _angular_core.Signal<string>;
697
+ protected readonly homeLabel: _angular_core.Signal<string>;
698
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<SettingsSideNavComponent, never>;
699
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<SettingsSideNavComponent, "mm-settings-side-nav", never, { "area": { "alias": "area"; "required": true; "isSignal": true; }; "activeTabId": { "alias": "activeTabId"; "required": false; "isSignal": true; }; "homeActive": { "alias": "homeActive"; "required": false; "isSignal": true; }; "badges": { "alias": "badges"; "required": false; "isSignal": true; }; "groups": { "alias": "groups"; "required": false; "isSignal": true; }; "messages": { "alias": "messages"; "required": false; "isSignal": true; }; }, { "homeSelected": "homeSelected"; "tabSelected": "tabSelected"; }, never, never, true, never>;
700
+ }
701
+
702
+ /** One density choice of the user menu (the host owns the density modes and applies them). */
703
+ interface ShellDensityOption {
704
+ mode: string;
705
+ label: string;
706
+ }
707
+ /** One language of the user menu's language choice. */
708
+ interface ShellLanguage {
709
+ /** Language code the host understands, e.g. `'en'` or `'de-AT'`. */
710
+ code: string;
711
+ /** Name of the language, ideally in that language ("Deutsch"). */
712
+ label: string;
713
+ }
714
+ /** The default language list: English only, shown as a fact instead of a choice. */
715
+ declare const DEFAULT_SHELL_LANGUAGES: readonly ShellLanguage[];
716
+ /** Theme preference of the user menu (same values as octo-ui's `ThemeModePreference`). */
717
+ type ShellThemePreference = 'system' | 'light' | 'dark';
718
+ /** The signed-in user as the user menu shows it. */
719
+ interface ShellUser {
720
+ /** Avatar initials; empty shows "?". */
721
+ initials?: string | null;
722
+ /** Full name, e.g. "Gerald Lochner". */
723
+ displayName?: string | null;
724
+ /** Login / account name, e.g. "gerald". */
725
+ userName?: string | null;
726
+ /** Account page of the identity provider; null leaves "Manage profile" out. */
727
+ profileUri?: string | null;
728
+ }
729
+ /**
730
+ * A host entry of the user menu (AB#5621), e.g. "My identities" or "Developer info". Listed
731
+ * above "Manage profile" and "Sign out".
732
+ */
733
+ interface ShellUserMenuItem {
734
+ id: string;
735
+ /** Visible label (already translated by the host). */
736
+ text: string;
737
+ svgIcon?: SVGIcon;
738
+ /** External link, opened in a new tab; without one choosing the entry emits `itemSelected`. */
739
+ href?: string;
740
+ }
741
+ interface ThemeOption {
742
+ value: ShellThemePreference;
743
+ label: string;
744
+ }
745
+ /**
746
+ * Avatar menu of the top bar. Besides sign-out and the profile link it holds
747
+ * the personal settings (concept §3.1, §10): theme mode, density and
748
+ * language. Tenant configuration belongs elsewhere (the Settings space).
749
+ *
750
+ * - **Session**: `sessionLoading` shows a placeholder, `user` null offers "Sign in"
751
+ * (`signIn` output), otherwise the avatar opens the panel; "Sign out" emits `signOut`.
752
+ * The host wires its auth service (e.g. shared-auth's `AuthorizeService`).
753
+ * - **Theme**: `theme` is the current preference, a choice emits `themeChange` (e.g. wired to
754
+ * octo-ui's `ThemeModeService`).
755
+ * - **Density** lists `densityOptions` (none: the group is left out); a choice emits
756
+ * `densityChange`, the host applies and stores it and feeds `density` back.
757
+ * - **Language** lists `languages`. With one language (the default, English) the entry
758
+ * states it instead of offering a choice that changes nothing; with several it is a
759
+ * radio group that emits `languageChange`. Persisting the choice (per user) and
760
+ * switching the translations is the host's job; it feeds the current code back
761
+ * through `language`.
762
+ * - **Version** shows `version` when set.
763
+ * - **Host entries** (AB#5621): `items` lists the host's own entries above "Manage profile" and
764
+ * "Sign out"; choosing one closes the panel and emits `itemSelected` (entries with `href`
765
+ * open in a new tab instead). For richer content the host may project elements with the
766
+ * `shellUserMenuItems` attribute into the same place; a click on a button or link there
767
+ * closes the panel as well.
768
+ *
769
+ * Opening moves focus into the panel, Escape or the avatar button close it
770
+ * and return focus to the avatar. Theme, density and language are native radio groups
771
+ * (arrow keys move and select, one tab stop each).
772
+ */
773
+ declare class ShellUserMenuComponent {
774
+ private readonly host;
775
+ /** The signed-in user; null shows the "Sign in" button. */
776
+ readonly user: _angular_core.InputSignal<ShellUser | null>;
777
+ /** The session is being restored: a placeholder instead of avatar or sign-in. */
778
+ readonly sessionLoading: _angular_core.InputSignal<boolean>;
779
+ /** The current theme preference. */
780
+ readonly theme: _angular_core.InputSignal<ShellThemePreference>;
781
+ /** Density choices; empty leaves the density group out. */
782
+ readonly densityOptions: _angular_core.InputSignal<readonly ShellDensityOption[]>;
783
+ /** The current density mode (one of `densityOptions`). */
784
+ readonly density: _angular_core.InputSignal<string | null>;
785
+ /** Languages to choose from; one entry is shown as a fact, none hides the entry. */
786
+ readonly languages: _angular_core.InputSignal<readonly ShellLanguage[]>;
787
+ /** The current language code; defaults to the first of `languages`. */
788
+ readonly language: _angular_core.InputSignal<string | null>;
789
+ /** App version shown at the bottom of the panel; null leaves the line out. */
790
+ readonly version: _angular_core.InputSignal<string | null>;
791
+ /** Host entries above "Manage profile" / "Sign out"; empty leaves the list out. */
792
+ readonly items: _angular_core.InputSignal<readonly ShellUserMenuItem[]>;
793
+ /** Translations; members left out fall back to {@link SHELL_MESSAGES}, then English. */
794
+ readonly messages: _angular_core.InputSignal<Partial<ShellMessages> | null>;
795
+ readonly signIn: _angular_core.OutputEmitterRef<void>;
796
+ readonly signOut: _angular_core.OutputEmitterRef<void>;
797
+ /** The person picked a theme preference. */
798
+ readonly themeChange: _angular_core.OutputEmitterRef<ShellThemePreference>;
799
+ /** The person picked a density mode. */
800
+ readonly densityChange: _angular_core.OutputEmitterRef<string>;
801
+ /** The person picked a language (its code). */
802
+ readonly languageChange: _angular_core.OutputEmitterRef<string>;
803
+ /** The person chose a host entry without `href`. */
804
+ readonly itemSelected: _angular_core.OutputEmitterRef<ShellUserMenuItem>;
805
+ protected readonly m: _angular_core.Signal<ShellMessages>;
806
+ protected readonly open: _angular_core.WritableSignal<boolean>;
807
+ protected readonly initials: _angular_core.Signal<string>;
808
+ protected readonly fullName: _angular_core.Signal<string | null>;
809
+ protected readonly userName: _angular_core.Signal<string | null>;
810
+ protected readonly profileUri: _angular_core.Signal<string | null>;
811
+ protected readonly avatarLabel: _angular_core.Signal<string>;
812
+ protected readonly versionText: _angular_core.Signal<string | null>;
813
+ protected readonly themeOptions: _angular_core.Signal<readonly ThemeOption[]>;
814
+ /** The code of the current language: `language`, else the first of `languages`. */
815
+ protected readonly currentLanguage: _angular_core.Signal<string>;
816
+ protected readonly currentLanguageLabel: _angular_core.Signal<string>;
817
+ protected toggle(): void;
818
+ /** Closes the panel; `restoreFocus` puts focus back on the avatar button. */
819
+ private close;
820
+ protected setTheme(value: ShellThemePreference): void;
821
+ protected setDensity(mode: string): void;
822
+ protected setLanguage(code: string): void;
823
+ /** A host entry: close the panel (focus back on the avatar), then let the host act. */
824
+ protected selectItem(item: ShellUserMenuItem): void;
825
+ /** An external host entry opens in a new tab; the panel closes and focus returns to the avatar. */
826
+ protected followItemLink(): void;
827
+ /** A click on a button or link of the projected `shellUserMenuItems` content closes the panel. */
828
+ protected onProjectedClick(event: Event): void;
829
+ protected login(): void;
830
+ protected logout(): void;
831
+ protected onEscape(): void;
832
+ /** A click outside closes without stealing focus from what was clicked. */
833
+ protected onDocumentClick(target: EventTarget | null): void;
834
+ /** Tabbing out of the panel closes it. */
835
+ protected onPanelFocusOut(event: FocusEvent): void;
836
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<ShellUserMenuComponent, never>;
837
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<ShellUserMenuComponent, "mm-shell-user-menu", never, { "user": { "alias": "user"; "required": false; "isSignal": true; }; "sessionLoading": { "alias": "sessionLoading"; "required": false; "isSignal": true; }; "theme": { "alias": "theme"; "required": false; "isSignal": true; }; "densityOptions": { "alias": "densityOptions"; "required": false; "isSignal": true; }; "density": { "alias": "density"; "required": false; "isSignal": true; }; "languages": { "alias": "languages"; "required": false; "isSignal": true; }; "language": { "alias": "language"; "required": false; "isSignal": true; }; "version": { "alias": "version"; "required": false; "isSignal": true; }; "items": { "alias": "items"; "required": false; "isSignal": true; }; "messages": { "alias": "messages"; "required": false; "isSignal": true; }; }, { "signIn": "signIn"; "signOut": "signOut"; "themeChange": "themeChange"; "densityChange": "densityChange"; "languageChange": "languageChange"; "itemSelected": "itemSelected"; }, never, ["[shellUserMenuItems]"], true, never>;
838
+ }
839
+
840
+ /** One choice of the top bar's mode switch (e.g. Home | Studio). */
841
+ interface ShellModeOption {
842
+ id: string;
843
+ label: string;
844
+ /** Tooltip. */
845
+ description?: string;
846
+ }
847
+ /**
848
+ * Top bar (concept §3.1, wireframe): brand mark + name, tenant switcher with the
849
+ * environment chip, the mode switch, the search trigger, the optional ✦ assistant
850
+ * toggle and the avatar menu (`mm-shell-user-menu`) with the personal settings.
851
+ *
852
+ * Pure presentation; the host feeds everything in and handles the outputs:
853
+ *
854
+ * - **Brand**: `brandName` and `brandMarkSrc` (an image URL of the host; none: no mark).
855
+ * - **Tenant**: inside a tenant (`tenantId`) the host projects its tenant switcher with the
856
+ * `shellTenant` attribute (e.g. octo-ui's `<mm-tenant-switcher shellTenant …>`, which the
857
+ * bar styles flat); the environment chip follows it.
858
+ * - **Environment**: `environment` (e.g. from {@link shellEnvironmentChip}); null hides the
859
+ * chip (also while the tenant mode is loading). `production: true` tints the bar.
860
+ * - **Mode switch**: `modes` + `currentMode`; shown with two or more modes inside a tenant
861
+ * the user may open. Picking the other mode emits `modeChange`; the host applies it.
862
+ * - **Search**: the button calls {@link ShellSearchTriggerService.request} and emits
863
+ * `searchRequested`; the host (or the palette) opens the command palette.
864
+ * - **Assistant**: `assistantAvailable` shows the ✦ toggle (inside a tenant the user may
865
+ * open); a click emits `assistantToggle`, `assistantOpen` reflects the panel state.
866
+ * - **User menu**: `user`, `sessionLoading`, `theme`, `densityOptions`, `density`,
867
+ * `languages`, `language`, `version` and the outputs `signIn`, `signOut`, `themeChange`,
868
+ * `densityChange` and `languageChange` are passed through to `mm-shell-user-menu`, as are the
869
+ * host entries (AB#5621): `userMenuItems` → `items`, `itemSelected` → `userMenuItemSelected`,
870
+ * and content with the `shellUserMenuItems` attribute, projected into the panel.
871
+ */
872
+ declare class ShellTopBarComponent {
873
+ private readonly searchTrigger;
874
+ readonly tenantId: _angular_core.InputSignal<string | null>;
875
+ readonly isDenied: _angular_core.InputSignal<boolean>;
876
+ /** Product name next to the mark, e.g. "OctoMesh Studio". */
877
+ readonly brandName: _angular_core.InputSignal<string>;
878
+ /** URL of the brand mark image (decorative); null leaves the mark out. */
879
+ readonly brandMarkSrc: _angular_core.InputSignal<string | null>;
880
+ /** The tenant's environment chip; null hides it. */
881
+ readonly environment: _angular_core.InputSignal<ShellEnvironmentChip | null>;
882
+ /** Choices of the mode switch; fewer than two hide it. */
883
+ readonly modes: _angular_core.InputSignal<readonly ShellModeOption[]>;
884
+ /** Id of the mode in effect. */
885
+ readonly currentMode: _angular_core.InputSignal<string | null>;
886
+ /** Shows the ✦ assistant toggle (feature flag on and the panel can be hosted). */
887
+ readonly assistantAvailable: _angular_core.InputSignal<boolean>;
888
+ /** The assistant panel is open (`aria-expanded` of the toggle). */
889
+ readonly assistantOpen: _angular_core.InputSignal<boolean>;
890
+ /** Id of the assistant panel element (`aria-controls` while open). */
891
+ readonly assistantPanelId: _angular_core.InputSignal<string>;
892
+ readonly user: _angular_core.InputSignal<ShellUser | null>;
893
+ readonly sessionLoading: _angular_core.InputSignal<boolean>;
894
+ readonly theme: _angular_core.InputSignal<ShellThemePreference>;
895
+ readonly densityOptions: _angular_core.InputSignal<readonly ShellDensityOption[]>;
896
+ readonly density: _angular_core.InputSignal<string | null>;
897
+ readonly languages: _angular_core.InputSignal<readonly ShellLanguage[]>;
898
+ readonly language: _angular_core.InputSignal<string | null>;
899
+ readonly version: _angular_core.InputSignal<string | null>;
900
+ /** Host entries of the user menu (its `items`). */
901
+ readonly userMenuItems: _angular_core.InputSignal<readonly ShellUserMenuItem[]>;
902
+ /** Translations; members left out fall back to {@link SHELL_MESSAGES}, then English. */
903
+ readonly messages: _angular_core.InputSignal<Partial<ShellMessages> | null>;
904
+ /** The person picked the other mode; the host applies it and rebuilds the navigation. */
905
+ readonly modeChange: _angular_core.OutputEmitterRef<string>;
906
+ /** The search trigger was used. */
907
+ readonly searchRequested: _angular_core.OutputEmitterRef<void>;
908
+ /** The ✦ toggle was used. */
909
+ readonly assistantToggle: _angular_core.OutputEmitterRef<void>;
910
+ readonly signIn: _angular_core.OutputEmitterRef<void>;
911
+ readonly signOut: _angular_core.OutputEmitterRef<void>;
912
+ readonly themeChange: _angular_core.OutputEmitterRef<ShellThemePreference>;
913
+ readonly densityChange: _angular_core.OutputEmitterRef<string>;
914
+ readonly languageChange: _angular_core.OutputEmitterRef<string>;
915
+ /** A host entry of the user menu was chosen (its `itemSelected`). */
916
+ readonly userMenuItemSelected: _angular_core.OutputEmitterRef<ShellUserMenuItem>;
917
+ protected readonly m: _angular_core.Signal<ShellMessages>;
918
+ protected readonly isProduction: _angular_core.Signal<boolean>;
919
+ protected readonly showEnvironment: _angular_core.Signal<boolean>;
920
+ /** A switch with one choice would be noise (e.g. users without builder roles). */
921
+ protected readonly showModeSwitch: _angular_core.Signal<boolean>;
922
+ /** The ✦ toggle: only when available and inside a tenant the user may open. */
923
+ protected readonly showAssistant: _angular_core.Signal<boolean>;
924
+ /** ⌘K on Apple platforms, Ctrl K elsewhere — the shortcut the palette binds. */
925
+ private readonly isApple;
926
+ protected readonly shortcutLabel: string;
927
+ /** ⌘J / Ctrl J — the assistant shortcut the host binds. */
928
+ protected readonly assistantShortcutLabel: string;
929
+ /** Both chords work everywhere; the platform's usual one is listed first. */
930
+ protected readonly assistantKeyShortcut: string;
931
+ protected selectMode(mode: string): void;
932
+ protected toggleAssistant(): void;
933
+ protected requestSearch(): void;
934
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<ShellTopBarComponent, never>;
935
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<ShellTopBarComponent, "mm-shell-top-bar", never, { "tenantId": { "alias": "tenantId"; "required": false; "isSignal": true; }; "isDenied": { "alias": "isDenied"; "required": false; "isSignal": true; }; "brandName": { "alias": "brandName"; "required": false; "isSignal": true; }; "brandMarkSrc": { "alias": "brandMarkSrc"; "required": false; "isSignal": true; }; "environment": { "alias": "environment"; "required": false; "isSignal": true; }; "modes": { "alias": "modes"; "required": false; "isSignal": true; }; "currentMode": { "alias": "currentMode"; "required": false; "isSignal": true; }; "assistantAvailable": { "alias": "assistantAvailable"; "required": false; "isSignal": true; }; "assistantOpen": { "alias": "assistantOpen"; "required": false; "isSignal": true; }; "assistantPanelId": { "alias": "assistantPanelId"; "required": false; "isSignal": true; }; "user": { "alias": "user"; "required": false; "isSignal": true; }; "sessionLoading": { "alias": "sessionLoading"; "required": false; "isSignal": true; }; "theme": { "alias": "theme"; "required": false; "isSignal": true; }; "densityOptions": { "alias": "densityOptions"; "required": false; "isSignal": true; }; "density": { "alias": "density"; "required": false; "isSignal": true; }; "languages": { "alias": "languages"; "required": false; "isSignal": true; }; "language": { "alias": "language"; "required": false; "isSignal": true; }; "version": { "alias": "version"; "required": false; "isSignal": true; }; "userMenuItems": { "alias": "userMenuItems"; "required": false; "isSignal": true; }; "messages": { "alias": "messages"; "required": false; "isSignal": true; }; }, { "modeChange": "modeChange"; "searchRequested": "searchRequested"; "assistantToggle": "assistantToggle"; "signIn": "signIn"; "signOut": "signOut"; "themeChange": "themeChange"; "densityChange": "densityChange"; "languageChange": "languageChange"; "userMenuItemSelected": "userMenuItemSelected"; }, never, ["[shellTenant]", "[shellUserMenuItems]"], true, never>;
936
+ }
937
+
938
+ export { DEFAULT_SHELL_LANGUAGES, DEFAULT_SHELL_MESSAGES, RAIL_BOTTOM_SEPARATOR_ID, RAIL_FLYOUT_CLOSE_DELAY, RAIL_FLYOUT_OPEN_DELAY, SHELL_BADGE_MAX, SHELL_MESSAGES, SHELL_NOTIFICATION_OPTIONS, SHELL_SETTINGS_SPACE, SettingsSideNavBadgesService, SettingsSideNavComponent, ShellNavigationService, ShellRailComponent, ShellSearchTriggerService, ShellTopBarComponent, ShellUserMenuComponent, SpaceHeaderService, SpaceShellComponent, areaId, crumbPath, firstNameOf, formatShellMessage, greetingPhrase, homeGreeting, homeMeta, isAreaCrumb, resolveShellBadge, resolveShellMessages, shellBadgeText, shellBreadcrumbs, shellEnvironmentChip, spaceOfAreaId, tabId };
939
+ export type { GreetingUser, SettingsSideNavBadge, SettingsSideNavGroup, ShellAreaCrumb, ShellBreadcrumbOptions, ShellDensityOption, ShellEnvironmentChip, ShellEnvironmentMode, ShellLanguage, ShellMessages, ShellModeOption, ShellNavBadge, ShellNavBadges, ShellNavItemKind, ShellNavNode, ShellRouteData, ShellStatus, ShellThemePreference, ShellUser, ShellUserMenuItem, SpaceMetaItem, SpaceStatusChip };