@memberjunction/ng-ui-components 5.38.0 → 5.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/applied-filters/applied-filters.component.d.ts +55 -0
- package/dist/lib/applied-filters/applied-filters.component.d.ts.map +1 -0
- package/dist/lib/applied-filters/applied-filters.component.js +128 -0
- package/dist/lib/applied-filters/applied-filters.component.js.map +1 -0
- package/dist/lib/filter-panel/filter-panel.component.d.ts +14 -0
- package/dist/lib/filter-panel/filter-panel.component.d.ts.map +1 -1
- package/dist/lib/filter-panel/filter-panel.component.js +30 -5
- package/dist/lib/filter-panel/filter-panel.component.js.map +1 -1
- package/dist/lib/filter-popover/filter-popover.component.d.ts +14 -2
- package/dist/lib/filter-popover/filter-popover.component.d.ts.map +1 -1
- package/dist/lib/filter-popover/filter-popover.component.js +153 -52
- package/dist/lib/filter-popover/filter-popover.component.js.map +1 -1
- package/dist/lib/left-nav/left-nav-content.component.d.ts.map +1 -1
- package/dist/lib/left-nav/left-nav-content.component.js +3 -3
- package/dist/lib/left-nav/left-nav-content.component.js.map +1 -1
- package/dist/lib/left-nav/left-nav.component.d.ts +36 -9
- package/dist/lib/left-nav/left-nav.component.d.ts.map +1 -1
- package/dist/lib/left-nav/left-nav.component.js +253 -117
- package/dist/lib/left-nav/left-nav.component.js.map +1 -1
- package/dist/lib/page-body/page-body.component.d.ts.map +1 -1
- package/dist/lib/page-body/page-body.component.js +3 -3
- package/dist/lib/page-body/page-body.component.js.map +1 -1
- package/dist/lib/page-header/page-header.component.js +2 -2
- package/dist/lib/page-header/page-header.scss +51 -4
- package/dist/lib/page-header-interior/page-header-interior.component.d.ts.map +1 -1
- package/dist/lib/page-header-interior/page-header-interior.component.js +3 -3
- package/dist/lib/page-header-interior/page-header-interior.component.js.map +1 -1
- package/dist/lib/refresh-button/refresh-button.component.d.ts.map +1 -1
- package/dist/lib/refresh-button/refresh-button.component.js +13 -10
- package/dist/lib/refresh-button/refresh-button.component.js.map +1 -1
- package/dist/lib/slide-panel/slide-panel.component.d.ts +64 -0
- package/dist/lib/slide-panel/slide-panel.component.d.ts.map +1 -0
- package/dist/lib/slide-panel/slide-panel.component.js +256 -0
- package/dist/lib/slide-panel/slide-panel.component.js.map +1 -0
- package/dist/public-api.d.ts +1 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +1 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
|
1
|
+
import { ChangeDetectorRef, Component, EventEmitter, Input, NgZone, Output, inject } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
2
3
|
import { OverlayModule } from '@angular/cdk/overlay';
|
|
3
4
|
import * as i0 from "@angular/core";
|
|
4
|
-
import * as i1 from "@angular/
|
|
5
|
+
import * as i1 from "@angular/common";
|
|
6
|
+
import * as i2 from "@angular/cdk/overlay";
|
|
5
7
|
const _c0 = ["*"];
|
|
6
8
|
function MJFilterPopoverComponent_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
7
|
-
i0.ɵɵelementStart(0, "span",
|
|
9
|
+
i0.ɵɵelementStart(0, "span", 4);
|
|
8
10
|
i0.ɵɵtext(1);
|
|
9
11
|
i0.ɵɵelementEnd();
|
|
10
12
|
} if (rf & 2) {
|
|
@@ -13,29 +15,77 @@ function MJFilterPopoverComponent_Conditional_5_Template(rf, ctx) { if (rf & 1)
|
|
|
13
15
|
i0.ɵɵadvance();
|
|
14
16
|
i0.ɵɵtextInterpolate1(" ", ctx_r1.ActiveCount, " ");
|
|
15
17
|
} }
|
|
16
|
-
function
|
|
18
|
+
function MJFilterPopoverComponent_ng_template_7_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
17
19
|
const _r3 = i0.ɵɵgetCurrentView();
|
|
18
|
-
i0.ɵɵelementStart(0, "button",
|
|
19
|
-
i0.ɵɵlistener("click", function
|
|
20
|
+
i0.ɵɵelementStart(0, "button", 11);
|
|
21
|
+
i0.ɵɵlistener("click", function MJFilterPopoverComponent_ng_template_7_Conditional_3_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ClearAll()); });
|
|
20
22
|
i0.ɵɵtext(1, " Clear all ");
|
|
21
23
|
i0.ɵɵelementEnd();
|
|
22
24
|
} }
|
|
23
25
|
function MJFilterPopoverComponent_ng_template_7_Template(rf, ctx) { if (rf & 1) {
|
|
24
|
-
i0.ɵɵelementStart(0, "div",
|
|
25
|
-
i0.ɵɵtext(
|
|
26
|
+
i0.ɵɵelementStart(0, "div", 7)(1, "span", 8);
|
|
27
|
+
i0.ɵɵtext(2);
|
|
26
28
|
i0.ɵɵelementEnd();
|
|
27
|
-
i0.ɵɵconditionalCreate(
|
|
29
|
+
i0.ɵɵconditionalCreate(3, MJFilterPopoverComponent_ng_template_7_Conditional_3_Template, 2, 0, "button", 9);
|
|
30
|
+
i0.ɵɵelementEnd();
|
|
31
|
+
i0.ɵɵelementStart(4, "div", 10);
|
|
32
|
+
i0.ɵɵprojection(5);
|
|
28
33
|
i0.ɵɵelementEnd();
|
|
29
|
-
i0.ɵɵelementStart(5, "div", 9);
|
|
30
|
-
i0.ɵɵprojection(6);
|
|
31
|
-
i0.ɵɵelementEnd()();
|
|
32
34
|
} if (rf & 2) {
|
|
33
35
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
34
|
-
i0.ɵɵ
|
|
35
|
-
i0.ɵɵadvance(3);
|
|
36
|
+
i0.ɵɵadvance(2);
|
|
36
37
|
i0.ɵɵtextInterpolate(ctx_r1.Label);
|
|
37
38
|
i0.ɵɵadvance();
|
|
38
|
-
i0.ɵɵconditional(ctx_r1.ActiveCount > 0 && ctx_r1.ShowClearAll ?
|
|
39
|
+
i0.ɵɵconditional(ctx_r1.ActiveCount > 0 && ctx_r1.ShowClearAll ? 3 : -1);
|
|
40
|
+
} }
|
|
41
|
+
function MJFilterPopoverComponent_Conditional_9_Conditional_0_ng_container_3_Template(rf, ctx) { if (rf & 1) {
|
|
42
|
+
i0.ɵɵelementContainer(0);
|
|
43
|
+
} }
|
|
44
|
+
function MJFilterPopoverComponent_Conditional_9_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
45
|
+
const _r4 = i0.ɵɵgetCurrentView();
|
|
46
|
+
i0.ɵɵelementStart(0, "div", 12);
|
|
47
|
+
i0.ɵɵlistener("click", function MJFilterPopoverComponent_Conditional_9_Conditional_0_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.Close()); });
|
|
48
|
+
i0.ɵɵelementEnd();
|
|
49
|
+
i0.ɵɵelementStart(1, "div", 13);
|
|
50
|
+
i0.ɵɵelement(2, "div", 14);
|
|
51
|
+
i0.ɵɵtemplate(3, MJFilterPopoverComponent_Conditional_9_Conditional_0_ng_container_3_Template, 1, 0, "ng-container", 15);
|
|
52
|
+
i0.ɵɵelementEnd();
|
|
53
|
+
} if (rf & 2) {
|
|
54
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
55
|
+
const panelBody_r5 = i0.ɵɵreference(8);
|
|
56
|
+
i0.ɵɵadvance();
|
|
57
|
+
i0.ɵɵattribute("aria-label", ctx_r1.Label);
|
|
58
|
+
i0.ɵɵadvance(2);
|
|
59
|
+
i0.ɵɵproperty("ngTemplateOutlet", panelBody_r5);
|
|
60
|
+
} }
|
|
61
|
+
function MJFilterPopoverComponent_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
62
|
+
i0.ɵɵconditionalCreate(0, MJFilterPopoverComponent_Conditional_9_Conditional_0_Template, 4, 2);
|
|
63
|
+
} if (rf & 2) {
|
|
64
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
65
|
+
i0.ɵɵconditional(ctx_r1.IsOpen ? 0 : -1);
|
|
66
|
+
} }
|
|
67
|
+
function MJFilterPopoverComponent_Conditional_10_ng_template_0_ng_container_1_Template(rf, ctx) { if (rf & 1) {
|
|
68
|
+
i0.ɵɵelementContainer(0);
|
|
69
|
+
} }
|
|
70
|
+
function MJFilterPopoverComponent_Conditional_10_ng_template_0_Template(rf, ctx) { if (rf & 1) {
|
|
71
|
+
i0.ɵɵelementStart(0, "div", 17);
|
|
72
|
+
i0.ɵɵtemplate(1, MJFilterPopoverComponent_Conditional_10_ng_template_0_ng_container_1_Template, 1, 0, "ng-container", 15);
|
|
73
|
+
i0.ɵɵelementEnd();
|
|
74
|
+
} if (rf & 2) {
|
|
75
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
76
|
+
const panelBody_r5 = i0.ɵɵreference(8);
|
|
77
|
+
i0.ɵɵattribute("aria-label", ctx_r1.Label);
|
|
78
|
+
i0.ɵɵadvance();
|
|
79
|
+
i0.ɵɵproperty("ngTemplateOutlet", panelBody_r5);
|
|
80
|
+
} }
|
|
81
|
+
function MJFilterPopoverComponent_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
82
|
+
const _r6 = i0.ɵɵgetCurrentView();
|
|
83
|
+
i0.ɵɵtemplate(0, MJFilterPopoverComponent_Conditional_10_ng_template_0_Template, 2, 2, "ng-template", 16);
|
|
84
|
+
i0.ɵɵlistener("backdropClick", function MJFilterPopoverComponent_Conditional_10_Template_ng_template_backdropClick_0_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.Close()); })("detach", function MJFilterPopoverComponent_Conditional_10_Template_ng_template_detach_0_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.Close()); });
|
|
85
|
+
} if (rf & 2) {
|
|
86
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
87
|
+
const overlayOrigin_r7 = i0.ɵɵreference(1);
|
|
88
|
+
i0.ɵɵproperty("cdkConnectedOverlayOrigin", overlayOrigin_r7)("cdkConnectedOverlayOpen", ctx_r1.IsOpen)("cdkConnectedOverlayPositions", ctx_r1.Positions)("cdkConnectedOverlayHasBackdrop", true);
|
|
39
89
|
} }
|
|
40
90
|
/**
|
|
41
91
|
* mj-filter-popover — Compact "Filters" trigger button that opens a popover
|
|
@@ -61,6 +111,38 @@ export class MJFilterPopoverComponent {
|
|
|
61
111
|
ActiveCount = 0;
|
|
62
112
|
ShowClearAll = false;
|
|
63
113
|
IsOpen = false;
|
|
114
|
+
/**
|
|
115
|
+
* True when the viewport is narrow enough that the popover should dock as a
|
|
116
|
+
* bottom sheet instead of an anchored overlay. Driven by matchMedia so it
|
|
117
|
+
* tracks live resize without Angular change-detection plumbing.
|
|
118
|
+
*/
|
|
119
|
+
IsMobile = false;
|
|
120
|
+
zone = inject(NgZone);
|
|
121
|
+
cdr = inject(ChangeDetectorRef);
|
|
122
|
+
mediaQuery = typeof window !== 'undefined' && typeof window.matchMedia === 'function'
|
|
123
|
+
? window.matchMedia('(max-width: 700px)')
|
|
124
|
+
: null;
|
|
125
|
+
// matchMedia 'change' fires OUTSIDE Angular's zone, so the flip must be
|
|
126
|
+
// re-entered into the zone — otherwise the IsMobile change lands mid-CD and
|
|
127
|
+
// the @if(IsMobile) branch swap throws ExpressionChangedAfterItHasBeenChecked
|
|
128
|
+
// when crossing the breakpoint. Also close across the switch so a sheet/overlay
|
|
129
|
+
// opened in one mode doesn't linger in the other.
|
|
130
|
+
onMediaChange = (e) => {
|
|
131
|
+
this.zone.run(() => {
|
|
132
|
+
this.IsMobile = e.matches;
|
|
133
|
+
this.IsOpen = false;
|
|
134
|
+
this.cdr.markForCheck();
|
|
135
|
+
});
|
|
136
|
+
};
|
|
137
|
+
constructor() {
|
|
138
|
+
if (this.mediaQuery) {
|
|
139
|
+
this.IsMobile = this.mediaQuery.matches;
|
|
140
|
+
this.mediaQuery.addEventListener('change', this.onMediaChange);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
ngOnDestroy() {
|
|
144
|
+
this.mediaQuery?.removeEventListener('change', this.onMediaChange);
|
|
145
|
+
}
|
|
64
146
|
// Note: NO offsetY here — CDK applies offsetY as `transform: translateY(...)` on the
|
|
65
147
|
// overlay pane, which creates a containing block for `position: fixed` descendants.
|
|
66
148
|
// Tree dropdowns (and any other component using position: fixed) would then mis-position.
|
|
@@ -79,22 +161,21 @@ export class MJFilterPopoverComponent {
|
|
|
79
161
|
this.ClearAllRequested.emit();
|
|
80
162
|
}
|
|
81
163
|
static ɵfac = function MJFilterPopoverComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || MJFilterPopoverComponent)(); };
|
|
82
|
-
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MJFilterPopoverComponent, selectors: [["mj-filter-popover"]], inputs: { Label: "Label", Icon: "Icon", ActiveCount: "ActiveCount", ShowClearAll: "ShowClearAll" }, outputs: { ClearAllRequested: "ClearAllRequested" }, ngContentSelectors: _c0, decls:
|
|
164
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MJFilterPopoverComponent, selectors: [["mj-filter-popover"]], inputs: { Label: "Label", Icon: "Icon", ActiveCount: "ActiveCount", ShowClearAll: "ShowClearAll" }, outputs: { ClearAllRequested: "ClearAllRequested" }, ngContentSelectors: _c0, decls: 11, vars: 11, consts: [["overlayOrigin", "cdkOverlayOrigin"], ["panelBody", ""], ["type", "button", "cdkOverlayOrigin", "", 1, "mj-filter-popover-trigger", 3, "click"], [1, "mj-filter-popover-label"], [1, "mj-filter-popover-badge"], [1, "fa-solid", "fa-chevron-down", "mj-filter-popover-chevron"], ["cdkConnectedOverlay", "", "cdkConnectedOverlayBackdropClass", "mj-filter-popover-backdrop", 3, "cdkConnectedOverlayOrigin", "cdkConnectedOverlayOpen", "cdkConnectedOverlayPositions", "cdkConnectedOverlayHasBackdrop"], [1, "mj-filter-popover-header"], [1, "mj-filter-popover-title"], ["type", "button", 1, "mj-filter-popover-clear"], [1, "mj-filter-popover-content"], ["type", "button", 1, "mj-filter-popover-clear", 3, "click"], ["aria-hidden", "true", 1, "mj-filter-popover-scrim", 3, "click"], ["role", "dialog", 1, "mj-filter-popover-sheet"], ["aria-hidden", "true", 1, "mj-filter-popover-grab"], [4, "ngTemplateOutlet"], ["cdkConnectedOverlay", "", "cdkConnectedOverlayBackdropClass", "mj-filter-popover-backdrop", 3, "backdropClick", "detach", "cdkConnectedOverlayOrigin", "cdkConnectedOverlayOpen", "cdkConnectedOverlayPositions", "cdkConnectedOverlayHasBackdrop"], ["role", "dialog", 1, "mj-filter-popover-panel"]], template: function MJFilterPopoverComponent_Template(rf, ctx) { if (rf & 1) {
|
|
83
165
|
const _r1 = i0.ɵɵgetCurrentView();
|
|
84
166
|
i0.ɵɵprojectionDef();
|
|
85
|
-
i0.ɵɵelementStart(0, "button",
|
|
167
|
+
i0.ɵɵelementStart(0, "button", 2, 0);
|
|
86
168
|
i0.ɵɵlistener("click", function MJFilterPopoverComponent_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.Toggle()); });
|
|
87
169
|
i0.ɵɵelement(2, "i");
|
|
88
|
-
i0.ɵɵelementStart(3, "span");
|
|
170
|
+
i0.ɵɵelementStart(3, "span", 3);
|
|
89
171
|
i0.ɵɵtext(4);
|
|
90
172
|
i0.ɵɵelementEnd();
|
|
91
|
-
i0.ɵɵconditionalCreate(5, MJFilterPopoverComponent_Conditional_5_Template, 2, 2, "span",
|
|
92
|
-
i0.ɵɵelement(6, "i",
|
|
173
|
+
i0.ɵɵconditionalCreate(5, MJFilterPopoverComponent_Conditional_5_Template, 2, 2, "span", 4);
|
|
174
|
+
i0.ɵɵelement(6, "i", 5);
|
|
93
175
|
i0.ɵɵelementEnd();
|
|
94
|
-
i0.ɵɵtemplate(7, MJFilterPopoverComponent_ng_template_7_Template,
|
|
95
|
-
i0.ɵɵ
|
|
176
|
+
i0.ɵɵtemplate(7, MJFilterPopoverComponent_ng_template_7_Template, 6, 2, "ng-template", null, 1, i0.ɵɵtemplateRefExtractor);
|
|
177
|
+
i0.ɵɵconditionalCreate(9, MJFilterPopoverComponent_Conditional_9_Template, 1, 1)(10, MJFilterPopoverComponent_Conditional_10_Template, 1, 4, null, 6);
|
|
96
178
|
} if (rf & 2) {
|
|
97
|
-
const overlayOrigin_r4 = i0.ɵɵreference(1);
|
|
98
179
|
i0.ɵɵclassProp("mj-filter-popover-trigger--active", ctx.IsOpen || ctx.ActiveCount > 0);
|
|
99
180
|
i0.ɵɵattribute("aria-expanded", ctx.IsOpen)("aria-haspopup", true);
|
|
100
181
|
i0.ɵɵadvance(2);
|
|
@@ -105,13 +186,13 @@ export class MJFilterPopoverComponent {
|
|
|
105
186
|
i0.ɵɵconditional(ctx.ActiveCount > 0 ? 5 : -1);
|
|
106
187
|
i0.ɵɵadvance();
|
|
107
188
|
i0.ɵɵclassProp("mj-filter-popover-chevron--open", ctx.IsOpen);
|
|
108
|
-
i0.ɵɵadvance();
|
|
109
|
-
i0.ɵɵ
|
|
110
|
-
} }, dependencies: [
|
|
189
|
+
i0.ɵɵadvance(3);
|
|
190
|
+
i0.ɵɵconditional(ctx.IsMobile ? 9 : 10);
|
|
191
|
+
} }, dependencies: [CommonModule, i1.NgTemplateOutlet, OverlayModule, i2.CdkConnectedOverlay, i2.CdkOverlayOrigin], styles: ["[_nghost-%COMP%] {\n display: inline-flex;\n }\n\n \n\n\n\n .mj-filter-popover-trigger[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n min-height: 32px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n color: var(--mj-text-primary);\n font-family: inherit;\n font-size: 0.8125rem;\n font-weight: var(--mj-font-semibold);\n line-height: 1.5;\n cursor: pointer;\n transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;\n white-space: nowrap;\n }\n\n .mj-filter-popover-trigger[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-active);\n border-color: var(--mj-border-strong);\n }\n\n .mj-filter-popover-trigger--active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-brand-primary) 30%, var(--mj-border-default));\n color: var(--mj-brand-primary);\n }\n\n .mj-filter-popover-trigger--active[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, var(--mj-bg-surface));\n }\n\n .mj-filter-popover-trigger[_ngcontent-%COMP%] > i[_ngcontent-%COMP%]:first-child {\n font-size: var(--mj-text-xs);\n color: var(--mj-brand-primary);\n }\n\n .mj-filter-popover-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 20px;\n height: 20px;\n padding: 0 var(--mj-space-1-5);\n border-radius: 10px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 11px;\n font-weight: 700;\n line-height: 1;\n }\n\n .mj-filter-popover-chevron[_ngcontent-%COMP%] {\n font-size: 10px;\n transition: transform 0.2s ease;\n color: var(--mj-text-muted);\n }\n\n .mj-filter-popover-chevron--open[_ngcontent-%COMP%] {\n transform: rotate(180deg);\n }\n\n .mj-filter-popover-panel[_ngcontent-%COMP%] {\n min-width: 320px;\n max-width: 480px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-md);\n margin-top: var(--mj-space-1-5);\n overflow: hidden;\n }\n\n .mj-filter-popover-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: var(--mj-space-3) var(--mj-space-4) 0;\n }\n\n .mj-filter-popover-title[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n }\n\n .mj-filter-popover-clear[_ngcontent-%COMP%] {\n background: transparent;\n border: none;\n color: var(--mj-brand-primary);\n font-size: var(--mj-text-xs);\n font-weight: 500;\n cursor: pointer;\n padding: var(--mj-space-1) var(--mj-space-2);\n border-radius: var(--mj-radius-sm);\n }\n\n .mj-filter-popover-clear[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n }\n\n .mj-filter-popover-content[_ngcontent-%COMP%] {\n padding: var(--mj-space-3) var(--mj-space-4) var(--mj-space-4);\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-2-5);\n }\n\n \n\n\n\n\n .mj-filter-popover-scrim[_ngcontent-%COMP%] {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n z-index: 9998;\n animation: _ngcontent-%COMP%_mj-fp-fade 0.2s ease;\n }\n .mj-filter-popover-sheet[_ngcontent-%COMP%] {\n position: fixed;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 9999;\n display: flex;\n flex-direction: column;\n max-height: 85vh;\n background: var(--mj-bg-surface);\n border-top-left-radius: 16px;\n border-top-right-radius: 16px;\n box-shadow: var(--mj-shadow-lg);\n animation: _ngcontent-%COMP%_mj-fp-slide-up 0.24s ease;\n }\n .mj-filter-popover-grab[_ngcontent-%COMP%] {\n flex-shrink: 0;\n width: 36px;\n height: 4px;\n border-radius: 2px;\n background: var(--mj-border-strong);\n margin: 10px auto 2px;\n }\n .mj-filter-popover-sheet[_ngcontent-%COMP%] .mj-filter-popover-header[_ngcontent-%COMP%] {\n flex-shrink: 0;\n }\n .mj-filter-popover-sheet[_ngcontent-%COMP%] .mj-filter-popover-content[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n -webkit-overflow-scrolling: touch;\n padding-bottom: var(--mj-space-6);\n }\n @keyframes _ngcontent-%COMP%_mj-fp-fade {\n from { opacity: 0; }\n to { opacity: 1; }\n }\n @keyframes _ngcontent-%COMP%_mj-fp-slide-up {\n from { transform: translateY(100%); }\n to { transform: translateY(0); }\n }\n @media (prefers-reduced-motion: reduce) {\n .mj-filter-popover-scrim[_ngcontent-%COMP%], \n .mj-filter-popover-sheet[_ngcontent-%COMP%] {\n animation: none;\n }\n }\n\n \n\n\n\n @media (max-width: 700px) {\n .mj-filter-popover-label[_ngcontent-%COMP%], \n .mj-filter-popover-chevron[_ngcontent-%COMP%] {\n display: none;\n }\n .mj-filter-popover-trigger[_ngcontent-%COMP%] {\n padding: 6px 10px;\n gap: 4px;\n }\n }"] });
|
|
111
192
|
}
|
|
112
193
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJFilterPopoverComponent, [{
|
|
113
194
|
type: Component,
|
|
114
|
-
args: [{ selector: 'mj-filter-popover', standalone: true, imports: [OverlayModule], template: `
|
|
195
|
+
args: [{ selector: 'mj-filter-popover', standalone: true, imports: [CommonModule, OverlayModule], template: `
|
|
115
196
|
<button
|
|
116
197
|
type="button"
|
|
117
198
|
class="mj-filter-popover-trigger"
|
|
@@ -122,7 +203,7 @@ export class MJFilterPopoverComponent {
|
|
|
122
203
|
[attr.aria-haspopup]="true"
|
|
123
204
|
(click)="Toggle()">
|
|
124
205
|
<i [class]="Icon"></i>
|
|
125
|
-
<span>{{ Label }}</span>
|
|
206
|
+
<span class="mj-filter-popover-label">{{ Label }}</span>
|
|
126
207
|
@if (ActiveCount > 0) {
|
|
127
208
|
<span class="mj-filter-popover-badge" [attr.aria-label]="ActiveCount + ' active filters'">
|
|
128
209
|
{{ ActiveCount }}
|
|
@@ -131,31 +212,51 @@ export class MJFilterPopoverComponent {
|
|
|
131
212
|
<i class="fa-solid fa-chevron-down mj-filter-popover-chevron" [class.mj-filter-popover-chevron--open]="IsOpen"></i>
|
|
132
213
|
</button>
|
|
133
214
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
</button>
|
|
150
|
-
}
|
|
151
|
-
</div>
|
|
152
|
-
<div class="mj-filter-popover-content">
|
|
153
|
-
<ng-content></ng-content>
|
|
154
|
-
</div>
|
|
215
|
+
<!-- The panel body (header + projected filter UI) is declared ONCE here and
|
|
216
|
+
stamped into whichever wrapper is active (anchored overlay on desktop,
|
|
217
|
+
docked sheet on mobile). A single <ng-content> avoids the duplicate-slot
|
|
218
|
+
bug where projected content lands in only one of two branches. -->
|
|
219
|
+
<ng-template #panelBody>
|
|
220
|
+
<div class="mj-filter-popover-header">
|
|
221
|
+
<span class="mj-filter-popover-title">{{ Label }}</span>
|
|
222
|
+
@if (ActiveCount > 0 && ShowClearAll) {
|
|
223
|
+
<button type="button" class="mj-filter-popover-clear" (click)="ClearAll()">
|
|
224
|
+
Clear all
|
|
225
|
+
</button>
|
|
226
|
+
}
|
|
227
|
+
</div>
|
|
228
|
+
<div class="mj-filter-popover-content">
|
|
229
|
+
<ng-content></ng-content>
|
|
155
230
|
</div>
|
|
156
231
|
</ng-template>
|
|
157
|
-
|
|
158
|
-
|
|
232
|
+
|
|
233
|
+
@if (IsMobile) {
|
|
234
|
+
<!-- Mobile: the popover docks as a bottom sheet — mirrors how mj-left-nav
|
|
235
|
+
becomes a drawer at this width. -->
|
|
236
|
+
@if (IsOpen) {
|
|
237
|
+
<div class="mj-filter-popover-scrim" (click)="Close()" aria-hidden="true"></div>
|
|
238
|
+
<div class="mj-filter-popover-sheet" role="dialog" [attr.aria-label]="Label">
|
|
239
|
+
<div class="mj-filter-popover-grab" aria-hidden="true"></div>
|
|
240
|
+
<ng-container *ngTemplateOutlet="panelBody"></ng-container>
|
|
241
|
+
</div>
|
|
242
|
+
}
|
|
243
|
+
} @else {
|
|
244
|
+
<ng-template
|
|
245
|
+
cdkConnectedOverlay
|
|
246
|
+
[cdkConnectedOverlayOrigin]="overlayOrigin"
|
|
247
|
+
[cdkConnectedOverlayOpen]="IsOpen"
|
|
248
|
+
[cdkConnectedOverlayPositions]="Positions"
|
|
249
|
+
[cdkConnectedOverlayHasBackdrop]="true"
|
|
250
|
+
cdkConnectedOverlayBackdropClass="mj-filter-popover-backdrop"
|
|
251
|
+
(backdropClick)="Close()"
|
|
252
|
+
(detach)="Close()">
|
|
253
|
+
<div class="mj-filter-popover-panel" role="dialog" [attr.aria-label]="Label">
|
|
254
|
+
<ng-container *ngTemplateOutlet="panelBody"></ng-container>
|
|
255
|
+
</div>
|
|
256
|
+
</ng-template>
|
|
257
|
+
}
|
|
258
|
+
`, styles: ["\n :host {\n display: inline-flex;\n }\n\n /* Trigger button \u2014 visually aligned with mjButton size=\"sm\" variant=\"secondary\"\n (same height, padding, font-size, font-weight, background) so it sits\n cleanly next to Refresh/Export/+Add in chrome and filter-card rows. */\n .mj-filter-popover-trigger {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n min-height: 32px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n color: var(--mj-text-primary);\n font-family: inherit;\n font-size: 0.8125rem;\n font-weight: var(--mj-font-semibold);\n line-height: 1.5;\n cursor: pointer;\n transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;\n white-space: nowrap;\n }\n\n .mj-filter-popover-trigger:hover {\n background: var(--mj-bg-surface-active);\n border-color: var(--mj-border-strong);\n }\n\n .mj-filter-popover-trigger--active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-brand-primary) 30%, var(--mj-border-default));\n color: var(--mj-brand-primary);\n }\n\n .mj-filter-popover-trigger--active:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, var(--mj-bg-surface));\n }\n\n .mj-filter-popover-trigger > i:first-child {\n font-size: var(--mj-text-xs);\n color: var(--mj-brand-primary);\n }\n\n .mj-filter-popover-badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 20px;\n height: 20px;\n padding: 0 var(--mj-space-1-5);\n border-radius: 10px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 11px;\n font-weight: 700;\n line-height: 1;\n }\n\n .mj-filter-popover-chevron {\n font-size: 10px;\n transition: transform 0.2s ease;\n color: var(--mj-text-muted);\n }\n\n .mj-filter-popover-chevron--open {\n transform: rotate(180deg);\n }\n\n .mj-filter-popover-panel {\n min-width: 320px;\n max-width: 480px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-md);\n margin-top: var(--mj-space-1-5);\n overflow: hidden;\n }\n\n .mj-filter-popover-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: var(--mj-space-3) var(--mj-space-4) 0;\n }\n\n .mj-filter-popover-title {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n }\n\n .mj-filter-popover-clear {\n background: transparent;\n border: none;\n color: var(--mj-brand-primary);\n font-size: var(--mj-text-xs);\n font-weight: 500;\n cursor: pointer;\n padding: var(--mj-space-1) var(--mj-space-2);\n border-radius: var(--mj-radius-sm);\n }\n\n .mj-filter-popover-clear:hover {\n background: var(--mj-bg-surface-hover);\n }\n\n .mj-filter-popover-content {\n padding: var(--mj-space-3) var(--mj-space-4) var(--mj-space-4);\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-2-5);\n }\n\n /* \u2500\u2500 Mobile bottom sheet (\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\n The trigger button stays inline; tapping it docks the panel body as a\n sheet at the bottom of the viewport over a scrim \u2014 same body, different\n wrapper. Mirrors the mj-left-nav drawer treatment. */\n .mj-filter-popover-scrim {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n z-index: 9998;\n animation: mj-fp-fade 0.2s ease;\n }\n .mj-filter-popover-sheet {\n position: fixed;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 9999;\n display: flex;\n flex-direction: column;\n max-height: 85vh;\n background: var(--mj-bg-surface);\n border-top-left-radius: 16px;\n border-top-right-radius: 16px;\n box-shadow: var(--mj-shadow-lg);\n animation: mj-fp-slide-up 0.24s ease;\n }\n .mj-filter-popover-grab {\n flex-shrink: 0;\n width: 36px;\n height: 4px;\n border-radius: 2px;\n background: var(--mj-border-strong);\n margin: 10px auto 2px;\n }\n .mj-filter-popover-sheet .mj-filter-popover-header {\n flex-shrink: 0;\n }\n .mj-filter-popover-sheet .mj-filter-popover-content {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n -webkit-overflow-scrolling: touch;\n padding-bottom: var(--mj-space-6);\n }\n @keyframes mj-fp-fade {\n from { opacity: 0; }\n to { opacity: 1; }\n }\n @keyframes mj-fp-slide-up {\n from { transform: translateY(100%); }\n to { transform: translateY(0); }\n }\n @media (prefers-reduced-motion: reduce) {\n .mj-filter-popover-scrim,\n .mj-filter-popover-sheet {\n animation: none;\n }\n }\n\n /* On mobile the trigger collapses to icon-only (the count badge still\n conveys active state) so the control bar \u2014 search \u00B7 Filter \u00B7 view \u2014\n stays on one line. */\n @media (max-width: 700px) {\n .mj-filter-popover-label,\n .mj-filter-popover-chevron {\n display: none;\n }\n .mj-filter-popover-trigger {\n padding: 6px 10px;\n gap: 4px;\n }\n }\n "] }]
|
|
259
|
+
}], () => [], { Label: [{
|
|
159
260
|
type: Input
|
|
160
261
|
}], Icon: [{
|
|
161
262
|
type: Input
|
|
@@ -166,5 +267,5 @@ export class MJFilterPopoverComponent {
|
|
|
166
267
|
}], ClearAllRequested: [{
|
|
167
268
|
type: Output
|
|
168
269
|
}] }); })();
|
|
169
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJFilterPopoverComponent, { className: "MJFilterPopoverComponent", filePath: "lib/filter-popover/filter-popover.component.ts", lineNumber:
|
|
270
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJFilterPopoverComponent, { className: "MJFilterPopoverComponent", filePath: "lib/filter-popover/filter-popover.component.ts", lineNumber: 283 }); })();
|
|
170
271
|
//# sourceMappingURL=filter-popover.component.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter-popover.component.js","sourceRoot":"","sources":["../../../src/lib/filter-popover/filter-popover.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvE,OAAO,EAAE,aAAa,EAAqB,MAAM,sBAAsB,CAAC;;;;;IAqChE,+BAA0F;IACxF,YACF;IAAA,iBAAO;;;;IADL,cACF;IADE,mDACF;;;;IAkBI,kCAA2E;IAArB,2MAAS,iBAAU,KAAC;IACxE,2BACF;IAAA,iBAAS;;;IAJX,AADF,AADF,8BAA6E,aACrC,cACE;IAAA,YAAW;IAAA,iBAAO;IACxD,2GAAuC;IAKzC,iBAAM;IACN,8BAAuC;IACrC,kBAAyB;IAE7B,AADE,iBAAM,EACF;;;;IAVoC,eAAW;IAAX,kCAAW;IACjD,cAIC;IAJD,wEAIC;;AA1DX;;;;;;;;;;;;;;;;;GAiBG;AAwKH,MAAM,OAAO,wBAAwB;IAC1B,KAAK,GAAW,SAAS,CAAC;IAC1B,IAAI,GAAW,oBAAoB,CAAC;IACpC,WAAW,GAAW,CAAC,CAAC;IACxB,YAAY,GAAY,KAAK,CAAC;IAEhC,MAAM,GAAY,KAAK,CAAC;IAE/B,qFAAqF;IACrF,oFAAoF;IACpF,0FAA0F;IAC1F,2FAA2F;IAC3E,SAAS,GAAwB;QAC/C,EAAE,OAAO,EAAE,KAAK,EAAI,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAI,QAAQ,EAAE,KAAK,EAAE;QAC3E,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE;QAC3E,EAAE,OAAO,EAAE,KAAK,EAAI,OAAO,EAAE,KAAK,EAAK,QAAQ,EAAE,KAAK,EAAI,QAAQ,EAAE,QAAQ,EAAE;KAC/E,CAAC;IAEK,MAAM,KAAW,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAC9C,IAAI,KAAW,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;IACpC,KAAK,KAAW,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC;IAE7C,mFAAmF;IAClE,iBAAiB,GAAG,IAAI,YAAY,EAAQ,CAAC;IAEvD,QAAQ;QACb,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC;IAChC,CAAC;kHA3BU,wBAAwB;6DAAxB,wBAAwB;;;YAlKjC,oCAQqB;YAAnB,2IAAS,YAAQ,KAAC;YAClB,oBAAsB;YACtB,4BAAM;YAAA,YAAW;YAAA,iBAAO;YACxB,2FAAuB;YAKvB,uBAAmH;YACrH,iBAAS;YAET,yFAQqB;YAAnB,AADA,gKAAiB,WAAO,KAAC,qIACf,WAAO,KAAC;;;YAxBlB,sFAAqE;;YAMlE,eAAc;YAAd,uBAAc;YACX,eAAW;YAAX,+BAAW;YACjB,cAIC;YAJD,8CAIC;YAC6D,cAAgD;YAAhD,6DAAgD;YAK9G,cAA2C;YAG3C,AADA,AADA,AADA,4DAA2C,uCACT,+CACQ,wCACH;4BA1BjC,aAAa;;iFAoKZ,wBAAwB;cAvKpC,SAAS;2BACE,mBAAmB,cACjB,IAAI,WACP,CAAC,aAAa,CAAC,YACd;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CT;;kBAyHA,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBAmBL,MAAM;;kFAvBI,wBAAwB","sourcesContent":["import { Component, EventEmitter, Input, Output } from '@angular/core';\nimport { OverlayModule, ConnectedPosition } from '@angular/cdk/overlay';\n\n/**\n * mj-filter-popover — Compact \"Filters\" trigger button that opens a popover\n * containing arbitrary filter UI. Use this in a dashboard's page-header to\n * keep the header chrome consistent regardless of filter density.\n *\n * Pass the popover content via `<ng-content>`. Drive the active-count badge\n * via the `ActiveCount` input.\n *\n * Example:\n * ```html\n * <mj-filter-popover [ActiveCount]=\"activeFilters.length\">\n * <div class=\"my-filter-grid\">\n * <mj-dropdown ...></mj-dropdown>\n * <mj-dropdown ...></mj-dropdown>\n * </div>\n * </mj-filter-popover>\n * ```\n */\n@Component({\n selector: 'mj-filter-popover',\n standalone: true,\n imports: [OverlayModule],\n template: `\n <button\n type=\"button\"\n class=\"mj-filter-popover-trigger\"\n [class.mj-filter-popover-trigger--active]=\"IsOpen || ActiveCount > 0\"\n cdkOverlayOrigin\n #overlayOrigin=\"cdkOverlayOrigin\"\n [attr.aria-expanded]=\"IsOpen\"\n [attr.aria-haspopup]=\"true\"\n (click)=\"Toggle()\">\n <i [class]=\"Icon\"></i>\n <span>{{ Label }}</span>\n @if (ActiveCount > 0) {\n <span class=\"mj-filter-popover-badge\" [attr.aria-label]=\"ActiveCount + ' active filters'\">\n {{ ActiveCount }}\n </span>\n }\n <i class=\"fa-solid fa-chevron-down mj-filter-popover-chevron\" [class.mj-filter-popover-chevron--open]=\"IsOpen\"></i>\n </button>\n\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"overlayOrigin\"\n [cdkConnectedOverlayOpen]=\"IsOpen\"\n [cdkConnectedOverlayPositions]=\"Positions\"\n [cdkConnectedOverlayHasBackdrop]=\"true\"\n cdkConnectedOverlayBackdropClass=\"mj-filter-popover-backdrop\"\n (backdropClick)=\"Close()\"\n (detach)=\"Close()\">\n <div class=\"mj-filter-popover-panel\" role=\"dialog\" [attr.aria-label]=\"Label\">\n <div class=\"mj-filter-popover-header\">\n <span class=\"mj-filter-popover-title\">{{ Label }}</span>\n @if (ActiveCount > 0 && ShowClearAll) {\n <button type=\"button\" class=\"mj-filter-popover-clear\" (click)=\"ClearAll()\">\n Clear all\n </button>\n }\n </div>\n <div class=\"mj-filter-popover-content\">\n <ng-content></ng-content>\n </div>\n </div>\n </ng-template>\n `,\n styles: [`\n :host {\n display: inline-flex;\n }\n\n /* Trigger button — visually aligned with mjButton size=\"sm\" variant=\"secondary\"\n (same height, padding, font-size, font-weight, background) so it sits\n cleanly next to Refresh/Export/+Add in chrome and filter-card rows. */\n .mj-filter-popover-trigger {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n min-height: 32px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n color: var(--mj-text-primary);\n font-family: inherit;\n font-size: 0.8125rem;\n font-weight: var(--mj-font-semibold);\n line-height: 1.5;\n cursor: pointer;\n transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;\n white-space: nowrap;\n }\n\n .mj-filter-popover-trigger:hover {\n background: var(--mj-bg-surface-active);\n border-color: var(--mj-border-strong);\n }\n\n .mj-filter-popover-trigger--active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-brand-primary) 30%, var(--mj-border-default));\n color: var(--mj-brand-primary);\n }\n\n .mj-filter-popover-trigger--active:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, var(--mj-bg-surface));\n }\n\n .mj-filter-popover-trigger > i:first-child {\n font-size: var(--mj-text-xs);\n color: var(--mj-brand-primary);\n }\n\n .mj-filter-popover-badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 20px;\n height: 20px;\n padding: 0 var(--mj-space-1-5);\n border-radius: 10px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 11px;\n font-weight: 700;\n line-height: 1;\n }\n\n .mj-filter-popover-chevron {\n font-size: 10px;\n transition: transform 0.2s ease;\n color: var(--mj-text-muted);\n }\n\n .mj-filter-popover-chevron--open {\n transform: rotate(180deg);\n }\n\n .mj-filter-popover-panel {\n min-width: 320px;\n max-width: 480px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-md);\n margin-top: var(--mj-space-1-5);\n overflow: hidden;\n }\n\n .mj-filter-popover-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: var(--mj-space-3) var(--mj-space-4) 0;\n }\n\n .mj-filter-popover-title {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n }\n\n .mj-filter-popover-clear {\n background: transparent;\n border: none;\n color: var(--mj-brand-primary);\n font-size: var(--mj-text-xs);\n font-weight: 500;\n cursor: pointer;\n padding: var(--mj-space-1) var(--mj-space-2);\n border-radius: var(--mj-radius-sm);\n }\n\n .mj-filter-popover-clear:hover {\n background: var(--mj-bg-surface-hover);\n }\n\n .mj-filter-popover-content {\n padding: var(--mj-space-3) var(--mj-space-4) var(--mj-space-4);\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-2-5);\n }\n `]\n})\nexport class MJFilterPopoverComponent {\n @Input() Label: string = 'Filters';\n @Input() Icon: string = 'fa-solid fa-filter';\n @Input() ActiveCount: number = 0;\n @Input() ShowClearAll: boolean = false;\n\n public IsOpen: boolean = false;\n\n // Note: NO offsetY here — CDK applies offsetY as `transform: translateY(...)` on the\n // overlay pane, which creates a containing block for `position: fixed` descendants.\n // Tree dropdowns (and any other component using position: fixed) would then mis-position.\n // The 6px spacing below the trigger is applied via margin-top on .mj-filter-popover-panel.\n public readonly Positions: ConnectedPosition[] = [\n { originX: 'end', originY: 'bottom', overlayX: 'end', overlayY: 'top' },\n { originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top' },\n { originX: 'end', originY: 'top', overlayX: 'end', overlayY: 'bottom' }\n ];\n\n public Toggle(): void { this.IsOpen = !this.IsOpen; }\n public Open(): void { this.IsOpen = true; }\n public Close(): void { this.IsOpen = false; }\n\n /** Emitted when the user clicks the \"Clear all\" link inside the popover header. */\n @Output() public ClearAllRequested = new EventEmitter<void>();\n\n public ClearAll(): void {\n this.ClearAllRequested.emit();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"filter-popover.component.js","sourceRoot":"","sources":["../../../src/lib/filter-popover/filter-popover.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChangeDetectorRef, Component, EventEmitter, Input, NgZone, OnDestroy, Output, inject } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { OverlayModule, ConnectedPosition } from '@angular/cdk/overlay';\n\n/**\n * mj-filter-popover — Compact \"Filters\" trigger button that opens a popover\n * containing arbitrary filter UI. Use this in a dashboard's page-header to\n * keep the header chrome consistent regardless of filter density.\n *\n * Pass the popover content via `<ng-content>`. Drive the active-count badge\n * via the `ActiveCount` input.\n *\n * Example:\n * ```html\n * <mj-filter-popover [ActiveCount]=\"activeFilters.length\">\n * <div class=\"my-filter-grid\">\n * <mj-dropdown ...></mj-dropdown>\n * <mj-dropdown ...></mj-dropdown>\n * </div>\n * </mj-filter-popover>\n * ```\n */\n@Component({\n selector: 'mj-filter-popover',\n standalone: true,\n imports: [CommonModule, OverlayModule],\n template: `\n <button\n type=\"button\"\n class=\"mj-filter-popover-trigger\"\n [class.mj-filter-popover-trigger--active]=\"IsOpen || ActiveCount > 0\"\n cdkOverlayOrigin\n #overlayOrigin=\"cdkOverlayOrigin\"\n [attr.aria-expanded]=\"IsOpen\"\n [attr.aria-haspopup]=\"true\"\n (click)=\"Toggle()\">\n <i [class]=\"Icon\"></i>\n <span class=\"mj-filter-popover-label\">{{ Label }}</span>\n @if (ActiveCount > 0) {\n <span class=\"mj-filter-popover-badge\" [attr.aria-label]=\"ActiveCount + ' active filters'\">\n {{ ActiveCount }}\n </span>\n }\n <i class=\"fa-solid fa-chevron-down mj-filter-popover-chevron\" [class.mj-filter-popover-chevron--open]=\"IsOpen\"></i>\n </button>\n\n <!-- The panel body (header + projected filter UI) is declared ONCE here and\n stamped into whichever wrapper is active (anchored overlay on desktop,\n docked sheet on mobile). A single <ng-content> avoids the duplicate-slot\n bug where projected content lands in only one of two branches. -->\n <ng-template #panelBody>\n <div class=\"mj-filter-popover-header\">\n <span class=\"mj-filter-popover-title\">{{ Label }}</span>\n @if (ActiveCount > 0 && ShowClearAll) {\n <button type=\"button\" class=\"mj-filter-popover-clear\" (click)=\"ClearAll()\">\n Clear all\n </button>\n }\n </div>\n <div class=\"mj-filter-popover-content\">\n <ng-content></ng-content>\n </div>\n </ng-template>\n\n @if (IsMobile) {\n <!-- Mobile: the popover docks as a bottom sheet — mirrors how mj-left-nav\n becomes a drawer at this width. -->\n @if (IsOpen) {\n <div class=\"mj-filter-popover-scrim\" (click)=\"Close()\" aria-hidden=\"true\"></div>\n <div class=\"mj-filter-popover-sheet\" role=\"dialog\" [attr.aria-label]=\"Label\">\n <div class=\"mj-filter-popover-grab\" aria-hidden=\"true\"></div>\n <ng-container *ngTemplateOutlet=\"panelBody\"></ng-container>\n </div>\n }\n } @else {\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"overlayOrigin\"\n [cdkConnectedOverlayOpen]=\"IsOpen\"\n [cdkConnectedOverlayPositions]=\"Positions\"\n [cdkConnectedOverlayHasBackdrop]=\"true\"\n cdkConnectedOverlayBackdropClass=\"mj-filter-popover-backdrop\"\n (backdropClick)=\"Close()\"\n (detach)=\"Close()\">\n <div class=\"mj-filter-popover-panel\" role=\"dialog\" [attr.aria-label]=\"Label\">\n <ng-container *ngTemplateOutlet=\"panelBody\"></ng-container>\n </div>\n </ng-template>\n }\n `,\n styles: [`\n :host {\n display: inline-flex;\n }\n\n /* Trigger button — visually aligned with mjButton size=\"sm\" variant=\"secondary\"\n (same height, padding, font-size, font-weight, background) so it sits\n cleanly next to Refresh/Export/+Add in chrome and filter-card rows. */\n .mj-filter-popover-trigger {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n min-height: 32px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n color: var(--mj-text-primary);\n font-family: inherit;\n font-size: 0.8125rem;\n font-weight: var(--mj-font-semibold);\n line-height: 1.5;\n cursor: pointer;\n transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;\n white-space: nowrap;\n }\n\n .mj-filter-popover-trigger:hover {\n background: var(--mj-bg-surface-active);\n border-color: var(--mj-border-strong);\n }\n\n .mj-filter-popover-trigger--active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-brand-primary) 30%, var(--mj-border-default));\n color: var(--mj-brand-primary);\n }\n\n .mj-filter-popover-trigger--active:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, var(--mj-bg-surface));\n }\n\n .mj-filter-popover-trigger > i:first-child {\n font-size: var(--mj-text-xs);\n color: var(--mj-brand-primary);\n }\n\n .mj-filter-popover-badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 20px;\n height: 20px;\n padding: 0 var(--mj-space-1-5);\n border-radius: 10px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 11px;\n font-weight: 700;\n line-height: 1;\n }\n\n .mj-filter-popover-chevron {\n font-size: 10px;\n transition: transform 0.2s ease;\n color: var(--mj-text-muted);\n }\n\n .mj-filter-popover-chevron--open {\n transform: rotate(180deg);\n }\n\n .mj-filter-popover-panel {\n min-width: 320px;\n max-width: 480px;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-md);\n margin-top: var(--mj-space-1-5);\n overflow: hidden;\n }\n\n .mj-filter-popover-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: var(--mj-space-3) var(--mj-space-4) 0;\n }\n\n .mj-filter-popover-title {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n }\n\n .mj-filter-popover-clear {\n background: transparent;\n border: none;\n color: var(--mj-brand-primary);\n font-size: var(--mj-text-xs);\n font-weight: 500;\n cursor: pointer;\n padding: var(--mj-space-1) var(--mj-space-2);\n border-radius: var(--mj-radius-sm);\n }\n\n .mj-filter-popover-clear:hover {\n background: var(--mj-bg-surface-hover);\n }\n\n .mj-filter-popover-content {\n padding: var(--mj-space-3) var(--mj-space-4) var(--mj-space-4);\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-2-5);\n }\n\n /* ── Mobile bottom sheet (≤700px) ─────────────────────────────────────\n The trigger button stays inline; tapping it docks the panel body as a\n sheet at the bottom of the viewport over a scrim — same body, different\n wrapper. Mirrors the mj-left-nav drawer treatment. */\n .mj-filter-popover-scrim {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n z-index: 9998;\n animation: mj-fp-fade 0.2s ease;\n }\n .mj-filter-popover-sheet {\n position: fixed;\n left: 0;\n right: 0;\n bottom: 0;\n z-index: 9999;\n display: flex;\n flex-direction: column;\n max-height: 85vh;\n background: var(--mj-bg-surface);\n border-top-left-radius: 16px;\n border-top-right-radius: 16px;\n box-shadow: var(--mj-shadow-lg);\n animation: mj-fp-slide-up 0.24s ease;\n }\n .mj-filter-popover-grab {\n flex-shrink: 0;\n width: 36px;\n height: 4px;\n border-radius: 2px;\n background: var(--mj-border-strong);\n margin: 10px auto 2px;\n }\n .mj-filter-popover-sheet .mj-filter-popover-header {\n flex-shrink: 0;\n }\n .mj-filter-popover-sheet .mj-filter-popover-content {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n -webkit-overflow-scrolling: touch;\n padding-bottom: var(--mj-space-6);\n }\n @keyframes mj-fp-fade {\n from { opacity: 0; }\n to { opacity: 1; }\n }\n @keyframes mj-fp-slide-up {\n from { transform: translateY(100%); }\n to { transform: translateY(0); }\n }\n @media (prefers-reduced-motion: reduce) {\n .mj-filter-popover-scrim,\n .mj-filter-popover-sheet {\n animation: none;\n }\n }\n\n /* On mobile the trigger collapses to icon-only (the count badge still\n conveys active state) so the control bar — search · Filter · view —\n stays on one line. */\n @media (max-width: 700px) {\n .mj-filter-popover-label,\n .mj-filter-popover-chevron {\n display: none;\n }\n .mj-filter-popover-trigger {\n padding: 6px 10px;\n gap: 4px;\n }\n }\n `]\n})\nexport class MJFilterPopoverComponent implements OnDestroy {\n @Input() Label: string = 'Filters';\n @Input() Icon: string = 'fa-solid fa-filter';\n @Input() ActiveCount: number = 0;\n @Input() ShowClearAll: boolean = false;\n\n public IsOpen: boolean = false;\n\n /**\n * True when the viewport is narrow enough that the popover should dock as a\n * bottom sheet instead of an anchored overlay. Driven by matchMedia so it\n * tracks live resize without Angular change-detection plumbing.\n */\n public IsMobile: boolean = false;\n\n private readonly zone = inject(NgZone);\n private readonly cdr = inject(ChangeDetectorRef);\n\n private readonly mediaQuery: MediaQueryList | null =\n typeof window !== 'undefined' && typeof window.matchMedia === 'function'\n ? window.matchMedia('(max-width: 700px)')\n : null;\n\n // matchMedia 'change' fires OUTSIDE Angular's zone, so the flip must be\n // re-entered into the zone — otherwise the IsMobile change lands mid-CD and\n // the @if(IsMobile) branch swap throws ExpressionChangedAfterItHasBeenChecked\n // when crossing the breakpoint. Also close across the switch so a sheet/overlay\n // opened in one mode doesn't linger in the other.\n private readonly onMediaChange = (e: MediaQueryListEvent): void => {\n this.zone.run(() => {\n this.IsMobile = e.matches;\n this.IsOpen = false;\n this.cdr.markForCheck();\n });\n };\n\n constructor() {\n if (this.mediaQuery) {\n this.IsMobile = this.mediaQuery.matches;\n this.mediaQuery.addEventListener('change', this.onMediaChange);\n }\n }\n\n ngOnDestroy(): void {\n this.mediaQuery?.removeEventListener('change', this.onMediaChange);\n }\n\n // Note: NO offsetY here — CDK applies offsetY as `transform: translateY(...)` on the\n // overlay pane, which creates a containing block for `position: fixed` descendants.\n // Tree dropdowns (and any other component using position: fixed) would then mis-position.\n // The 6px spacing below the trigger is applied via margin-top on .mj-filter-popover-panel.\n public readonly Positions: ConnectedPosition[] = [\n { originX: 'end', originY: 'bottom', overlayX: 'end', overlayY: 'top' },\n { originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top' },\n { originX: 'end', originY: 'top', overlayX: 'end', overlayY: 'bottom' }\n ];\n\n public Toggle(): void { this.IsOpen = !this.IsOpen; }\n public Open(): void { this.IsOpen = true; }\n public Close(): void { this.IsOpen = false; }\n\n /** Emitted when the user clicks the \"Clear all\" link inside the popover header. */\n @Output() public ClearAllRequested = new EventEmitter<void>();\n\n public ClearAll(): void {\n this.ClearAllRequested.emit();\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"left-nav-content.component.d.ts","sourceRoot":"","sources":["../../../src/lib/left-nav/left-nav-content.component.ts"],"names":[],"mappings":";AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,
|
|
1
|
+
{"version":3,"file":"left-nav-content.component.d.ts","sourceRoot":"","sources":["../../../src/lib/left-nav/left-nav-content.component.ts"],"names":[],"mappings":";AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,qBAuFa,yBAAyB;IACpC;;;OAGG;IACM,OAAO,EAAE,OAAO,CAAS;IAElC;;;OAGG;IACM,KAAK,EAAE,MAAM,GAAG,IAAI,CAAQ;IAErC,gEAAgE;IACvD,YAAY,EAAE,MAAM,CAAc;IAE3C;;;OAGG;IACH,IACI,MAAM,IAAI,OAAO,CAEpB;IAED,IACI,QAAQ,IAAI,MAAM,GAAG,IAAI,CAE5B;yCA5BU,yBAAyB;2CAAzB,yBAAyB;CA6BrC"}
|
|
@@ -86,7 +86,7 @@ export class MJLeftNavContentComponent {
|
|
|
86
86
|
i0.ɵɵprojection(2);
|
|
87
87
|
} if (rf & 2) {
|
|
88
88
|
i0.ɵɵconditional(ctx.Error ? 0 : ctx.Loading ? 1 : -1);
|
|
89
|
-
} }, dependencies: [CommonModule], styles: ["[_nghost-%COMP%] {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-page);\n overflow: hidden;\n }\n\n \n\n\n\n\n\n\n\n\n\n\n\n [_nghost-%COMP%] > *:not(.mj-left-nav-content__error):not(.mj-left-nav-content__loading):not(mj-page-header-interior):not(mj-page-body-interior) {\n flex: 1 1 auto;\n min-height: 0;\n height: 100%;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n\n \n\n\n .mj-left-nav-content--busy[_nghost-%COMP%] > *:not(.mj-left-nav-content__error):not(.mj-left-nav-content__loading) {\n display: none;\n }\n\n .mj-left-nav-content__error[_ngcontent-%COMP%], \n .mj-left-nav-content__loading[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 10px;\n color: var(--mj-text-muted);\n font-size: 13px;\n padding: 32px;\n text-align: center;\n }\n\n .mj-left-nav-content__error[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n }\n\n .mj-left-nav-content__error[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n }\n\n .mj-left-nav-content__loading[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n color: var(--mj-brand-primary);\n }"] });
|
|
89
|
+
} }, dependencies: [CommonModule], styles: ["[_nghost-%COMP%] {\n flex: 1;\n min-width: 0;\n \n\n\n\n\n\n min-height: 0;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-page);\n overflow: hidden;\n }\n\n \n\n\n\n\n\n\n\n\n\n\n\n [_nghost-%COMP%] > *:not(.mj-left-nav-content__error):not(.mj-left-nav-content__loading):not(mj-page-header-interior):not(mj-page-body-interior) {\n flex: 1 1 auto;\n min-height: 0;\n height: 100%;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n\n \n\n\n .mj-left-nav-content--busy[_nghost-%COMP%] > *:not(.mj-left-nav-content__error):not(.mj-left-nav-content__loading) {\n display: none;\n }\n\n .mj-left-nav-content__error[_ngcontent-%COMP%], \n .mj-left-nav-content__loading[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 10px;\n color: var(--mj-text-muted);\n font-size: 13px;\n padding: 32px;\n text-align: center;\n }\n\n .mj-left-nav-content__error[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n }\n\n .mj-left-nav-content__error[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n }\n\n .mj-left-nav-content__loading[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n color: var(--mj-brand-primary);\n }"] });
|
|
90
90
|
}
|
|
91
91
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJLeftNavContentComponent, [{
|
|
92
92
|
type: Component,
|
|
@@ -103,7 +103,7 @@ export class MJLeftNavContentComponent {
|
|
|
103
103
|
</div>
|
|
104
104
|
}
|
|
105
105
|
<ng-content></ng-content>
|
|
106
|
-
`, styles: ["\n :host {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-page);\n overflow: hidden;\n }\n\n /* Force dynamically-projected components (via ViewContainerRef.createComponent\n or ng-content) to fill the host with a proper flex-column layout. ::ng-deep\n is required because Angular's emulated encapsulation gives the host a scope\n attribute that dynamically-created components do not inherit, so a plain\n direct-child selector would not match them. The :not() filters skip our own\n error / loading elements AND the interior chrome primitives, which already\n self-declare their flex behavior on :host (header-interior is display:block\n with natural height; body-interior is flex:1 1 auto with overflow-y:auto)\n and competing with them would break multi-sibling chrome layouts inside a\n single content pane. This replaces the bespoke inline-style hack admin\n shells used to apply via applyHostSizing(). */\n :host ::ng-deep > *:not(.mj-left-nav-content__error):not(.mj-left-nav-content__loading):not(mj-page-header-interior):not(mj-page-body-interior) {\n flex: 1 1 auto;\n min-height: 0;\n height: 100%;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n\n /* When busy, hide projected content but keep cached components attached\n to the DOM so their state survives the loading / error transition. */\n :host(.mj-left-nav-content--busy) ::ng-deep > *:not(.mj-left-nav-content__error):not(.mj-left-nav-content__loading) {\n display: none;\n }\n\n .mj-left-nav-content__error,\n .mj-left-nav-content__loading {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 10px;\n color: var(--mj-text-muted);\n font-size: 13px;\n padding: 32px;\n text-align: center;\n }\n\n .mj-left-nav-content__error {\n color: var(--mj-status-error);\n }\n\n .mj-left-nav-content__error i {\n font-size: 20px;\n }\n\n .mj-left-nav-content__loading i {\n font-size: 16px;\n color: var(--mj-brand-primary);\n }\n "] }]
|
|
106
|
+
`, styles: ["\n :host {\n flex: 1;\n min-width: 0;\n /* min-height: 0 is essential when the parent <mj-page-body> reflows from\n row \u2192 column on mobile: without it this pane can't shrink below its\n content height, so the inner scroller (mj-page-body-interior) never\n gets a bounded height and the page can't scroll. Harmless in the row\n (desktop) case. */\n min-height: 0;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-page);\n overflow: hidden;\n }\n\n /* Force dynamically-projected components (via ViewContainerRef.createComponent\n or ng-content) to fill the host with a proper flex-column layout. ::ng-deep\n is required because Angular's emulated encapsulation gives the host a scope\n attribute that dynamically-created components do not inherit, so a plain\n direct-child selector would not match them. The :not() filters skip our own\n error / loading elements AND the interior chrome primitives, which already\n self-declare their flex behavior on :host (header-interior is display:block\n with natural height; body-interior is flex:1 1 auto with overflow-y:auto)\n and competing with them would break multi-sibling chrome layouts inside a\n single content pane. This replaces the bespoke inline-style hack admin\n shells used to apply via applyHostSizing(). */\n :host ::ng-deep > *:not(.mj-left-nav-content__error):not(.mj-left-nav-content__loading):not(mj-page-header-interior):not(mj-page-body-interior) {\n flex: 1 1 auto;\n min-height: 0;\n height: 100%;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n\n /* When busy, hide projected content but keep cached components attached\n to the DOM so their state survives the loading / error transition. */\n :host(.mj-left-nav-content--busy) ::ng-deep > *:not(.mj-left-nav-content__error):not(.mj-left-nav-content__loading) {\n display: none;\n }\n\n .mj-left-nav-content__error,\n .mj-left-nav-content__loading {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 10px;\n color: var(--mj-text-muted);\n font-size: 13px;\n padding: 32px;\n text-align: center;\n }\n\n .mj-left-nav-content__error {\n color: var(--mj-status-error);\n }\n\n .mj-left-nav-content__error i {\n font-size: 20px;\n }\n\n .mj-left-nav-content__loading i {\n font-size: 16px;\n color: var(--mj-brand-primary);\n }\n "] }]
|
|
107
107
|
}], null, { Loading: [{
|
|
108
108
|
type: Input
|
|
109
109
|
}], Error: [{
|
|
@@ -117,5 +117,5 @@ export class MJLeftNavContentComponent {
|
|
|
117
117
|
type: HostBinding,
|
|
118
118
|
args: ['attr.aria-busy']
|
|
119
119
|
}] }); })();
|
|
120
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJLeftNavContentComponent, { className: "MJLeftNavContentComponent", filePath: "lib/left-nav/left-nav-content.component.ts", lineNumber:
|
|
120
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJLeftNavContentComponent, { className: "MJLeftNavContentComponent", filePath: "lib/left-nav/left-nav-content.component.ts", lineNumber: 120 }); })();
|
|
121
121
|
//# sourceMappingURL=left-nav-content.component.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"left-nav-content.component.js","sourceRoot":"","sources":["../../../src/lib/left-nav/left-nav-content.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;;;;IAqCzC,iCAAqD;IACnD,0BAAmE;IACnE,+BAAM;IAAA,YAAW;IACnB,AADmB,oBAAO,EACpB;;;IADE,eAAW;IAAX,kCAAW;;;IAGnB,iCAA2E;IACzE,0BAA8D;IAC9D,+BAAM;IAAA,YAAkB;IAC1B,AAD0B,oBAAO,EAC3B;;;IADE,eAAkB;IAAlB,yCAAkB;;AA1ChC;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;
|
|
1
|
+
{"version":3,"file":"left-nav-content.component.js","sourceRoot":"","sources":["../../../src/lib/left-nav/left-nav-content.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;;;;IAqCzC,iCAAqD;IACnD,0BAAmE;IACnE,+BAAM;IAAA,YAAW;IACnB,AADmB,oBAAO,EACpB;;;IADE,eAAW;IAAX,kCAAW;;;IAGnB,iCAA2E;IACzE,0BAA8D;IAC9D,+BAAM;IAAA,YAAkB;IAC1B,AAD0B,oBAAO,EAC3B;;;IADE,eAAkB;IAAlB,yCAAkB;;AA1ChC;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAwFH,MAAM,OAAO,yBAAyB;IACpC;;;OAGG;IACM,OAAO,GAAY,KAAK,CAAC;IAElC;;;OAGG;IACM,KAAK,GAAkB,IAAI,CAAC;IAErC,gEAAgE;IACvD,YAAY,GAAW,UAAU,CAAC;IAE3C;;;OAGG;IACH,IACI,MAAM;QACR,OAAO,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;IACtC,CAAC;IAED,IACI,QAAQ;QACV,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;IACtC,CAAC;mHA5BU,yBAAyB;6DAAzB,yBAAyB;;YAAzB,uDAAyB;;;YA7EhC,AALF,2FAAa,qEAKS;YAMtB,kBAAyB;;YAXzB,sDAUC;4BAZO,YAAY;;iFAoFX,yBAAyB;cAvFrC,SAAS;2BACE,qBAAqB,cACnB,IAAI,WACP,CAAC,YAAY,CAAC,YACb;;;;;;;;;;;;;GAaT;;kBA2EA,KAAK;;kBAML,KAAK;;kBAGL,KAAK;;kBAML,WAAW;mBAAC,iCAAiC;;kBAK7C,WAAW;mBAAC,gBAAgB;;kFAzBlB,yBAAyB","sourcesContent":["import { Component, HostBinding, Input } from '@angular/core';\nimport { CommonModule } from '@angular/common';\n\n/**\n * `<mj-left-nav-content>` — Content pane paired with `<mj-left-nav>`.\n *\n * Sits to the right of `<mj-left-nav>` inside `<mj-page-body [Flex]=\"true\"\n * Direction=\"row\">` and holds the active section's content. Provides the\n * standard layout box (`flex: 1`, page background, vertical overflow control)\n * plus built-in `[Loading]` / `[Error]` states so each shell doesn't reinvent\n * them.\n *\n * Projected content stays attached but hides via CSS when loading or errored —\n * matches the cached-component pattern used by admin shells where dynamically\n * loaded sub-pages should retain their state across section switches.\n *\n * ## Example\n *\n * ```html\n * <mj-page-body [Flex]=\"true\" [Padding]=\"false\" Direction=\"row\">\n * <mj-left-nav [Sections]=\"NavSections\" [ActiveId]=\"ActiveSection\"\n * (ItemClicked)=\"OnNavItemClicked($event)\" />\n * <mj-left-nav-content [Loading]=\"IsLoading\" [Error]=\"LoadError\">\n * <ng-container #contentHost></ng-container>\n * </mj-left-nav-content>\n * </mj-page-body>\n * ```\n *\n * Replaces the bespoke `.{shell}-container__content` + `.{shell}-container__host`\n * + `.{shell}-container__loading` + `.{shell}-container__error` pattern that\n * every left-nav shell used to declare independently.\n */\n@Component({\n selector: 'mj-left-nav-content',\n standalone: true,\n imports: [CommonModule],\n template: `\n @if (Error) {\n <div class=\"mj-left-nav-content__error\" role=\"alert\">\n <i class=\"fa-solid fa-triangle-exclamation\" aria-hidden=\"true\"></i>\n <span>{{ Error }}</span>\n </div>\n } @else if (Loading) {\n <div class=\"mj-left-nav-content__loading\" role=\"status\" aria-live=\"polite\">\n <i class=\"fa-solid fa-spinner fa-spin\" aria-hidden=\"true\"></i>\n <span>{{ LoadingLabel }}</span>\n </div>\n }\n <ng-content></ng-content>\n `,\n styles: [`\n :host {\n flex: 1;\n min-width: 0;\n /* min-height: 0 is essential when the parent <mj-page-body> reflows from\n row → column on mobile: without it this pane can't shrink below its\n content height, so the inner scroller (mj-page-body-interior) never\n gets a bounded height and the page can't scroll. Harmless in the row\n (desktop) case. */\n min-height: 0;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-page);\n overflow: hidden;\n }\n\n /* Force dynamically-projected components (via ViewContainerRef.createComponent\n or ng-content) to fill the host with a proper flex-column layout. ::ng-deep\n is required because Angular's emulated encapsulation gives the host a scope\n attribute that dynamically-created components do not inherit, so a plain\n direct-child selector would not match them. The :not() filters skip our own\n error / loading elements AND the interior chrome primitives, which already\n self-declare their flex behavior on :host (header-interior is display:block\n with natural height; body-interior is flex:1 1 auto with overflow-y:auto)\n and competing with them would break multi-sibling chrome layouts inside a\n single content pane. This replaces the bespoke inline-style hack admin\n shells used to apply via applyHostSizing(). */\n :host ::ng-deep > *:not(.mj-left-nav-content__error):not(.mj-left-nav-content__loading):not(mj-page-header-interior):not(mj-page-body-interior) {\n flex: 1 1 auto;\n min-height: 0;\n height: 100%;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n\n /* When busy, hide projected content but keep cached components attached\n to the DOM so their state survives the loading / error transition. */\n :host(.mj-left-nav-content--busy) ::ng-deep > *:not(.mj-left-nav-content__error):not(.mj-left-nav-content__loading) {\n display: none;\n }\n\n .mj-left-nav-content__error,\n .mj-left-nav-content__loading {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 10px;\n color: var(--mj-text-muted);\n font-size: 13px;\n padding: 32px;\n text-align: center;\n }\n\n .mj-left-nav-content__error {\n color: var(--mj-status-error);\n }\n\n .mj-left-nav-content__error i {\n font-size: 20px;\n }\n\n .mj-left-nav-content__loading i {\n font-size: 16px;\n color: var(--mj-brand-primary);\n }\n `]\n})\nexport class MJLeftNavContentComponent {\n /**\n * When `true`, shows a centered loading state (spinner + label) and hides\n * any projected content via CSS. Cached components remain attached.\n */\n @Input() Loading: boolean = false;\n\n /**\n * When non-empty, shows a centered error state with this message and hides\n * any projected content.\n */\n @Input() Error: string | null = null;\n\n /** Label shown in the loading state. Defaults to \"Loading…\". */\n @Input() LoadingLabel: string = 'Loading…';\n\n /**\n * Drives the busy-state class on the host. When set, CSS hides projected\n * content (cached components stay attached, just not visible).\n */\n @HostBinding('class.mj-left-nav-content--busy')\n get IsBusy(): boolean {\n return this.Loading || !!this.Error;\n }\n\n @HostBinding('attr.aria-busy')\n get AriaBusy(): string | null {\n return this.Loading ? 'true' : null;\n }\n}\n"]}
|
|
@@ -53,9 +53,10 @@ export interface MJLeftNavSection {
|
|
|
53
53
|
* - Items with a count badge (APIKeys pattern)
|
|
54
54
|
* - Sections with uppercase headers (Communication / Credentials pattern)
|
|
55
55
|
* - Optional `[header]` and `[footer]` content slots (KH Config logo header, etc.)
|
|
56
|
-
* - Responsive
|
|
57
|
-
*
|
|
58
|
-
*
|
|
56
|
+
* - Responsive mobile drawer (≤700px): the rail hides off-canvas and a compact
|
|
57
|
+
* section switcher takes its place; tapping it slides the full rail in over a
|
|
58
|
+
* scrim. The rail keeps its full content (trees, slots, descriptions, badges)
|
|
59
|
+
* inside the drawer — no flattening. Set `[MobileTitle]` for the drawer label.
|
|
59
60
|
*
|
|
60
61
|
* ## Example
|
|
61
62
|
*
|
|
@@ -79,10 +80,11 @@ export interface MJLeftNavSection {
|
|
|
79
80
|
* </mj-left-nav>
|
|
80
81
|
* ```
|
|
81
82
|
*
|
|
82
|
-
* Responsive
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
83
|
+
* Responsive — at ≤700px the rail becomes an off-canvas drawer (see the feature
|
|
84
|
+
* list above). The consumer should still switch the parent's flex-direction from
|
|
85
|
+
* row → column at the same breakpoint (e.g. `<mj-page-body>` Direction="row" with
|
|
86
|
+
* a `@media` override) so the in-flow section switcher stacks above the content
|
|
87
|
+
* pane rather than competing with it for horizontal space.
|
|
86
88
|
*/
|
|
87
89
|
export declare class MJLeftNavComponent {
|
|
88
90
|
/**
|
|
@@ -97,9 +99,16 @@ export declare class MJLeftNavComponent {
|
|
|
97
99
|
ActiveId: string | null;
|
|
98
100
|
/**
|
|
99
101
|
* Width of the rail in pixels. Defaults to 240. Set to a smaller value
|
|
100
|
-
* (e.g., 200) for denser shells.
|
|
102
|
+
* (e.g., 200) for denser shells. Only applies to the desktop rail — on mobile
|
|
103
|
+
* the rail becomes a fixed-width off-canvas drawer.
|
|
101
104
|
*/
|
|
102
105
|
Width: number;
|
|
106
|
+
/**
|
|
107
|
+
* Label shown on the mobile drawer header and used as the switcher fallback
|
|
108
|
+
* label when no item is active. Defaults to `'Menu'`. Set to something
|
|
109
|
+
* domain-specific (e.g. `'Sections'`, `'Test Suites'`) for clearer context.
|
|
110
|
+
*/
|
|
111
|
+
MobileTitle: string;
|
|
103
112
|
/**
|
|
104
113
|
* Ids of currently-expanded tree items. Items whose id appears here render
|
|
105
114
|
* with a down-chevron and their `children` are visible; items not in this
|
|
@@ -118,8 +127,26 @@ export declare class MJLeftNavComponent {
|
|
|
118
127
|
* the item's id in / out of `ExpandedIds`. Does NOT also fire `ItemClicked`.
|
|
119
128
|
*/
|
|
120
129
|
ItemToggled: EventEmitter<MJLeftNavItem>;
|
|
130
|
+
/**
|
|
131
|
+
* Whether the mobile off-canvas drawer is open. Component-owned, transient UI
|
|
132
|
+
* state — no effect above the 700px breakpoint where the rail is always inline.
|
|
133
|
+
*/
|
|
134
|
+
MobileNavOpen: boolean;
|
|
135
|
+
/** Reflects {@link MobileNavOpen} onto the host so CSS can drive the drawer. */
|
|
136
|
+
get isMobileNavOpen(): boolean;
|
|
137
|
+
OpenMobileNav(): void;
|
|
138
|
+
CloseMobileNav(): void;
|
|
139
|
+
/** Escape closes the mobile drawer. No-op when it's already closed. */
|
|
140
|
+
onEscape(): void;
|
|
121
141
|
OnItemClick(item: MJLeftNavItem): void;
|
|
122
142
|
OnItemToggle(event: Event, item: MJLeftNavItem): void;
|
|
143
|
+
/**
|
|
144
|
+
* The item matching {@link ActiveId} (searched recursively through trees),
|
|
145
|
+
* used to label the mobile section switcher with the current section's icon
|
|
146
|
+
* and label. Returns `undefined` when nothing is active.
|
|
147
|
+
*/
|
|
148
|
+
get ActiveTriggerItem(): MJLeftNavItem | undefined;
|
|
149
|
+
private findItemById;
|
|
123
150
|
IsExpanded(id: string): boolean;
|
|
124
151
|
/**
|
|
125
152
|
* Whether any top-level item in this section actually has children to expand.
|
|
@@ -132,6 +159,6 @@ export declare class MJLeftNavComponent {
|
|
|
132
159
|
*/
|
|
133
160
|
HasExpandableItems(items: MJLeftNavItem[]): boolean;
|
|
134
161
|
static ɵfac: i0.ɵɵFactoryDeclaration<MJLeftNavComponent, never>;
|
|
135
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<MJLeftNavComponent, "mj-left-nav", never, { "Sections": { "alias": "Sections"; "required": false; }; "ActiveId": { "alias": "ActiveId"; "required": false; }; "Width": { "alias": "Width"; "required": false; }; "ExpandedIds": { "alias": "ExpandedIds"; "required": false; }; }, { "ItemClicked": "ItemClicked"; "ItemToggled": "ItemToggled"; }, never, ["[header]", "[footer]"], true, never>;
|
|
162
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<MJLeftNavComponent, "mj-left-nav", never, { "Sections": { "alias": "Sections"; "required": false; }; "ActiveId": { "alias": "ActiveId"; "required": false; }; "Width": { "alias": "Width"; "required": false; }; "MobileTitle": { "alias": "MobileTitle"; "required": false; }; "ExpandedIds": { "alias": "ExpandedIds"; "required": false; }; }, { "ItemClicked": "ItemClicked"; "ItemToggled": "ItemToggled"; }, never, ["[header]", "[footer]"], true, never>;
|
|
136
163
|
}
|
|
137
164
|
//# sourceMappingURL=left-nav.component.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"left-nav.component.d.ts","sourceRoot":"","sources":["../../../src/lib/left-nav/left-nav.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,YAAY,
|
|
1
|
+
{"version":3,"file":"left-nav.component.d.ts","sourceRoot":"","sources":["../../../src/lib/left-nav/left-nav.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,YAAY,EAA4C,MAAM,eAAe,CAAC;;AAGlG;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,+EAA+E;IAC/E,EAAE,EAAE,MAAM,CAAC;IACX,sDAAsD;IACtD,KAAK,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8DAA8D;IAC9D,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,iEAAiE;IACjE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAC;CAC5B;AAED;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,iEAAiE;IACjE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2CAA2C;IAC3C,KAAK,EAAE,aAAa,EAAE,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,qBA8ba,kBAAkB;IAC7B;;;OAGG;IACM,QAAQ,EAAE,gBAAgB,EAAE,CAAM;IAE3C;;;OAGG;IACM,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAExC;;;;OAIG;IACM,KAAK,EAAE,MAAM,CAAO;IAE7B;;;;OAIG;IACM,WAAW,EAAE,MAAM,CAAU;IAEtC;;;;;;;OAOG;IACM,WAAW,EAAE,MAAM,EAAE,CAAM;IAEpC;;OAEG;IACO,WAAW,8BAAqC;IAE1D;;;OAGG;IACO,WAAW,8BAAqC;IAE1D;;;OAGG;IACI,aAAa,UAAS;IAE7B,gFAAgF;IAChF,IACI,eAAe,IAAI,OAAO,CAE7B;IAED,aAAa,IAAI,IAAI;IAIrB,cAAc,IAAI,IAAI;IAItB,uEAAuE;IAEvE,QAAQ,IAAI,IAAI;IAMhB,WAAW,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI;IAOtC,YAAY,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,aAAa,GAAG,IAAI;IAMrD;;;;OAIG;IACH,IAAI,iBAAiB,IAAI,aAAa,GAAG,SAAS,CAGjD;IAED,OAAO,CAAC,YAAY;IAWpB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAI/B;;;;;;;;OAQG;IACH,kBAAkB,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,OAAO;yCA3HxC,kBAAkB;2CAAlB,kBAAkB;CAiI9B"}
|