@filip.mazev/blocks 1.4.16 → 1.4.18
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.
- package/core/styles/_field-actions.scss +36 -0
- package/core/styles/_helpers.scss +2 -0
- package/core/styles/_slider-rail.scss +11 -0
- package/core/styles/_slider.scss +3 -5
- package/fesm2022/filip.mazev-blocks-core.mjs +56 -9
- package/fesm2022/filip.mazev-blocks-core.mjs.map +1 -1
- package/fesm2022/filip.mazev-blocks-forms.mjs +342 -77
- package/fesm2022/filip.mazev-blocks-forms.mjs.map +1 -1
- package/fesm2022/filip.mazev-blocks-navigation.mjs +1176 -11
- package/fesm2022/filip.mazev-blocks-navigation.mjs.map +1 -1
- package/fesm2022/filip.mazev-blocks-primitives.mjs +441 -7
- package/fesm2022/filip.mazev-blocks-primitives.mjs.map +1 -1
- package/fesm2022/filip.mazev-blocks.mjs +1 -1
- package/fesm2022/filip.mazev-blocks.mjs.map +1 -1
- package/package.json +1 -1
- package/types/filip.mazev-blocks-core.d.ts +19 -2
- package/types/filip.mazev-blocks-forms.d.ts +77 -3
- package/types/filip.mazev-blocks-navigation.d.ts +348 -4
- package/types/filip.mazev-blocks-primitives.d.ts +112 -0
- package/types/filip.mazev-blocks.d.ts +1 -1
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
import * as i0 from "@angular/core";
|
|
2
|
-
import { ChangeDetectionStrategy, Component, Injectable, InjectionToken, computed, inject, input } from "@angular/core";
|
|
2
|
+
import { ChangeDetectionStrategy, Component, DOCUMENT, DestroyRef, Directive, ElementRef, Injectable, InjectionToken, Injector, TemplateRef, afterNextRender, afterRenderEffect, computed, effect, inject, input, model, output, signal, untracked, viewChild } from "@angular/core";
|
|
3
3
|
import { NavigationEnd, Router, RouterLink } from "@angular/router";
|
|
4
|
-
import { filter } from "rxjs";
|
|
5
|
-
import { toSignal } from "@angular/core/rxjs-interop";
|
|
6
|
-
import { BX_I18N, BxA11yService, isTextWithKey } from "@filip.mazev/blocks/core";
|
|
4
|
+
import { Subject, filter } from "rxjs";
|
|
5
|
+
import { takeUntilDestroyed, toSignal } from "@angular/core/rxjs-interop";
|
|
6
|
+
import { BX_I18N, BxA11yService, ScrollLockService, WindowDimensionsService, isTextWithKey, resolveText, uuidv4 } from "@filip.mazev/blocks/core";
|
|
7
7
|
import { Icon } from "@filip.mazev/blocks/icons";
|
|
8
|
+
import { NgTemplateOutlet } from "@angular/common";
|
|
9
|
+
import * as i1 from "@angular/cdk/a11y";
|
|
10
|
+
import { A11yModule, FocusMonitor } from "@angular/cdk/a11y";
|
|
11
|
+
import * as i2 from "@angular/forms";
|
|
12
|
+
import { FormsModule } from "@angular/forms";
|
|
13
|
+
import { Button, SearchInput } from "@filip.mazev/blocks/forms";
|
|
14
|
+
import { BxSurfaceDirective } from "@filip.mazev/blocks/effects";
|
|
15
|
+
import { Menu, MenuCascadeService, MenuTriggerDirective, Tag, TooltipDirective, navigateMenuKey } from "@filip.mazev/blocks/primitives";
|
|
8
16
|
const NAVIGATION_CONFIG = new InjectionToken("NAVIGATION_CONFIG");
|
|
9
17
|
const NAVIGATION_ACCESS_ADAPTER = new InjectionToken("NAVIGATION_ACCESS_ADAPTER");
|
|
10
18
|
var NavigationService = class NavigationService {
|
|
@@ -22,6 +30,7 @@ var NavigationService = class NavigationService {
|
|
|
22
30
|
return this.accessAdapter?.resolveBaseRoute();
|
|
23
31
|
}, ...ngDevMode ? [{ debugName: "routeBase" }] : /* istanbul ignore next */ []);
|
|
24
32
|
routes = computed(() => {
|
|
33
|
+
this.navEnd();
|
|
25
34
|
this.i18n?.version?.();
|
|
26
35
|
return this.extractRoutes(this.router.config);
|
|
27
36
|
}, ...ngDevMode ? [{ debugName: "routes" }] : /* istanbul ignore next */ []);
|
|
@@ -48,7 +57,7 @@ var NavigationService = class NavigationService {
|
|
|
48
57
|
const sections = [...this.config?.sections ?? []].sort((a, b) => (a.order ?? Number.POSITIVE_INFINITY) - (b.order ?? Number.POSITIVE_INFINITY));
|
|
49
58
|
const groups = new Map(sections.map((section) => [section.id, {
|
|
50
59
|
id: section.id,
|
|
51
|
-
title: section.title ?? section.id,
|
|
60
|
+
title: resolveText(section.title ?? section.id, this.i18n),
|
|
52
61
|
items: []
|
|
53
62
|
}]));
|
|
54
63
|
for (const item of this.flattenRoutes(this.menu())) {
|
|
@@ -70,6 +79,17 @@ var NavigationService = class NavigationService {
|
|
|
70
79
|
}
|
|
71
80
|
return [...groups.values()].filter((group) => group.items.length > 0);
|
|
72
81
|
}, ...ngDevMode ? [{ debugName: "menuGroups" }] : /* istanbul ignore next */ []);
|
|
82
|
+
menuTreeGroups = computed(() => {
|
|
83
|
+
this.i18n?.version?.();
|
|
84
|
+
const sections = [...this.config?.sections ?? []].sort((a, b) => (a.order ?? Infinity) - (b.order ?? Infinity));
|
|
85
|
+
const groups = new Map(sections.map((section) => [section.id, {
|
|
86
|
+
...section,
|
|
87
|
+
title: resolveText(section.title ?? section.id, this.i18n),
|
|
88
|
+
items: []
|
|
89
|
+
}]));
|
|
90
|
+
this.groupTree(this.menu(), groups);
|
|
91
|
+
return [...groups.values()].filter((group) => group.items.length > 0);
|
|
92
|
+
}, ...ngDevMode ? [{ debugName: "menuTreeGroups" }] : /* istanbul ignore next */ []);
|
|
73
93
|
navigateBack() {
|
|
74
94
|
const breadcrumbs = this.current().breadcrumbs;
|
|
75
95
|
if (breadcrumbs.length > 1) {
|
|
@@ -77,7 +97,38 @@ var NavigationService = class NavigationService {
|
|
|
77
97
|
this.router.navigateByUrl(previousBreadcrumb.route);
|
|
78
98
|
} else this.router.navigateByUrl(this.routeBase() ?? "/");
|
|
79
99
|
}
|
|
80
|
-
|
|
100
|
+
groupTree(items, groups, inheritedSection = "", parent) {
|
|
101
|
+
for (const item of items) {
|
|
102
|
+
const section = item.section ?? inheritedSection;
|
|
103
|
+
let group = groups.get(section);
|
|
104
|
+
if (!group) {
|
|
105
|
+
group = {
|
|
106
|
+
id: section,
|
|
107
|
+
title: section,
|
|
108
|
+
items: []
|
|
109
|
+
};
|
|
110
|
+
groups.set(section, group);
|
|
111
|
+
}
|
|
112
|
+
if (!item.visible || item.data?.hidden) continue;
|
|
113
|
+
if (item.data?.menu === false) {
|
|
114
|
+
this.groupTree(item.children ?? [], groups, section, section === inheritedSection ? parent : void 0);
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
const entry = {
|
|
118
|
+
...item,
|
|
119
|
+
section,
|
|
120
|
+
children: []
|
|
121
|
+
};
|
|
122
|
+
(parent && section === inheritedSection ? parent.children ??= [] : group.items).push(entry);
|
|
123
|
+
this.groupTree(item.children ?? [], groups, section, entry);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
includeBreadcrumb(item) {
|
|
127
|
+
if (item.data?.hidden && !this.config?.includeHiddenInBreadcrumbs) return false;
|
|
128
|
+
const section = this.config?.sections?.find((candidate) => candidate.id === item.section);
|
|
129
|
+
return item.showInBreadcrumbs ?? item.data?.showInBreadcrumbs ?? section?.showInBreadcrumbs ?? true;
|
|
130
|
+
}
|
|
131
|
+
extractRoutes(routes, parentSegment = [], parentSection) {
|
|
81
132
|
const items = [];
|
|
82
133
|
for (const route of routes) {
|
|
83
134
|
if (route.redirectTo) continue;
|
|
@@ -85,8 +136,8 @@ var NavigationService = class NavigationService {
|
|
|
85
136
|
const ownPath = route.path ?? "";
|
|
86
137
|
const fullSegments = ownPath ? [...parentSegment, ownPath] : [...parentSegment];
|
|
87
138
|
const fullRoute = "/" + fullSegments.filter(Boolean).join("/");
|
|
88
|
-
const children = route.children?.length ? this.extractRoutes(route.children, fullSegments) : [];
|
|
89
139
|
const nav = route.data?.["nav"];
|
|
140
|
+
const children = route.children?.length ? this.extractRoutes(route.children, fullSegments, nav?.section ?? parentSection) : [];
|
|
90
141
|
if (!nav) {
|
|
91
142
|
items.push(...children);
|
|
92
143
|
continue;
|
|
@@ -96,7 +147,8 @@ var NavigationService = class NavigationService {
|
|
|
96
147
|
route: fullRoute,
|
|
97
148
|
label: this.resolveNavText(nav.label, { snapshot: void 0 }) ?? "",
|
|
98
149
|
icon: nav.icon,
|
|
99
|
-
|
|
150
|
+
showInBreadcrumbs: nav.showInBreadcrumbs,
|
|
151
|
+
section: nav.section ?? parentSection,
|
|
100
152
|
visible: nav.visible ? nav.visible() : true,
|
|
101
153
|
data: nav,
|
|
102
154
|
children
|
|
@@ -124,7 +176,7 @@ var NavigationService = class NavigationService {
|
|
|
124
176
|
for (const segment of urlSegments) {
|
|
125
177
|
currentUrl += "/" + segment;
|
|
126
178
|
const matchingItem = this.matchRouteToUrl(allItems, currentUrl);
|
|
127
|
-
if (matchingItem &&
|
|
179
|
+
if (matchingItem?.data && this.includeBreadcrumb(matchingItem)) {
|
|
128
180
|
const ctx = { snapshot: finalSnapshot };
|
|
129
181
|
const label = this.resolveNavText(matchingItem.data.breadcrumb, ctx) ?? this.resolveNavText(matchingItem.data.label, ctx);
|
|
130
182
|
if (label && breadcrumbs[breadcrumbs.length - 1]?.label !== label) breadcrumbs.push({
|
|
@@ -141,6 +193,7 @@ var NavigationService = class NavigationService {
|
|
|
141
193
|
route: fullUrl,
|
|
142
194
|
label: this.resolveNavText(leafNav.label, { snapshot: finalSnapshot }) ?? "",
|
|
143
195
|
icon: leafNav.icon,
|
|
196
|
+
showInBreadcrumbs: leafNav.showInBreadcrumbs,
|
|
144
197
|
section: leafNav.section,
|
|
145
198
|
visible: leafNav.visible ? leafNav.visible() : true,
|
|
146
199
|
data: leafNav
|
|
@@ -152,6 +205,7 @@ var NavigationService = class NavigationService {
|
|
|
152
205
|
}
|
|
153
206
|
buildMenu(items) {
|
|
154
207
|
return items.map((item) => {
|
|
208
|
+
if (!item.visible || item.data?.hidden) return null;
|
|
155
209
|
const children = this.buildMenu(item.children ?? []);
|
|
156
210
|
if (!(item.visible && item.data?.menu !== false) && !children.length) return null;
|
|
157
211
|
return {
|
|
@@ -188,7 +242,7 @@ var NavigationService = class NavigationService {
|
|
|
188
242
|
resolveNavText(textDef, ctx) {
|
|
189
243
|
if (!textDef) return void 0;
|
|
190
244
|
const text = typeof textDef === "function" ? textDef(ctx) : textDef;
|
|
191
|
-
if (isTextWithKey(text)) return this.i18n?.translate(text.key, { route: ctx.snapshot });
|
|
245
|
+
if (isTextWithKey(text)) return this.i18n?.translate(text.key, { route: ctx.snapshot }) ?? text.key;
|
|
192
246
|
return text;
|
|
193
247
|
}
|
|
194
248
|
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
@@ -362,6 +416,1117 @@ function withNav(route, nav) {
|
|
|
362
416
|
}
|
|
363
417
|
};
|
|
364
418
|
}
|
|
365
|
-
|
|
419
|
+
const SIDE_NAV_DEFAULTS = {
|
|
420
|
+
side: "left",
|
|
421
|
+
position: "fixed",
|
|
422
|
+
width: "17rem",
|
|
423
|
+
collapsedWidth: "4.5rem",
|
|
424
|
+
searchable: true,
|
|
425
|
+
showItemIcons: true,
|
|
426
|
+
showSectionIcons: true,
|
|
427
|
+
collapsible: true,
|
|
428
|
+
collapsed: false,
|
|
429
|
+
mobileBreakpoint: "lg",
|
|
430
|
+
showMobileTrigger: true,
|
|
431
|
+
ariaLabel: "Main navigation",
|
|
432
|
+
searchPlaceholder: "Search navigation…",
|
|
433
|
+
searchLabel: "Search navigation",
|
|
434
|
+
clearSearchLabel: "Clear search",
|
|
435
|
+
emptyText: "No matching pages.",
|
|
436
|
+
openLabel: "Open navigation",
|
|
437
|
+
closeLabel: "Close navigation",
|
|
438
|
+
collapseLabel: "Collapse navigation",
|
|
439
|
+
expandLabel: "Expand navigation",
|
|
440
|
+
submenuLabel: "Open submenu",
|
|
441
|
+
resultLabel: "Search result"
|
|
442
|
+
};
|
|
443
|
+
const SIDE_NAV_ACTIVE_OPTIONS = {
|
|
444
|
+
paths: "subset",
|
|
445
|
+
queryParams: "ignored",
|
|
446
|
+
matrixParams: "ignored",
|
|
447
|
+
fragment: "ignored"
|
|
448
|
+
};
|
|
449
|
+
const SIDE_NAV_CURRENT_OPTIONS = {
|
|
450
|
+
...SIDE_NAV_ACTIVE_OPTIONS,
|
|
451
|
+
paths: "exact"
|
|
452
|
+
};
|
|
453
|
+
function normalizeNavText(value) {
|
|
454
|
+
return value.normalize("NFD").replace(/\p{M}/gu, "").toLocaleLowerCase().trim();
|
|
455
|
+
}
|
|
456
|
+
function navMatchScore(label, query) {
|
|
457
|
+
const text = normalizeNavText(label);
|
|
458
|
+
const term = normalizeNavText(query);
|
|
459
|
+
if (!term) return 0;
|
|
460
|
+
if (text === term) return 1e3;
|
|
461
|
+
if (text.includes(term)) return Math.max(600, 800 - text.indexOf(term) - (text.length - term.length));
|
|
462
|
+
let index = 0;
|
|
463
|
+
let gaps = 0;
|
|
464
|
+
for (const letter of text) if (letter === term[index]) index++;
|
|
465
|
+
else if (index) gaps++;
|
|
466
|
+
if (index === term.length) return Math.max(1, 500 - gaps - text.length);
|
|
467
|
+
if (term.length < 4) return -1;
|
|
468
|
+
for (const word of text.split(/\s+/)) {
|
|
469
|
+
if (Math.abs(word.length - term.length) > 1) continue;
|
|
470
|
+
const previous = Array.from({ length: term.length + 1 }, (_, i) => i);
|
|
471
|
+
for (let row = 1; row <= word.length; row++) {
|
|
472
|
+
let diagonal = previous[0];
|
|
473
|
+
previous[0] = row;
|
|
474
|
+
for (let column = 1; column <= term.length; column++) {
|
|
475
|
+
const saved = previous[column];
|
|
476
|
+
previous[column] = Math.min(previous[column] + 1, previous[column - 1] + 1, diagonal + (word[row - 1] === term[column - 1] ? 0 : 1));
|
|
477
|
+
diagonal = saved;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
if (previous[term.length] <= 1) return 250;
|
|
481
|
+
}
|
|
482
|
+
return -1;
|
|
483
|
+
}
|
|
484
|
+
function searchNavigation(groups, query) {
|
|
485
|
+
if (!query.trim()) return {
|
|
486
|
+
groups,
|
|
487
|
+
path: []
|
|
488
|
+
};
|
|
489
|
+
let bestScore = -1;
|
|
490
|
+
let bestPath = [];
|
|
491
|
+
let bestLabel;
|
|
492
|
+
const filter = (items, path, sectionTitle) => items.flatMap((item) => {
|
|
493
|
+
const nextPath = [...path, item.id];
|
|
494
|
+
const children = item.data?.disabled ? [] : filter(item.children ?? [], nextPath, sectionTitle);
|
|
495
|
+
const keywords = item.data?.keywords?.filter((keyword) => typeof keyword === "string") ?? [];
|
|
496
|
+
const score = Math.max(navMatchScore(item.label, query), ...keywords.map((term) => navMatchScore(term, query)), navMatchScore(sectionTitle, query) - 100);
|
|
497
|
+
if (score > bestScore && !item.data?.disabled) {
|
|
498
|
+
bestScore = score;
|
|
499
|
+
bestPath = nextPath;
|
|
500
|
+
bestLabel = item.label;
|
|
501
|
+
}
|
|
502
|
+
return score >= 0 || children.length ? [{
|
|
503
|
+
...item,
|
|
504
|
+
children: score >= 0 && !children.length ? item.children : children
|
|
505
|
+
}] : [];
|
|
506
|
+
});
|
|
507
|
+
return {
|
|
508
|
+
groups: groups.map((group) => ({
|
|
509
|
+
...group,
|
|
510
|
+
items: filter(group.items, [], group.title)
|
|
511
|
+
})).filter((group) => group.items.length),
|
|
512
|
+
path: bestPath,
|
|
513
|
+
target: bestPath.at(-1),
|
|
514
|
+
label: bestLabel
|
|
515
|
+
};
|
|
516
|
+
}
|
|
517
|
+
function findNavigationPath(groups, id) {
|
|
518
|
+
const visit = (items, path) => {
|
|
519
|
+
for (const item of items) {
|
|
520
|
+
const next = [...path, item.id];
|
|
521
|
+
if (item.id === id) return next;
|
|
522
|
+
const found = visit(item.children ?? [], next);
|
|
523
|
+
if (found) return found;
|
|
524
|
+
}
|
|
525
|
+
};
|
|
526
|
+
for (const group of groups) {
|
|
527
|
+
const result = visit(group.items, []);
|
|
528
|
+
if (result) return result;
|
|
529
|
+
}
|
|
530
|
+
return [];
|
|
531
|
+
}
|
|
532
|
+
var SideNavStateService = class SideNavStateService {
|
|
533
|
+
router = inject(Router);
|
|
534
|
+
activeRoute = toSignal(this.router.events.pipe(filter((event) => event instanceof NavigationEnd)));
|
|
535
|
+
i18n = inject(BX_I18N, { optional: true });
|
|
536
|
+
lastSelected = signal(void 0, ...ngDevMode ? [{ debugName: "lastSelected" }] : /* istanbul ignore next */ []);
|
|
537
|
+
rememberedPath = signal([], ...ngDevMode ? [{ debugName: "rememberedPath" }] : /* istanbul ignore next */ []);
|
|
538
|
+
searchSelected = signal(false, ...ngDevMode ? [{ debugName: "searchSelected" }] : /* istanbul ignore next */ []);
|
|
539
|
+
config = signal({}, ...ngDevMode ? [{ debugName: "config" }] : /* istanbul ignore next */ []);
|
|
540
|
+
sourceGroups = signal([], ...ngDevMode ? [{ debugName: "sourceGroups" }] : /* istanbul ignore next */ []);
|
|
541
|
+
query = signal("", ...ngDevMode ? [{ debugName: "query" }] : /* istanbul ignore next */ []);
|
|
542
|
+
itemTemplate = signal(void 0, ...ngDevMode ? [{ debugName: "itemTemplate" }] : /* istanbul ignore next */ []);
|
|
543
|
+
activated = new Subject();
|
|
544
|
+
groups = computed(() => {
|
|
545
|
+
this.i18n?.version?.();
|
|
546
|
+
const resolveItems = (items) => items.filter((item) => item.visible && !item.data?.hidden).map((item) => ({
|
|
547
|
+
...item,
|
|
548
|
+
label: item.data?.label === void 0 ? item.label : this.resolveNav(item.data.label),
|
|
549
|
+
data: {
|
|
550
|
+
...item.data,
|
|
551
|
+
keywords: item.data?.keywords?.map((term) => this.resolveNav(term))
|
|
552
|
+
},
|
|
553
|
+
children: resolveItems(item.children ?? [])
|
|
554
|
+
}));
|
|
555
|
+
return this.sourceGroups().map((group) => ({
|
|
556
|
+
...group,
|
|
557
|
+
items: resolveItems(group.items)
|
|
558
|
+
}));
|
|
559
|
+
}, ...ngDevMode ? [{ debugName: "groups" }] : /* istanbul ignore next */ []);
|
|
560
|
+
activeItem = computed(() => {
|
|
561
|
+
this.activeRoute();
|
|
562
|
+
return this.findActiveItem(this.groups().flatMap((group) => group.items));
|
|
563
|
+
}, ...ngDevMode ? [{ debugName: "activeItem" }] : /* istanbul ignore next */ []);
|
|
564
|
+
activeIds = computed(() => {
|
|
565
|
+
const item = this.activeItem();
|
|
566
|
+
return new Set(item ? findNavigationPath(this.groups(), item.id) : []);
|
|
567
|
+
}, ...ngDevMode ? [{ debugName: "activeIds" }] : /* istanbul ignore next */ []);
|
|
568
|
+
searchResult = computed(() => searchNavigation(this.groups(), this.query()), ...ngDevMode ? [{ debugName: "searchResult" }] : /* istanbul ignore next */ []);
|
|
569
|
+
revealPath = computed(() => this.query().trim() ? this.searchSelected() ? [] : this.searchResult().path : this.rememberedPath(), ...ngDevMode ? [{ debugName: "revealPath" }] : /* istanbul ignore next */ []);
|
|
570
|
+
target = computed(() => this.query().trim() && !this.searchSelected() ? this.searchResult().target : void 0, ...ngDevMode ? [{ debugName: "target" }] : /* istanbul ignore next */ []);
|
|
571
|
+
text = computed(() => {
|
|
572
|
+
this.i18n?.version?.();
|
|
573
|
+
const config = this.config();
|
|
574
|
+
return {
|
|
575
|
+
ariaLabel: resolveText(config.ariaLabel ?? SIDE_NAV_DEFAULTS.ariaLabel, this.i18n),
|
|
576
|
+
searchPlaceholder: resolveText(config.searchPlaceholder ?? SIDE_NAV_DEFAULTS.searchPlaceholder, this.i18n),
|
|
577
|
+
searchLabel: resolveText(config.searchLabel ?? SIDE_NAV_DEFAULTS.searchLabel, this.i18n),
|
|
578
|
+
clearSearchLabel: resolveText(config.clearSearchLabel ?? SIDE_NAV_DEFAULTS.clearSearchLabel, this.i18n),
|
|
579
|
+
emptyText: resolveText(config.emptyText ?? SIDE_NAV_DEFAULTS.emptyText, this.i18n),
|
|
580
|
+
openLabel: resolveText(config.openLabel ?? SIDE_NAV_DEFAULTS.openLabel, this.i18n),
|
|
581
|
+
closeLabel: resolveText(config.closeLabel ?? SIDE_NAV_DEFAULTS.closeLabel, this.i18n),
|
|
582
|
+
collapseLabel: resolveText(config.collapseLabel ?? SIDE_NAV_DEFAULTS.collapseLabel, this.i18n),
|
|
583
|
+
expandLabel: resolveText(config.expandLabel ?? SIDE_NAV_DEFAULTS.expandLabel, this.i18n),
|
|
584
|
+
submenuLabel: resolveText(config.submenuLabel ?? SIDE_NAV_DEFAULTS.submenuLabel, this.i18n),
|
|
585
|
+
resultLabel: resolveText(config.resultLabel ?? SIDE_NAV_DEFAULTS.resultLabel, this.i18n)
|
|
586
|
+
};
|
|
587
|
+
}, ...ngDevMode ? [{ debugName: "text" }] : /* istanbul ignore next */ []);
|
|
588
|
+
constructor() {
|
|
589
|
+
inject(DestroyRef).onDestroy(() => this.activated.complete());
|
|
590
|
+
}
|
|
591
|
+
isCurrent(item) {
|
|
592
|
+
this.activeRoute();
|
|
593
|
+
return !item.data?.disabled && this.router.isActive(item.route, SIDE_NAV_CURRENT_OPTIONS);
|
|
594
|
+
}
|
|
595
|
+
search(query) {
|
|
596
|
+
const wasSearching = !!this.query().trim();
|
|
597
|
+
this.searchSelected.set(false);
|
|
598
|
+
this.query.set(query);
|
|
599
|
+
if (wasSearching && !query.trim()) {
|
|
600
|
+
const selected = this.lastSelected();
|
|
601
|
+
this.rememberedPath.set(selected ? findNavigationPath(this.groups(), selected) : []);
|
|
602
|
+
} else this.rememberedPath.set([]);
|
|
603
|
+
}
|
|
604
|
+
select(item) {
|
|
605
|
+
if (item.data?.disabled) return;
|
|
606
|
+
this.lastSelected.set(item.id);
|
|
607
|
+
this.searchSelected.set(true);
|
|
608
|
+
this.rememberedPath.set([]);
|
|
609
|
+
this.activated.next(item);
|
|
610
|
+
}
|
|
611
|
+
findActiveItem(items) {
|
|
612
|
+
let selected;
|
|
613
|
+
for (const item of items) {
|
|
614
|
+
const child = this.findActiveItem(item.children ?? []);
|
|
615
|
+
const own = !item.data?.disabled && this.router.isActive(item.route, SIDE_NAV_ACTIVE_OPTIONS) ? item : void 0;
|
|
616
|
+
const candidate = child && (!own || this.routeSpecificity(child) >= this.routeSpecificity(own)) ? child : own;
|
|
617
|
+
if (candidate && (!selected || this.routeSpecificity(candidate) > this.routeSpecificity(selected))) selected = candidate;
|
|
618
|
+
}
|
|
619
|
+
return selected;
|
|
620
|
+
}
|
|
621
|
+
routeSpecificity(item) {
|
|
622
|
+
return item.route.split(/[?#]/)[0].length;
|
|
623
|
+
}
|
|
624
|
+
resolveNav(text) {
|
|
625
|
+
return resolveText(typeof text === "function" ? text({ snapshot: void 0 }) : text, this.i18n);
|
|
626
|
+
}
|
|
627
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
628
|
+
minVersion: "12.0.0",
|
|
629
|
+
version: "22.2.3",
|
|
630
|
+
ngImport: i0,
|
|
631
|
+
type: SideNavStateService,
|
|
632
|
+
deps: [],
|
|
633
|
+
target: i0.ɵɵFactoryTarget.Injectable
|
|
634
|
+
});
|
|
635
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({
|
|
636
|
+
minVersion: "12.0.0",
|
|
637
|
+
version: "22.2.3",
|
|
638
|
+
ngImport: i0,
|
|
639
|
+
type: SideNavStateService
|
|
640
|
+
});
|
|
641
|
+
};
|
|
642
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
643
|
+
minVersion: "12.0.0",
|
|
644
|
+
version: "22.2.3",
|
|
645
|
+
ngImport: i0,
|
|
646
|
+
type: SideNavStateService,
|
|
647
|
+
decorators: [{ type: Injectable }],
|
|
648
|
+
ctorParameters: () => []
|
|
649
|
+
});
|
|
650
|
+
var SideNavBranch = class SideNavBranch {
|
|
651
|
+
element = inject(ElementRef).nativeElement;
|
|
652
|
+
a11y = inject(BxA11yService);
|
|
653
|
+
trigger = viewChild(MenuTriggerDirective, ...ngDevMode ? [{ debugName: "trigger" }] : /* istanbul ignore next */ []);
|
|
654
|
+
state = inject(SideNavStateService);
|
|
655
|
+
active = computed(() => this.state.activeItem()?.id === this.item().id, ...ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []);
|
|
656
|
+
ancestor = computed(() => !this.active() && this.state.activeIds().has(this.item().id), ...ngDevMode ? [{ debugName: "ancestor" }] : /* istanbul ignore next */ []);
|
|
657
|
+
current = computed(() => this.state.isCurrent(this.item()), ...ngDevMode ? [{ debugName: "current" }] : /* istanbul ignore next */ []);
|
|
658
|
+
side = computed(() => this.state.config().side === "right" ? "left" : "right", ...ngDevMode ? [{ debugName: "side" }] : /* istanbul ignore next */ []);
|
|
659
|
+
submenuOpen = computed(() => this.trigger()?.isOpen() ?? false, ...ngDevMode ? [{ debugName: "submenuOpen" }] : /* istanbul ignore next */ []);
|
|
660
|
+
highlighted = computed(() => this.state.target() === this.item().id, ...ngDevMode ? [{ debugName: "highlighted" }] : /* istanbul ignore next */ []);
|
|
661
|
+
animated = computed(() => !this.a11y.isReducedMotion(), ...ngDevMode ? [{ debugName: "animated" }] : /* istanbul ignore next */ []);
|
|
662
|
+
item = input.required(...ngDevMode ? [{ debugName: "item" }] : /* istanbul ignore next */ []);
|
|
663
|
+
compact = input(false, ...ngDevMode ? [{ debugName: "compact" }] : /* istanbul ignore next */ []);
|
|
664
|
+
parentTrigger = input(void 0, ...ngDevMode ? [{ debugName: "parentTrigger" }] : /* istanbul ignore next */ []);
|
|
665
|
+
constructor() {
|
|
666
|
+
afterRenderEffect(() => {
|
|
667
|
+
const item = this.item();
|
|
668
|
+
const reveal = this.state.revealPath().includes(item.id);
|
|
669
|
+
const trigger = this.trigger();
|
|
670
|
+
if (!reveal) return;
|
|
671
|
+
untracked(() => {
|
|
672
|
+
this.scrollIntoPanel();
|
|
673
|
+
if (item.children?.length) trigger?.open();
|
|
674
|
+
});
|
|
675
|
+
});
|
|
676
|
+
}
|
|
677
|
+
select() {
|
|
678
|
+
this.state.select(this.item());
|
|
679
|
+
}
|
|
680
|
+
hover(event) {
|
|
681
|
+
if (event.pointerType !== "touch" && !this.item().data?.disabled) this.trigger()?.open();
|
|
682
|
+
}
|
|
683
|
+
leave() {
|
|
684
|
+
this.trigger()?.scheduleClose();
|
|
685
|
+
}
|
|
686
|
+
openOnArrow(event) {
|
|
687
|
+
if (event.key !== (this.side() === "right" ? "ArrowRight" : "ArrowLeft") || !this.item().children?.length) return;
|
|
688
|
+
event.preventDefault();
|
|
689
|
+
event.stopPropagation();
|
|
690
|
+
this.trigger()?.open(true);
|
|
691
|
+
}
|
|
692
|
+
scrollIntoPanel() {
|
|
693
|
+
const scroller = this.element.closest(".bx-side-nav-scroll, .bx-nav-flyout");
|
|
694
|
+
if (!scroller) return;
|
|
695
|
+
const row = this.element.getBoundingClientRect();
|
|
696
|
+
const viewport = scroller.getBoundingClientRect();
|
|
697
|
+
if (row.top < viewport.top) scroller.scrollTop += row.top - viewport.top;
|
|
698
|
+
else if (row.bottom > viewport.bottom) scroller.scrollTop += row.bottom - viewport.bottom;
|
|
699
|
+
}
|
|
700
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
701
|
+
minVersion: "12.0.0",
|
|
702
|
+
version: "22.2.3",
|
|
703
|
+
ngImport: i0,
|
|
704
|
+
type: SideNavBranch,
|
|
705
|
+
deps: [],
|
|
706
|
+
target: i0.ɵɵFactoryTarget.Component
|
|
707
|
+
});
|
|
708
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
709
|
+
minVersion: "17.0.0",
|
|
710
|
+
version: "22.2.3",
|
|
711
|
+
type: SideNavBranch,
|
|
712
|
+
isStandalone: true,
|
|
713
|
+
selector: "bx-side-nav-branch",
|
|
714
|
+
inputs: {
|
|
715
|
+
item: {
|
|
716
|
+
classPropertyName: "item",
|
|
717
|
+
publicName: "item",
|
|
718
|
+
isSignal: true,
|
|
719
|
+
isRequired: true,
|
|
720
|
+
transformFunction: null
|
|
721
|
+
},
|
|
722
|
+
compact: {
|
|
723
|
+
classPropertyName: "compact",
|
|
724
|
+
publicName: "compact",
|
|
725
|
+
isSignal: true,
|
|
726
|
+
isRequired: false,
|
|
727
|
+
transformFunction: null
|
|
728
|
+
},
|
|
729
|
+
parentTrigger: {
|
|
730
|
+
classPropertyName: "parentTrigger",
|
|
731
|
+
publicName: "parentTrigger",
|
|
732
|
+
isSignal: true,
|
|
733
|
+
isRequired: false,
|
|
734
|
+
transformFunction: null
|
|
735
|
+
}
|
|
736
|
+
},
|
|
737
|
+
host: { attributes: { "role": "none" } },
|
|
738
|
+
viewQueries: [{
|
|
739
|
+
propertyName: "trigger",
|
|
740
|
+
first: true,
|
|
741
|
+
predicate: MenuTriggerDirective,
|
|
742
|
+
descendants: true,
|
|
743
|
+
isSignal: true
|
|
744
|
+
}],
|
|
745
|
+
ngImport: i0,
|
|
746
|
+
template: "<div #row class=\"bx-nav-row\" role=\"none\" [class.is-active]=\"active()\" [class.is-ancestor]=\"ancestor()\" [class.is-open]=\"submenuOpen()\" [class.is-compact]=\"compact()\" [class.is-highlighted]=\"highlighted()\"\n [class.is-animated]=\"animated()\" [class.is-right]=\"state.config().side === 'right'\" [class.is-disabled]=\"item().data?.disabled\"\n [attr.data-nav-id]=\"item().id\" (pointerenter)=\"hover($event)\" (pointerleave)=\"leave()\">\n @if (!(compact() && item().children?.length)) {\n <a class=\"bx-nav-link\" role=\"menuitem\" [routerLink]=\"item().data?.disabled ? null : item().route\"\n [attr.aria-current]=\"current() ? 'page' : null\"\n [attr.aria-disabled]=\"item().data?.disabled || null\" [attr.tabindex]=\"item().data?.disabled ? -1 : 0\"\n [attr.aria-label]=\"compact() ? item().label : null\" [bxTooltip]=\"compact() ? item().label : ''\"\n [placement]=\"side()\" (click)=\"select()\" (keydown)=\"openOnArrow($event)\">\n @if (state.itemTemplate(); as template) {\n <ng-container [ngTemplateOutlet]=\"template\" [ngTemplateOutletContext]=\"{ $implicit: item(), active: active(), collapsed: compact() }\" />\n } @else {\n <ng-container [ngTemplateOutlet]=\"label\" />\n }\n </a>\n }\n @if (item().children?.length) {\n <button type=\"button\" role=\"menuitem\" class=\"bx-nav-disclosure\" [class.bx-nav-link]=\"compact()\" [disabled]=\"item().data?.disabled\"\n [attr.aria-label]=\"state.text().submenuLabel + ': ' + item().label\" [bxMenuTrigger]=\"flyout\" #trigger=\"bxMenuTrigger\"\n [menuOrigin]=\"row\" [menuParent]=\"parentTrigger()\" [menuSide]=\"side()\" [menuLabel]=\"item().label\" [menuHover]=\"true\" [menuPinned]=\"state.revealPath().includes(item().id)\">\n @if (compact()) { <ng-container [ngTemplateOutlet]=\"label\" /> }\n @else { <bx-icon [name]=\"side() === 'right' ? 'chevron-right' : 'chevron-left'\" size=\"16\" /> }\n </button>\n <ng-template #flyout>\n <div class=\"bx-nav-flyout\" [class.is-right]=\"state.config().side === 'right'\">\n <bx-menu>\n @if (compact()) {\n <a role=\"menuitem\" class=\"bx-nav-parent-link\" [class.is-active]=\"active()\" [attr.aria-current]=\"current() ? 'page' : null\" [routerLink]=\"item().route\" (click)=\"select()\">{{ item().label }}</a>\n }\n @for (child of item().children; track child.id) {\n <bx-side-nav-branch [item]=\"child\" [parentTrigger]=\"trigger\" />\n }\n </bx-menu>\n </div>\n </ng-template>\n }\n @if (highlighted()) {\n <span class=\"bx-nav-target\" aria-hidden=\"true\"><bx-icon [name]=\"side() === 'right' ? 'arrow-left' : 'arrow-right'\" size=\"20\" /></span>\n }\n</div>\n<ng-template #label>\n @if (compact() || state.config().showItemIcons !== false) {\n <bx-icon class=\"bx-nav-icon\" [name]=\"item().icon?.name ?? item().data?.icon?.name ?? 'circle'\" [size]=\"item().icon?.size ?? item().data?.icon?.size ?? '20'\" [color]=\"item().icon?.color ?? item().data?.icon?.color\"\n [bgColor]=\"item().icon?.bgColor ?? item().data?.icon?.bgColor\" [strokeWidth]=\"item().icon?.strokeWidth ?? item().data?.icon?.strokeWidth\" />\n }\n @if (!compact()) {\n <span class=\"bx-nav-label\">{{ item().label }}</span>\n @for (tag of item().data?.tags; track $index) { <bx-tag [opaque]=\"true\" [text]=\"tag.text\" [config]=\"tag.config ?? {}\" size=\"small\" [focusable]=\"false\" /> }\n @if (item().data?.endIcon; as icon) { <bx-icon [name]=\"icon.name\" [size]=\"icon.size ?? '16'\" [color]=\"icon.color\" [bgColor]=\"icon.bgColor\" [strokeWidth]=\"icon.strokeWidth\" /> }\n }\n</ng-template>\n",
|
|
747
|
+
styles: [":host{display:block;min-width:0}.bx-nav-row{display:flex;position:relative;align-items:stretch;gap:.25rem;border:1px solid transparent;border-radius:var(--bx-side-nav-item-radius, .5rem);background:var(--bx-side-nav-item-background, transparent);color:var(--bx-text-primary)}.bx-nav-row:not(.is-disabled):is(:hover,:focus-within,.is-open){background:var(--bx-side-nav-item-hover-background, var(--bx-accent-subtle));color:var(--bx-text-accent)}.bx-nav-row.is-active:not(.is-disabled){background:var(--bx-side-nav-item-active-background, var(--bx-accent-subtle));border-color:var(--bx-border-accent);color:var(--bx-text-accent)}.bx-nav-row.is-highlighted:not(.is-disabled){background:var(--bx-side-nav-item-highlight-background, var(--bx-accent-subtle));color:var(--bx-text-accent);outline:2px dashed var(--bx-border-accent);outline-offset:-2px}.bx-nav-row:has(:focus-visible),.bx-nav-row:focus-visible{outline:2px solid var(--bx-border-brand);outline-offset:-2px}@media(forced-colors:active){.bx-nav-row.is-active{border-color:Highlight}.bx-nav-row.is-highlighted{outline-color:Highlight}}.bx-nav-row.is-ancestor{color:var(--bx-text-accent)}.bx-nav-row.is-disabled{opacity:.5}.bx-nav-link,.bx-nav-disclosure,.bx-nav-parent-link{display:flex;align-items:center;justify-content:flex-start;gap:.5rem;min-height:2.75rem;padding:.5rem .75rem;border:0;border-radius:inherit;background:transparent;color:inherit;font:inherit;font-size:.875rem;text-align:start;text-decoration:none;cursor:pointer;box-sizing:border-box}.bx-nav-link:focus-visible,.bx-nav-disclosure:focus-visible,.bx-nav-parent-link:focus-visible{outline:none}.bx-nav-link[aria-disabled=true],.bx-nav-link:disabled,.bx-nav-disclosure[aria-disabled=true],.bx-nav-disclosure:disabled,.bx-nav-parent-link[aria-disabled=true],.bx-nav-parent-link:disabled{cursor:default}.bx-nav-link{flex:1;min-width:0}.bx-nav-label{flex:1;min-width:0;overflow-wrap:anywhere}.bx-nav-icon{flex:none}.bx-nav-disclosure{flex:none;padding-inline:.5rem}.bx-nav-parent-link{border:1px solid transparent;border-radius:var(--bx-side-nav-item-radius, .5rem);background:var(--bx-side-nav-item-background, transparent);color:var(--bx-text-primary)}.bx-nav-parent-link:not(.is-disabled):is(:hover,:focus-within,.is-open){background:var(--bx-side-nav-item-hover-background, var(--bx-accent-subtle));color:var(--bx-text-accent)}.bx-nav-parent-link.is-active:not(.is-disabled){background:var(--bx-side-nav-item-active-background, var(--bx-accent-subtle));border-color:var(--bx-border-accent);color:var(--bx-text-accent)}.bx-nav-parent-link.is-highlighted:not(.is-disabled){background:var(--bx-side-nav-item-highlight-background, var(--bx-accent-subtle));color:var(--bx-text-accent);outline:2px dashed var(--bx-border-accent);outline-offset:-2px}.bx-nav-parent-link:has(:focus-visible),.bx-nav-parent-link:focus-visible{outline:2px solid var(--bx-border-brand);outline-offset:-2px}@media(forced-colors:active){.bx-nav-parent-link.is-active{border-color:Highlight}.bx-nav-parent-link.is-highlighted{outline-color:Highlight}}.bx-nav-parent-link{font-weight:600}.is-compact{justify-content:center}.is-compact .bx-nav-link{flex:1;justify-content:center;min-width:0;padding-inline:0}.is-compact.is-right{justify-content:center}.bx-nav-flyout{--bx-menu-min-width: 0;--bx-menu-item-gap: var(--bx-side-nav-item-gap, .5rem);box-sizing:border-box;width:var(--bx-side-nav-menu-width, 17rem);max-width:calc(100dvw - 1rem);max-height:min(var(--bx-side-nav-menu-max-height, 32rem),100dvh - 1rem);overflow:hidden auto;scrollbar-gutter:stable;overscroll-behavior:contain;border-radius:.75rem;color:var(--bx-text-primary);box-shadow:0 12px 20px -3px #0003,0 4px 6px -2px #0000001a}.bx-nav-target{display:flex;position:absolute;inset-inline-end:.25rem;top:50%;translate:0 -50%;pointer-events:none;color:var(--bx-text-accent);background:var(--bx-accent-subtle);border:1px solid var(--bx-border-accent);border-radius:9999px;padding:.25rem}.is-highlighted .bx-nav-link{padding-inline-end:2.5rem}.is-animated .bx-nav-target{animation:bx-nav-point .9s ease-in-out infinite alternate}@keyframes bx-nav-point{to{transform:translate(-.25rem)}}@media(forced-colors:active){.bx-nav-row.is-highlighted,.bx-nav-target{outline:2px solid Highlight}.bx-nav-row.is-active .bx-nav-link{text-decoration:underline}}\n"],
|
|
748
|
+
dependencies: [
|
|
749
|
+
{
|
|
750
|
+
kind: "component",
|
|
751
|
+
type: SideNavBranch,
|
|
752
|
+
selector: "bx-side-nav-branch",
|
|
753
|
+
inputs: [
|
|
754
|
+
"item",
|
|
755
|
+
"compact",
|
|
756
|
+
"parentTrigger"
|
|
757
|
+
]
|
|
758
|
+
},
|
|
759
|
+
{
|
|
760
|
+
kind: "directive",
|
|
761
|
+
type: NgTemplateOutlet,
|
|
762
|
+
selector: "[ngTemplateOutlet]",
|
|
763
|
+
inputs: [
|
|
764
|
+
"ngTemplateOutletContext",
|
|
765
|
+
"ngTemplateOutlet",
|
|
766
|
+
"ngTemplateOutletInjector"
|
|
767
|
+
]
|
|
768
|
+
},
|
|
769
|
+
{
|
|
770
|
+
kind: "directive",
|
|
771
|
+
type: RouterLink,
|
|
772
|
+
selector: "[routerLink]",
|
|
773
|
+
inputs: [
|
|
774
|
+
"target",
|
|
775
|
+
"queryParams",
|
|
776
|
+
"fragment",
|
|
777
|
+
"queryParamsHandling",
|
|
778
|
+
"state",
|
|
779
|
+
"info",
|
|
780
|
+
"relativeTo",
|
|
781
|
+
"preserveFragment",
|
|
782
|
+
"skipLocationChange",
|
|
783
|
+
"replaceUrl",
|
|
784
|
+
"browserUrl",
|
|
785
|
+
"routerLink"
|
|
786
|
+
]
|
|
787
|
+
},
|
|
788
|
+
{
|
|
789
|
+
kind: "component",
|
|
790
|
+
type: Icon,
|
|
791
|
+
selector: "bx-icon",
|
|
792
|
+
inputs: [
|
|
793
|
+
"name",
|
|
794
|
+
"size",
|
|
795
|
+
"color",
|
|
796
|
+
"bgColor",
|
|
797
|
+
"strokeWidth",
|
|
798
|
+
"decorative",
|
|
799
|
+
"ariaLabel"
|
|
800
|
+
]
|
|
801
|
+
},
|
|
802
|
+
{
|
|
803
|
+
kind: "component",
|
|
804
|
+
type: Menu,
|
|
805
|
+
selector: "bx-menu"
|
|
806
|
+
},
|
|
807
|
+
{
|
|
808
|
+
kind: "component",
|
|
809
|
+
type: Tag,
|
|
810
|
+
selector: "bx-tag",
|
|
811
|
+
inputs: [
|
|
812
|
+
"opaque",
|
|
813
|
+
"text",
|
|
814
|
+
"config",
|
|
815
|
+
"color",
|
|
816
|
+
"variant",
|
|
817
|
+
"size",
|
|
818
|
+
"disabled",
|
|
819
|
+
"leadingIcon",
|
|
820
|
+
"trailingIcon",
|
|
821
|
+
"iconSize",
|
|
822
|
+
"leadingNumber",
|
|
823
|
+
"trailingNumber",
|
|
824
|
+
"locale",
|
|
825
|
+
"tooltip",
|
|
826
|
+
"tooltipOnTruncate",
|
|
827
|
+
"tooltipPlacement",
|
|
828
|
+
"ariaLabel",
|
|
829
|
+
"focusable"
|
|
830
|
+
]
|
|
831
|
+
},
|
|
832
|
+
{
|
|
833
|
+
kind: "directive",
|
|
834
|
+
type: TooltipDirective,
|
|
835
|
+
selector: "[bxTooltip]",
|
|
836
|
+
inputs: [
|
|
837
|
+
"bxTooltip",
|
|
838
|
+
"placement",
|
|
839
|
+
"bxTooltipTouch",
|
|
840
|
+
"bxTooltipHover"
|
|
841
|
+
]
|
|
842
|
+
},
|
|
843
|
+
{
|
|
844
|
+
kind: "directive",
|
|
845
|
+
type: MenuTriggerDirective,
|
|
846
|
+
selector: "[bxMenuTrigger]",
|
|
847
|
+
inputs: [
|
|
848
|
+
"bxMenuTrigger",
|
|
849
|
+
"menuOrigin",
|
|
850
|
+
"menuParent",
|
|
851
|
+
"menuSide",
|
|
852
|
+
"menuHover",
|
|
853
|
+
"menuLabel",
|
|
854
|
+
"menuPinned"
|
|
855
|
+
],
|
|
856
|
+
outputs: ["menuOpened", "menuClosed"],
|
|
857
|
+
exportAs: ["bxMenuTrigger"]
|
|
858
|
+
}
|
|
859
|
+
],
|
|
860
|
+
changeDetection: i0.ChangeDetectionStrategy.OnPush
|
|
861
|
+
});
|
|
862
|
+
};
|
|
863
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
864
|
+
minVersion: "12.0.0",
|
|
865
|
+
version: "22.2.3",
|
|
866
|
+
ngImport: i0,
|
|
867
|
+
type: SideNavBranch,
|
|
868
|
+
decorators: [{
|
|
869
|
+
type: Component,
|
|
870
|
+
args: [{
|
|
871
|
+
selector: "bx-side-nav-branch",
|
|
872
|
+
imports: [
|
|
873
|
+
NgTemplateOutlet,
|
|
874
|
+
RouterLink,
|
|
875
|
+
Icon,
|
|
876
|
+
Menu,
|
|
877
|
+
Tag,
|
|
878
|
+
TooltipDirective,
|
|
879
|
+
MenuTriggerDirective
|
|
880
|
+
],
|
|
881
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
882
|
+
host: { role: "none" },
|
|
883
|
+
template: "<div #row class=\"bx-nav-row\" role=\"none\" [class.is-active]=\"active()\" [class.is-ancestor]=\"ancestor()\" [class.is-open]=\"submenuOpen()\" [class.is-compact]=\"compact()\" [class.is-highlighted]=\"highlighted()\"\n [class.is-animated]=\"animated()\" [class.is-right]=\"state.config().side === 'right'\" [class.is-disabled]=\"item().data?.disabled\"\n [attr.data-nav-id]=\"item().id\" (pointerenter)=\"hover($event)\" (pointerleave)=\"leave()\">\n @if (!(compact() && item().children?.length)) {\n <a class=\"bx-nav-link\" role=\"menuitem\" [routerLink]=\"item().data?.disabled ? null : item().route\"\n [attr.aria-current]=\"current() ? 'page' : null\"\n [attr.aria-disabled]=\"item().data?.disabled || null\" [attr.tabindex]=\"item().data?.disabled ? -1 : 0\"\n [attr.aria-label]=\"compact() ? item().label : null\" [bxTooltip]=\"compact() ? item().label : ''\"\n [placement]=\"side()\" (click)=\"select()\" (keydown)=\"openOnArrow($event)\">\n @if (state.itemTemplate(); as template) {\n <ng-container [ngTemplateOutlet]=\"template\" [ngTemplateOutletContext]=\"{ $implicit: item(), active: active(), collapsed: compact() }\" />\n } @else {\n <ng-container [ngTemplateOutlet]=\"label\" />\n }\n </a>\n }\n @if (item().children?.length) {\n <button type=\"button\" role=\"menuitem\" class=\"bx-nav-disclosure\" [class.bx-nav-link]=\"compact()\" [disabled]=\"item().data?.disabled\"\n [attr.aria-label]=\"state.text().submenuLabel + ': ' + item().label\" [bxMenuTrigger]=\"flyout\" #trigger=\"bxMenuTrigger\"\n [menuOrigin]=\"row\" [menuParent]=\"parentTrigger()\" [menuSide]=\"side()\" [menuLabel]=\"item().label\" [menuHover]=\"true\" [menuPinned]=\"state.revealPath().includes(item().id)\">\n @if (compact()) { <ng-container [ngTemplateOutlet]=\"label\" /> }\n @else { <bx-icon [name]=\"side() === 'right' ? 'chevron-right' : 'chevron-left'\" size=\"16\" /> }\n </button>\n <ng-template #flyout>\n <div class=\"bx-nav-flyout\" [class.is-right]=\"state.config().side === 'right'\">\n <bx-menu>\n @if (compact()) {\n <a role=\"menuitem\" class=\"bx-nav-parent-link\" [class.is-active]=\"active()\" [attr.aria-current]=\"current() ? 'page' : null\" [routerLink]=\"item().route\" (click)=\"select()\">{{ item().label }}</a>\n }\n @for (child of item().children; track child.id) {\n <bx-side-nav-branch [item]=\"child\" [parentTrigger]=\"trigger\" />\n }\n </bx-menu>\n </div>\n </ng-template>\n }\n @if (highlighted()) {\n <span class=\"bx-nav-target\" aria-hidden=\"true\"><bx-icon [name]=\"side() === 'right' ? 'arrow-left' : 'arrow-right'\" size=\"20\" /></span>\n }\n</div>\n<ng-template #label>\n @if (compact() || state.config().showItemIcons !== false) {\n <bx-icon class=\"bx-nav-icon\" [name]=\"item().icon?.name ?? item().data?.icon?.name ?? 'circle'\" [size]=\"item().icon?.size ?? item().data?.icon?.size ?? '20'\" [color]=\"item().icon?.color ?? item().data?.icon?.color\"\n [bgColor]=\"item().icon?.bgColor ?? item().data?.icon?.bgColor\" [strokeWidth]=\"item().icon?.strokeWidth ?? item().data?.icon?.strokeWidth\" />\n }\n @if (!compact()) {\n <span class=\"bx-nav-label\">{{ item().label }}</span>\n @for (tag of item().data?.tags; track $index) { <bx-tag [opaque]=\"true\" [text]=\"tag.text\" [config]=\"tag.config ?? {}\" size=\"small\" [focusable]=\"false\" /> }\n @if (item().data?.endIcon; as icon) { <bx-icon [name]=\"icon.name\" [size]=\"icon.size ?? '16'\" [color]=\"icon.color\" [bgColor]=\"icon.bgColor\" [strokeWidth]=\"icon.strokeWidth\" /> }\n }\n</ng-template>\n",
|
|
884
|
+
styles: [":host{display:block;min-width:0}.bx-nav-row{display:flex;position:relative;align-items:stretch;gap:.25rem;border:1px solid transparent;border-radius:var(--bx-side-nav-item-radius, .5rem);background:var(--bx-side-nav-item-background, transparent);color:var(--bx-text-primary)}.bx-nav-row:not(.is-disabled):is(:hover,:focus-within,.is-open){background:var(--bx-side-nav-item-hover-background, var(--bx-accent-subtle));color:var(--bx-text-accent)}.bx-nav-row.is-active:not(.is-disabled){background:var(--bx-side-nav-item-active-background, var(--bx-accent-subtle));border-color:var(--bx-border-accent);color:var(--bx-text-accent)}.bx-nav-row.is-highlighted:not(.is-disabled){background:var(--bx-side-nav-item-highlight-background, var(--bx-accent-subtle));color:var(--bx-text-accent);outline:2px dashed var(--bx-border-accent);outline-offset:-2px}.bx-nav-row:has(:focus-visible),.bx-nav-row:focus-visible{outline:2px solid var(--bx-border-brand);outline-offset:-2px}@media(forced-colors:active){.bx-nav-row.is-active{border-color:Highlight}.bx-nav-row.is-highlighted{outline-color:Highlight}}.bx-nav-row.is-ancestor{color:var(--bx-text-accent)}.bx-nav-row.is-disabled{opacity:.5}.bx-nav-link,.bx-nav-disclosure,.bx-nav-parent-link{display:flex;align-items:center;justify-content:flex-start;gap:.5rem;min-height:2.75rem;padding:.5rem .75rem;border:0;border-radius:inherit;background:transparent;color:inherit;font:inherit;font-size:.875rem;text-align:start;text-decoration:none;cursor:pointer;box-sizing:border-box}.bx-nav-link:focus-visible,.bx-nav-disclosure:focus-visible,.bx-nav-parent-link:focus-visible{outline:none}.bx-nav-link[aria-disabled=true],.bx-nav-link:disabled,.bx-nav-disclosure[aria-disabled=true],.bx-nav-disclosure:disabled,.bx-nav-parent-link[aria-disabled=true],.bx-nav-parent-link:disabled{cursor:default}.bx-nav-link{flex:1;min-width:0}.bx-nav-label{flex:1;min-width:0;overflow-wrap:anywhere}.bx-nav-icon{flex:none}.bx-nav-disclosure{flex:none;padding-inline:.5rem}.bx-nav-parent-link{border:1px solid transparent;border-radius:var(--bx-side-nav-item-radius, .5rem);background:var(--bx-side-nav-item-background, transparent);color:var(--bx-text-primary)}.bx-nav-parent-link:not(.is-disabled):is(:hover,:focus-within,.is-open){background:var(--bx-side-nav-item-hover-background, var(--bx-accent-subtle));color:var(--bx-text-accent)}.bx-nav-parent-link.is-active:not(.is-disabled){background:var(--bx-side-nav-item-active-background, var(--bx-accent-subtle));border-color:var(--bx-border-accent);color:var(--bx-text-accent)}.bx-nav-parent-link.is-highlighted:not(.is-disabled){background:var(--bx-side-nav-item-highlight-background, var(--bx-accent-subtle));color:var(--bx-text-accent);outline:2px dashed var(--bx-border-accent);outline-offset:-2px}.bx-nav-parent-link:has(:focus-visible),.bx-nav-parent-link:focus-visible{outline:2px solid var(--bx-border-brand);outline-offset:-2px}@media(forced-colors:active){.bx-nav-parent-link.is-active{border-color:Highlight}.bx-nav-parent-link.is-highlighted{outline-color:Highlight}}.bx-nav-parent-link{font-weight:600}.is-compact{justify-content:center}.is-compact .bx-nav-link{flex:1;justify-content:center;min-width:0;padding-inline:0}.is-compact.is-right{justify-content:center}.bx-nav-flyout{--bx-menu-min-width: 0;--bx-menu-item-gap: var(--bx-side-nav-item-gap, .5rem);box-sizing:border-box;width:var(--bx-side-nav-menu-width, 17rem);max-width:calc(100dvw - 1rem);max-height:min(var(--bx-side-nav-menu-max-height, 32rem),100dvh - 1rem);overflow:hidden auto;scrollbar-gutter:stable;overscroll-behavior:contain;border-radius:.75rem;color:var(--bx-text-primary);box-shadow:0 12px 20px -3px #0003,0 4px 6px -2px #0000001a}.bx-nav-target{display:flex;position:absolute;inset-inline-end:.25rem;top:50%;translate:0 -50%;pointer-events:none;color:var(--bx-text-accent);background:var(--bx-accent-subtle);border:1px solid var(--bx-border-accent);border-radius:9999px;padding:.25rem}.is-highlighted .bx-nav-link{padding-inline-end:2.5rem}.is-animated .bx-nav-target{animation:bx-nav-point .9s ease-in-out infinite alternate}@keyframes bx-nav-point{to{transform:translate(-.25rem)}}@media(forced-colors:active){.bx-nav-row.is-highlighted,.bx-nav-target{outline:2px solid Highlight}.bx-nav-row.is-active .bx-nav-link{text-decoration:underline}}\n"]
|
|
885
|
+
}]
|
|
886
|
+
}],
|
|
887
|
+
ctorParameters: () => [],
|
|
888
|
+
propDecorators: {
|
|
889
|
+
trigger: [{
|
|
890
|
+
type: i0.ViewChild,
|
|
891
|
+
args: [i0.forwardRef(() => MenuTriggerDirective), { isSignal: true }]
|
|
892
|
+
}],
|
|
893
|
+
item: [{
|
|
894
|
+
type: i0.Input,
|
|
895
|
+
args: [{
|
|
896
|
+
isSignal: true,
|
|
897
|
+
alias: "item",
|
|
898
|
+
required: true
|
|
899
|
+
}]
|
|
900
|
+
}],
|
|
901
|
+
compact: [{
|
|
902
|
+
type: i0.Input,
|
|
903
|
+
args: [{
|
|
904
|
+
isSignal: true,
|
|
905
|
+
alias: "compact",
|
|
906
|
+
required: false
|
|
907
|
+
}]
|
|
908
|
+
}],
|
|
909
|
+
parentTrigger: [{
|
|
910
|
+
type: i0.Input,
|
|
911
|
+
args: [{
|
|
912
|
+
isSignal: true,
|
|
913
|
+
alias: "parentTrigger",
|
|
914
|
+
required: false
|
|
915
|
+
}]
|
|
916
|
+
}]
|
|
917
|
+
}
|
|
918
|
+
});
|
|
919
|
+
function definedSideNavConfig(config) {
|
|
920
|
+
return Object.fromEntries(Object.entries(config ?? {}).filter(([, value]) => value !== void 0));
|
|
921
|
+
}
|
|
922
|
+
var SideNav = class SideNav {
|
|
923
|
+
document = inject(DOCUMENT);
|
|
924
|
+
router = inject(Router);
|
|
925
|
+
destroyRef = inject(DestroyRef);
|
|
926
|
+
dimensions = inject(WindowDimensionsService);
|
|
927
|
+
navigation = inject(NavigationService);
|
|
928
|
+
defaults = inject(NAVIGATION_CONFIG, { optional: true });
|
|
929
|
+
scrollLock = inject(ScrollLockService);
|
|
930
|
+
cascade = inject(MenuCascadeService);
|
|
931
|
+
a11y = inject(BxA11yService);
|
|
932
|
+
injector = inject(Injector);
|
|
933
|
+
focusMonitor = inject(FocusMonitor);
|
|
934
|
+
toggleElement = viewChild("mobileToggle", {
|
|
935
|
+
...ngDevMode ? { debugName: "toggleElement" } : /* istanbul ignore next */ {},
|
|
936
|
+
read: ElementRef
|
|
937
|
+
});
|
|
938
|
+
saved = signal({ sections: {} }, ...ngDevMode ? [{ debugName: "saved" }] : /* istanbul ignore next */ []);
|
|
939
|
+
loadedKey = signal(void 0, ...ngDevMode ? [{ debugName: "loadedKey" }] : /* istanbul ignore next */ []);
|
|
940
|
+
lockId = uuidv4();
|
|
941
|
+
presentation = computed(() => `${this.isMobile()}:${this.resolvedConfig().position}:${this.resolvedConfig().side}`, ...ngDevMode ? [{ debugName: "presentation" }] : /* istanbul ignore next */ []);
|
|
942
|
+
drawerAnimated = signal(false, ...ngDevMode ? [{ debugName: "drawerAnimated" }] : /* istanbul ignore next */ []);
|
|
943
|
+
state = inject(SideNavStateService);
|
|
944
|
+
id = `bx-side-nav-${this.lockId}`;
|
|
945
|
+
headerTemplate = signal(null, ...ngDevMode ? [{ debugName: "headerTemplate" }] : /* istanbul ignore next */ []);
|
|
946
|
+
footerTemplate = signal(null, ...ngDevMode ? [{ debugName: "footerTemplate" }] : /* istanbul ignore next */ []);
|
|
947
|
+
reducedMotion = this.a11y.isReducedMotion;
|
|
948
|
+
visibleGroups = computed(() => this.state.searchResult().groups, ...ngDevMode ? [{ debugName: "visibleGroups" }] : /* istanbul ignore next */ []);
|
|
949
|
+
slotContext = computed(() => ({
|
|
950
|
+
$implicit: this.isCollapsed(),
|
|
951
|
+
collapsed: this.isCollapsed(),
|
|
952
|
+
mobile: this.isMobile()
|
|
953
|
+
}), ...ngDevMode ? [{ debugName: "slotContext" }] : /* istanbul ignore next */ []);
|
|
954
|
+
config = input({}, ...ngDevMode ? [{ debugName: "config" }] : /* istanbul ignore next */ []);
|
|
955
|
+
groups = input(void 0, ...ngDevMode ? [{ debugName: "groups" }] : /* istanbul ignore next */ []);
|
|
956
|
+
itemTemplate = input(void 0, ...ngDevMode ? [{ debugName: "itemTemplate" }] : /* istanbul ignore next */ []);
|
|
957
|
+
collapsed = input(void 0, ...ngDevMode ? [{ debugName: "collapsed" }] : /* istanbul ignore next */ []);
|
|
958
|
+
collapsedChange = output();
|
|
959
|
+
mobileOpen = model(false, ...ngDevMode ? [{ debugName: "mobileOpen" }] : /* istanbul ignore next */ []);
|
|
960
|
+
itemSelected = output();
|
|
961
|
+
layoutChange = output();
|
|
962
|
+
resolvedConfig = computed(() => ({
|
|
963
|
+
...SIDE_NAV_DEFAULTS,
|
|
964
|
+
...definedSideNavConfig(this.defaults?.sideNav),
|
|
965
|
+
...definedSideNavConfig(this.config())
|
|
966
|
+
}), ...ngDevMode ? [{ debugName: "resolvedConfig" }] : /* istanbul ignore next */ []);
|
|
967
|
+
isMobile = computed(() => this.resolvedConfig().mobile ?? this.dimensions.dimensions().width <= this.dimensions.breakpoints[this.resolvedConfig().mobileBreakpoint], ...ngDevMode ? [{ debugName: "isMobile" }] : /* istanbul ignore next */ []);
|
|
968
|
+
isCollapsed = computed(() => !this.isMobile() && !this.state.query().trim() && (this.collapsed() ?? this.saved().collapsed ?? this.resolvedConfig().collapsed), ...ngDevMode ? [{ debugName: "isCollapsed" }] : /* istanbul ignore next */ []);
|
|
969
|
+
query = this.state.query.asReadonly();
|
|
970
|
+
layout = computed(() => ({
|
|
971
|
+
side: this.resolvedConfig().side,
|
|
972
|
+
offset: this.isMobile() ? "0px" : this.isCollapsed() ? this.resolvedConfig().collapsedWidth : this.resolvedConfig().width,
|
|
973
|
+
collapsed: this.isCollapsed(),
|
|
974
|
+
mobile: this.isMobile(),
|
|
975
|
+
open: !this.isMobile() || this.mobileOpen()
|
|
976
|
+
}), ...ngDevMode ? [{ debugName: "layout" }] : /* istanbul ignore next */ []);
|
|
977
|
+
restoreFocus;
|
|
978
|
+
focusReturnOrigin = "program";
|
|
979
|
+
focusRevision = 0;
|
|
980
|
+
constructor() {
|
|
981
|
+
effect(() => {
|
|
982
|
+
this.state.config.set(this.resolvedConfig());
|
|
983
|
+
this.state.sourceGroups.set(this.groups() ?? this.navigation.menuTreeGroups());
|
|
984
|
+
this.state.itemTemplate.set(this.itemTemplate());
|
|
985
|
+
});
|
|
986
|
+
effect(() => {
|
|
987
|
+
const key = this.resolvedConfig().persistenceKey;
|
|
988
|
+
untracked(() => {
|
|
989
|
+
this.saved.set(this.readSavedState(key));
|
|
990
|
+
this.loadedKey.set(key);
|
|
991
|
+
});
|
|
992
|
+
});
|
|
993
|
+
effect(() => {
|
|
994
|
+
const key = this.resolvedConfig().persistenceKey;
|
|
995
|
+
const loaded = this.loadedKey();
|
|
996
|
+
const saved = this.saved();
|
|
997
|
+
const collapsed = this.collapsed() ?? saved.collapsed ?? this.resolvedConfig().collapsed;
|
|
998
|
+
if (!key || loaded !== key || !this.document.defaultView) return;
|
|
999
|
+
try {
|
|
1000
|
+
this.document.defaultView.localStorage.setItem(key, JSON.stringify({
|
|
1001
|
+
collapsed,
|
|
1002
|
+
sections: saved.sections
|
|
1003
|
+
}));
|
|
1004
|
+
} catch {}
|
|
1005
|
+
});
|
|
1006
|
+
effect(() => {
|
|
1007
|
+
if (this.isMobile() && this.mobileOpen() && this.resolvedConfig().position !== "inline") this.scrollLock.disableScroll(this.lockId, { handleTouchInput: false });
|
|
1008
|
+
else this.scrollLock.enableScroll(this.lockId);
|
|
1009
|
+
});
|
|
1010
|
+
effect(() => {
|
|
1011
|
+
this.presentation();
|
|
1012
|
+
untracked(() => {
|
|
1013
|
+
this.drawerAnimated.set(false);
|
|
1014
|
+
this.cascade.closeAll();
|
|
1015
|
+
if (this.mobileOpen()) this.close();
|
|
1016
|
+
});
|
|
1017
|
+
});
|
|
1018
|
+
effect(() => this.layoutChange.emit(this.layout()));
|
|
1019
|
+
this.state.activated.pipe(takeUntilDestroyed()).subscribe((item) => {
|
|
1020
|
+
this.itemSelected.emit(item);
|
|
1021
|
+
this.cascade.closeAll();
|
|
1022
|
+
if (this.isMobile()) this.close();
|
|
1023
|
+
});
|
|
1024
|
+
this.router.events.pipe(takeUntilDestroyed()).subscribe((event) => {
|
|
1025
|
+
if (event instanceof NavigationEnd) {
|
|
1026
|
+
this.cascade.closeAll();
|
|
1027
|
+
if (this.mobileOpen()) this.close();
|
|
1028
|
+
}
|
|
1029
|
+
});
|
|
1030
|
+
this.destroyRef.onDestroy(() => {
|
|
1031
|
+
this.scrollLock.enableScroll(this.lockId);
|
|
1032
|
+
});
|
|
1033
|
+
}
|
|
1034
|
+
setHeaderTemplate(template) {
|
|
1035
|
+
this.headerTemplate.set(template);
|
|
1036
|
+
}
|
|
1037
|
+
setFooterTemplate(template) {
|
|
1038
|
+
this.footerTemplate.set(template);
|
|
1039
|
+
}
|
|
1040
|
+
toggle(origin) {
|
|
1041
|
+
if (this.mobileOpen()) this.close();
|
|
1042
|
+
else this.open(origin);
|
|
1043
|
+
}
|
|
1044
|
+
open(origin) {
|
|
1045
|
+
const view = this.document.defaultView;
|
|
1046
|
+
if (!view || !this.isMobile() || this.mobileOpen()) return;
|
|
1047
|
+
const target = origin && "currentTarget" in origin ? origin.currentTarget : origin;
|
|
1048
|
+
const opener = target instanceof view.HTMLElement ? target : void 0;
|
|
1049
|
+
const active = this.document.activeElement;
|
|
1050
|
+
const previous = active && active !== this.document.body && active !== this.document.documentElement ? active : void 0;
|
|
1051
|
+
this.restoreFocus = opener ?? previous ?? this.toggleElement()?.nativeElement;
|
|
1052
|
+
this.focusReturnOrigin = this.restoreFocus?.matches(":focus-visible") ? "keyboard" : "program";
|
|
1053
|
+
++this.focusRevision;
|
|
1054
|
+
if (this.restoreFocus) this.focusMonitor.focusVia(this.restoreFocus, this.focusReturnOrigin, { preventScroll: true });
|
|
1055
|
+
this.drawerAnimated.set(true);
|
|
1056
|
+
this.mobileOpen.set(true);
|
|
1057
|
+
}
|
|
1058
|
+
close() {
|
|
1059
|
+
if (!this.mobileOpen()) return;
|
|
1060
|
+
this.cascade.closeAll();
|
|
1061
|
+
const target = this.restoreFocus?.isConnected ? this.restoreFocus : this.toggleElement()?.nativeElement;
|
|
1062
|
+
const origin = this.focusReturnOrigin;
|
|
1063
|
+
const revision = ++this.focusRevision;
|
|
1064
|
+
this.restoreFocus = void 0;
|
|
1065
|
+
this.mobileOpen.set(false);
|
|
1066
|
+
afterNextRender(() => {
|
|
1067
|
+
if (!this.destroyRef.destroyed && revision === this.focusRevision && !this.mobileOpen() && target?.isConnected) this.focusMonitor.focusVia(target, origin, { preventScroll: true });
|
|
1068
|
+
}, { injector: this.injector });
|
|
1069
|
+
}
|
|
1070
|
+
toggleCollapsed() {
|
|
1071
|
+
const next = !(this.collapsed() ?? this.saved().collapsed ?? this.resolvedConfig().collapsed);
|
|
1072
|
+
this.saved.update((saved) => ({
|
|
1073
|
+
...saved,
|
|
1074
|
+
collapsed: next
|
|
1075
|
+
}));
|
|
1076
|
+
this.collapsedChange.emit(next);
|
|
1077
|
+
}
|
|
1078
|
+
search(query) {
|
|
1079
|
+
this.cascade.closeAll();
|
|
1080
|
+
this.state.search(query);
|
|
1081
|
+
}
|
|
1082
|
+
closeFromControl(event) {
|
|
1083
|
+
this.focusReturnOrigin = event.detail === 0 ? "keyboard" : "program";
|
|
1084
|
+
this.close();
|
|
1085
|
+
}
|
|
1086
|
+
sectionActive(group) {
|
|
1087
|
+
return group.items.some((item) => this.state.activeIds().has(item.id));
|
|
1088
|
+
}
|
|
1089
|
+
sectionHighlighted(group) {
|
|
1090
|
+
return group.items.some((item) => this.state.revealPath().includes(item.id));
|
|
1091
|
+
}
|
|
1092
|
+
sectionCollapsed(group) {
|
|
1093
|
+
const revealing = this.state.revealPath();
|
|
1094
|
+
if (this.query().trim() || group.items.some((item) => revealing.includes(item.id))) return false;
|
|
1095
|
+
return !this.isCollapsed() && !!group.collapsible && (this.saved().sections[group.id] ?? group.collapsed ?? false);
|
|
1096
|
+
}
|
|
1097
|
+
toggleSection(group) {
|
|
1098
|
+
if (!group.collapsible) return;
|
|
1099
|
+
const collapsed = !this.sectionCollapsed(group);
|
|
1100
|
+
this.saved.update((saved) => ({
|
|
1101
|
+
...saved,
|
|
1102
|
+
sections: {
|
|
1103
|
+
...saved.sections,
|
|
1104
|
+
[group.id]: collapsed
|
|
1105
|
+
}
|
|
1106
|
+
}));
|
|
1107
|
+
}
|
|
1108
|
+
menuKey(event) {
|
|
1109
|
+
const menu = event.target?.closest("[role=\"menu\"]");
|
|
1110
|
+
if (menu) navigateMenuKey(event, menu);
|
|
1111
|
+
}
|
|
1112
|
+
panelKey(event) {
|
|
1113
|
+
if (event.defaultPrevented || event.key !== "Escape" || !this.mobileOpen() || this.cascade.hasOpenMenus()) return;
|
|
1114
|
+
event.preventDefault();
|
|
1115
|
+
event.stopPropagation();
|
|
1116
|
+
this.focusReturnOrigin = "keyboard";
|
|
1117
|
+
this.close();
|
|
1118
|
+
}
|
|
1119
|
+
readSavedState(key) {
|
|
1120
|
+
if (!key || !this.document.defaultView) return { sections: {} };
|
|
1121
|
+
try {
|
|
1122
|
+
const value = JSON.parse(this.document.defaultView.localStorage.getItem(key) ?? "null");
|
|
1123
|
+
if (!value || typeof value !== "object") return { sections: {} };
|
|
1124
|
+
const collapsed = "collapsed" in value && typeof value.collapsed === "boolean" ? value.collapsed : void 0;
|
|
1125
|
+
const raw = "sections" in value && value.sections && typeof value.sections === "object" ? value.sections : {};
|
|
1126
|
+
return {
|
|
1127
|
+
collapsed,
|
|
1128
|
+
sections: Object.fromEntries(Object.entries(raw).filter((entry) => typeof entry[1] === "boolean"))
|
|
1129
|
+
};
|
|
1130
|
+
} catch {
|
|
1131
|
+
return { sections: {} };
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
1135
|
+
minVersion: "12.0.0",
|
|
1136
|
+
version: "22.2.3",
|
|
1137
|
+
ngImport: i0,
|
|
1138
|
+
type: SideNav,
|
|
1139
|
+
deps: [],
|
|
1140
|
+
target: i0.ɵɵFactoryTarget.Component
|
|
1141
|
+
});
|
|
1142
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
1143
|
+
minVersion: "17.0.0",
|
|
1144
|
+
version: "22.2.3",
|
|
1145
|
+
type: SideNav,
|
|
1146
|
+
isStandalone: true,
|
|
1147
|
+
selector: "bx-side-nav",
|
|
1148
|
+
inputs: {
|
|
1149
|
+
config: {
|
|
1150
|
+
classPropertyName: "config",
|
|
1151
|
+
publicName: "config",
|
|
1152
|
+
isSignal: true,
|
|
1153
|
+
isRequired: false,
|
|
1154
|
+
transformFunction: null
|
|
1155
|
+
},
|
|
1156
|
+
groups: {
|
|
1157
|
+
classPropertyName: "groups",
|
|
1158
|
+
publicName: "groups",
|
|
1159
|
+
isSignal: true,
|
|
1160
|
+
isRequired: false,
|
|
1161
|
+
transformFunction: null
|
|
1162
|
+
},
|
|
1163
|
+
itemTemplate: {
|
|
1164
|
+
classPropertyName: "itemTemplate",
|
|
1165
|
+
publicName: "itemTemplate",
|
|
1166
|
+
isSignal: true,
|
|
1167
|
+
isRequired: false,
|
|
1168
|
+
transformFunction: null
|
|
1169
|
+
},
|
|
1170
|
+
collapsed: {
|
|
1171
|
+
classPropertyName: "collapsed",
|
|
1172
|
+
publicName: "collapsed",
|
|
1173
|
+
isSignal: true,
|
|
1174
|
+
isRequired: false,
|
|
1175
|
+
transformFunction: null
|
|
1176
|
+
},
|
|
1177
|
+
mobileOpen: {
|
|
1178
|
+
classPropertyName: "mobileOpen",
|
|
1179
|
+
publicName: "mobileOpen",
|
|
1180
|
+
isSignal: true,
|
|
1181
|
+
isRequired: false,
|
|
1182
|
+
transformFunction: null
|
|
1183
|
+
}
|
|
1184
|
+
},
|
|
1185
|
+
outputs: {
|
|
1186
|
+
collapsedChange: "collapsedChange",
|
|
1187
|
+
mobileOpen: "mobileOpenChange",
|
|
1188
|
+
itemSelected: "itemSelected",
|
|
1189
|
+
layoutChange: "layoutChange"
|
|
1190
|
+
},
|
|
1191
|
+
host: { properties: {
|
|
1192
|
+
"class.is-mobile": "isMobile()",
|
|
1193
|
+
"class.is-collapsed": "isCollapsed()",
|
|
1194
|
+
"class.is-right": "resolvedConfig().side === \"right\"",
|
|
1195
|
+
"class.is-inline": "resolvedConfig().position === \"inline\"",
|
|
1196
|
+
"class.is-animated": "!reducedMotion()",
|
|
1197
|
+
"class.is-drawer-animated": "drawerAnimated() && !reducedMotion()",
|
|
1198
|
+
"style.--bx-side-nav-width": "resolvedConfig().width",
|
|
1199
|
+
"style.--bx-side-nav-collapsed-width": "resolvedConfig().collapsedWidth"
|
|
1200
|
+
} },
|
|
1201
|
+
providers: [SideNavStateService],
|
|
1202
|
+
viewQueries: [{
|
|
1203
|
+
propertyName: "toggleElement",
|
|
1204
|
+
first: true,
|
|
1205
|
+
predicate: ["mobileToggle"],
|
|
1206
|
+
descendants: true,
|
|
1207
|
+
read: ElementRef,
|
|
1208
|
+
isSignal: true
|
|
1209
|
+
}],
|
|
1210
|
+
exportAs: ["bxSideNav"],
|
|
1211
|
+
ngImport: i0,
|
|
1212
|
+
template: "@if (isMobile() && resolvedConfig().showMobileTrigger) {\n <button #mobileToggle bx-button variant=\"tonal\" color=\"grayscale\" class=\"bx-nav-hamburger\" type=\"button\" [class.is-open]=\"mobileOpen()\"\n [attr.aria-label]=\"state.text().openLabel\" [attr.aria-hidden]=\"mobileOpen() ? true : null\" [attr.inert]=\"mobileOpen() ? '' : null\" [attr.aria-expanded]=\"mobileOpen()\" [attr.aria-controls]=\"id\" (click)=\"toggle($event)\">\n <bx-icon name=\"menu\" size=\"20\" />\n </button>\n}\n@if (isMobile() && mobileOpen()) {\n <button class=\"bx-nav-backdrop\" type=\"button\" tabindex=\"-1\" [attr.aria-label]=\"state.text().closeLabel\" (click)=\"closeFromControl($event)\"></button>\n}\n<aside tabindex=\"-1\" bxSurface [bxSurfaceInteractive]=\"false\" class=\"bx-nav-panel\" [id]=\"id\" [class.is-open]=\"!isMobile() || mobileOpen()\"\n [attr.role]=\"isMobile() ? 'dialog' : null\" [attr.aria-modal]=\"isMobile() && mobileOpen() ? true : null\" [attr.aria-label]=\"state.text().ariaLabel\"\n [attr.inert]=\"isMobile() && !mobileOpen() ? '' : null\" [attr.aria-hidden]=\"isMobile() && !mobileOpen() ? true : null\"\n [cdkTrapFocus]=\"isMobile() && mobileOpen()\" [cdkTrapFocusAutoCapture]=\"isMobile() && mobileOpen()\" (keydown)=\"panelKey($event)\">\n <div class=\"bx-nav-header\">\n @if (headerTemplate(); as template) { <ng-container [ngTemplateOutlet]=\"template\" [ngTemplateOutletContext]=\"slotContext()\" /> }\n @else if (!isCollapsed()) { <strong>{{ state.text().ariaLabel }}</strong> }\n @if (isMobile()) {\n <button bx-button variant=\"icon\" color=\"grayscale\" class=\"bx-nav-panel-toggle\" type=\"button\" [attr.aria-label]=\"state.text().closeLabel\" (click)=\"closeFromControl($event)\"><bx-icon name=\"x\" size=\"20\" /></button>\n } @else if (resolvedConfig().collapsible) {\n <button bx-button variant=\"icon\" color=\"grayscale\" class=\"bx-nav-panel-toggle\" type=\"button\" [attr.aria-label]=\"isCollapsed() ? state.text().expandLabel : state.text().collapseLabel\"\n [attr.aria-expanded]=\"!isCollapsed()\" (click)=\"toggleCollapsed()\">\n <bx-icon [name]=\"(resolvedConfig().side === 'left') !== isCollapsed() ? 'panel-left-close' : 'panel-right-close'\" size=\"20\" />\n </button>\n }\n </div>\n @if (resolvedConfig().searchable) {\n @if (isCollapsed()) {\n <button bx-button variant=\"icon\" color=\"grayscale\" type=\"button\" class=\"bx-nav-search-toggle\" [attr.aria-label]=\"state.text().searchLabel\" (click)=\"toggleCollapsed()\"><bx-icon name=\"search\" size=\"20\" /></button>\n } @else {\n <bx-search-input class=\"bx-nav-search\" [placeholder]=\"state.text().searchPlaceholder\" [ariaLabel]=\"state.text().searchLabel\" [clearLabel]=\"state.text().clearSearchLabel\"\n [ngModel]=\"query()\" (ngModelChange)=\"search($event)\" />\n }\n }\n <div class=\"bx-side-nav-scroll\">\n <nav [attr.aria-label]=\"state.text().ariaLabel\">\n @for (group of visibleGroups(); track group.id) {\n <section class=\"bx-nav-section\" [attr.aria-label]=\"group.title || state.text().ariaLabel\">\n @if (group.title) {\n @if (isCollapsed()) {\n <button type=\"button\" class=\"bx-nav-section-toggle is-compact\" [class.is-active]=\"sectionActive(group)\" [class.is-highlighted]=\"sectionHighlighted(group)\" [class.is-open]=\"sectionTrigger.isOpen()\" [attr.aria-label]=\"group.title\" [bxMenuTrigger]=\"sectionMenu\" #sectionTrigger=\"bxMenuTrigger\"\n [menuSide]=\"resolvedConfig().side === 'left' ? 'right' : 'left'\" [menuLabel]=\"group.title\">\n <bx-icon [name]=\"group.icon?.name ?? 'folder'\" size=\"20\" />\n </button>\n <ng-template #sectionMenu>\n <div class=\"bx-nav-section-flyout\">\n <bx-menu>\n @for (item of group.items; track item.id) { <bx-side-nav-branch [item]=\"item\" [parentTrigger]=\"sectionTrigger\" /> }\n </bx-menu>\n </div>\n </ng-template>\n } @else if (group.collapsible) {\n <button type=\"button\" class=\"bx-nav-section-toggle\" [class.is-active]=\"sectionActive(group)\" [class.is-highlighted]=\"sectionHighlighted(group)\" [attr.aria-expanded]=\"!sectionCollapsed(group)\" [attr.aria-controls]=\"id + '-section-' + $index\" (click)=\"toggleSection(group)\">\n @if (resolvedConfig().showSectionIcons) { <bx-icon [name]=\"group.icon?.name ?? 'folder'\" size=\"20\" /> }<span>{{ group.title }}</span><bx-icon [name]=\"sectionCollapsed(group) ? 'chevron-right' : 'chevron-down'\" size=\"16\" />\n </button>\n } @else {\n <h2 class=\"bx-nav-section-heading\" [class.is-active]=\"sectionActive(group)\" [class.is-highlighted]=\"sectionHighlighted(group)\">@if (resolvedConfig().showSectionIcons) { <bx-icon [name]=\"group.icon?.name ?? 'folder'\" size=\"20\" /> }<span>{{ group.title }}</span></h2>\n }\n }\n <div class=\"bx-nav-items\" role=\"menu\" [attr.aria-label]=\"group.title || state.text().ariaLabel\" [id]=\"id + '-section-' + $index\" [hidden]=\"sectionCollapsed(group)\" tabindex=\"-1\" (keydown)=\"menuKey($event)\">\n @for (item of group.items; track item.id) { <bx-side-nav-branch [item]=\"item\" [compact]=\"isCollapsed()\" /> }\n </div>\n </section>\n } @empty { <p class=\"bx-nav-empty\" role=\"status\">{{ state.text().emptyText }}</p> }\n </nav>\n </div>\n @if (footerTemplate(); as template) { <footer class=\"bx-nav-footer\"><ng-container [ngTemplateOutlet]=\"template\" [ngTemplateOutletContext]=\"slotContext()\" /></footer> }\n <span class=\"cdk-visually-hidden\" role=\"status\" aria-live=\"polite\">@if (state.target()) { {{ state.text().resultLabel }}: {{ state.searchResult().label }} }</span>\n</aside>\n",
|
|
1213
|
+
styles: [":host{display:block;order:0;flex:0 0 var(--bx-side-nav-width, 17rem);width:var(--bx-side-nav-width, 17rem);color:var(--bx-text-primary);font-family:inherit}.bx-nav-panel{--bx-glass-radius: 0;--bx-glass-min-opacity: .8;position:fixed;inset-block:0;left:0;display:flex;flex-direction:column;box-sizing:border-box;width:var(--bx-side-nav-width, 17rem);max-width:100dvw;height:100dvh;min-height:0;overflow:hidden;border-inline-end:1px solid var(--bx-border-default);z-index:300}.bx-nav-header,.bx-nav-footer{display:flex;flex:none;flex-wrap:wrap;align-items:center;gap:.5rem;padding:1rem .75rem;min-width:0;overflow-wrap:anywhere}.bx-nav-header>:first-child{min-width:0}.bx-nav-footer{border-block-start:1px solid var(--bx-border-default)}.bx-nav-panel-toggle,.bx-nav-search-toggle{--bx-glass-radius: 9999px;flex:none;width:2.5rem;height:2.5rem;padding:0}.bx-nav-panel-toggle{margin-inline-start:auto}.bx-nav-search{display:block;flex:none;padding-inline:.75rem}.bx-nav-search-toggle{margin-inline:auto}.bx-side-nav-scroll{flex:1;min-height:0;min-width:0;overflow:hidden auto;scrollbar-gutter:stable;overscroll-behavior:contain;padding:.5rem;scroll-behavior:auto}.bx-nav-items{display:flex;flex-direction:column;gap:var(--bx-side-nav-item-gap, .5rem)}.bx-nav-items[hidden]{display:none}.bx-nav-section+.bx-nav-section{margin-block-start:1rem}.bx-nav-section-heading,.bx-nav-section-toggle{border:1px solid transparent;border-radius:var(--bx-side-nav-item-radius, .5rem);background:transparent;color:var(--bx-text-secondary)}.bx-nav-section-heading.is-active,.bx-nav-section-heading.is-highlighted,.bx-nav-section-toggle.is-active,.bx-nav-section-toggle.is-highlighted{color:var(--bx-text-accent)}.bx-nav-section-heading:focus-visible,.bx-nav-section-toggle:focus-visible{outline:2px solid var(--bx-border-brand);outline-offset:-2px}.bx-nav-section-heading,.bx-nav-section-toggle{display:flex;align-items:center;gap:.5rem;width:100%;box-sizing:border-box;margin:0 0 .25rem;padding:.5rem;font-size:.75rem;font-weight:600;text-align:start;overflow-wrap:anywhere}.bx-nav-section-heading span,.bx-nav-section-toggle span{flex:1;min-width:0}.bx-nav-section-heading bx-icon,.bx-nav-section-toggle bx-icon{flex:none}.bx-nav-section-toggle{min-height:2.75rem;cursor:pointer;font-family:inherit}.bx-nav-section-toggle:hover,.bx-nav-section-toggle.is-open{background:var(--bx-primary-subtle);color:var(--bx-text-brand)}.bx-nav-section-toggle.is-compact{width:100%;min-width:0;justify-content:center;padding-inline:0}.bx-nav-empty{color:var(--bx-text-secondary);padding:.75rem}.bx-nav-section-flyout{--bx-menu-min-width: 0;--bx-menu-item-gap: var(--bx-side-nav-item-gap, .5rem);box-sizing:border-box;width:var(--bx-side-nav-menu-width, 17rem);max-width:calc(100dvw - 1rem);max-height:calc(100dvh - 1rem);overflow:hidden auto;scrollbar-gutter:stable;overscroll-behavior:contain;background:var(--bx-bg-surface);border:1px solid var(--bx-border-default);border-radius:.75rem;box-shadow:0 12px 20px -3px #0003,0 4px 6px -2px #0000001a;padding:.25rem}.bx-nav-backdrop{position:fixed;inset:0;z-index:300;border:0;background:var(--bx-side-nav-backdrop, var(--bx-backdrop-color, rgba(0, 0, 0, .4)));cursor:pointer}.bx-nav-hamburger{position:fixed;top:.5rem;left:.5rem;z-index:302;--bx-glass-radius: .5rem;width:2.5rem;height:2.5rem;padding:0}.bx-nav-hamburger.is-open{visibility:hidden;pointer-events:none}:host(.is-animated:not(.is-mobile)) .bx-nav-panel{transition-property:width;transition-duration:calc(var(--bx-side-nav-duration, .25s) * (1 - var(--bx-reduced-motion, 0)));transition-timing-function:var(--bx-side-nav-easing, ease)}:host(.is-collapsed) .bx-side-nav-scroll{scrollbar-gutter:stable both-edges;padding-inline:.25rem}:host(.is-collapsed){width:var(--bx-side-nav-collapsed-width, 4.5rem);flex-basis:var(--bx-side-nav-collapsed-width, 4.5rem)}:host(.is-collapsed) .bx-nav-panel{width:var(--bx-side-nav-collapsed-width, 4.5rem)}:host(.is-collapsed) .bx-nav-header{align-items:center;flex-direction:column;padding-inline:.25rem}:host(.is-collapsed) .bx-nav-panel-toggle{margin-inline:auto}:host(.is-collapsed) .bx-nav-footer{justify-content:center;padding-inline:.25rem}:host(.is-inline) .bx-nav-panel{position:relative;height:var(--bx-side-nav-height, 38rem);max-height:100dvh}:host(.is-inline) .bx-nav-hamburger{position:relative;inset:auto}:host(.is-right) .bx-nav-panel{left:auto;right:0;border-inline-end:0;border-inline-start:1px solid var(--bx-border-default)}:host(.is-right) .bx-nav-hamburger{left:auto;right:.5rem}:host(.is-mobile){width:0;flex-basis:0}:host(.is-mobile) .bx-nav-panel{position:fixed;height:100dvh;width:min(var(--bx-side-nav-width, 17rem),100dvw - 3rem);transform:translate(-100%);visibility:hidden}:host(.is-mobile) .bx-nav-panel.is-open{transform:translate(0);visibility:visible;z-index:301}:host(.is-mobile) .bx-nav-header{padding-top:.75rem}:host(.is-mobile.is-right) .bx-nav-panel{transform:translate(100%)}:host(.is-mobile.is-right) .bx-nav-panel.is-open{transform:translate(0)}:host(.is-inline.is-mobile){position:absolute;inset:0;width:100%;height:100%;pointer-events:none}:host(.is-inline.is-mobile) .bx-nav-panel{position:absolute;inset-block:0;height:100%;max-height:100%;width:min(var(--bx-side-nav-width, 17rem),100% - 3rem);pointer-events:auto}:host(.is-inline.is-mobile) .bx-nav-backdrop{position:absolute;pointer-events:auto}:host(.is-inline.is-mobile) .bx-nav-hamburger{position:absolute;inset-block-start:.5rem;inset-inline-start:.5rem;pointer-events:auto}@media(forced-colors:active){.bx-nav-panel,.bx-nav-hamburger{border:1px solid CanvasText}.bx-nav-backdrop{background:Canvas;opacity:.7}}:host(.is-mobile.is-drawer-animated) .bx-nav-panel{transition:transform var(--bx-side-nav-duration, .25s) var(--bx-side-nav-easing, ease),visibility 0s var(--bx-side-nav-duration, .25s)}:host(.is-mobile.is-drawer-animated) .bx-nav-panel.is-open{transition-delay:0s}:host(.is-right){order:1}:host(:dir(rtl)){order:1}:host(.is-right:dir(rtl)){order:0}\n"],
|
|
1214
|
+
dependencies: [
|
|
1215
|
+
{
|
|
1216
|
+
kind: "directive",
|
|
1217
|
+
type: NgTemplateOutlet,
|
|
1218
|
+
selector: "[ngTemplateOutlet]",
|
|
1219
|
+
inputs: [
|
|
1220
|
+
"ngTemplateOutletContext",
|
|
1221
|
+
"ngTemplateOutlet",
|
|
1222
|
+
"ngTemplateOutletInjector"
|
|
1223
|
+
]
|
|
1224
|
+
},
|
|
1225
|
+
{
|
|
1226
|
+
kind: "ngmodule",
|
|
1227
|
+
type: A11yModule
|
|
1228
|
+
},
|
|
1229
|
+
{
|
|
1230
|
+
kind: "directive",
|
|
1231
|
+
type: i1.CdkTrapFocus,
|
|
1232
|
+
selector: "[cdkTrapFocus]",
|
|
1233
|
+
inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"],
|
|
1234
|
+
exportAs: ["cdkTrapFocus"]
|
|
1235
|
+
},
|
|
1236
|
+
{
|
|
1237
|
+
kind: "ngmodule",
|
|
1238
|
+
type: FormsModule
|
|
1239
|
+
},
|
|
1240
|
+
{
|
|
1241
|
+
kind: "directive",
|
|
1242
|
+
type: i2.NgControlStatus,
|
|
1243
|
+
selector: "[formControlName],[ngModel],[formControl]"
|
|
1244
|
+
},
|
|
1245
|
+
{
|
|
1246
|
+
kind: "directive",
|
|
1247
|
+
type: i2.NgModel,
|
|
1248
|
+
selector: "[ngModel]:not([formControlName]):not([formControl])",
|
|
1249
|
+
inputs: [
|
|
1250
|
+
"name",
|
|
1251
|
+
"disabled",
|
|
1252
|
+
"ngModel",
|
|
1253
|
+
"ngModelOptions"
|
|
1254
|
+
],
|
|
1255
|
+
outputs: ["ngModelChange"],
|
|
1256
|
+
exportAs: ["ngModel"]
|
|
1257
|
+
},
|
|
1258
|
+
{
|
|
1259
|
+
kind: "component",
|
|
1260
|
+
type: SearchInput,
|
|
1261
|
+
selector: "bx-search-input",
|
|
1262
|
+
inputs: [
|
|
1263
|
+
"clearLabel",
|
|
1264
|
+
"autocomplete",
|
|
1265
|
+
"loadError",
|
|
1266
|
+
"loadingLabel",
|
|
1267
|
+
"loadingAriaLabel",
|
|
1268
|
+
"retryLabel",
|
|
1269
|
+
"retryConfig"
|
|
1270
|
+
],
|
|
1271
|
+
outputs: ["search", "retry"]
|
|
1272
|
+
},
|
|
1273
|
+
{
|
|
1274
|
+
kind: "component",
|
|
1275
|
+
type: Button,
|
|
1276
|
+
selector: "bx-button, button[bx-button], a[bx-button]",
|
|
1277
|
+
inputs: [
|
|
1278
|
+
"variant",
|
|
1279
|
+
"color",
|
|
1280
|
+
"outlined",
|
|
1281
|
+
"elevated",
|
|
1282
|
+
"disabled",
|
|
1283
|
+
"loading",
|
|
1284
|
+
"interactive",
|
|
1285
|
+
"surfaceEffects"
|
|
1286
|
+
]
|
|
1287
|
+
},
|
|
1288
|
+
{
|
|
1289
|
+
kind: "directive",
|
|
1290
|
+
type: BxSurfaceDirective,
|
|
1291
|
+
selector: "[bxSurface]",
|
|
1292
|
+
inputs: [
|
|
1293
|
+
"bxSurfaceInteractive",
|
|
1294
|
+
"bxSurfaceGlassiness",
|
|
1295
|
+
"bxSurfaceEmission",
|
|
1296
|
+
"bxSurfaceFocusEmission",
|
|
1297
|
+
"bxReducedTransparency"
|
|
1298
|
+
],
|
|
1299
|
+
exportAs: ["bxSurface"]
|
|
1300
|
+
},
|
|
1301
|
+
{
|
|
1302
|
+
kind: "component",
|
|
1303
|
+
type: Icon,
|
|
1304
|
+
selector: "bx-icon",
|
|
1305
|
+
inputs: [
|
|
1306
|
+
"name",
|
|
1307
|
+
"size",
|
|
1308
|
+
"color",
|
|
1309
|
+
"bgColor",
|
|
1310
|
+
"strokeWidth",
|
|
1311
|
+
"decorative",
|
|
1312
|
+
"ariaLabel"
|
|
1313
|
+
]
|
|
1314
|
+
},
|
|
1315
|
+
{
|
|
1316
|
+
kind: "component",
|
|
1317
|
+
type: SideNavBranch,
|
|
1318
|
+
selector: "bx-side-nav-branch",
|
|
1319
|
+
inputs: [
|
|
1320
|
+
"item",
|
|
1321
|
+
"compact",
|
|
1322
|
+
"parentTrigger"
|
|
1323
|
+
]
|
|
1324
|
+
},
|
|
1325
|
+
{
|
|
1326
|
+
kind: "directive",
|
|
1327
|
+
type: MenuTriggerDirective,
|
|
1328
|
+
selector: "[bxMenuTrigger]",
|
|
1329
|
+
inputs: [
|
|
1330
|
+
"bxMenuTrigger",
|
|
1331
|
+
"menuOrigin",
|
|
1332
|
+
"menuParent",
|
|
1333
|
+
"menuSide",
|
|
1334
|
+
"menuHover",
|
|
1335
|
+
"menuLabel",
|
|
1336
|
+
"menuPinned"
|
|
1337
|
+
],
|
|
1338
|
+
outputs: ["menuOpened", "menuClosed"],
|
|
1339
|
+
exportAs: ["bxMenuTrigger"]
|
|
1340
|
+
},
|
|
1341
|
+
{
|
|
1342
|
+
kind: "component",
|
|
1343
|
+
type: Menu,
|
|
1344
|
+
selector: "bx-menu"
|
|
1345
|
+
}
|
|
1346
|
+
],
|
|
1347
|
+
changeDetection: i0.ChangeDetectionStrategy.OnPush
|
|
1348
|
+
});
|
|
1349
|
+
};
|
|
1350
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
1351
|
+
minVersion: "12.0.0",
|
|
1352
|
+
version: "22.2.3",
|
|
1353
|
+
ngImport: i0,
|
|
1354
|
+
type: SideNav,
|
|
1355
|
+
decorators: [{
|
|
1356
|
+
type: Component,
|
|
1357
|
+
args: [{
|
|
1358
|
+
selector: "bx-side-nav",
|
|
1359
|
+
exportAs: "bxSideNav",
|
|
1360
|
+
imports: [
|
|
1361
|
+
NgTemplateOutlet,
|
|
1362
|
+
A11yModule,
|
|
1363
|
+
FormsModule,
|
|
1364
|
+
SearchInput,
|
|
1365
|
+
Button,
|
|
1366
|
+
BxSurfaceDirective,
|
|
1367
|
+
Icon,
|
|
1368
|
+
SideNavBranch,
|
|
1369
|
+
MenuTriggerDirective,
|
|
1370
|
+
Menu
|
|
1371
|
+
],
|
|
1372
|
+
providers: [SideNavStateService],
|
|
1373
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
1374
|
+
host: {
|
|
1375
|
+
"[class.is-mobile]": "isMobile()",
|
|
1376
|
+
"[class.is-collapsed]": "isCollapsed()",
|
|
1377
|
+
"[class.is-right]": "resolvedConfig().side === \"right\"",
|
|
1378
|
+
"[class.is-inline]": "resolvedConfig().position === \"inline\"",
|
|
1379
|
+
"[class.is-animated]": "!reducedMotion()",
|
|
1380
|
+
"[class.is-drawer-animated]": "drawerAnimated() && !reducedMotion()",
|
|
1381
|
+
"[style.--bx-side-nav-width]": "resolvedConfig().width",
|
|
1382
|
+
"[style.--bx-side-nav-collapsed-width]": "resolvedConfig().collapsedWidth"
|
|
1383
|
+
},
|
|
1384
|
+
template: "@if (isMobile() && resolvedConfig().showMobileTrigger) {\n <button #mobileToggle bx-button variant=\"tonal\" color=\"grayscale\" class=\"bx-nav-hamburger\" type=\"button\" [class.is-open]=\"mobileOpen()\"\n [attr.aria-label]=\"state.text().openLabel\" [attr.aria-hidden]=\"mobileOpen() ? true : null\" [attr.inert]=\"mobileOpen() ? '' : null\" [attr.aria-expanded]=\"mobileOpen()\" [attr.aria-controls]=\"id\" (click)=\"toggle($event)\">\n <bx-icon name=\"menu\" size=\"20\" />\n </button>\n}\n@if (isMobile() && mobileOpen()) {\n <button class=\"bx-nav-backdrop\" type=\"button\" tabindex=\"-1\" [attr.aria-label]=\"state.text().closeLabel\" (click)=\"closeFromControl($event)\"></button>\n}\n<aside tabindex=\"-1\" bxSurface [bxSurfaceInteractive]=\"false\" class=\"bx-nav-panel\" [id]=\"id\" [class.is-open]=\"!isMobile() || mobileOpen()\"\n [attr.role]=\"isMobile() ? 'dialog' : null\" [attr.aria-modal]=\"isMobile() && mobileOpen() ? true : null\" [attr.aria-label]=\"state.text().ariaLabel\"\n [attr.inert]=\"isMobile() && !mobileOpen() ? '' : null\" [attr.aria-hidden]=\"isMobile() && !mobileOpen() ? true : null\"\n [cdkTrapFocus]=\"isMobile() && mobileOpen()\" [cdkTrapFocusAutoCapture]=\"isMobile() && mobileOpen()\" (keydown)=\"panelKey($event)\">\n <div class=\"bx-nav-header\">\n @if (headerTemplate(); as template) { <ng-container [ngTemplateOutlet]=\"template\" [ngTemplateOutletContext]=\"slotContext()\" /> }\n @else if (!isCollapsed()) { <strong>{{ state.text().ariaLabel }}</strong> }\n @if (isMobile()) {\n <button bx-button variant=\"icon\" color=\"grayscale\" class=\"bx-nav-panel-toggle\" type=\"button\" [attr.aria-label]=\"state.text().closeLabel\" (click)=\"closeFromControl($event)\"><bx-icon name=\"x\" size=\"20\" /></button>\n } @else if (resolvedConfig().collapsible) {\n <button bx-button variant=\"icon\" color=\"grayscale\" class=\"bx-nav-panel-toggle\" type=\"button\" [attr.aria-label]=\"isCollapsed() ? state.text().expandLabel : state.text().collapseLabel\"\n [attr.aria-expanded]=\"!isCollapsed()\" (click)=\"toggleCollapsed()\">\n <bx-icon [name]=\"(resolvedConfig().side === 'left') !== isCollapsed() ? 'panel-left-close' : 'panel-right-close'\" size=\"20\" />\n </button>\n }\n </div>\n @if (resolvedConfig().searchable) {\n @if (isCollapsed()) {\n <button bx-button variant=\"icon\" color=\"grayscale\" type=\"button\" class=\"bx-nav-search-toggle\" [attr.aria-label]=\"state.text().searchLabel\" (click)=\"toggleCollapsed()\"><bx-icon name=\"search\" size=\"20\" /></button>\n } @else {\n <bx-search-input class=\"bx-nav-search\" [placeholder]=\"state.text().searchPlaceholder\" [ariaLabel]=\"state.text().searchLabel\" [clearLabel]=\"state.text().clearSearchLabel\"\n [ngModel]=\"query()\" (ngModelChange)=\"search($event)\" />\n }\n }\n <div class=\"bx-side-nav-scroll\">\n <nav [attr.aria-label]=\"state.text().ariaLabel\">\n @for (group of visibleGroups(); track group.id) {\n <section class=\"bx-nav-section\" [attr.aria-label]=\"group.title || state.text().ariaLabel\">\n @if (group.title) {\n @if (isCollapsed()) {\n <button type=\"button\" class=\"bx-nav-section-toggle is-compact\" [class.is-active]=\"sectionActive(group)\" [class.is-highlighted]=\"sectionHighlighted(group)\" [class.is-open]=\"sectionTrigger.isOpen()\" [attr.aria-label]=\"group.title\" [bxMenuTrigger]=\"sectionMenu\" #sectionTrigger=\"bxMenuTrigger\"\n [menuSide]=\"resolvedConfig().side === 'left' ? 'right' : 'left'\" [menuLabel]=\"group.title\">\n <bx-icon [name]=\"group.icon?.name ?? 'folder'\" size=\"20\" />\n </button>\n <ng-template #sectionMenu>\n <div class=\"bx-nav-section-flyout\">\n <bx-menu>\n @for (item of group.items; track item.id) { <bx-side-nav-branch [item]=\"item\" [parentTrigger]=\"sectionTrigger\" /> }\n </bx-menu>\n </div>\n </ng-template>\n } @else if (group.collapsible) {\n <button type=\"button\" class=\"bx-nav-section-toggle\" [class.is-active]=\"sectionActive(group)\" [class.is-highlighted]=\"sectionHighlighted(group)\" [attr.aria-expanded]=\"!sectionCollapsed(group)\" [attr.aria-controls]=\"id + '-section-' + $index\" (click)=\"toggleSection(group)\">\n @if (resolvedConfig().showSectionIcons) { <bx-icon [name]=\"group.icon?.name ?? 'folder'\" size=\"20\" /> }<span>{{ group.title }}</span><bx-icon [name]=\"sectionCollapsed(group) ? 'chevron-right' : 'chevron-down'\" size=\"16\" />\n </button>\n } @else {\n <h2 class=\"bx-nav-section-heading\" [class.is-active]=\"sectionActive(group)\" [class.is-highlighted]=\"sectionHighlighted(group)\">@if (resolvedConfig().showSectionIcons) { <bx-icon [name]=\"group.icon?.name ?? 'folder'\" size=\"20\" /> }<span>{{ group.title }}</span></h2>\n }\n }\n <div class=\"bx-nav-items\" role=\"menu\" [attr.aria-label]=\"group.title || state.text().ariaLabel\" [id]=\"id + '-section-' + $index\" [hidden]=\"sectionCollapsed(group)\" tabindex=\"-1\" (keydown)=\"menuKey($event)\">\n @for (item of group.items; track item.id) { <bx-side-nav-branch [item]=\"item\" [compact]=\"isCollapsed()\" /> }\n </div>\n </section>\n } @empty { <p class=\"bx-nav-empty\" role=\"status\">{{ state.text().emptyText }}</p> }\n </nav>\n </div>\n @if (footerTemplate(); as template) { <footer class=\"bx-nav-footer\"><ng-container [ngTemplateOutlet]=\"template\" [ngTemplateOutletContext]=\"slotContext()\" /></footer> }\n <span class=\"cdk-visually-hidden\" role=\"status\" aria-live=\"polite\">@if (state.target()) { {{ state.text().resultLabel }}: {{ state.searchResult().label }} }</span>\n</aside>\n",
|
|
1385
|
+
styles: [":host{display:block;order:0;flex:0 0 var(--bx-side-nav-width, 17rem);width:var(--bx-side-nav-width, 17rem);color:var(--bx-text-primary);font-family:inherit}.bx-nav-panel{--bx-glass-radius: 0;--bx-glass-min-opacity: .8;position:fixed;inset-block:0;left:0;display:flex;flex-direction:column;box-sizing:border-box;width:var(--bx-side-nav-width, 17rem);max-width:100dvw;height:100dvh;min-height:0;overflow:hidden;border-inline-end:1px solid var(--bx-border-default);z-index:300}.bx-nav-header,.bx-nav-footer{display:flex;flex:none;flex-wrap:wrap;align-items:center;gap:.5rem;padding:1rem .75rem;min-width:0;overflow-wrap:anywhere}.bx-nav-header>:first-child{min-width:0}.bx-nav-footer{border-block-start:1px solid var(--bx-border-default)}.bx-nav-panel-toggle,.bx-nav-search-toggle{--bx-glass-radius: 9999px;flex:none;width:2.5rem;height:2.5rem;padding:0}.bx-nav-panel-toggle{margin-inline-start:auto}.bx-nav-search{display:block;flex:none;padding-inline:.75rem}.bx-nav-search-toggle{margin-inline:auto}.bx-side-nav-scroll{flex:1;min-height:0;min-width:0;overflow:hidden auto;scrollbar-gutter:stable;overscroll-behavior:contain;padding:.5rem;scroll-behavior:auto}.bx-nav-items{display:flex;flex-direction:column;gap:var(--bx-side-nav-item-gap, .5rem)}.bx-nav-items[hidden]{display:none}.bx-nav-section+.bx-nav-section{margin-block-start:1rem}.bx-nav-section-heading,.bx-nav-section-toggle{border:1px solid transparent;border-radius:var(--bx-side-nav-item-radius, .5rem);background:transparent;color:var(--bx-text-secondary)}.bx-nav-section-heading.is-active,.bx-nav-section-heading.is-highlighted,.bx-nav-section-toggle.is-active,.bx-nav-section-toggle.is-highlighted{color:var(--bx-text-accent)}.bx-nav-section-heading:focus-visible,.bx-nav-section-toggle:focus-visible{outline:2px solid var(--bx-border-brand);outline-offset:-2px}.bx-nav-section-heading,.bx-nav-section-toggle{display:flex;align-items:center;gap:.5rem;width:100%;box-sizing:border-box;margin:0 0 .25rem;padding:.5rem;font-size:.75rem;font-weight:600;text-align:start;overflow-wrap:anywhere}.bx-nav-section-heading span,.bx-nav-section-toggle span{flex:1;min-width:0}.bx-nav-section-heading bx-icon,.bx-nav-section-toggle bx-icon{flex:none}.bx-nav-section-toggle{min-height:2.75rem;cursor:pointer;font-family:inherit}.bx-nav-section-toggle:hover,.bx-nav-section-toggle.is-open{background:var(--bx-primary-subtle);color:var(--bx-text-brand)}.bx-nav-section-toggle.is-compact{width:100%;min-width:0;justify-content:center;padding-inline:0}.bx-nav-empty{color:var(--bx-text-secondary);padding:.75rem}.bx-nav-section-flyout{--bx-menu-min-width: 0;--bx-menu-item-gap: var(--bx-side-nav-item-gap, .5rem);box-sizing:border-box;width:var(--bx-side-nav-menu-width, 17rem);max-width:calc(100dvw - 1rem);max-height:calc(100dvh - 1rem);overflow:hidden auto;scrollbar-gutter:stable;overscroll-behavior:contain;background:var(--bx-bg-surface);border:1px solid var(--bx-border-default);border-radius:.75rem;box-shadow:0 12px 20px -3px #0003,0 4px 6px -2px #0000001a;padding:.25rem}.bx-nav-backdrop{position:fixed;inset:0;z-index:300;border:0;background:var(--bx-side-nav-backdrop, var(--bx-backdrop-color, rgba(0, 0, 0, .4)));cursor:pointer}.bx-nav-hamburger{position:fixed;top:.5rem;left:.5rem;z-index:302;--bx-glass-radius: .5rem;width:2.5rem;height:2.5rem;padding:0}.bx-nav-hamburger.is-open{visibility:hidden;pointer-events:none}:host(.is-animated:not(.is-mobile)) .bx-nav-panel{transition-property:width;transition-duration:calc(var(--bx-side-nav-duration, .25s) * (1 - var(--bx-reduced-motion, 0)));transition-timing-function:var(--bx-side-nav-easing, ease)}:host(.is-collapsed) .bx-side-nav-scroll{scrollbar-gutter:stable both-edges;padding-inline:.25rem}:host(.is-collapsed){width:var(--bx-side-nav-collapsed-width, 4.5rem);flex-basis:var(--bx-side-nav-collapsed-width, 4.5rem)}:host(.is-collapsed) .bx-nav-panel{width:var(--bx-side-nav-collapsed-width, 4.5rem)}:host(.is-collapsed) .bx-nav-header{align-items:center;flex-direction:column;padding-inline:.25rem}:host(.is-collapsed) .bx-nav-panel-toggle{margin-inline:auto}:host(.is-collapsed) .bx-nav-footer{justify-content:center;padding-inline:.25rem}:host(.is-inline) .bx-nav-panel{position:relative;height:var(--bx-side-nav-height, 38rem);max-height:100dvh}:host(.is-inline) .bx-nav-hamburger{position:relative;inset:auto}:host(.is-right) .bx-nav-panel{left:auto;right:0;border-inline-end:0;border-inline-start:1px solid var(--bx-border-default)}:host(.is-right) .bx-nav-hamburger{left:auto;right:.5rem}:host(.is-mobile){width:0;flex-basis:0}:host(.is-mobile) .bx-nav-panel{position:fixed;height:100dvh;width:min(var(--bx-side-nav-width, 17rem),100dvw - 3rem);transform:translate(-100%);visibility:hidden}:host(.is-mobile) .bx-nav-panel.is-open{transform:translate(0);visibility:visible;z-index:301}:host(.is-mobile) .bx-nav-header{padding-top:.75rem}:host(.is-mobile.is-right) .bx-nav-panel{transform:translate(100%)}:host(.is-mobile.is-right) .bx-nav-panel.is-open{transform:translate(0)}:host(.is-inline.is-mobile){position:absolute;inset:0;width:100%;height:100%;pointer-events:none}:host(.is-inline.is-mobile) .bx-nav-panel{position:absolute;inset-block:0;height:100%;max-height:100%;width:min(var(--bx-side-nav-width, 17rem),100% - 3rem);pointer-events:auto}:host(.is-inline.is-mobile) .bx-nav-backdrop{position:absolute;pointer-events:auto}:host(.is-inline.is-mobile) .bx-nav-hamburger{position:absolute;inset-block-start:.5rem;inset-inline-start:.5rem;pointer-events:auto}@media(forced-colors:active){.bx-nav-panel,.bx-nav-hamburger{border:1px solid CanvasText}.bx-nav-backdrop{background:Canvas;opacity:.7}}:host(.is-mobile.is-drawer-animated) .bx-nav-panel{transition:transform var(--bx-side-nav-duration, .25s) var(--bx-side-nav-easing, ease),visibility 0s var(--bx-side-nav-duration, .25s)}:host(.is-mobile.is-drawer-animated) .bx-nav-panel.is-open{transition-delay:0s}:host(.is-right){order:1}:host(:dir(rtl)){order:1}:host(.is-right:dir(rtl)){order:0}\n"]
|
|
1386
|
+
}]
|
|
1387
|
+
}],
|
|
1388
|
+
ctorParameters: () => [],
|
|
1389
|
+
propDecorators: {
|
|
1390
|
+
toggleElement: [{
|
|
1391
|
+
type: i0.ViewChild,
|
|
1392
|
+
args: ["mobileToggle", {
|
|
1393
|
+
read: ElementRef,
|
|
1394
|
+
isSignal: true
|
|
1395
|
+
}]
|
|
1396
|
+
}],
|
|
1397
|
+
config: [{
|
|
1398
|
+
type: i0.Input,
|
|
1399
|
+
args: [{
|
|
1400
|
+
isSignal: true,
|
|
1401
|
+
alias: "config",
|
|
1402
|
+
required: false
|
|
1403
|
+
}]
|
|
1404
|
+
}],
|
|
1405
|
+
groups: [{
|
|
1406
|
+
type: i0.Input,
|
|
1407
|
+
args: [{
|
|
1408
|
+
isSignal: true,
|
|
1409
|
+
alias: "groups",
|
|
1410
|
+
required: false
|
|
1411
|
+
}]
|
|
1412
|
+
}],
|
|
1413
|
+
itemTemplate: [{
|
|
1414
|
+
type: i0.Input,
|
|
1415
|
+
args: [{
|
|
1416
|
+
isSignal: true,
|
|
1417
|
+
alias: "itemTemplate",
|
|
1418
|
+
required: false
|
|
1419
|
+
}]
|
|
1420
|
+
}],
|
|
1421
|
+
collapsed: [{
|
|
1422
|
+
type: i0.Input,
|
|
1423
|
+
args: [{
|
|
1424
|
+
isSignal: true,
|
|
1425
|
+
alias: "collapsed",
|
|
1426
|
+
required: false
|
|
1427
|
+
}]
|
|
1428
|
+
}],
|
|
1429
|
+
collapsedChange: [{
|
|
1430
|
+
type: i0.Output,
|
|
1431
|
+
args: ["collapsedChange"]
|
|
1432
|
+
}],
|
|
1433
|
+
mobileOpen: [{
|
|
1434
|
+
type: i0.Input,
|
|
1435
|
+
args: [{
|
|
1436
|
+
isSignal: true,
|
|
1437
|
+
alias: "mobileOpen",
|
|
1438
|
+
required: false
|
|
1439
|
+
}]
|
|
1440
|
+
}, {
|
|
1441
|
+
type: i0.Output,
|
|
1442
|
+
args: ["mobileOpenChange"]
|
|
1443
|
+
}],
|
|
1444
|
+
itemSelected: [{
|
|
1445
|
+
type: i0.Output,
|
|
1446
|
+
args: ["itemSelected"]
|
|
1447
|
+
}],
|
|
1448
|
+
layoutChange: [{
|
|
1449
|
+
type: i0.Output,
|
|
1450
|
+
args: ["layoutChange"]
|
|
1451
|
+
}]
|
|
1452
|
+
}
|
|
1453
|
+
});
|
|
1454
|
+
var SideNavHeaderDirective = class SideNavHeaderDirective {
|
|
1455
|
+
template = inject(TemplateRef);
|
|
1456
|
+
nav = inject(SideNav);
|
|
1457
|
+
constructor() {
|
|
1458
|
+
this.nav.setHeaderTemplate(this.template);
|
|
1459
|
+
inject(DestroyRef).onDestroy(() => this.nav.setHeaderTemplate(null));
|
|
1460
|
+
}
|
|
1461
|
+
static ngTemplateContextGuard(_directive, _context) {
|
|
1462
|
+
return true;
|
|
1463
|
+
}
|
|
1464
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
1465
|
+
minVersion: "12.0.0",
|
|
1466
|
+
version: "22.2.3",
|
|
1467
|
+
ngImport: i0,
|
|
1468
|
+
type: SideNavHeaderDirective,
|
|
1469
|
+
deps: [],
|
|
1470
|
+
target: i0.ɵɵFactoryTarget.Directive
|
|
1471
|
+
});
|
|
1472
|
+
static ɵdir = i0.ɵɵngDeclareDirective({
|
|
1473
|
+
minVersion: "14.0.0",
|
|
1474
|
+
version: "22.2.3",
|
|
1475
|
+
type: SideNavHeaderDirective,
|
|
1476
|
+
isStandalone: true,
|
|
1477
|
+
selector: "[bxSideNavHeader]",
|
|
1478
|
+
ngImport: i0
|
|
1479
|
+
});
|
|
1480
|
+
};
|
|
1481
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
1482
|
+
minVersion: "12.0.0",
|
|
1483
|
+
version: "22.2.3",
|
|
1484
|
+
ngImport: i0,
|
|
1485
|
+
type: SideNavHeaderDirective,
|
|
1486
|
+
decorators: [{
|
|
1487
|
+
type: Directive,
|
|
1488
|
+
args: [{ selector: "[bxSideNavHeader]" }]
|
|
1489
|
+
}],
|
|
1490
|
+
ctorParameters: () => []
|
|
1491
|
+
});
|
|
1492
|
+
var SideNavFooterDirective = class SideNavFooterDirective {
|
|
1493
|
+
template = inject(TemplateRef);
|
|
1494
|
+
nav = inject(SideNav);
|
|
1495
|
+
constructor() {
|
|
1496
|
+
this.nav.setFooterTemplate(this.template);
|
|
1497
|
+
inject(DestroyRef).onDestroy(() => this.nav.setFooterTemplate(null));
|
|
1498
|
+
}
|
|
1499
|
+
static ngTemplateContextGuard(_directive, _context) {
|
|
1500
|
+
return true;
|
|
1501
|
+
}
|
|
1502
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
1503
|
+
minVersion: "12.0.0",
|
|
1504
|
+
version: "22.2.3",
|
|
1505
|
+
ngImport: i0,
|
|
1506
|
+
type: SideNavFooterDirective,
|
|
1507
|
+
deps: [],
|
|
1508
|
+
target: i0.ɵɵFactoryTarget.Directive
|
|
1509
|
+
});
|
|
1510
|
+
static ɵdir = i0.ɵɵngDeclareDirective({
|
|
1511
|
+
minVersion: "14.0.0",
|
|
1512
|
+
version: "22.2.3",
|
|
1513
|
+
type: SideNavFooterDirective,
|
|
1514
|
+
isStandalone: true,
|
|
1515
|
+
selector: "[bxSideNavFooter]",
|
|
1516
|
+
ngImport: i0
|
|
1517
|
+
});
|
|
1518
|
+
};
|
|
1519
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
1520
|
+
minVersion: "12.0.0",
|
|
1521
|
+
version: "22.2.3",
|
|
1522
|
+
ngImport: i0,
|
|
1523
|
+
type: SideNavFooterDirective,
|
|
1524
|
+
decorators: [{
|
|
1525
|
+
type: Directive,
|
|
1526
|
+
args: [{ selector: "[bxSideNavFooter]" }]
|
|
1527
|
+
}],
|
|
1528
|
+
ctorParameters: () => []
|
|
1529
|
+
});
|
|
1530
|
+
export { Breadcrumbs, NAVIGATION_ACCESS_ADAPTER, NAVIGATION_CONFIG, NavigationService, SideNav, SideNavFooterDirective, SideNavHeaderDirective, defineNavigation, provideNavigation, withNav };
|
|
366
1531
|
|
|
367
1532
|
//# sourceMappingURL=filip.mazev-blocks-navigation.mjs.map
|