@memberjunction/ng-ui-components 5.51.0 → 6.1.0-edge.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/LICENSE +7 -0
  2. package/README.md +51 -2
  3. package/dist/lib/bottom-sheet/bottom-sheet.component.d.ts +96 -0
  4. package/dist/lib/bottom-sheet/bottom-sheet.component.d.ts.map +1 -0
  5. package/dist/lib/bottom-sheet/bottom-sheet.component.js +300 -0
  6. package/dist/lib/bottom-sheet/bottom-sheet.component.js.map +1 -0
  7. package/dist/lib/left-nav/left-nav.component.d.ts +142 -3
  8. package/dist/lib/left-nav/left-nav.component.d.ts.map +1 -1
  9. package/dist/lib/left-nav/left-nav.component.js +391 -117
  10. package/dist/lib/left-nav/left-nav.component.js.map +1 -1
  11. package/dist/lib/slide-panel/slide-panel.component.js +6 -6
  12. package/dist/lib/slide-panel/slide-panel.component.js.map +1 -1
  13. package/dist/lib/tabs/tab-chrome-guard.d.ts +14 -0
  14. package/dist/lib/tabs/tab-chrome-guard.d.ts.map +1 -0
  15. package/dist/lib/tabs/tab-chrome-guard.js +36 -0
  16. package/dist/lib/tabs/tab-chrome-guard.js.map +1 -0
  17. package/dist/lib/tabs/tab-list.directive.d.ts +93 -0
  18. package/dist/lib/tabs/tab-list.directive.d.ts.map +1 -0
  19. package/dist/lib/tabs/tab-list.directive.js +202 -0
  20. package/dist/lib/tabs/tab-list.directive.js.map +1 -0
  21. package/dist/lib/tabs/tabs.scss +242 -0
  22. package/dist/lib/workspace-tabs/workspace-card.component.d.ts +63 -0
  23. package/dist/lib/workspace-tabs/workspace-card.component.d.ts.map +1 -0
  24. package/dist/lib/workspace-tabs/workspace-card.component.js +256 -0
  25. package/dist/lib/workspace-tabs/workspace-card.component.js.map +1 -0
  26. package/dist/lib/workspace-tabs/workspace-tab-store.d.ts +47 -0
  27. package/dist/lib/workspace-tabs/workspace-tab-store.d.ts.map +1 -0
  28. package/dist/lib/workspace-tabs/workspace-tab-store.js +112 -0
  29. package/dist/lib/workspace-tabs/workspace-tab-store.js.map +1 -0
  30. package/dist/lib/workspace-tabs/workspace-tab-strip.component.d.ts +75 -0
  31. package/dist/lib/workspace-tabs/workspace-tab-strip.component.d.ts.map +1 -0
  32. package/dist/lib/workspace-tabs/workspace-tab-strip.component.js +252 -0
  33. package/dist/lib/workspace-tabs/workspace-tab-strip.component.js.map +1 -0
  34. package/dist/lib/workspace-tabs/workspace-tabs.types.d.ts +40 -0
  35. package/dist/lib/workspace-tabs/workspace-tabs.types.d.ts.map +1 -0
  36. package/dist/lib/workspace-tabs/workspace-tabs.types.js +13 -0
  37. package/dist/lib/workspace-tabs/workspace-tabs.types.js.map +1 -0
  38. package/dist/lib/workspace-tabs/workspace-tip.directive.d.ts +34 -0
  39. package/dist/lib/workspace-tabs/workspace-tip.directive.d.ts.map +1 -0
  40. package/dist/lib/workspace-tabs/workspace-tip.directive.js +123 -0
  41. package/dist/lib/workspace-tabs/workspace-tip.directive.js.map +1 -0
  42. package/dist/public-api.d.ts +8 -0
  43. package/dist/public-api.d.ts.map +1 -1
  44. package/dist/public-api.js +8 -0
  45. package/dist/public-api.js.map +1 -1
  46. package/package.json +14 -12
@@ -1,4 +1,4 @@
1
- import { Component, EventEmitter, HostBinding, HostListener, Input, Output } from '@angular/core';
1
+ import { ChangeDetectorRef, Component, EventEmitter, HostBinding, HostListener, Input, NgZone, Output, inject, } from '@angular/core';
2
2
  import { CommonModule } from '@angular/common';
3
3
  import * as i0 from "@angular/core";
4
4
  import * as i1 from "@angular/common";
@@ -14,164 +14,191 @@ function MJLeftNavComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
14
14
  const ctx_r1 = i0.ɵɵnextContext();
15
15
  i0.ɵɵclassMap(ctx_r1.ActiveTriggerItem.icon);
16
16
  } }
17
- function MJLeftNavComponent_For_14_Conditional_0_Template(rf, ctx) { if (rf & 1) {
18
- i0.ɵɵelementStart(0, "div", 13);
17
+ function MJLeftNavComponent_Conditional_7_Template(rf, ctx) { if (rf & 1) {
18
+ const _r3 = i0.ɵɵgetCurrentView();
19
+ i0.ɵɵelementStart(0, "button", 13);
20
+ i0.ɵɵlistener("click", function MJLeftNavComponent_Conditional_7_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ToggleCollapsed()); });
21
+ i0.ɵɵelement(1, "i", 14);
22
+ i0.ɵɵelementEnd();
23
+ i0.ɵɵelement(2, "div", 15);
24
+ } if (rf & 2) {
25
+ const ctx_r1 = i0.ɵɵnextContext();
26
+ i0.ɵɵstyleProp("margin-left", ctx_r1.CollapseToggleMarginPx, "px");
27
+ i0.ɵɵproperty("title", ctx_r1.Collapsed ? "Expand navigation" : "Collapse navigation");
28
+ i0.ɵɵattribute("aria-label", ctx_r1.Collapsed ? "Expand navigation" : "Collapse navigation")("aria-expanded", !ctx_r1.Collapsed)("aria-controls", ctx_r1.NavRegionId);
29
+ i0.ɵɵadvance();
30
+ i0.ɵɵclassProp("fa-angles-right", ctx_r1.Collapsed)("fa-angles-left", !ctx_r1.Collapsed);
31
+ } }
32
+ function MJLeftNavComponent_For_15_Conditional_0_Template(rf, ctx) { if (rf & 1) {
33
+ i0.ɵɵelementStart(0, "div", 16);
19
34
  i0.ɵɵtext(1);
20
35
  i0.ɵɵelementEnd();
21
36
  } if (rf & 2) {
22
- const section_r3 = i0.ɵɵnextContext().$implicit;
37
+ const section_r4 = i0.ɵɵnextContext().$implicit;
23
38
  i0.ɵɵadvance();
24
- i0.ɵɵtextInterpolate(section_r3.label);
39
+ i0.ɵɵtextInterpolate(section_r4.label);
25
40
  } }
26
- function MJLeftNavComponent_For_14_For_2_ng_container_0_Template(rf, ctx) { if (rf & 1) {
41
+ function MJLeftNavComponent_For_15_For_2_ng_container_0_Template(rf, ctx) { if (rf & 1) {
27
42
  i0.ɵɵelementContainer(0);
28
43
  } }
29
- function MJLeftNavComponent_For_14_For_2_Template(rf, ctx) { if (rf & 1) {
30
- i0.ɵɵtemplate(0, MJLeftNavComponent_For_14_For_2_ng_container_0_Template, 1, 0, "ng-container", 14);
44
+ function MJLeftNavComponent_For_15_For_2_Template(rf, ctx) { if (rf & 1) {
45
+ i0.ɵɵtemplate(0, MJLeftNavComponent_For_15_For_2_ng_container_0_Template, 1, 0, "ng-container", 17);
31
46
  } if (rf & 2) {
32
- const item_r4 = ctx.$implicit;
33
- const section_r3 = i0.ɵɵnextContext().$implicit;
47
+ const item_r5 = ctx.$implicit;
48
+ const section_r4 = i0.ɵɵnextContext().$implicit;
34
49
  const ctx_r1 = i0.ɵɵnextContext();
35
- const itemTpl_r5 = i0.ɵɵreference(17);
36
- i0.ɵɵproperty("ngTemplateOutlet", itemTpl_r5)("ngTemplateOutletContext", i0.ɵɵpureFunction2(2, _c2, item_r4, ctx_r1.HasExpandableItems(section_r3.items)));
50
+ const itemTpl_r6 = i0.ɵɵreference(18);
51
+ i0.ɵɵproperty("ngTemplateOutlet", itemTpl_r6)("ngTemplateOutletContext", i0.ɵɵpureFunction2(2, _c2, item_r5, ctx_r1.ShowTreeStructure && ctx_r1.HasExpandableItems(section_r4.items)));
37
52
  } }
38
- function MJLeftNavComponent_For_14_Template(rf, ctx) { if (rf & 1) {
39
- i0.ɵɵconditionalCreate(0, MJLeftNavComponent_For_14_Conditional_0_Template, 2, 1, "div", 13);
40
- i0.ɵɵrepeaterCreate(1, MJLeftNavComponent_For_14_For_2_Template, 1, 5, "ng-container", null, _forTrack0);
53
+ function MJLeftNavComponent_For_15_Template(rf, ctx) { if (rf & 1) {
54
+ i0.ɵɵconditionalCreate(0, MJLeftNavComponent_For_15_Conditional_0_Template, 2, 1, "div", 16);
55
+ i0.ɵɵrepeaterCreate(1, MJLeftNavComponent_For_15_For_2_Template, 1, 5, "ng-container", null, _forTrack0);
41
56
  } if (rf & 2) {
42
- const section_r3 = ctx.$implicit;
43
- i0.ɵɵconditional(section_r3.label ? 0 : -1);
57
+ const section_r4 = ctx.$implicit;
58
+ i0.ɵɵconditional(section_r4.label ? 0 : -1);
44
59
  i0.ɵɵadvance();
45
- i0.ɵɵrepeater(section_r3.items);
60
+ i0.ɵɵrepeater(section_r4.items);
46
61
  } }
47
- function MJLeftNavComponent_ng_template_16_Conditional_0_Conditional_1_Template(rf, ctx) { if (rf & 1) {
48
- const _r6 = i0.ɵɵgetCurrentView();
49
- i0.ɵɵelementStart(0, "button", 18);
50
- i0.ɵɵlistener("click", function MJLeftNavComponent_ng_template_16_Conditional_0_Conditional_1_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r6); const item_r7 = i0.ɵɵnextContext(2).item; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnItemToggle($event, item_r7)); });
51
- i0.ɵɵelement(1, "i", 19);
62
+ function MJLeftNavComponent_ng_template_17_Conditional_0_Conditional_1_Template(rf, ctx) { if (rf & 1) {
63
+ const _r7 = i0.ɵɵgetCurrentView();
64
+ i0.ɵɵelementStart(0, "button", 21);
65
+ i0.ɵɵlistener("click", function MJLeftNavComponent_ng_template_17_Conditional_0_Conditional_1_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r7); const item_r8 = i0.ɵɵnextContext(2).item; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnItemToggle($event, item_r8)); });
66
+ i0.ɵɵelement(1, "i", 22);
52
67
  i0.ɵɵelementEnd();
53
68
  } if (rf & 2) {
54
- const item_r7 = i0.ɵɵnextContext(2).item;
69
+ const item_r8 = i0.ɵɵnextContext(2).item;
55
70
  const ctx_r1 = i0.ɵɵnextContext();
56
- i0.ɵɵattribute("aria-label", ctx_r1.IsExpanded(item_r7.id) ? "Collapse" : "Expand")("aria-expanded", ctx_r1.IsExpanded(item_r7.id));
71
+ i0.ɵɵattribute("aria-label", ctx_r1.IsExpanded(item_r8.id) ? "Collapse" : "Expand")("aria-expanded", ctx_r1.IsExpanded(item_r8.id));
57
72
  i0.ɵɵadvance();
58
- i0.ɵɵclassProp("fa-chevron-down", ctx_r1.IsExpanded(item_r7.id))("fa-chevron-right", !ctx_r1.IsExpanded(item_r7.id));
73
+ i0.ɵɵclassProp("fa-chevron-down", ctx_r1.IsExpanded(item_r8.id))("fa-chevron-right", !ctx_r1.IsExpanded(item_r8.id));
59
74
  } }
60
- function MJLeftNavComponent_ng_template_16_Conditional_0_Conditional_2_Template(rf, ctx) { if (rf & 1) {
61
- i0.ɵɵelement(0, "span", 17);
75
+ function MJLeftNavComponent_ng_template_17_Conditional_0_Conditional_2_Template(rf, ctx) { if (rf & 1) {
76
+ i0.ɵɵelement(0, "span", 20);
62
77
  } }
63
- function MJLeftNavComponent_ng_template_16_Conditional_0_ng_container_3_Template(rf, ctx) { if (rf & 1) {
78
+ function MJLeftNavComponent_ng_template_17_Conditional_0_ng_container_3_Template(rf, ctx) { if (rf & 1) {
64
79
  i0.ɵɵelementContainer(0);
65
80
  } }
66
- function MJLeftNavComponent_ng_template_16_Conditional_0_Conditional_4_For_1_ng_container_0_Template(rf, ctx) { if (rf & 1) {
81
+ function MJLeftNavComponent_ng_template_17_Conditional_0_Conditional_4_For_1_ng_container_0_Template(rf, ctx) { if (rf & 1) {
67
82
  i0.ɵɵelementContainer(0);
68
83
  } }
69
- function MJLeftNavComponent_ng_template_16_Conditional_0_Conditional_4_For_1_Template(rf, ctx) { if (rf & 1) {
70
- i0.ɵɵtemplate(0, MJLeftNavComponent_ng_template_16_Conditional_0_Conditional_4_For_1_ng_container_0_Template, 1, 0, "ng-container", 14);
84
+ function MJLeftNavComponent_ng_template_17_Conditional_0_Conditional_4_For_1_Template(rf, ctx) { if (rf & 1) {
85
+ i0.ɵɵtemplate(0, MJLeftNavComponent_ng_template_17_Conditional_0_Conditional_4_For_1_ng_container_0_Template, 1, 0, "ng-container", 17);
71
86
  } if (rf & 2) {
72
- const child_r8 = ctx.$implicit;
73
- const ctx_r8 = i0.ɵɵnextContext(3);
74
- const depth_r10 = ctx_r8.depth;
75
- const hasExpandable_r11 = ctx_r8.hasExpandable;
87
+ const child_r9 = ctx.$implicit;
88
+ const ctx_r9 = i0.ɵɵnextContext(3);
89
+ const depth_r11 = ctx_r9.depth;
90
+ const hasExpandable_r12 = ctx_r9.hasExpandable;
76
91
  i0.ɵɵnextContext();
77
- const itemTpl_r5 = i0.ɵɵreference(17);
78
- i0.ɵɵproperty("ngTemplateOutlet", itemTpl_r5)("ngTemplateOutletContext", i0.ɵɵpureFunction3(2, _c4, child_r8, depth_r10 + 1, hasExpandable_r11));
92
+ const itemTpl_r6 = i0.ɵɵreference(18);
93
+ i0.ɵɵproperty("ngTemplateOutlet", itemTpl_r6)("ngTemplateOutletContext", i0.ɵɵpureFunction3(2, _c4, child_r9, depth_r11 + 1, hasExpandable_r12));
79
94
  } }
80
- function MJLeftNavComponent_ng_template_16_Conditional_0_Conditional_4_Template(rf, ctx) { if (rf & 1) {
81
- i0.ɵɵrepeaterCreate(0, MJLeftNavComponent_ng_template_16_Conditional_0_Conditional_4_For_1_Template, 1, 6, "ng-container", null, _forTrack0);
95
+ function MJLeftNavComponent_ng_template_17_Conditional_0_Conditional_4_Template(rf, ctx) { if (rf & 1) {
96
+ i0.ɵɵrepeaterCreate(0, MJLeftNavComponent_ng_template_17_Conditional_0_Conditional_4_For_1_Template, 1, 6, "ng-container", null, _forTrack0);
82
97
  } if (rf & 2) {
83
- const item_r7 = i0.ɵɵnextContext(2).item;
84
- i0.ɵɵrepeater(item_r7.children);
98
+ const item_r8 = i0.ɵɵnextContext(2).item;
99
+ i0.ɵɵrepeater(item_r8.children);
85
100
  } }
86
- function MJLeftNavComponent_ng_template_16_Conditional_0_Template(rf, ctx) { if (rf & 1) {
87
- i0.ɵɵelementStart(0, "div", 15);
88
- i0.ɵɵconditionalCreate(1, MJLeftNavComponent_ng_template_16_Conditional_0_Conditional_1_Template, 2, 6, "button", 16)(2, MJLeftNavComponent_ng_template_16_Conditional_0_Conditional_2_Template, 1, 0, "span", 17);
89
- i0.ɵɵtemplate(3, MJLeftNavComponent_ng_template_16_Conditional_0_ng_container_3_Template, 1, 0, "ng-container", 14);
101
+ function MJLeftNavComponent_ng_template_17_Conditional_0_Template(rf, ctx) { if (rf & 1) {
102
+ i0.ɵɵelementStart(0, "div", 18);
103
+ i0.ɵɵconditionalCreate(1, MJLeftNavComponent_ng_template_17_Conditional_0_Conditional_1_Template, 2, 6, "button", 19)(2, MJLeftNavComponent_ng_template_17_Conditional_0_Conditional_2_Template, 1, 0, "span", 20);
104
+ i0.ɵɵtemplate(3, MJLeftNavComponent_ng_template_17_Conditional_0_ng_container_3_Template, 1, 0, "ng-container", 17);
90
105
  i0.ɵɵelementEnd();
91
- i0.ɵɵconditionalCreate(4, MJLeftNavComponent_ng_template_16_Conditional_0_Conditional_4_Template, 2, 0);
106
+ i0.ɵɵconditionalCreate(4, MJLeftNavComponent_ng_template_17_Conditional_0_Conditional_4_Template, 2, 0);
92
107
  } if (rf & 2) {
93
- const ctx_r8 = i0.ɵɵnextContext();
94
- const item_r7 = ctx_r8.item;
95
- const depth_r10 = ctx_r8.depth;
108
+ const ctx_r9 = i0.ɵɵnextContext();
109
+ const item_r8 = ctx_r9.item;
110
+ const depth_r11 = ctx_r9.depth;
96
111
  const ctx_r1 = i0.ɵɵnextContext();
97
- const itemBtn_r12 = i0.ɵɵreference(19);
98
- i0.ɵɵstyleProp("padding-left", depth_r10 * 14, "px");
112
+ const itemBtn_r13 = i0.ɵɵreference(20);
113
+ i0.ɵɵstyleProp("padding-left", depth_r11 * 14, "px");
99
114
  i0.ɵɵadvance();
100
- i0.ɵɵconditional(item_r7.children.length > 0 ? 1 : 2);
115
+ i0.ɵɵconditional(item_r8.children.length > 0 ? 1 : 2);
101
116
  i0.ɵɵadvance(2);
102
- i0.ɵɵproperty("ngTemplateOutlet", itemBtn_r12)("ngTemplateOutletContext", i0.ɵɵpureFunction1(6, _c3, item_r7));
117
+ i0.ɵɵproperty("ngTemplateOutlet", itemBtn_r13)("ngTemplateOutletContext", i0.ɵɵpureFunction1(6, _c3, item_r8));
103
118
  i0.ɵɵadvance();
104
- i0.ɵɵconditional(item_r7.children.length > 0 && ctx_r1.IsExpanded(item_r7.id) ? 4 : -1);
119
+ i0.ɵɵconditional(item_r8.children.length > 0 && ctx_r1.IsExpanded(item_r8.id) ? 4 : -1);
105
120
  } }
106
- function MJLeftNavComponent_ng_template_16_Conditional_1_ng_container_0_Template(rf, ctx) { if (rf & 1) {
121
+ function MJLeftNavComponent_ng_template_17_Conditional_1_ng_container_0_Template(rf, ctx) { if (rf & 1) {
107
122
  i0.ɵɵelementContainer(0);
108
123
  } }
109
- function MJLeftNavComponent_ng_template_16_Conditional_1_Template(rf, ctx) { if (rf & 1) {
110
- i0.ɵɵtemplate(0, MJLeftNavComponent_ng_template_16_Conditional_1_ng_container_0_Template, 1, 0, "ng-container", 14);
124
+ function MJLeftNavComponent_ng_template_17_Conditional_1_Template(rf, ctx) { if (rf & 1) {
125
+ i0.ɵɵtemplate(0, MJLeftNavComponent_ng_template_17_Conditional_1_ng_container_0_Template, 1, 0, "ng-container", 17);
111
126
  } if (rf & 2) {
112
- const item_r7 = i0.ɵɵnextContext().item;
127
+ const item_r8 = i0.ɵɵnextContext().item;
113
128
  i0.ɵɵnextContext();
114
- const itemBtn_r12 = i0.ɵɵreference(19);
115
- i0.ɵɵproperty("ngTemplateOutlet", itemBtn_r12)("ngTemplateOutletContext", i0.ɵɵpureFunction1(2, _c3, item_r7));
129
+ const itemBtn_r13 = i0.ɵɵreference(20);
130
+ i0.ɵɵproperty("ngTemplateOutlet", itemBtn_r13)("ngTemplateOutletContext", i0.ɵɵpureFunction1(2, _c3, item_r8));
116
131
  } }
117
- function MJLeftNavComponent_ng_template_16_Template(rf, ctx) { if (rf & 1) {
118
- i0.ɵɵconditionalCreate(0, MJLeftNavComponent_ng_template_16_Conditional_0_Template, 5, 8)(1, MJLeftNavComponent_ng_template_16_Conditional_1_Template, 1, 4, "ng-container");
132
+ function MJLeftNavComponent_ng_template_17_Template(rf, ctx) { if (rf & 1) {
133
+ i0.ɵɵconditionalCreate(0, MJLeftNavComponent_ng_template_17_Conditional_0_Template, 5, 8)(1, MJLeftNavComponent_ng_template_17_Conditional_1_Template, 1, 4, "ng-container");
119
134
  } if (rf & 2) {
120
- const item_r7 = ctx.item;
121
- const hasExpandable_r11 = ctx.hasExpandable;
122
- i0.ɵɵconditional(item_r7.children !== undefined && hasExpandable_r11 ? 0 : 1);
135
+ const item_r8 = ctx.item;
136
+ const hasExpandable_r12 = ctx.hasExpandable;
137
+ i0.ɵɵconditional(item_r8.children !== undefined && hasExpandable_r12 ? 0 : 1);
123
138
  } }
124
- function MJLeftNavComponent_ng_template_18_Conditional_1_Template(rf, ctx) { if (rf & 1) {
125
- i0.ɵɵelement(0, "i", 26);
139
+ function MJLeftNavComponent_ng_template_19_Conditional_1_Template(rf, ctx) { if (rf & 1) {
140
+ i0.ɵɵelement(0, "i", 30);
126
141
  } if (rf & 2) {
127
- const item_r14 = i0.ɵɵnextContext().item;
128
- i0.ɵɵclassMap(item_r14.icon);
142
+ const item_r15 = i0.ɵɵnextContext().item;
143
+ i0.ɵɵclassMap(item_r15.icon);
129
144
  } }
130
- function MJLeftNavComponent_ng_template_18_Conditional_5_Template(rf, ctx) { if (rf & 1) {
131
- i0.ɵɵelementStart(0, "span", 24);
145
+ function MJLeftNavComponent_ng_template_19_Conditional_2_Template(rf, ctx) { if (rf & 1) {
146
+ i0.ɵɵelementStart(0, "span", 25);
132
147
  i0.ɵɵtext(1);
133
148
  i0.ɵɵelementEnd();
134
149
  } if (rf & 2) {
135
- const item_r14 = i0.ɵɵnextContext().item;
150
+ const item_r15 = i0.ɵɵnextContext().item;
151
+ const ctx_r1 = i0.ɵɵnextContext();
136
152
  i0.ɵɵadvance();
137
- i0.ɵɵtextInterpolate(item_r14.description);
153
+ i0.ɵɵtextInterpolate(ctx_r1.ItemInitial(item_r15));
138
154
  } }
139
- function MJLeftNavComponent_ng_template_18_Conditional_6_Template(rf, ctx) { if (rf & 1) {
140
- i0.ɵɵelementStart(0, "span", 25);
155
+ function MJLeftNavComponent_ng_template_19_Conditional_6_Template(rf, ctx) { if (rf & 1) {
156
+ i0.ɵɵelementStart(0, "span", 28);
141
157
  i0.ɵɵtext(1);
142
158
  i0.ɵɵelementEnd();
143
159
  } if (rf & 2) {
144
- const item_r14 = i0.ɵɵnextContext().item;
160
+ const item_r15 = i0.ɵɵnextContext().item;
145
161
  i0.ɵɵadvance();
146
- i0.ɵɵtextInterpolate(item_r14.badge);
162
+ i0.ɵɵtextInterpolate(item_r15.description);
147
163
  } }
148
- function MJLeftNavComponent_ng_template_18_Template(rf, ctx) { if (rf & 1) {
149
- const _r13 = i0.ɵɵgetCurrentView();
150
- i0.ɵɵelementStart(0, "button", 20);
151
- i0.ɵɵlistener("click", function MJLeftNavComponent_ng_template_18_Template_button_click_0_listener() { const item_r14 = i0.ɵɵrestoreView(_r13).item; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnItemClick(item_r14)); });
152
- i0.ɵɵconditionalCreate(1, MJLeftNavComponent_ng_template_18_Conditional_1_Template, 1, 2, "i", 21);
153
- i0.ɵɵelementStart(2, "span", 22)(3, "span", 23);
154
- i0.ɵɵtext(4);
164
+ function MJLeftNavComponent_ng_template_19_Conditional_7_Template(rf, ctx) { if (rf & 1) {
165
+ i0.ɵɵelementStart(0, "span", 29);
166
+ i0.ɵɵtext(1);
155
167
  i0.ɵɵelementEnd();
156
- i0.ɵɵconditionalCreate(5, MJLeftNavComponent_ng_template_18_Conditional_5_Template, 2, 1, "span", 24);
168
+ } if (rf & 2) {
169
+ const item_r15 = i0.ɵɵnextContext().item;
170
+ i0.ɵɵadvance();
171
+ i0.ɵɵtextInterpolate(item_r15.badge);
172
+ } }
173
+ function MJLeftNavComponent_ng_template_19_Template(rf, ctx) { if (rf & 1) {
174
+ const _r14 = i0.ɵɵgetCurrentView();
175
+ i0.ɵɵelementStart(0, "button", 23);
176
+ i0.ɵɵlistener("click", function MJLeftNavComponent_ng_template_19_Template_button_click_0_listener() { const item_r15 = i0.ɵɵrestoreView(_r14).item; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnItemClick(item_r15)); });
177
+ i0.ɵɵconditionalCreate(1, MJLeftNavComponent_ng_template_19_Conditional_1_Template, 1, 2, "i", 24)(2, MJLeftNavComponent_ng_template_19_Conditional_2_Template, 2, 1, "span", 25);
178
+ i0.ɵɵelementStart(3, "span", 26)(4, "span", 27);
179
+ i0.ɵɵtext(5);
180
+ i0.ɵɵelementEnd();
181
+ i0.ɵɵconditionalCreate(6, MJLeftNavComponent_ng_template_19_Conditional_6_Template, 2, 1, "span", 28);
157
182
  i0.ɵɵelementEnd();
158
- i0.ɵɵconditionalCreate(6, MJLeftNavComponent_ng_template_18_Conditional_6_Template, 2, 1, "span", 25);
183
+ i0.ɵɵconditionalCreate(7, MJLeftNavComponent_ng_template_19_Conditional_7_Template, 2, 1, "span", 29);
159
184
  i0.ɵɵelementEnd();
160
185
  } if (rf & 2) {
161
- const item_r14 = ctx.item;
186
+ const item_r15 = ctx.item;
162
187
  const ctx_r1 = i0.ɵɵnextContext();
163
- i0.ɵɵclassProp("mj-left-nav__item--active", item_r14.id === ctx_r1.ActiveId)("mj-left-nav__item--disabled", item_r14.disabled);
164
- i0.ɵɵproperty("disabled", item_r14.disabled);
165
- i0.ɵɵattribute("aria-current", item_r14.id === ctx_r1.ActiveId ? "page" : null);
188
+ i0.ɵɵclassProp("mj-left-nav__item--active", ctx_r1.IsItemActive(item_r15))("mj-left-nav__item--disabled", item_r15.disabled);
189
+ i0.ɵɵproperty("disabled", item_r15.disabled);
190
+ i0.ɵɵattribute("aria-current", ctx_r1.AriaCurrentFor(item_r15))("title", ctx_r1.EffectiveIconOnly ? ctx_r1.ItemTooltip(item_r15) : null)("aria-label", ctx_r1.EffectiveIconOnly ? ctx_r1.ItemTooltip(item_r15) : null);
166
191
  i0.ɵɵadvance();
167
- i0.ɵɵconditional(item_r14.icon ? 1 : -1);
168
- i0.ɵɵadvance(3);
169
- i0.ɵɵtextInterpolate(item_r14.label);
192
+ i0.ɵɵconditional(item_r15.icon ? 1 : ctx_r1.EffectiveIconOnly ? 2 : -1);
193
+ i0.ɵɵadvance(4);
194
+ i0.ɵɵtextInterpolate(item_r15.label);
170
195
  i0.ɵɵadvance();
171
- i0.ɵɵconditional(item_r14.description ? 5 : -1);
196
+ i0.ɵɵconditional(item_r15.description ? 6 : -1);
172
197
  i0.ɵɵadvance();
173
- i0.ɵɵconditional(item_r14.badge != null ? 6 : -1);
198
+ i0.ɵɵconditional(item_r15.badge != null ? 7 : -1);
174
199
  } }
200
+ /** Source of per-instance DOM ids — see {@link MJLeftNavComponent.NavRegionId}. */
201
+ let navRegionSeq = 0;
175
202
  /**
176
203
  * `<mj-left-nav>` — Canonical left rail for MJ Explorer dashboards that have
177
204
  * an internal section-nav (Admin shells, KH Config, KH Analytics, AI Analytics,
@@ -220,6 +247,11 @@ function MJLeftNavComponent_ng_template_18_Template(rf, ctx) { if (rf & 1) {
220
247
  * pane rather than competing with it for horizontal space.
221
248
  */
222
249
  export class MJLeftNavComponent {
250
+ /**
251
+ * DOM id of the `<aside>`, so the collapse toggle's `aria-expanded` can name the region it
252
+ * expands via `aria-controls`. Per-instance because a page may host more than one rail.
253
+ */
254
+ NavRegionId = `mj-left-nav-${++navRegionSeq}`;
223
255
  /**
224
256
  * The sections + items that make up the rail. Sections render top-to-bottom
225
257
  * in array order; items inside each section render in array order.
@@ -236,6 +268,192 @@ export class MJLeftNavComponent {
236
268
  * the rail becomes a fixed-width off-canvas drawer.
237
269
  */
238
270
  Width = 240;
271
+ /**
272
+ * Set by a consumer that has visually collapsed the rail to an icons-only strip (via `Width` plus
273
+ * its own CSS hiding the labels). When true, each item gains a native `title` tooltip AND an
274
+ * `aria-label` carrying its full text.
275
+ *
276
+ * Why it is opt-in rather than always-on:
277
+ * - **Tooltip**: with labels visible, a tooltip that just repeats the label is redundant noise on
278
+ * every hover. Icon-only rails everywhere (VS Code's activity bar, Slack, Linear, Jira, Figma)
279
+ * show one; expanded rails do not.
280
+ * - **aria-label**: when the label IS visible it already names the button, and adding an identical
281
+ * aria-label is at best a no-op. When the consumer's CSS hides `.mj-left-nav__text`, the button's
282
+ * accessible name goes EMPTY — a screen reader announces "button" with no destination. That is
283
+ * the hole this closes.
284
+ *
285
+ * Leaving it false reproduces the previous markup exactly, so existing consumers are unaffected.
286
+ */
287
+ IconOnly = false;
288
+ /**
289
+ * Opt-in desktop collapse: renders a compact double-angle toggle chip at the top of the rail and,
290
+ * when {@link Collapsed}, presents the rail as an icons-only strip ({@link CollapsedWidth} wide) —
291
+ * labels visually hidden but kept in the a11y tree, section labels folded to divider lines,
292
+ * badges docked on the icon corner, and per-item tooltips/aria auto-enabled.
293
+ *
294
+ * The component owns the PRESENTATION only — the consumer owns the STATE (bind `[(Collapsed)]`
295
+ * and persist it however the app persists preferences), the same split as `ExpandedIds`.
296
+ * Desktop-only: ≤700px the rail is the off-canvas drawer and the toggle hides.
297
+ *
298
+ * Two things to know when the rail's content is richer than a flat icon list:
299
+ * - **Tree sections fold to their top level while collapsed** (see {@link ShowTreeStructure});
300
+ * a top-level item stands in as active for an active descendant, and the tree returns intact
301
+ * on expand. Items with no `icon` render a monogram so they stay visible and hittable.
302
+ * - **The `[header]` / `[footer]` slots are yours.** The rail can't restyle projected content,
303
+ * so a wide header (logo lockup + wordmark, a filter box) will overflow a `CollapsedWidth`
304
+ * strip. Bind the same collapsed flag in the consumer and project a compact variant.
305
+ *
306
+ * Deliberately NOT included: hover-to-peek (auto-expand on pointer hover) — removed by ruling
307
+ * (2026-07-30): a rail that expands when the pointer grazes it moves the target the user was
308
+ * aiming at. Deliberate toggling beats clever hovering.
309
+ */
310
+ Collapsible = false;
311
+ /** Whether the rail is currently collapsed to icons. Two-way bindable via `[(Collapsed)]`. */
312
+ Collapsed = false;
313
+ /** Emitted when the user clicks the collapse toggle. Consumer updates + persists the state. */
314
+ CollapsedChange = new EventEmitter();
315
+ /**
316
+ * Width of the collapsed icons-only strip. The default 60 is derived from the rail's own
317
+ * numbers — 8+8 container padding, 12+12 item padding, 18px icon, 1px border — so icons stay
318
+ * centred; retune it if those change.
319
+ */
320
+ CollapsedWidth = 60;
321
+ /**
322
+ * True below the 701px breakpoint, where the rail stops being a rail and becomes the off-canvas
323
+ * drawer. Tracked in TS — not just CSS — because collapse is more than styling: it also decides
324
+ * whether tree sections fold and whether items are named by tooltip. The collapsed STYLES are
325
+ * gated to ≥701px, so without this the drawer would keep the collapsed BEHAVIOR while showing
326
+ * full labels: a flattened tree, and a monogram beside the very label it stands in for.
327
+ *
328
+ * Mirrors the matchMedia pattern in `mj-filter-popover` (same package).
329
+ */
330
+ isMobileViewport = false;
331
+ zone = inject(NgZone);
332
+ cdr = inject(ChangeDetectorRef);
333
+ mediaQuery = typeof window !== 'undefined' && typeof window.matchMedia === 'function'
334
+ ? window.matchMedia('(max-width: 700px)')
335
+ : null;
336
+ // matchMedia 'change' fires OUTSIDE Angular's zone, so re-enter before flipping state the
337
+ // template reads.
338
+ onMediaChange = (e) => {
339
+ this.zone.run(() => {
340
+ this.isMobileViewport = e.matches;
341
+ this.cdr.markForCheck();
342
+ });
343
+ };
344
+ constructor() {
345
+ if (this.mediaQuery) {
346
+ this.isMobileViewport = this.mediaQuery.matches;
347
+ this.mediaQuery.addEventListener('change', this.onMediaChange);
348
+ }
349
+ }
350
+ ngOnDestroy() {
351
+ this.mediaQuery?.removeEventListener('change', this.onMediaChange);
352
+ }
353
+ /**
354
+ * Whether the rail is collapsed *and* in a viewport where collapse means anything. Below 701px
355
+ * the rail is the off-canvas drawer — already dismissable, already showing full labels — so a
356
+ * persisted `Collapsed = true` must not follow the user down there.
357
+ */
358
+ get IsNativelyCollapsed() {
359
+ return this.Collapsible && this.Collapsed && !this.isMobileViewport;
360
+ }
361
+ /** The width the rail actually renders at, honoring the collapse state. */
362
+ get EffectiveWidth() {
363
+ return this.IsNativelyCollapsed ? this.CollapsedWidth : this.Width;
364
+ }
365
+ /**
366
+ * Icon-only presentation is on when the consumer forces it OR the rail is natively collapsed.
367
+ *
368
+ * `IconOnly` is deliberately NOT viewport-gated: that flag means the CONSUMER's own CSS has
369
+ * narrowed the rail, and we can't know which breakpoints they gated it to. Withdrawing the
370
+ * accessible names on their behalf could leave a genuinely icons-only rail unnamed — the exact
371
+ * hole `IconOnly` exists to close. Native collapse is ours to gate; theirs is theirs.
372
+ */
373
+ get EffectiveIconOnly() {
374
+ return this.IconOnly || this.IsNativelyCollapsed;
375
+ }
376
+ /**
377
+ * Whether tree structure (chevrons, depth indentation, expanded children) renders at all.
378
+ *
379
+ * An icons-only rail is ~60px wide and shows nothing but a centred glyph per row, which leaves a
380
+ * tree with no way to express itself: the chevron would eat a third of the width and shove the
381
+ * icon off-centre, each depth level would push its icon 14px further right until the rail clipped
382
+ * it, and a child's icon (optional, and usually absent on tree leaves) would say nothing about
383
+ * which branch it belongs to. So while icons-only, each section renders its TOP-LEVEL items only —
384
+ * the same choice every icon rail makes (VS Code's activity bar shows one icon per container and
385
+ * defers the tree to the expanded pane).
386
+ *
387
+ * Nothing is lost on the way back: `ExpandedIds` is consumer-owned and untouched here, so the tree
388
+ * returns exactly as the user left it the moment the rail expands.
389
+ */
390
+ get ShowTreeStructure() {
391
+ return !this.EffectiveIconOnly;
392
+ }
393
+ /**
394
+ * Whether an item paints as active. Normally an exact {@link ActiveId} match — but while the tree
395
+ * is suppressed (see {@link ShowTreeStructure}) the active item may be a child that isn't rendered,
396
+ * which would leave the collapsed rail with NOTHING highlighted and no sense of place. In that
397
+ * state a top-level item stands in for its active descendant.
398
+ */
399
+ IsItemActive(item) {
400
+ if (item.id === this.ActiveId)
401
+ return true;
402
+ return this.EffectiveIconOnly && this.hasActiveDescendant(item);
403
+ }
404
+ /**
405
+ * `'page'` for the active item itself; `'true'` for a stand-in ancestor, which is current in the
406
+ * set but is not the page the user is on. Distinguishing them keeps the announcement honest.
407
+ */
408
+ AriaCurrentFor(item) {
409
+ if (item.id === this.ActiveId)
410
+ return 'page';
411
+ return this.IsItemActive(item) ? 'true' : null;
412
+ }
413
+ hasActiveDescendant(item) {
414
+ if (!this.ActiveId || !item.children?.length)
415
+ return false;
416
+ return this.findItemById(item.children, this.ActiveId) !== undefined;
417
+ }
418
+ /**
419
+ * Monogram for an icon-less item in an icons-only rail. `Array.from` rather than `charAt` so a
420
+ * label starting with an emoji or an astral character yields that whole character instead of half
421
+ * a surrogate pair. Falls back to a bullet for a blank label so the button is never empty.
422
+ */
423
+ ItemInitial(item) {
424
+ return Array.from(item.label?.trim() ?? '')[0] ?? '•';
425
+ }
426
+ /**
427
+ * Left margin that pins the toggle chip at the collapsed band's centre in BOTH modes, so the
428
+ * chip never relocates on toggle (the user never re-aims). Derived, not magic:
429
+ * (CollapsedWidth − 38px chip)/2 from the rail edge, minus the rail's 8px container padding.
430
+ * 38 = the 18px icon box + 2×10px chip padding.
431
+ */
432
+ get CollapseToggleMarginPx() {
433
+ return Math.max(0, Math.round((this.CollapsedWidth - 38) / 2 - 8));
434
+ }
435
+ /** Reflects the collapsed state onto the host so the collapsed CSS can scope to it. */
436
+ get isCollapsedHost() {
437
+ return this.IsNativelyCollapsed;
438
+ }
439
+ /** Flip + announce. The consumer receives the new value and persists it. */
440
+ ToggleCollapsed() {
441
+ this.Collapsed = !this.Collapsed;
442
+ this.CollapsedChange.emit(this.Collapsed);
443
+ }
444
+ /**
445
+ * The text surfaced as an icon-only item's tooltip / accessible name. Folds in the description and
446
+ * badge because collapsing the rail hides both: the badge survives as an unlabeled corner count,
447
+ * so "Batch approvals (2)" is the only place a hovering user learns what the 2 counts.
448
+ */
449
+ ItemTooltip(item) {
450
+ const parts = [item.label];
451
+ if (item.description)
452
+ parts.push(`— ${item.description}`);
453
+ if (item.badge != null)
454
+ parts.push(`(${item.badge})`);
455
+ return parts.join(' ');
456
+ }
239
457
  /**
240
458
  * Label shown on the mobile drawer header and used as the switcher fallback
241
459
  * label when no item is active. Defaults to `'Menu'`. Set to something
@@ -335,11 +553,11 @@ export class MJLeftNavComponent {
335
553
  return false;
336
554
  }
337
555
  static ɵfac = function MJLeftNavComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || MJLeftNavComponent)(); };
338
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MJLeftNavComponent, selectors: [["mj-left-nav"]], hostVars: 2, hostBindings: function MJLeftNavComponent_HostBindings(rf, ctx) { if (rf & 1) {
556
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MJLeftNavComponent, selectors: [["mj-left-nav"]], hostVars: 4, hostBindings: function MJLeftNavComponent_HostBindings(rf, ctx) { if (rf & 1) {
339
557
  i0.ɵɵlistener("keydown.escape", function MJLeftNavComponent_keydown_escape_HostBindingHandler() { return ctx.onEscape(); }, i0.ɵɵresolveDocument);
340
558
  } if (rf & 2) {
341
- i0.ɵɵclassProp("mj-left-nav-host--open", ctx.isMobileNavOpen);
342
- } }, inputs: { Sections: "Sections", ActiveId: "ActiveId", Width: "Width", MobileTitle: "MobileTitle", ExpandedIds: "ExpandedIds" }, outputs: { ItemClicked: "ItemClicked", ItemToggled: "ItemToggled" }, ngContentSelectors: _c1, decls: 20, vars: 7, consts: [["itemTpl", ""], ["itemBtn", ""], ["type", "button", "aria-haspopup", "dialog", 1, "mj-left-nav__switcher", 3, "click"], ["aria-hidden", "true", 1, "mj-left-nav__switcher-icon", 3, "class"], [1, "mj-left-nav__switcher-label"], ["aria-hidden", "true", 1, "fa-solid", "fa-bars-staggered", "mj-left-nav__switcher-hint"], ["aria-hidden", "true", 1, "mj-left-nav__scrim", 3, "click"], ["role", "navigation", 1, "mj-left-nav"], [1, "mj-left-nav__drawer-header"], [1, "mj-left-nav__drawer-title"], ["type", "button", "aria-label", "Close menu", 1, "mj-left-nav__drawer-close", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-xmark"], ["aria-hidden", "true", 1, "mj-left-nav__switcher-icon"], [1, "mj-left-nav__section-label"], [4, "ngTemplateOutlet", "ngTemplateOutletContext"], [1, "mj-left-nav__row"], ["type", "button", 1, "mj-left-nav__chevron"], ["aria-hidden", "true", 1, "mj-left-nav__chevron-placeholder"], ["type", "button", 1, "mj-left-nav__chevron", 3, "click"], ["aria-hidden", "true", 1, "fa-solid"], ["type", "button", 1, "mj-left-nav__item", 3, "click", "disabled"], ["aria-hidden", "true", 1, "mj-left-nav__icon", 3, "class"], [1, "mj-left-nav__text"], [1, "mj-left-nav__label"], [1, "mj-left-nav__description"], [1, "mj-left-nav__badge"], ["aria-hidden", "true", 1, "mj-left-nav__icon"]], template: function MJLeftNavComponent_Template(rf, ctx) { if (rf & 1) {
559
+ i0.ɵɵclassProp("mj-left-nav-host--collapsed", ctx.isCollapsedHost)("mj-left-nav-host--open", ctx.isMobileNavOpen);
560
+ } }, inputs: { Sections: "Sections", ActiveId: "ActiveId", Width: "Width", IconOnly: "IconOnly", Collapsible: "Collapsible", Collapsed: "Collapsed", CollapsedWidth: "CollapsedWidth", MobileTitle: "MobileTitle", ExpandedIds: "ExpandedIds" }, outputs: { CollapsedChange: "CollapsedChange", ItemClicked: "ItemClicked", ItemToggled: "ItemToggled" }, ngContentSelectors: _c1, decls: 21, vars: 9, consts: [["itemTpl", ""], ["itemBtn", ""], ["type", "button", "aria-haspopup", "dialog", 1, "mj-left-nav__switcher", 3, "click"], ["aria-hidden", "true", 1, "mj-left-nav__switcher-icon", 3, "class"], [1, "mj-left-nav__switcher-label"], ["aria-hidden", "true", 1, "fa-solid", "fa-bars-staggered", "mj-left-nav__switcher-hint"], ["aria-hidden", "true", 1, "mj-left-nav__scrim", 3, "click"], ["role", "navigation", 1, "mj-left-nav", 3, "id"], [1, "mj-left-nav__drawer-header"], [1, "mj-left-nav__drawer-title"], ["type", "button", "aria-label", "Close menu", 1, "mj-left-nav__drawer-close", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-xmark"], ["aria-hidden", "true", 1, "mj-left-nav__switcher-icon"], ["type", "button", 1, "mj-left-nav__collapse-toggle", 3, "click", "title"], ["aria-hidden", "true", 1, "fa-solid", "mj-left-nav__collapse-icon"], ["aria-hidden", "true", 1, "mj-left-nav__collapse-divider"], [1, "mj-left-nav__section-label"], [4, "ngTemplateOutlet", "ngTemplateOutletContext"], [1, "mj-left-nav__row"], ["type", "button", 1, "mj-left-nav__chevron"], ["aria-hidden", "true", 1, "mj-left-nav__chevron-placeholder"], ["type", "button", 1, "mj-left-nav__chevron", 3, "click"], ["aria-hidden", "true", 1, "fa-solid"], ["type", "button", 1, "mj-left-nav__item", 3, "click", "disabled"], ["aria-hidden", "true", 1, "mj-left-nav__icon", 3, "class"], ["aria-hidden", "true", 1, "mj-left-nav__initial"], [1, "mj-left-nav__text"], [1, "mj-left-nav__label"], [1, "mj-left-nav__description"], [1, "mj-left-nav__badge"], ["aria-hidden", "true", 1, "mj-left-nav__icon"]], template: function MJLeftNavComponent_Template(rf, ctx) { if (rf & 1) {
343
561
  const _r1 = i0.ɵɵgetCurrentView();
344
562
  i0.ɵɵprojectionDef(_c0);
345
563
  i0.ɵɵelementStart(0, "button", 2);
@@ -353,18 +571,20 @@ export class MJLeftNavComponent {
353
571
  i0.ɵɵelementStart(5, "div", 6);
354
572
  i0.ɵɵlistener("click", function MJLeftNavComponent_Template_div_click_5_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.CloseMobileNav()); });
355
573
  i0.ɵɵelementEnd();
356
- i0.ɵɵelementStart(6, "aside", 7)(7, "div", 8)(8, "span", 9);
357
- i0.ɵɵtext(9);
574
+ i0.ɵɵelementStart(6, "aside", 7);
575
+ i0.ɵɵconditionalCreate(7, MJLeftNavComponent_Conditional_7_Template, 3, 10);
576
+ i0.ɵɵelementStart(8, "div", 8)(9, "span", 9);
577
+ i0.ɵɵtext(10);
358
578
  i0.ɵɵelementEnd();
359
- i0.ɵɵelementStart(10, "button", 10);
360
- i0.ɵɵlistener("click", function MJLeftNavComponent_Template_button_click_10_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.CloseMobileNav()); });
361
- i0.ɵɵelement(11, "i", 11);
579
+ i0.ɵɵelementStart(11, "button", 10);
580
+ i0.ɵɵlistener("click", function MJLeftNavComponent_Template_button_click_11_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.CloseMobileNav()); });
581
+ i0.ɵɵelement(12, "i", 11);
362
582
  i0.ɵɵelementEnd()();
363
- i0.ɵɵprojection(12);
364
- i0.ɵɵrepeaterCreate(13, MJLeftNavComponent_For_14_Template, 3, 1, null, null, i0.ɵɵrepeaterTrackByIndex);
365
- i0.ɵɵprojection(15, 1);
583
+ i0.ɵɵprojection(13);
584
+ i0.ɵɵrepeaterCreate(14, MJLeftNavComponent_For_15_Template, 3, 1, null, null, i0.ɵɵrepeaterTrackByIndex);
585
+ i0.ɵɵprojection(16, 1);
366
586
  i0.ɵɵelementEnd();
367
- i0.ɵɵtemplate(16, MJLeftNavComponent_ng_template_16_Template, 2, 1, "ng-template", null, 0, i0.ɵɵtemplateRefExtractor)(18, MJLeftNavComponent_ng_template_18_Template, 7, 10, "ng-template", null, 1, i0.ɵɵtemplateRefExtractor);
587
+ i0.ɵɵtemplate(17, MJLeftNavComponent_ng_template_17_Template, 2, 1, "ng-template", null, 0, i0.ɵɵtemplateRefExtractor)(19, MJLeftNavComponent_ng_template_19_Template, 8, 12, "ng-template", null, 1, i0.ɵɵtemplateRefExtractor);
368
588
  } if (rf & 2) {
369
589
  i0.ɵɵattribute("aria-expanded", ctx.MobileNavOpen);
370
590
  i0.ɵɵadvance();
@@ -372,13 +592,16 @@ export class MJLeftNavComponent {
372
592
  i0.ɵɵadvance(2);
373
593
  i0.ɵɵtextInterpolate((ctx.ActiveTriggerItem == null ? null : ctx.ActiveTriggerItem.label) || ctx.MobileTitle);
374
594
  i0.ɵɵadvance(3);
375
- i0.ɵɵstyleProp("width", ctx.Width, "px");
595
+ i0.ɵɵstyleProp("width", ctx.EffectiveWidth, "px");
596
+ i0.ɵɵproperty("id", ctx.NavRegionId);
376
597
  i0.ɵɵattribute("aria-modal", ctx.MobileNavOpen ? true : null);
598
+ i0.ɵɵadvance();
599
+ i0.ɵɵconditional(ctx.Collapsible ? 7 : -1);
377
600
  i0.ɵɵadvance(3);
378
601
  i0.ɵɵtextInterpolate(ctx.MobileTitle);
379
602
  i0.ɵɵadvance(4);
380
603
  i0.ɵɵrepeater(ctx.Sections);
381
- } }, dependencies: [CommonModule, i1.NgTemplateOutlet], styles: ["[_nghost-%COMP%] {\n display: block;\n flex-shrink: 0;\n }\n\n .mj-left-nav[_ngcontent-%COMP%] {\n height: 100%;\n background: var(--mj-bg-surface);\n border-right: 1px solid var(--mj-border-default);\n overflow-y: auto;\n padding: 8px;\n box-sizing: border-box;\n }\n\n .mj-left-nav__section-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mj-text-muted);\n padding: 12px 12px 6px;\n }\n\n .mj-left-nav__section-label[_ngcontent-%COMP%]:first-child {\n padding-top: 6px;\n }\n\n .mj-left-nav__item[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 10px 12px;\n width: 100%;\n border: none;\n background: transparent;\n border-radius: 8px;\n cursor: pointer;\n transition: background-color 0.12s ease, color 0.12s ease;\n margin-bottom: 2px;\n font-family: inherit;\n color: var(--mj-text-secondary);\n text-align: left;\n }\n\n .mj-left-nav__item[_ngcontent-%COMP%]:hover:not(.mj-left-nav__item--disabled) {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n }\n\n .mj-left-nav__item--active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--mj-brand-primary);\n }\n\n .mj-left-nav__item--active[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, transparent);\n }\n\n .mj-left-nav__item--disabled[_ngcontent-%COMP%] {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n .mj-left-nav__icon[_ngcontent-%COMP%] {\n width: 18px;\n text-align: center;\n font-size: 13px;\n margin-top: 1px;\n flex-shrink: 0;\n color: inherit;\n }\n\n .mj-left-nav__text[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n }\n\n .mj-left-nav__label[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n line-height: 1.2;\n }\n\n .mj-left-nav__description[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n margin-top: 3px;\n line-height: 1.3;\n }\n\n .mj-left-nav__item--active[_ngcontent-%COMP%] .mj-left-nav__description[_ngcontent-%COMP%] {\n color: color-mix(in srgb, var(--mj-brand-primary) 70%, var(--mj-text-muted));\n }\n\n .mj-left-nav__badge[_ngcontent-%COMP%] {\n margin-left: auto;\n font-size: 11px;\n font-weight: 600;\n padding: 2px 8px;\n border-radius: 999px;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n align-self: center;\n }\n\n .mj-left-nav__item--active[_ngcontent-%COMP%] .mj-left-nav__badge[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n color: var(--mj-brand-primary);\n }\n\n \n\n\n\n\n\n\n .mj-left-nav__row[_ngcontent-%COMP%] {\n display: flex;\n align-items: stretch;\n gap: 2px;\n }\n\n .mj-left-nav__row[_ngcontent-%COMP%] .mj-left-nav__item[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n }\n\n .mj-left-nav__chevron[_ngcontent-%COMP%] {\n flex-shrink: 0;\n width: 20px;\n height: 32px;\n align-self: center;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n border-radius: 4px;\n cursor: pointer;\n color: var(--mj-text-muted);\n font-size: 10px;\n padding: 0;\n transition: background-color 0.12s ease, color 0.12s ease;\n font-family: inherit;\n }\n\n .mj-left-nav__chevron[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n }\n\n .mj-left-nav__chevron-placeholder[_ngcontent-%COMP%] {\n flex-shrink: 0;\n width: 20px;\n display: inline-block;\n }\n\n \n\n\n\n\n\n\n\n\n\n .mj-left-nav__switcher[_ngcontent-%COMP%], \n .mj-left-nav__scrim[_ngcontent-%COMP%], \n .mj-left-nav__drawer-header[_ngcontent-%COMP%] {\n display: none;\n }\n\n @media (max-width: 700px) {\n \n\n [_nghost-%COMP%] {\n width: 100% !important;\n }\n\n \n\n\n .mj-left-nav__description[_ngcontent-%COMP%] {\n display: none;\n }\n\n \n\n .mj-left-nav__switcher[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 11px 14px;\n border: none;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-family: inherit;\n font-size: 14px;\n font-weight: 600;\n text-align: left;\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n }\n .mj-left-nav__switcher[_ngcontent-%COMP%]:active {\n background: var(--mj-bg-surface-active);\n }\n .mj-left-nav__switcher-icon[_ngcontent-%COMP%] {\n width: 18px;\n text-align: center;\n font-size: 14px;\n flex-shrink: 0;\n color: var(--mj-brand-primary);\n }\n .mj-left-nav__switcher-label[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .mj-left-nav__switcher-hint[_ngcontent-%COMP%] {\n flex-shrink: 0;\n font-size: 15px;\n color: var(--mj-text-muted);\n }\n\n \n\n .mj-left-nav__scrim[_ngcontent-%COMP%] {\n display: block;\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.24s ease;\n z-index: 9998;\n }\n .mj-left-nav-host--open[_nghost-%COMP%] .mj-left-nav__scrim[_ngcontent-%COMP%] {\n opacity: 1;\n pointer-events: auto;\n }\n\n \n\n .mj-left-nav[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n bottom: 0;\n width: min(320px, 84vw) !important;\n height: 100%;\n max-height: none;\n border-right: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-lg);\n transform: translateX(-100%);\n transition: transform 0.24s ease;\n z-index: 9999;\n padding-top: 0;\n }\n .mj-left-nav-host--open[_nghost-%COMP%] .mj-left-nav[_ngcontent-%COMP%] {\n transform: translateX(0);\n }\n\n \n\n .mj-left-nav__drawer-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n position: sticky;\n top: 0;\n z-index: 1;\n padding: 14px 12px 10px;\n margin: 0 -8px 4px;\n padding-left: 16px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-subtle);\n }\n .mj-left-nav__drawer-title[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mj-text-muted);\n }\n .mj-left-nav__drawer-close[_ngcontent-%COMP%] {\n flex-shrink: 0;\n width: 32px;\n height: 32px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n border-radius: 8px;\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-size: 16px;\n font-family: inherit;\n }\n .mj-left-nav__drawer-close[_ngcontent-%COMP%]:active {\n background: var(--mj-bg-surface-active);\n }\n }\n\n @media (max-width: 700px) and (prefers-reduced-motion: reduce) {\n .mj-left-nav[_ngcontent-%COMP%], \n .mj-left-nav__scrim[_ngcontent-%COMP%] {\n transition: none;\n }\n }"] });
604
+ } }, dependencies: [CommonModule, i1.NgTemplateOutlet], styles: ["[_nghost-%COMP%] {\n display: block;\n flex-shrink: 0;\n }\n\n .mj-left-nav[_ngcontent-%COMP%] {\n height: 100%;\n background: var(--mj-bg-surface);\n border-right: 1px solid var(--mj-border-default);\n overflow-y: auto;\n padding: 8px;\n box-sizing: border-box;\n }\n\n .mj-left-nav__section-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mj-text-muted);\n padding: 12px 12px 6px;\n }\n\n .mj-left-nav__section-label[_ngcontent-%COMP%]:first-child {\n padding-top: 6px;\n }\n\n .mj-left-nav__item[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 10px 12px;\n width: 100%;\n border: none;\n background: transparent;\n border-radius: 8px;\n cursor: pointer;\n transition: background-color 0.12s ease, color 0.12s ease;\n margin-bottom: 2px;\n font-family: inherit;\n color: var(--mj-text-secondary);\n text-align: left;\n }\n\n .mj-left-nav__item[_ngcontent-%COMP%]:hover:not(.mj-left-nav__item--disabled) {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n }\n\n .mj-left-nav__item--active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--mj-brand-primary);\n }\n\n .mj-left-nav__item--active[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, transparent);\n }\n\n .mj-left-nav__item--disabled[_ngcontent-%COMP%] {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n .mj-left-nav__icon[_ngcontent-%COMP%] {\n width: 18px;\n text-align: center;\n font-size: 13px;\n margin-top: 1px;\n flex-shrink: 0;\n color: inherit;\n }\n\n \n\n\n\n .mj-left-nav__initial[_ngcontent-%COMP%] {\n width: 18px;\n text-align: center;\n font-size: 12px;\n font-weight: 600;\n line-height: 1.2;\n margin-top: 1px;\n flex-shrink: 0;\n color: inherit;\n text-transform: uppercase;\n }\n\n .mj-left-nav__text[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n }\n\n .mj-left-nav__label[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n line-height: 1.2;\n }\n\n .mj-left-nav__description[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n margin-top: 3px;\n line-height: 1.3;\n }\n\n .mj-left-nav__item--active[_ngcontent-%COMP%] .mj-left-nav__description[_ngcontent-%COMP%] {\n color: color-mix(in srgb, var(--mj-brand-primary) 70%, var(--mj-text-muted));\n }\n\n .mj-left-nav__badge[_ngcontent-%COMP%] {\n margin-left: auto;\n font-size: 11px;\n font-weight: 600;\n padding: 2px 8px;\n border-radius: 999px;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n align-self: center;\n }\n\n .mj-left-nav__item--active[_ngcontent-%COMP%] .mj-left-nav__badge[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n color: var(--mj-brand-primary);\n }\n\n \n\n\n\n\n\n\n .mj-left-nav__row[_ngcontent-%COMP%] {\n display: flex;\n align-items: stretch;\n gap: 2px;\n }\n\n .mj-left-nav__row[_ngcontent-%COMP%] .mj-left-nav__item[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n }\n\n .mj-left-nav__chevron[_ngcontent-%COMP%] {\n flex-shrink: 0;\n width: 20px;\n height: 32px;\n align-self: center;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n border-radius: 4px;\n cursor: pointer;\n color: var(--mj-text-muted);\n font-size: 10px;\n padding: 0;\n transition: background-color 0.12s ease, color 0.12s ease;\n font-family: inherit;\n }\n\n .mj-left-nav__chevron[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n }\n\n .mj-left-nav__chevron-placeholder[_ngcontent-%COMP%] {\n flex-shrink: 0;\n width: 20px;\n display: inline-block;\n }\n\n \n\n\n\n\n\n\n\n .mj-left-nav__collapse-toggle[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: fit-content;\n padding: 8px 10px;\n border: none;\n border-radius: 8px;\n background: transparent;\n color: var(--mj-text-muted);\n font-family: inherit;\n cursor: pointer;\n box-sizing: border-box;\n transition: background-color 0.12s ease, color 0.12s ease;\n margin-bottom: 2px;\n }\n\n .mj-left-nav__collapse-toggle[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n }\n\n .mj-left-nav__collapse-toggle[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--mj-border-focus);\n outline-offset: -2px;\n }\n\n \n\n\n\n .mj-left-nav__collapse-icon[_ngcontent-%COMP%] {\n width: 18px;\n text-align: center;\n font-size: 12px;\n flex-shrink: 0;\n }\n\n .mj-left-nav__collapse-divider[_ngcontent-%COMP%] {\n height: 1px;\n margin: 4px 0;\n background: var(--mj-border-default);\n }\n\n @media (max-width: 700px) {\n .mj-left-nav__collapse-toggle[_ngcontent-%COMP%], \n .mj-left-nav__collapse-divider[_ngcontent-%COMP%] {\n display: none;\n }\n }\n\n @media (min-width: 701px) {\n \n\n\n\n\n .mj-left-nav-host--collapsed[_nghost-%COMP%] .mj-left-nav__text[_ngcontent-%COMP%] {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n border: 0;\n }\n\n \n\n .mj-left-nav-host--collapsed[_nghost-%COMP%] .mj-left-nav__item[_ngcontent-%COMP%] {\n justify-content: center;\n gap: 0;\n margin-inline: auto;\n position: relative;\n }\n\n \n\n\n\n\n\n .mj-left-nav-host--collapsed[_nghost-%COMP%] .mj-left-nav__section-label[_ngcontent-%COMP%] {\n position: relative;\n color: transparent;\n overflow: hidden;\n }\n .mj-left-nav-host--collapsed[_nghost-%COMP%] .mj-left-nav__section-label[_ngcontent-%COMP%]::after {\n content: '';\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n width: 20px;\n height: 1px;\n background: var(--mj-border-default);\n }\n\n \n\n\n\n .mj-left-nav-host--collapsed[_nghost-%COMP%] .mj-left-nav__badge[_ngcontent-%COMP%] {\n margin-left: 0;\n align-self: auto;\n position: absolute;\n left: calc(50% + 4px);\n top: 4px;\n min-width: 15px;\n height: 15px;\n padding: 0 4px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-size: 9px;\n line-height: 1;\n white-space: nowrap;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n }\n\n \n\n .mj-left-nav-host--collapsed[_nghost-%COMP%] .mj-left-nav[_ngcontent-%COMP%] {\n overflow-x: hidden;\n }\n }\n\n \n\n\n\n\n\n\n\n\n\n .mj-left-nav__switcher[_ngcontent-%COMP%], \n .mj-left-nav__scrim[_ngcontent-%COMP%], \n .mj-left-nav__drawer-header[_ngcontent-%COMP%] {\n display: none;\n }\n\n @media (max-width: 700px) {\n \n\n [_nghost-%COMP%] {\n width: 100% !important;\n }\n\n \n\n\n .mj-left-nav__description[_ngcontent-%COMP%] {\n display: none;\n }\n\n \n\n .mj-left-nav__switcher[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 11px 14px;\n border: none;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-family: inherit;\n font-size: 14px;\n font-weight: 600;\n text-align: left;\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n }\n .mj-left-nav__switcher[_ngcontent-%COMP%]:active {\n background: var(--mj-bg-surface-active);\n }\n .mj-left-nav__switcher-icon[_ngcontent-%COMP%] {\n width: 18px;\n text-align: center;\n font-size: 14px;\n flex-shrink: 0;\n color: var(--mj-brand-primary);\n }\n .mj-left-nav__switcher-label[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .mj-left-nav__switcher-hint[_ngcontent-%COMP%] {\n flex-shrink: 0;\n font-size: 15px;\n color: var(--mj-text-muted);\n }\n\n \n\n .mj-left-nav__scrim[_ngcontent-%COMP%] {\n display: block;\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.24s ease;\n z-index: 9998;\n }\n .mj-left-nav-host--open[_nghost-%COMP%] .mj-left-nav__scrim[_ngcontent-%COMP%] {\n opacity: 1;\n pointer-events: auto;\n }\n\n \n\n .mj-left-nav[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n bottom: 0;\n width: min(320px, 84vw) !important;\n height: 100%;\n max-height: none;\n border-right: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-lg);\n transform: translateX(-100%);\n transition: transform 0.24s ease;\n z-index: 9999;\n padding-top: 0;\n }\n .mj-left-nav-host--open[_nghost-%COMP%] .mj-left-nav[_ngcontent-%COMP%] {\n transform: translateX(0);\n }\n\n \n\n .mj-left-nav__drawer-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n position: sticky;\n top: 0;\n z-index: 1;\n padding: 14px 12px 10px;\n margin: 0 -8px 4px;\n padding-left: 16px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-subtle);\n }\n .mj-left-nav__drawer-title[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mj-text-muted);\n }\n .mj-left-nav__drawer-close[_ngcontent-%COMP%] {\n flex-shrink: 0;\n width: 32px;\n height: 32px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n border-radius: 8px;\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-size: 16px;\n font-family: inherit;\n }\n .mj-left-nav__drawer-close[_ngcontent-%COMP%]:active {\n background: var(--mj-bg-surface-active);\n }\n }\n\n @media (max-width: 700px) and (prefers-reduced-motion: reduce) {\n .mj-left-nav[_ngcontent-%COMP%], \n .mj-left-nav__scrim[_ngcontent-%COMP%] {\n transition: none;\n }\n }"] });
382
605
  }
383
606
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJLeftNavComponent, [{
384
607
  type: Component,
@@ -405,9 +628,37 @@ export class MJLeftNavComponent {
405
628
 
406
629
  <aside
407
630
  class="mj-left-nav"
408
- [style.width.px]="Width"
631
+ [id]="NavRegionId"
632
+ [style.width.px]="EffectiveWidth"
409
633
  role="navigation"
410
634
  [attr.aria-modal]="MobileNavOpen ? true : null">
635
+ <!-- Desktop collapse toggle (opt-in via [Collapsible]) — a compact double-angle chip, NOT a
636
+ hamburger (a lone hamburger row reads as a broken nav item) and NOT a nav-row lookalike.
637
+ The chip is LOCKED in one spot — centred in the collapsed band — in BOTH modes: only the
638
+ glyph flips on toggle, so the user never re-aims (a control that relocates when clicked
639
+ makes the user chase it). « = collapse toward the left edge, » = expand. Hidden ≤700px:
640
+ the mobile drawer is its own affordance and collapsing a drawer is meaningless. -->
641
+ @if (Collapsible) {
642
+ <button
643
+ type="button"
644
+ class="mj-left-nav__collapse-toggle"
645
+ [style.margin-left.px]="CollapseToggleMarginPx"
646
+ [attr.aria-label]="Collapsed ? 'Expand navigation' : 'Collapse navigation'"
647
+ [attr.aria-expanded]="!Collapsed"
648
+ [attr.aria-controls]="NavRegionId"
649
+ [title]="Collapsed ? 'Expand navigation' : 'Collapse navigation'"
650
+ (click)="ToggleCollapsed()">
651
+ <i
652
+ class="fa-solid mj-left-nav__collapse-icon"
653
+ [class.fa-angles-right]="Collapsed"
654
+ [class.fa-angles-left]="!Collapsed"
655
+ aria-hidden="true"></i>
656
+ </button>
657
+ <!-- Wordless hairline between the toggle and the nav content: without a boundary the chip
658
+ reads as a destination. Same height in both modes, so items never shift on toggle. -->
659
+ <div class="mj-left-nav__collapse-divider" aria-hidden="true"></div>
660
+ }
661
+
411
662
  <!-- Drawer header — only visible on mobile when the rail is a drawer. -->
412
663
  <div class="mj-left-nav__drawer-header">
413
664
  <span class="mj-left-nav__drawer-title">{{ MobileTitle }}</span>
@@ -427,8 +678,10 @@ export class MJLeftNavComponent {
427
678
  <div class="mj-left-nav__section-label">{{ section.label }}</div>
428
679
  }
429
680
  @for (item of section.items; track item.id) {
681
+ <!-- hasExpandable goes false while icons-only, collapsing each section to its TOP-LEVEL
682
+ items only — see ShowTreeStructure for why a tree can't survive a 60px rail. -->
430
683
  <ng-container
431
- *ngTemplateOutlet="itemTpl; context: { item: item, depth: 0, hasExpandable: HasExpandableItems(section.items) }">
684
+ *ngTemplateOutlet="itemTpl; context: { item: item, depth: 0, hasExpandable: ShowTreeStructure && HasExpandableItems(section.items) }">
432
685
  </ng-container>
433
686
  }
434
687
  }
@@ -490,13 +743,21 @@ export class MJLeftNavComponent {
490
743
  <button
491
744
  type="button"
492
745
  class="mj-left-nav__item"
493
- [class.mj-left-nav__item--active]="item.id === ActiveId"
746
+ [class.mj-left-nav__item--active]="IsItemActive(item)"
494
747
  [class.mj-left-nav__item--disabled]="item.disabled"
495
748
  [disabled]="item.disabled"
496
- [attr.aria-current]="item.id === ActiveId ? 'page' : null"
749
+ [attr.aria-current]="AriaCurrentFor(item)"
750
+ [attr.title]="EffectiveIconOnly ? ItemTooltip(item) : null"
751
+ [attr.aria-label]="EffectiveIconOnly ? ItemTooltip(item) : null"
497
752
  (click)="OnItemClick(item)">
498
753
  @if (item.icon) {
499
754
  <i class="mj-left-nav__icon" [class]="item.icon" aria-hidden="true"></i>
755
+ } @else if (EffectiveIconOnly) {
756
+ <!-- An icon-less item collapses to a button with NOTHING visible in it (the label is the
757
+ only content and it is clipped away) — an invisible-but-clickable row. The icon is
758
+ optional on MJLeftNavItem, so the rail cannot require one; a monogram keeps every item
759
+ identifiable and hittable. Only rendered icons-only: expanded rails are unchanged. -->
760
+ <span class="mj-left-nav__initial" aria-hidden="true">{{ ItemInitial(item) }}</span>
500
761
  }
501
762
  <span class="mj-left-nav__text">
502
763
  <span class="mj-left-nav__label">{{ item.label }}</span>
@@ -509,13 +770,26 @@ export class MJLeftNavComponent {
509
770
  }
510
771
  </button>
511
772
  </ng-template>
512
- `, styles: ["\n :host {\n display: block;\n flex-shrink: 0;\n }\n\n .mj-left-nav {\n height: 100%;\n background: var(--mj-bg-surface);\n border-right: 1px solid var(--mj-border-default);\n overflow-y: auto;\n padding: 8px;\n box-sizing: border-box;\n }\n\n .mj-left-nav__section-label {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mj-text-muted);\n padding: 12px 12px 6px;\n }\n\n .mj-left-nav__section-label:first-child {\n padding-top: 6px;\n }\n\n .mj-left-nav__item {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 10px 12px;\n width: 100%;\n border: none;\n background: transparent;\n border-radius: 8px;\n cursor: pointer;\n transition: background-color 0.12s ease, color 0.12s ease;\n margin-bottom: 2px;\n font-family: inherit;\n color: var(--mj-text-secondary);\n text-align: left;\n }\n\n .mj-left-nav__item:hover:not(.mj-left-nav__item--disabled) {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n }\n\n .mj-left-nav__item--active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--mj-brand-primary);\n }\n\n .mj-left-nav__item--active:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, transparent);\n }\n\n .mj-left-nav__item--disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n .mj-left-nav__icon {\n width: 18px;\n text-align: center;\n font-size: 13px;\n margin-top: 1px;\n flex-shrink: 0;\n color: inherit;\n }\n\n .mj-left-nav__text {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n }\n\n .mj-left-nav__label {\n font-size: 13px;\n font-weight: 500;\n line-height: 1.2;\n }\n\n .mj-left-nav__description {\n font-size: 11px;\n color: var(--mj-text-muted);\n margin-top: 3px;\n line-height: 1.3;\n }\n\n .mj-left-nav__item--active .mj-left-nav__description {\n color: color-mix(in srgb, var(--mj-brand-primary) 70%, var(--mj-text-muted));\n }\n\n .mj-left-nav__badge {\n margin-left: auto;\n font-size: 11px;\n font-weight: 600;\n padding: 2px 8px;\n border-radius: 999px;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n align-self: center;\n }\n\n .mj-left-nav__item--active .mj-left-nav__badge {\n background: color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n color: var(--mj-brand-primary);\n }\n\n /* \u2500\u2500 Tree rendering \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n Used when MJLeftNavItem.children is defined (even as an empty array).\n The row wraps a chevron/placeholder + the item button so they sit on\n one line, and depth-based padding-left is applied to the row (not the\n item) so the chevron aligns with the depth column. */\n\n .mj-left-nav__row {\n display: flex;\n align-items: stretch;\n gap: 2px;\n }\n\n .mj-left-nav__row .mj-left-nav__item {\n flex: 1;\n min-width: 0;\n }\n\n .mj-left-nav__chevron {\n flex-shrink: 0;\n width: 20px;\n height: 32px;\n align-self: center;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n border-radius: 4px;\n cursor: pointer;\n color: var(--mj-text-muted);\n font-size: 10px;\n padding: 0;\n transition: background-color 0.12s ease, color 0.12s ease;\n font-family: inherit;\n }\n\n .mj-left-nav__chevron:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n }\n\n .mj-left-nav__chevron-placeholder {\n flex-shrink: 0;\n width: 20px;\n display: inline-block;\n }\n\n /* \u2500\u2500 Mobile drawer pattern (\u2264700px) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n Desktop shows the rail inline. On mobile the rail would otherwise eat the\n top of the screen, so we hide it off-canvas and surface a compact section\n switcher in its place. Tapping the switcher slides the full rail in from\n the left over a scrim \u2014 preserving trees, header/footer slots and badges\n (item descriptions hide in the drawer for a tighter list).\n\n The switcher / scrim / drawer-header are display:none above the\n breakpoint; the rail keeps its desktop layout there. */\n .mj-left-nav__switcher,\n .mj-left-nav__scrim,\n .mj-left-nav__drawer-header {\n display: none;\n }\n\n @media (max-width: 700px) {\n /* Host collapses to the switcher's footprint; the rail goes out of flow. */\n :host {\n width: 100% !important;\n }\n\n /* Hide item descriptions in the drawer \u2014 the label + icon are enough on a\n narrow sheet; the secondary line just adds clutter. */\n .mj-left-nav__description {\n display: none;\n }\n\n /* Section switcher \u2014 reads as a picker for the current section. */\n .mj-left-nav__switcher {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 11px 14px;\n border: none;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-family: inherit;\n font-size: 14px;\n font-weight: 600;\n text-align: left;\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n }\n .mj-left-nav__switcher:active {\n background: var(--mj-bg-surface-active);\n }\n .mj-left-nav__switcher-icon {\n width: 18px;\n text-align: center;\n font-size: 14px;\n flex-shrink: 0;\n color: var(--mj-brand-primary);\n }\n .mj-left-nav__switcher-label {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .mj-left-nav__switcher-hint {\n flex-shrink: 0;\n font-size: 15px;\n color: var(--mj-text-muted);\n }\n\n /* Scrim \u2014 fades in with the drawer. */\n .mj-left-nav__scrim {\n display: block;\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.24s ease;\n z-index: 9998;\n }\n :host(.mj-left-nav-host--open) .mj-left-nav__scrim {\n opacity: 1;\n pointer-events: auto;\n }\n\n /* Rail becomes a left off-canvas drawer. */\n .mj-left-nav {\n position: fixed;\n top: 0;\n left: 0;\n bottom: 0;\n width: min(320px, 84vw) !important;\n height: 100%;\n max-height: none;\n border-right: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-lg);\n transform: translateX(-100%);\n transition: transform 0.24s ease;\n z-index: 9999;\n padding-top: 0;\n }\n :host(.mj-left-nav-host--open) .mj-left-nav {\n transform: translateX(0);\n }\n\n /* Drawer header \u2014 sticky title + close button. */\n .mj-left-nav__drawer-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n position: sticky;\n top: 0;\n z-index: 1;\n padding: 14px 12px 10px;\n margin: 0 -8px 4px;\n padding-left: 16px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-subtle);\n }\n .mj-left-nav__drawer-title {\n font-size: 13px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mj-text-muted);\n }\n .mj-left-nav__drawer-close {\n flex-shrink: 0;\n width: 32px;\n height: 32px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n border-radius: 8px;\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-size: 16px;\n font-family: inherit;\n }\n .mj-left-nav__drawer-close:active {\n background: var(--mj-bg-surface-active);\n }\n }\n\n @media (max-width: 700px) and (prefers-reduced-motion: reduce) {\n .mj-left-nav,\n .mj-left-nav__scrim {\n transition: none;\n }\n }\n "] }]
513
- }], null, { Sections: [{
773
+ `, styles: ["\n :host {\n display: block;\n flex-shrink: 0;\n }\n\n .mj-left-nav {\n height: 100%;\n background: var(--mj-bg-surface);\n border-right: 1px solid var(--mj-border-default);\n overflow-y: auto;\n padding: 8px;\n box-sizing: border-box;\n }\n\n .mj-left-nav__section-label {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mj-text-muted);\n padding: 12px 12px 6px;\n }\n\n .mj-left-nav__section-label:first-child {\n padding-top: 6px;\n }\n\n .mj-left-nav__item {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 10px 12px;\n width: 100%;\n border: none;\n background: transparent;\n border-radius: 8px;\n cursor: pointer;\n transition: background-color 0.12s ease, color 0.12s ease;\n margin-bottom: 2px;\n font-family: inherit;\n color: var(--mj-text-secondary);\n text-align: left;\n }\n\n .mj-left-nav__item:hover:not(.mj-left-nav__item--disabled) {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n }\n\n .mj-left-nav__item--active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--mj-brand-primary);\n }\n\n .mj-left-nav__item--active:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, transparent);\n }\n\n .mj-left-nav__item--disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n .mj-left-nav__icon {\n width: 18px;\n text-align: center;\n font-size: 13px;\n margin-top: 1px;\n flex-shrink: 0;\n color: inherit;\n }\n\n /* Stand-in glyph for an icon-less item while the rail is icons-only. Same 18px box as\n .mj-left-nav__icon so it sits on the identical optical column \u2014 the rail reads as one\n consistent strip whether an item brought an icon or not. */\n .mj-left-nav__initial {\n width: 18px;\n text-align: center;\n font-size: 12px;\n font-weight: 600;\n line-height: 1.2;\n margin-top: 1px;\n flex-shrink: 0;\n color: inherit;\n text-transform: uppercase;\n }\n\n .mj-left-nav__text {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n }\n\n .mj-left-nav__label {\n font-size: 13px;\n font-weight: 500;\n line-height: 1.2;\n }\n\n .mj-left-nav__description {\n font-size: 11px;\n color: var(--mj-text-muted);\n margin-top: 3px;\n line-height: 1.3;\n }\n\n .mj-left-nav__item--active .mj-left-nav__description {\n color: color-mix(in srgb, var(--mj-brand-primary) 70%, var(--mj-text-muted));\n }\n\n .mj-left-nav__badge {\n margin-left: auto;\n font-size: 11px;\n font-weight: 600;\n padding: 2px 8px;\n border-radius: 999px;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n align-self: center;\n }\n\n .mj-left-nav__item--active .mj-left-nav__badge {\n background: color-mix(in srgb, var(--mj-brand-primary) 18%, transparent);\n color: var(--mj-brand-primary);\n }\n\n /* \u2500\u2500 Tree rendering \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n Used when MJLeftNavItem.children is defined (even as an empty array).\n The row wraps a chevron/placeholder + the item button so they sit on\n one line, and depth-based padding-left is applied to the row (not the\n item) so the chevron aligns with the depth column. */\n\n .mj-left-nav__row {\n display: flex;\n align-items: stretch;\n gap: 2px;\n }\n\n .mj-left-nav__row .mj-left-nav__item {\n flex: 1;\n min-width: 0;\n }\n\n .mj-left-nav__chevron {\n flex-shrink: 0;\n width: 20px;\n height: 32px;\n align-self: center;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n border-radius: 4px;\n cursor: pointer;\n color: var(--mj-text-muted);\n font-size: 10px;\n padding: 0;\n transition: background-color 0.12s ease, color 0.12s ease;\n font-family: inherit;\n }\n\n .mj-left-nav__chevron:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n }\n\n .mj-left-nav__chevron-placeholder {\n flex-shrink: 0;\n width: 20px;\n display: inline-block;\n }\n\n /* \u2500\u2500 Desktop collapse (opt-in via [Collapsible]) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n The toggle chip + the icons-only collapsed presentation. DESKTOP ONLY: below 701px the rail\n is the off-canvas drawer, which is already dismissable \u2014 collapsing it would be nonsense \u2014\n so the toggle hides and the collapsed rules never apply there. Hover-to-peek is deliberately\n NOT part of this feature (removed by ruling 2026-07-30: a rail that expands when the pointer\n grazes it moves the target the user was aiming at). */\n\n .mj-left-nav__collapse-toggle {\n display: flex;\n align-items: center;\n justify-content: center;\n width: fit-content;\n padding: 8px 10px;\n border: none;\n border-radius: 8px;\n background: transparent;\n color: var(--mj-text-muted);\n font-family: inherit;\n cursor: pointer;\n box-sizing: border-box;\n transition: background-color 0.12s ease, color 0.12s ease;\n margin-bottom: 2px;\n }\n\n .mj-left-nav__collapse-toggle:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n }\n\n .mj-left-nav__collapse-toggle:focus-visible {\n outline: 2px solid var(--mj-border-focus);\n outline-offset: -2px;\n }\n\n /* 18px box = the same footprint as .mj-left-nav__icon, so the chip sits on the items' optical\n icon column when centred in the collapsed band. Slightly smaller glyph than the nav icons \u2014\n this is a chrome control, not a destination. */\n .mj-left-nav__collapse-icon {\n width: 18px;\n text-align: center;\n font-size: 12px;\n flex-shrink: 0;\n }\n\n .mj-left-nav__collapse-divider {\n height: 1px;\n margin: 4px 0;\n background: var(--mj-border-default);\n }\n\n @media (max-width: 700px) {\n .mj-left-nav__collapse-toggle,\n .mj-left-nav__collapse-divider {\n display: none;\n }\n }\n\n @media (min-width: 701px) {\n /* ITEM labels are HIDDEN VISUALLY, NOT REMOVED. display:none would drop them from the\n accessibility tree too, leaving every rail button unnamed \u2014 an icon-only rail a screen\n reader cannot read. This keeps the name and only takes the pixels. (The tooltips/aria the\n items grow while collapsed come from EffectiveIconOnly.) */\n :host(.mj-left-nav-host--collapsed) .mj-left-nav__text {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n border: 0;\n }\n\n /* With the text out of flow the icon is the only thing left; centre it in the narrow rail. */\n :host(.mj-left-nav-host--collapsed) .mj-left-nav__item {\n justify-content: center;\n gap: 0;\n margin-inline: auto;\n position: relative;\n }\n\n /* SECTION labels become a small centred divider line, keeping the label's OWN box (padding +\n height) so the vertical rhythm is IDENTICAL to the expanded rail \u2014 the words come back in\n the exact same place on expand. color: transparent hides the glyphs without removing them\n from the a11y tree or changing the box height; overflow clips the transparent glyphs so\n they can never make the narrow rail horizontally scrollable. */\n :host(.mj-left-nav-host--collapsed) .mj-left-nav__section-label {\n position: relative;\n color: transparent;\n overflow: hidden;\n }\n :host(.mj-left-nav-host--collapsed) .mj-left-nav__section-label::after {\n content: '';\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n width: 20px;\n height: 1px;\n background: var(--mj-border-default);\n }\n\n /* No row edge exists in the narrow rail, so the badge docks on the icon's top-right corner\n (the activity-bar idiom) as a compact attention count \u2014 presence = action needed. The\n centred icon itself never moves. */\n :host(.mj-left-nav-host--collapsed) .mj-left-nav__badge {\n margin-left: 0;\n align-self: auto;\n position: absolute;\n left: calc(50% + 4px);\n top: 4px;\n min-width: 15px;\n height: 15px;\n padding: 0 4px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-size: 9px;\n line-height: 1;\n white-space: nowrap;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n }\n\n /* Belt-and-braces: a collapsed rail never scrolls sideways. */\n :host(.mj-left-nav-host--collapsed) .mj-left-nav {\n overflow-x: hidden;\n }\n }\n\n /* \u2500\u2500 Mobile drawer pattern (\u2264700px) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n Desktop shows the rail inline. On mobile the rail would otherwise eat the\n top of the screen, so we hide it off-canvas and surface a compact section\n switcher in its place. Tapping the switcher slides the full rail in from\n the left over a scrim \u2014 preserving trees, header/footer slots and badges\n (item descriptions hide in the drawer for a tighter list).\n\n The switcher / scrim / drawer-header are display:none above the\n breakpoint; the rail keeps its desktop layout there. */\n .mj-left-nav__switcher,\n .mj-left-nav__scrim,\n .mj-left-nav__drawer-header {\n display: none;\n }\n\n @media (max-width: 700px) {\n /* Host collapses to the switcher's footprint; the rail goes out of flow. */\n :host {\n width: 100% !important;\n }\n\n /* Hide item descriptions in the drawer \u2014 the label + icon are enough on a\n narrow sheet; the secondary line just adds clutter. */\n .mj-left-nav__description {\n display: none;\n }\n\n /* Section switcher \u2014 reads as a picker for the current section. */\n .mj-left-nav__switcher {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 11px 14px;\n border: none;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-family: inherit;\n font-size: 14px;\n font-weight: 600;\n text-align: left;\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n }\n .mj-left-nav__switcher:active {\n background: var(--mj-bg-surface-active);\n }\n .mj-left-nav__switcher-icon {\n width: 18px;\n text-align: center;\n font-size: 14px;\n flex-shrink: 0;\n color: var(--mj-brand-primary);\n }\n .mj-left-nav__switcher-label {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .mj-left-nav__switcher-hint {\n flex-shrink: 0;\n font-size: 15px;\n color: var(--mj-text-muted);\n }\n\n /* Scrim \u2014 fades in with the drawer. */\n .mj-left-nav__scrim {\n display: block;\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.24s ease;\n z-index: 9998;\n }\n :host(.mj-left-nav-host--open) .mj-left-nav__scrim {\n opacity: 1;\n pointer-events: auto;\n }\n\n /* Rail becomes a left off-canvas drawer. */\n .mj-left-nav {\n position: fixed;\n top: 0;\n left: 0;\n bottom: 0;\n width: min(320px, 84vw) !important;\n height: 100%;\n max-height: none;\n border-right: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-lg);\n transform: translateX(-100%);\n transition: transform 0.24s ease;\n z-index: 9999;\n padding-top: 0;\n }\n :host(.mj-left-nav-host--open) .mj-left-nav {\n transform: translateX(0);\n }\n\n /* Drawer header \u2014 sticky title + close button. */\n .mj-left-nav__drawer-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n position: sticky;\n top: 0;\n z-index: 1;\n padding: 14px 12px 10px;\n margin: 0 -8px 4px;\n padding-left: 16px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-subtle);\n }\n .mj-left-nav__drawer-title {\n font-size: 13px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--mj-text-muted);\n }\n .mj-left-nav__drawer-close {\n flex-shrink: 0;\n width: 32px;\n height: 32px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: none;\n background: transparent;\n border-radius: 8px;\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-size: 16px;\n font-family: inherit;\n }\n .mj-left-nav__drawer-close:active {\n background: var(--mj-bg-surface-active);\n }\n }\n\n @media (max-width: 700px) and (prefers-reduced-motion: reduce) {\n .mj-left-nav,\n .mj-left-nav__scrim {\n transition: none;\n }\n }\n "] }]
774
+ }], () => [], { Sections: [{
514
775
  type: Input
515
776
  }], ActiveId: [{
516
777
  type: Input
517
778
  }], Width: [{
518
779
  type: Input
780
+ }], IconOnly: [{
781
+ type: Input
782
+ }], Collapsible: [{
783
+ type: Input
784
+ }], Collapsed: [{
785
+ type: Input
786
+ }], CollapsedChange: [{
787
+ type: Output
788
+ }], CollapsedWidth: [{
789
+ type: Input
790
+ }], isCollapsedHost: [{
791
+ type: HostBinding,
792
+ args: ['class.mj-left-nav-host--collapsed']
519
793
  }], MobileTitle: [{
520
794
  type: Input
521
795
  }], ExpandedIds: [{
@@ -531,5 +805,5 @@ export class MJLeftNavComponent {
531
805
  type: HostListener,
532
806
  args: ['document:keydown.escape']
533
807
  }] }); })();
534
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJLeftNavComponent, { className: "MJLeftNavComponent", filePath: "lib/left-nav/left-nav.component.ts", lineNumber: 538 }); })();
808
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJLeftNavComponent, { className: "MJLeftNavComponent", filePath: "lib/left-nav/left-nav.component.ts", lineNumber: 736 }); })();
535
809
  //# sourceMappingURL=left-nav.component.js.map