@filip.mazev/blocks 1.4.17 → 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.
@@ -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
- extractRoutes(routes, parentSegment = []) {
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
- section: nav.section,
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 && matchingItem.data && !matchingItem.data.hidden) {
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
- export { Breadcrumbs, NAVIGATION_ACCESS_ADAPTER, NAVIGATION_CONFIG, NavigationService, defineNavigation, provideNavigation, withNav };
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