@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
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { EventEmitter, OnInit, OnDestroy, ChangeDetectorRef, ElementRef, NgZone } from '@angular/core';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
/** Display mode for the slide panel container. */
|
|
4
|
+
export type SlidePanelMode = 'slide' | 'dialog';
|
|
5
|
+
/**
|
|
6
|
+
* Generic slide-in / centered-dialog panel primitive.
|
|
7
|
+
*
|
|
8
|
+
* - `Mode='slide'` → slides in from the right edge, full viewport height, optionally resizable.
|
|
9
|
+
* - `Mode='dialog'` → centered modal card.
|
|
10
|
+
*
|
|
11
|
+
* Pure chrome: it owns the backdrop, open/close animation, resize handle, optional
|
|
12
|
+
* title bar, and content projection. It performs no data work and has no routing.
|
|
13
|
+
* Consumers project their content and handle Save/close via the projected UI and the
|
|
14
|
+
* `Closed` output.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```html
|
|
18
|
+
* <mj-slide-panel [Visible]="open" Title="Details" (Closed)="open = false">
|
|
19
|
+
* <my-content></my-content>
|
|
20
|
+
* </mj-slide-panel>
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export declare class MjSlidePanelComponent implements OnInit, OnDestroy {
|
|
24
|
+
private cdr;
|
|
25
|
+
private ngZone;
|
|
26
|
+
private elRef;
|
|
27
|
+
Mode: SlidePanelMode;
|
|
28
|
+
Title: string;
|
|
29
|
+
set Visible(value: boolean);
|
|
30
|
+
get Visible(): boolean;
|
|
31
|
+
private _visible;
|
|
32
|
+
private initialized;
|
|
33
|
+
Resizable: boolean;
|
|
34
|
+
MinWidthPx: number;
|
|
35
|
+
MaxWidthRatio: number;
|
|
36
|
+
/** Initial width in pixels. Defaults to 65% of viewport for slide, 800px for dialog. */
|
|
37
|
+
set WidthPx(value: number);
|
|
38
|
+
get WidthPx(): number;
|
|
39
|
+
Closed: EventEmitter<void>;
|
|
40
|
+
WidthChanged: EventEmitter<number>;
|
|
41
|
+
/**
|
|
42
|
+
* Optional guard called before any close gesture (X button, backdrop click, Escape).
|
|
43
|
+
* Return `false` to cancel the close — e.g., when an in-progress operation is running.
|
|
44
|
+
* The panel itself never shows a dialog; the consumer is responsible for any confirmation UI.
|
|
45
|
+
*/
|
|
46
|
+
CanClose: (() => boolean) | null;
|
|
47
|
+
IsVisible: boolean;
|
|
48
|
+
private _widthPx;
|
|
49
|
+
private isResizing;
|
|
50
|
+
private boundOnResizeMove;
|
|
51
|
+
private boundOnResizeEnd;
|
|
52
|
+
constructor(cdr: ChangeDetectorRef, ngZone: NgZone, elRef: ElementRef);
|
|
53
|
+
ngOnInit(): void;
|
|
54
|
+
ngOnDestroy(): void;
|
|
55
|
+
OnEscapeKey(): void;
|
|
56
|
+
OnClose(): void;
|
|
57
|
+
OnBackdropClick(): void;
|
|
58
|
+
OnResizeStart(event: MouseEvent): void;
|
|
59
|
+
private onResizeMove;
|
|
60
|
+
private onResizeEnd;
|
|
61
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<MjSlidePanelComponent, never>;
|
|
62
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<MjSlidePanelComponent, "mj-slide-panel", never, { "Mode": { "alias": "Mode"; "required": false; }; "Title": { "alias": "Title"; "required": false; }; "Visible": { "alias": "Visible"; "required": false; }; "Resizable": { "alias": "Resizable"; "required": false; }; "MinWidthPx": { "alias": "MinWidthPx"; "required": false; }; "MaxWidthRatio": { "alias": "MaxWidthRatio"; "required": false; }; "WidthPx": { "alias": "WidthPx"; "required": false; }; "CanClose": { "alias": "CanClose"; "required": false; }; }, { "Closed": "Closed"; "WidthChanged": "WidthChanged"; }, never, ["*", "[dialog-content]"], true, never>;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=slide-panel.component.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slide-panel.component.d.ts","sourceRoot":"","sources":["../../../src/lib/slide-panel/slide-panel.component.ts"],"names":[],"mappings":"AAAA,OAAO,EACqB,YAAY,EAAE,MAAM,EAAE,SAAS,EACzD,iBAAiB,EAAyC,UAAU,EAAE,MAAM,EAC7E,MAAM,eAAe,CAAC;;AAEvB,kDAAkD;AAClD,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEhD;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAOa,qBAAsB,YAAW,MAAM,EAAE,SAAS;IAyD3D,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,KAAK;IA1DN,IAAI,EAAE,cAAc,CAAW;IAC/B,KAAK,SAAM;IACpB,IACI,OAAO,CAAC,KAAK,EAAE,OAAO,EAezB;IACD,IAAI,OAAO,IAAI,OAAO,CAErB;IACD,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,WAAW,CAAS;IAEnB,SAAS,UAAQ;IACjB,UAAU,SAAO;IACjB,aAAa,SAAQ;IAE9B,wFAAwF;IACxF,IACI,OAAO,CAAC,KAAK,EAAE,MAAM,EAExB;IACD,IAAI,OAAO,IAAI,MAAM,CAEpB;IAES,MAAM,qBAA4B;IAClC,YAAY,uBAA8B;IAEpD;;;;OAIG;IACM,QAAQ,EAAE,CAAC,MAAM,OAAO,CAAC,GAAG,IAAI,CAAQ;IAE1C,SAAS,UAAS;IACzB,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,UAAU,CAAS;IAE3B,OAAO,CAAC,iBAAiB,CAAgC;IACzD,OAAO,CAAC,gBAAgB,CAA+B;gBAG7C,GAAG,EAAE,iBAAiB,EACtB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,UAAU;IAG3B,QAAQ,IAAI,IAAI;IAkBhB,WAAW,IAAI,IAAI;IAMZ,WAAW,IAAI,IAAI;IAInB,OAAO,IAAI,IAAI;IASf,eAAe,IAAI,IAAI;IAQvB,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAa7C,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,WAAW;yCAhIR,qBAAqB;2CAArB,qBAAqB;CAyIjC"}
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy, HostListener } from '@angular/core';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
const _c0 = ["*", [["", "dialog-content", ""]]];
|
|
4
|
+
const _c1 = ["*", "[dialog-content]"];
|
|
5
|
+
function MjSlidePanelComponent_Conditional_1_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
6
|
+
const _r1 = i0.ɵɵgetCurrentView();
|
|
7
|
+
i0.ɵɵdomElementStart(0, "div", 7);
|
|
8
|
+
i0.ɵɵdomListener("mousedown", function MjSlidePanelComponent_Conditional_1_Conditional_1_Template_div_mousedown_0_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnResizeStart($event)); });
|
|
9
|
+
i0.ɵɵdomElement(1, "div", 8);
|
|
10
|
+
i0.ɵɵdomElementEnd();
|
|
11
|
+
} }
|
|
12
|
+
function MjSlidePanelComponent_Conditional_1_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
13
|
+
const _r3 = i0.ɵɵgetCurrentView();
|
|
14
|
+
i0.ɵɵdomElementStart(0, "div", 5)(1, "h2", 9);
|
|
15
|
+
i0.ɵɵtext(2);
|
|
16
|
+
i0.ɵɵdomElementEnd();
|
|
17
|
+
i0.ɵɵdomElementStart(3, "button", 10);
|
|
18
|
+
i0.ɵɵdomListener("click", function MjSlidePanelComponent_Conditional_1_Conditional_2_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnClose()); });
|
|
19
|
+
i0.ɵɵdomElement(4, "i", 11);
|
|
20
|
+
i0.ɵɵdomElementEnd()();
|
|
21
|
+
} if (rf & 2) {
|
|
22
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
23
|
+
i0.ɵɵadvance(2);
|
|
24
|
+
i0.ɵɵtextInterpolate(ctx_r1.Title);
|
|
25
|
+
} }
|
|
26
|
+
function MjSlidePanelComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
27
|
+
i0.ɵɵdomElementStart(0, "div", 3);
|
|
28
|
+
i0.ɵɵconditionalCreate(1, MjSlidePanelComponent_Conditional_1_Conditional_1_Template, 2, 0, "div", 4);
|
|
29
|
+
i0.ɵɵconditionalCreate(2, MjSlidePanelComponent_Conditional_1_Conditional_2_Template, 5, 1, "div", 5);
|
|
30
|
+
i0.ɵɵdomElementStart(3, "div", 6);
|
|
31
|
+
i0.ɵɵprojection(4);
|
|
32
|
+
i0.ɵɵdomElementEnd()();
|
|
33
|
+
} if (rf & 2) {
|
|
34
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
35
|
+
i0.ɵɵstyleProp("width", ctx_r1.WidthPx, "px")("max-width", ctx_r1.MaxWidthRatio * 100 + "vw");
|
|
36
|
+
i0.ɵɵclassProp("visible", ctx_r1.IsVisible);
|
|
37
|
+
i0.ɵɵadvance();
|
|
38
|
+
i0.ɵɵconditional(ctx_r1.Resizable ? 1 : -1);
|
|
39
|
+
i0.ɵɵadvance();
|
|
40
|
+
i0.ɵɵconditional(ctx_r1.Title ? 2 : -1);
|
|
41
|
+
} }
|
|
42
|
+
function MjSlidePanelComponent_Conditional_2_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
43
|
+
const _r4 = i0.ɵɵgetCurrentView();
|
|
44
|
+
i0.ɵɵdomElementStart(0, "div", 5)(1, "h2", 9);
|
|
45
|
+
i0.ɵɵtext(2);
|
|
46
|
+
i0.ɵɵdomElementEnd();
|
|
47
|
+
i0.ɵɵdomElementStart(3, "button", 10);
|
|
48
|
+
i0.ɵɵdomListener("click", function MjSlidePanelComponent_Conditional_2_Conditional_1_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnClose()); });
|
|
49
|
+
i0.ɵɵdomElement(4, "i", 11);
|
|
50
|
+
i0.ɵɵdomElementEnd()();
|
|
51
|
+
} if (rf & 2) {
|
|
52
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
53
|
+
i0.ɵɵadvance(2);
|
|
54
|
+
i0.ɵɵtextInterpolate(ctx_r1.Title);
|
|
55
|
+
} }
|
|
56
|
+
function MjSlidePanelComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
57
|
+
i0.ɵɵdomElementStart(0, "div", 12);
|
|
58
|
+
i0.ɵɵconditionalCreate(1, MjSlidePanelComponent_Conditional_2_Conditional_1_Template, 5, 1, "div", 5);
|
|
59
|
+
i0.ɵɵdomElementStart(2, "div", 13);
|
|
60
|
+
i0.ɵɵprojection(3, 1);
|
|
61
|
+
i0.ɵɵdomElementEnd()();
|
|
62
|
+
} if (rf & 2) {
|
|
63
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
64
|
+
i0.ɵɵstyleProp("width", ctx_r1.WidthPx, "px");
|
|
65
|
+
i0.ɵɵclassProp("visible", ctx_r1.IsVisible);
|
|
66
|
+
i0.ɵɵadvance();
|
|
67
|
+
i0.ɵɵconditional(ctx_r1.Title ? 1 : -1);
|
|
68
|
+
} }
|
|
69
|
+
/**
|
|
70
|
+
* Generic slide-in / centered-dialog panel primitive.
|
|
71
|
+
*
|
|
72
|
+
* - `Mode='slide'` → slides in from the right edge, full viewport height, optionally resizable.
|
|
73
|
+
* - `Mode='dialog'` → centered modal card.
|
|
74
|
+
*
|
|
75
|
+
* Pure chrome: it owns the backdrop, open/close animation, resize handle, optional
|
|
76
|
+
* title bar, and content projection. It performs no data work and has no routing.
|
|
77
|
+
* Consumers project their content and handle Save/close via the projected UI and the
|
|
78
|
+
* `Closed` output.
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```html
|
|
82
|
+
* <mj-slide-panel [Visible]="open" Title="Details" (Closed)="open = false">
|
|
83
|
+
* <my-content></my-content>
|
|
84
|
+
* </mj-slide-panel>
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
export class MjSlidePanelComponent {
|
|
88
|
+
cdr;
|
|
89
|
+
ngZone;
|
|
90
|
+
elRef;
|
|
91
|
+
Mode = 'slide';
|
|
92
|
+
Title = '';
|
|
93
|
+
set Visible(value) {
|
|
94
|
+
const changed = this._visible !== value;
|
|
95
|
+
this._visible = value;
|
|
96
|
+
if (changed && this.initialized) {
|
|
97
|
+
if (value) {
|
|
98
|
+
// Opening: animate in on next microtask
|
|
99
|
+
Promise.resolve().then(() => {
|
|
100
|
+
this.IsVisible = true;
|
|
101
|
+
this.cdr.markForCheck();
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
this.IsVisible = false;
|
|
106
|
+
this.cdr.markForCheck();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
get Visible() {
|
|
111
|
+
return this._visible;
|
|
112
|
+
}
|
|
113
|
+
_visible = true;
|
|
114
|
+
initialized = false;
|
|
115
|
+
Resizable = true;
|
|
116
|
+
MinWidthPx = 400;
|
|
117
|
+
MaxWidthRatio = 0.92;
|
|
118
|
+
/** Initial width in pixels. Defaults to 65% of viewport for slide, 800px for dialog. */
|
|
119
|
+
set WidthPx(value) {
|
|
120
|
+
this._widthPx = value;
|
|
121
|
+
}
|
|
122
|
+
get WidthPx() {
|
|
123
|
+
return this._widthPx;
|
|
124
|
+
}
|
|
125
|
+
Closed = new EventEmitter();
|
|
126
|
+
WidthChanged = new EventEmitter();
|
|
127
|
+
/**
|
|
128
|
+
* Optional guard called before any close gesture (X button, backdrop click, Escape).
|
|
129
|
+
* Return `false` to cancel the close — e.g., when an in-progress operation is running.
|
|
130
|
+
* The panel itself never shows a dialog; the consumer is responsible for any confirmation UI.
|
|
131
|
+
*/
|
|
132
|
+
CanClose = null;
|
|
133
|
+
IsVisible = false;
|
|
134
|
+
_widthPx = 0;
|
|
135
|
+
isResizing = false;
|
|
136
|
+
boundOnResizeMove = this.onResizeMove.bind(this);
|
|
137
|
+
boundOnResizeEnd = this.onResizeEnd.bind(this);
|
|
138
|
+
constructor(cdr, ngZone, elRef) {
|
|
139
|
+
this.cdr = cdr;
|
|
140
|
+
this.ngZone = ngZone;
|
|
141
|
+
this.elRef = elRef;
|
|
142
|
+
}
|
|
143
|
+
ngOnInit() {
|
|
144
|
+
if (this._widthPx === 0) {
|
|
145
|
+
this._widthPx = this.Mode === 'dialog'
|
|
146
|
+
? 800
|
|
147
|
+
: Math.max(this.MinWidthPx, Math.min(window.innerWidth * 0.65, 1000));
|
|
148
|
+
}
|
|
149
|
+
this.initialized = true;
|
|
150
|
+
// Animate in on next microtask if initially visible
|
|
151
|
+
if (this._visible) {
|
|
152
|
+
Promise.resolve().then(() => {
|
|
153
|
+
this.IsVisible = true;
|
|
154
|
+
this.cdr.markForCheck();
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
ngOnDestroy() {
|
|
159
|
+
document.removeEventListener('mousemove', this.boundOnResizeMove);
|
|
160
|
+
document.removeEventListener('mouseup', this.boundOnResizeEnd);
|
|
161
|
+
}
|
|
162
|
+
OnEscapeKey() {
|
|
163
|
+
this.OnClose();
|
|
164
|
+
}
|
|
165
|
+
OnClose() {
|
|
166
|
+
if (this.CanClose && !this.CanClose())
|
|
167
|
+
return;
|
|
168
|
+
this.IsVisible = false;
|
|
169
|
+
this._visible = false;
|
|
170
|
+
this.cdr.markForCheck();
|
|
171
|
+
// Wait for CSS transition to complete
|
|
172
|
+
setTimeout(() => this.Closed.emit(), 300);
|
|
173
|
+
}
|
|
174
|
+
OnBackdropClick() {
|
|
175
|
+
this.OnClose();
|
|
176
|
+
}
|
|
177
|
+
// =========================================================================
|
|
178
|
+
// Resize
|
|
179
|
+
// =========================================================================
|
|
180
|
+
OnResizeStart(event) {
|
|
181
|
+
if (!this.Resizable || this.Mode === 'dialog')
|
|
182
|
+
return;
|
|
183
|
+
event.preventDefault();
|
|
184
|
+
this.isResizing = true;
|
|
185
|
+
document.body.style.cursor = 'col-resize';
|
|
186
|
+
document.body.style.userSelect = 'none';
|
|
187
|
+
this.ngZone.runOutsideAngular(() => {
|
|
188
|
+
document.addEventListener('mousemove', this.boundOnResizeMove);
|
|
189
|
+
document.addEventListener('mouseup', this.boundOnResizeEnd);
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
onResizeMove(event) {
|
|
193
|
+
if (!this.isResizing)
|
|
194
|
+
return;
|
|
195
|
+
const viewportWidth = window.innerWidth;
|
|
196
|
+
const maxWidth = viewportWidth * this.MaxWidthRatio;
|
|
197
|
+
this._widthPx = Math.max(this.MinWidthPx, Math.min(maxWidth, viewportWidth - event.clientX));
|
|
198
|
+
this.ngZone.run(() => this.cdr.markForCheck());
|
|
199
|
+
}
|
|
200
|
+
onResizeEnd() {
|
|
201
|
+
if (!this.isResizing)
|
|
202
|
+
return;
|
|
203
|
+
this.isResizing = false;
|
|
204
|
+
document.body.style.cursor = '';
|
|
205
|
+
document.body.style.userSelect = '';
|
|
206
|
+
document.removeEventListener('mousemove', this.boundOnResizeMove);
|
|
207
|
+
document.removeEventListener('mouseup', this.boundOnResizeEnd);
|
|
208
|
+
this.WidthChanged.emit(this._widthPx);
|
|
209
|
+
}
|
|
210
|
+
static ɵfac = function MjSlidePanelComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || MjSlidePanelComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i0.NgZone), i0.ɵɵdirectiveInject(i0.ElementRef)); };
|
|
211
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MjSlidePanelComponent, selectors: [["mj-slide-panel"]], hostBindings: function MjSlidePanelComponent_HostBindings(rf, ctx) { if (rf & 1) {
|
|
212
|
+
i0.ɵɵlistener("keydown.escape", function MjSlidePanelComponent_keydown_escape_HostBindingHandler() { return ctx.OnEscapeKey(); }, i0.ɵɵresolveDocument);
|
|
213
|
+
} }, inputs: { Mode: "Mode", Title: "Title", Visible: "Visible", Resizable: "Resizable", MinWidthPx: "MinWidthPx", MaxWidthRatio: "MaxWidthRatio", WidthPx: "WidthPx", CanClose: "CanClose" }, outputs: { Closed: "Closed", WidthChanged: "WidthChanged" }, ngContentSelectors: _c1, decls: 3, vars: 6, consts: [[1, "sp-backdrop", 3, "click"], [1, "sp-panel", 3, "visible", "width", "max-width"], [1, "sp-dialog", 3, "visible", "width"], [1, "sp-panel"], [1, "sp-resize-handle"], [1, "sp-header"], [1, "sp-body"], [1, "sp-resize-handle", 3, "mousedown"], [1, "sp-resize-grip"], [1, "sp-title"], [1, "sp-close-btn", 3, "click"], [1, "fa-solid", "fa-xmark"], [1, "sp-dialog"], [1, "sp-body", "sp-dialog-body"]], template: function MjSlidePanelComponent_Template(rf, ctx) { if (rf & 1) {
|
|
214
|
+
i0.ɵɵprojectionDef(_c0);
|
|
215
|
+
i0.ɵɵdomElementStart(0, "div", 0);
|
|
216
|
+
i0.ɵɵdomListener("click", function MjSlidePanelComponent_Template_div_click_0_listener() { return ctx.OnBackdropClick(); });
|
|
217
|
+
i0.ɵɵdomElementEnd();
|
|
218
|
+
i0.ɵɵconditionalCreate(1, MjSlidePanelComponent_Conditional_1_Template, 5, 8, "div", 1);
|
|
219
|
+
i0.ɵɵconditionalCreate(2, MjSlidePanelComponent_Conditional_2_Template, 4, 5, "div", 2);
|
|
220
|
+
} if (rf & 2) {
|
|
221
|
+
i0.ɵɵclassProp("visible", ctx.IsVisible)("sp-dialog-backdrop", ctx.Mode === "dialog");
|
|
222
|
+
i0.ɵɵadvance();
|
|
223
|
+
i0.ɵɵconditional(ctx.Mode === "slide" ? 1 : -1);
|
|
224
|
+
i0.ɵɵadvance();
|
|
225
|
+
i0.ɵɵconditional(ctx.Mode === "dialog" ? 2 : -1);
|
|
226
|
+
} }, styles: ["\n\n\n\n\n\n\n.sp-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n inset: 0;\n background: transparent;\n z-index: 1000;\n transition: background 0.3s ease;\n pointer-events: none;\n}\n\n.sp-backdrop.visible[_ngcontent-%COMP%] {\n background: var(--mj-bg-overlay);\n pointer-events: auto;\n}\n\n.sp-dialog-backdrop.visible[_ngcontent-%COMP%] {\n background: var(--mj-bg-overlay);\n}\n\n\n\n\n\n\n\n\n.sp-panel[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n right: 0;\n height: 100vh;\n background: var(--mj-bg-surface);\n box-shadow: var(--mj-shadow-lg);\n z-index: 1001;\n display: flex;\n flex-direction: column;\n transform: translateX(100%);\n transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1);\n min-width: 400px;\n max-width: 92vw;\n}\n\n.sp-panel.visible[_ngcontent-%COMP%] {\n transform: translateX(0);\n}\n\n\n\n\n\n\n\n\n.sp-dialog[_ngcontent-%COMP%] {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%) scale(0.95);\n max-height: 85vh;\n background: var(--mj-bg-surface);\n border-radius: 16px;\n box-shadow: var(--mj-shadow-lg);\n z-index: 1001;\n display: flex;\n flex-direction: column;\n opacity: 0;\n transition: opacity 0.25s ease, transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);\n min-width: 360px;\n max-width: 95vw;\n}\n\n.sp-dialog.visible[_ngcontent-%COMP%] {\n opacity: 1;\n transform: translate(-50%, -50%) scale(1);\n}\n\n\n\n\n\n\n\n\n.sp-resize-handle[_ngcontent-%COMP%] {\n position: absolute;\n left: -4px;\n top: 0;\n width: 8px;\n height: 100%;\n cursor: col-resize;\n z-index: 10;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.sp-resize-handle[_ngcontent-%COMP%]:hover .sp-resize-grip[_ngcontent-%COMP%], \n.sp-resize-handle[_ngcontent-%COMP%]:active .sp-resize-grip[_ngcontent-%COMP%] {\n opacity: 1;\n background: var(--mj-brand-primary);\n}\n\n.sp-resize-grip[_ngcontent-%COMP%] {\n width: 3px;\n height: 40px;\n background: var(--mj-border-strong);\n border-radius: 3px;\n opacity: 0;\n transition: opacity 0.2s ease, background 0.2s ease;\n}\n\n.sp-resize-handle[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 4%, transparent);\n}\n\n\n\n\n\n\n\n\n.sp-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 24px;\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.sp-title[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n flex: 1;\n}\n\n.sp-close-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n background: none;\n border: none;\n border-radius: 8px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.15s ease;\n font-size: 16px;\n flex-shrink: 0;\n}\n\n.sp-close-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n\n\n\n\n\n\n\n.sp-body[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n}\n\n.sp-dialog-body[_ngcontent-%COMP%] {\n padding: 0;\n}\n\n\n\n\n\n\n\n\n@media (max-width: 768px) {\n .sp-panel[_ngcontent-%COMP%] {\n width: 100% !important;\n min-width: unset;\n }\n\n .sp-resize-handle[_ngcontent-%COMP%] {\n display: none;\n }\n\n .sp-dialog[_ngcontent-%COMP%] {\n width: 95vw !important;\n max-height: 90vh;\n }\n}"], changeDetection: 0 });
|
|
227
|
+
}
|
|
228
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MjSlidePanelComponent, [{
|
|
229
|
+
type: Component,
|
|
230
|
+
args: [{ standalone: true, selector: 'mj-slide-panel', changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Backdrop overlay -->\n<div class=\"sp-backdrop\"\n [class.visible]=\"IsVisible\"\n [class.sp-dialog-backdrop]=\"Mode === 'dialog'\"\n (click)=\"OnBackdropClick()\">\n</div>\n\n<!-- Panel (slide-in from right) -->\n@if (Mode === 'slide') {\n <div\n class=\"sp-panel\"\n [class.visible]=\"IsVisible\"\n [style.width.px]=\"WidthPx\"\n [style.max-width]=\"(MaxWidthRatio * 100) + 'vw'\">\n <!-- Resize handle -->\n @if (Resizable) {\n <div class=\"sp-resize-handle\" (mousedown)=\"OnResizeStart($event)\">\n <div class=\"sp-resize-grip\"></div>\n </div>\n }\n <!-- Header (if Title provided) -->\n @if (Title) {\n <div class=\"sp-header\">\n <h2 class=\"sp-title\">{{Title}}</h2>\n <button class=\"sp-close-btn\" (click)=\"OnClose()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n }\n <!-- Content projection -->\n <div class=\"sp-body\">\n <ng-content></ng-content>\n </div>\n </div>\n}\n\n<!-- Dialog (centered modal) -->\n@if (Mode === 'dialog') {\n <div\n class=\"sp-dialog\"\n [class.visible]=\"IsVisible\"\n [style.width.px]=\"WidthPx\">\n <!-- Header (if Title provided) -->\n @if (Title) {\n <div class=\"sp-header\">\n <h2 class=\"sp-title\">{{Title}}</h2>\n <button class=\"sp-close-btn\" (click)=\"OnClose()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n }\n <!-- Content projection -->\n <div class=\"sp-body sp-dialog-body\">\n <ng-content select=\"[dialog-content]\"></ng-content>\n </div>\n </div>\n}\n", styles: ["/* ================================================================= */\n/* BACKDROP */\n/* ================================================================= */\n\n.sp-backdrop {\n position: fixed;\n inset: 0;\n background: transparent;\n z-index: 1000;\n transition: background 0.3s ease;\n pointer-events: none;\n}\n\n.sp-backdrop.visible {\n background: var(--mj-bg-overlay);\n pointer-events: auto;\n}\n\n.sp-dialog-backdrop.visible {\n background: var(--mj-bg-overlay);\n}\n\n/* ================================================================= */\n/* SLIDE PANEL */\n/* ================================================================= */\n\n.sp-panel {\n position: fixed;\n top: 0;\n right: 0;\n height: 100vh;\n background: var(--mj-bg-surface);\n box-shadow: var(--mj-shadow-lg);\n z-index: 1001;\n display: flex;\n flex-direction: column;\n transform: translateX(100%);\n transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1);\n min-width: 400px;\n max-width: 92vw;\n}\n\n.sp-panel.visible {\n transform: translateX(0);\n}\n\n/* ================================================================= */\n/* DIALOG (centered modal) */\n/* ================================================================= */\n\n.sp-dialog {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%) scale(0.95);\n max-height: 85vh;\n background: var(--mj-bg-surface);\n border-radius: 16px;\n box-shadow: var(--mj-shadow-lg);\n z-index: 1001;\n display: flex;\n flex-direction: column;\n opacity: 0;\n transition: opacity 0.25s ease, transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);\n min-width: 360px;\n max-width: 95vw;\n}\n\n.sp-dialog.visible {\n opacity: 1;\n transform: translate(-50%, -50%) scale(1);\n}\n\n/* ================================================================= */\n/* RESIZE HANDLE */\n/* ================================================================= */\n\n.sp-resize-handle {\n position: absolute;\n left: -4px;\n top: 0;\n width: 8px;\n height: 100%;\n cursor: col-resize;\n z-index: 10;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.sp-resize-handle:hover .sp-resize-grip,\n.sp-resize-handle:active .sp-resize-grip {\n opacity: 1;\n background: var(--mj-brand-primary);\n}\n\n.sp-resize-grip {\n width: 3px;\n height: 40px;\n background: var(--mj-border-strong);\n border-radius: 3px;\n opacity: 0;\n transition: opacity 0.2s ease, background 0.2s ease;\n}\n\n.sp-resize-handle:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 4%, transparent);\n}\n\n/* ================================================================= */\n/* HEADER */\n/* ================================================================= */\n\n.sp-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 24px;\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.sp-title {\n font-size: 18px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n flex: 1;\n}\n\n.sp-close-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n background: none;\n border: none;\n border-radius: 8px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.15s ease;\n font-size: 16px;\n flex-shrink: 0;\n}\n\n.sp-close-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n/* ================================================================= */\n/* BODY */\n/* ================================================================= */\n\n.sp-body {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n}\n\n.sp-dialog-body {\n padding: 0;\n}\n\n/* ================================================================= */\n/* RESPONSIVE */\n/* ================================================================= */\n\n@media (max-width: 768px) {\n .sp-panel {\n width: 100% !important;\n min-width: unset;\n }\n\n .sp-resize-handle {\n display: none;\n }\n\n .sp-dialog {\n width: 95vw !important;\n max-height: 90vh;\n }\n}\n"] }]
|
|
231
|
+
}], () => [{ type: i0.ChangeDetectorRef }, { type: i0.NgZone }, { type: i0.ElementRef }], { Mode: [{
|
|
232
|
+
type: Input
|
|
233
|
+
}], Title: [{
|
|
234
|
+
type: Input
|
|
235
|
+
}], Visible: [{
|
|
236
|
+
type: Input
|
|
237
|
+
}], Resizable: [{
|
|
238
|
+
type: Input
|
|
239
|
+
}], MinWidthPx: [{
|
|
240
|
+
type: Input
|
|
241
|
+
}], MaxWidthRatio: [{
|
|
242
|
+
type: Input
|
|
243
|
+
}], WidthPx: [{
|
|
244
|
+
type: Input
|
|
245
|
+
}], Closed: [{
|
|
246
|
+
type: Output
|
|
247
|
+
}], WidthChanged: [{
|
|
248
|
+
type: Output
|
|
249
|
+
}], CanClose: [{
|
|
250
|
+
type: Input
|
|
251
|
+
}], OnEscapeKey: [{
|
|
252
|
+
type: HostListener,
|
|
253
|
+
args: ['document:keydown.escape']
|
|
254
|
+
}] }); })();
|
|
255
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MjSlidePanelComponent, { className: "MjSlidePanelComponent", filePath: "lib/slide-panel/slide-panel.component.ts", lineNumber: 34 }); })();
|
|
256
|
+
//# sourceMappingURL=slide-panel.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slide-panel.component.js","sourceRoot":"","sources":["../../../src/lib/slide-panel/slide-panel.component.ts","../../../src/lib/slide-panel/slide-panel.component.html"],"names":[],"mappings":"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","sourcesContent":["import {\n Component, Input, Output, EventEmitter, OnInit, OnDestroy,\n ChangeDetectorRef, ChangeDetectionStrategy, HostListener, ElementRef, NgZone\n} from '@angular/core';\n\n/** Display mode for the slide panel container. */\nexport type SlidePanelMode = 'slide' | 'dialog';\n\n/**\n * Generic slide-in / centered-dialog panel primitive.\n *\n * - `Mode='slide'` → slides in from the right edge, full viewport height, optionally resizable.\n * - `Mode='dialog'` → centered modal card.\n *\n * Pure chrome: it owns the backdrop, open/close animation, resize handle, optional\n * title bar, and content projection. It performs no data work and has no routing.\n * Consumers project their content and handle Save/close via the projected UI and the\n * `Closed` output.\n *\n * @example\n * ```html\n * <mj-slide-panel [Visible]=\"open\" Title=\"Details\" (Closed)=\"open = false\">\n * <my-content></my-content>\n * </mj-slide-panel>\n * ```\n */\n@Component({\n standalone: true,\n selector: 'mj-slide-panel',\n templateUrl: './slide-panel.component.html',\n styleUrls: ['./slide-panel.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class MjSlidePanelComponent implements OnInit, OnDestroy {\n @Input() Mode: SlidePanelMode = 'slide';\n @Input() Title = '';\n @Input()\n set Visible(value: boolean) {\n const changed = this._visible !== value;\n this._visible = value;\n if (changed && this.initialized) {\n if (value) {\n // Opening: animate in on next microtask\n Promise.resolve().then(() => {\n this.IsVisible = true;\n this.cdr.markForCheck();\n });\n } else {\n this.IsVisible = false;\n this.cdr.markForCheck();\n }\n }\n }\n get Visible(): boolean {\n return this._visible;\n }\n private _visible = true;\n private initialized = false;\n\n @Input() Resizable = true;\n @Input() MinWidthPx = 400;\n @Input() MaxWidthRatio = 0.92;\n\n /** Initial width in pixels. Defaults to 65% of viewport for slide, 800px for dialog. */\n @Input()\n set WidthPx(value: number) {\n this._widthPx = value;\n }\n get WidthPx(): number {\n return this._widthPx;\n }\n\n @Output() Closed = new EventEmitter<void>();\n @Output() WidthChanged = new EventEmitter<number>();\n\n /**\n * Optional guard called before any close gesture (X button, backdrop click, Escape).\n * Return `false` to cancel the close — e.g., when an in-progress operation is running.\n * The panel itself never shows a dialog; the consumer is responsible for any confirmation UI.\n */\n @Input() CanClose: (() => boolean) | null = null;\n\n public IsVisible = false;\n private _widthPx = 0;\n private isResizing = false;\n\n private boundOnResizeMove = this.onResizeMove.bind(this);\n private boundOnResizeEnd = this.onResizeEnd.bind(this);\n\n constructor(\n private cdr: ChangeDetectorRef,\n private ngZone: NgZone,\n private elRef: ElementRef\n ) {}\n\n ngOnInit(): void {\n if (this._widthPx === 0) {\n this._widthPx = this.Mode === 'dialog'\n ? 800\n : Math.max(this.MinWidthPx, Math.min(window.innerWidth * 0.65, 1000));\n }\n\n this.initialized = true;\n\n // Animate in on next microtask if initially visible\n if (this._visible) {\n Promise.resolve().then(() => {\n this.IsVisible = true;\n this.cdr.markForCheck();\n });\n }\n }\n\n ngOnDestroy(): void {\n document.removeEventListener('mousemove', this.boundOnResizeMove);\n document.removeEventListener('mouseup', this.boundOnResizeEnd);\n }\n\n @HostListener('document:keydown.escape')\n public OnEscapeKey(): void {\n this.OnClose();\n }\n\n public OnClose(): void {\n if (this.CanClose && !this.CanClose()) return;\n this.IsVisible = false;\n this._visible = false;\n this.cdr.markForCheck();\n // Wait for CSS transition to complete\n setTimeout(() => this.Closed.emit(), 300);\n }\n\n public OnBackdropClick(): void {\n this.OnClose();\n }\n\n // =========================================================================\n // Resize\n // =========================================================================\n\n public OnResizeStart(event: MouseEvent): void {\n if (!this.Resizable || this.Mode === 'dialog') return;\n event.preventDefault();\n this.isResizing = true;\n document.body.style.cursor = 'col-resize';\n document.body.style.userSelect = 'none';\n\n this.ngZone.runOutsideAngular(() => {\n document.addEventListener('mousemove', this.boundOnResizeMove);\n document.addEventListener('mouseup', this.boundOnResizeEnd);\n });\n }\n\n private onResizeMove(event: MouseEvent): void {\n if (!this.isResizing) return;\n const viewportWidth = window.innerWidth;\n const maxWidth = viewportWidth * this.MaxWidthRatio;\n this._widthPx = Math.max(this.MinWidthPx, Math.min(maxWidth, viewportWidth - event.clientX));\n this.ngZone.run(() => this.cdr.markForCheck());\n }\n\n private onResizeEnd(): void {\n if (!this.isResizing) return;\n this.isResizing = false;\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n document.removeEventListener('mousemove', this.boundOnResizeMove);\n document.removeEventListener('mouseup', this.boundOnResizeEnd);\n this.WidthChanged.emit(this._widthPx);\n }\n}\n","<!-- Backdrop overlay -->\n<div class=\"sp-backdrop\"\n [class.visible]=\"IsVisible\"\n [class.sp-dialog-backdrop]=\"Mode === 'dialog'\"\n (click)=\"OnBackdropClick()\">\n</div>\n\n<!-- Panel (slide-in from right) -->\n@if (Mode === 'slide') {\n <div\n class=\"sp-panel\"\n [class.visible]=\"IsVisible\"\n [style.width.px]=\"WidthPx\"\n [style.max-width]=\"(MaxWidthRatio * 100) + 'vw'\">\n <!-- Resize handle -->\n @if (Resizable) {\n <div class=\"sp-resize-handle\" (mousedown)=\"OnResizeStart($event)\">\n <div class=\"sp-resize-grip\"></div>\n </div>\n }\n <!-- Header (if Title provided) -->\n @if (Title) {\n <div class=\"sp-header\">\n <h2 class=\"sp-title\">{{Title}}</h2>\n <button class=\"sp-close-btn\" (click)=\"OnClose()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n }\n <!-- Content projection -->\n <div class=\"sp-body\">\n <ng-content></ng-content>\n </div>\n </div>\n}\n\n<!-- Dialog (centered modal) -->\n@if (Mode === 'dialog') {\n <div\n class=\"sp-dialog\"\n [class.visible]=\"IsVisible\"\n [style.width.px]=\"WidthPx\">\n <!-- Header (if Title provided) -->\n @if (Title) {\n <div class=\"sp-header\">\n <h2 class=\"sp-title\">{{Title}}</h2>\n <button class=\"sp-close-btn\" (click)=\"OnClose()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n }\n <!-- Content projection -->\n <div class=\"sp-body sp-dialog-body\">\n <ng-content select=\"[dialog-content]\"></ng-content>\n </div>\n </div>\n}\n"]}
|
package/dist/public-api.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ export * from './lib/datepicker/datepicker.component';
|
|
|
10
10
|
export * from './lib/splitter/splitter.component';
|
|
11
11
|
export * from './lib/accordion/accordion.component';
|
|
12
12
|
export * from './lib/window/window.component';
|
|
13
|
+
export * from './lib/slide-panel/slide-panel.component';
|
|
13
14
|
export * from './lib/combobox/combobox.component';
|
|
14
15
|
export * from './lib/page-header/page-header.component';
|
|
15
16
|
export * from './lib/page-layout/page-layout.component';
|
package/dist/public-api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public-api.d.ts","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAGA,cAAc,+BAA+B,CAAC;AAC9C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,mCAAmC,CAAC;AAClD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6CAA6C,CAAC;AAC5D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,+BAA+B,CAAC;AAC9C,cAAc,uCAAuC,CAAC;AACtD,cAAc,mCAAmC,CAAC;AAClD,cAAc,qCAAqC,CAAC;AACpD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,mCAAmC,CAAC;AAClD,cAAc,yCAAyC,CAAC;AACxD,cAAc,yCAAyC,CAAC;AACxD,cAAc,qCAAqC,CAAC;AACpD,cAAc,uCAAuC,CAAC;AACtD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,+CAA+C,CAAC;AAC9D,cAAc,yCAAyC,CAAC;AACxD,cAAc,yCAAyC,CAAC;AACxD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,iCAAiC,CAAC;AAChD,cAAc,yCAAyC,CAAC;AACxD,cAAc,mCAAmC,CAAC;AAClD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,2DAA2D,CAAC;AAC1E,cAAc,uDAAuD,CAAC"}
|
|
1
|
+
{"version":3,"file":"public-api.d.ts","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAGA,cAAc,+BAA+B,CAAC;AAC9C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,mCAAmC,CAAC;AAClD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6CAA6C,CAAC;AAC5D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,+BAA+B,CAAC;AAC9C,cAAc,uCAAuC,CAAC;AACtD,cAAc,mCAAmC,CAAC;AAClD,cAAc,qCAAqC,CAAC;AACpD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,yCAAyC,CAAC;AACxD,cAAc,mCAAmC,CAAC;AAClD,cAAc,yCAAyC,CAAC;AACxD,cAAc,yCAAyC,CAAC;AACxD,cAAc,qCAAqC,CAAC;AACpD,cAAc,uCAAuC,CAAC;AACtD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,+CAA+C,CAAC;AAC9D,cAAc,yCAAyC,CAAC;AACxD,cAAc,yCAAyC,CAAC;AACxD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,iCAAiC,CAAC;AAChD,cAAc,yCAAyC,CAAC;AACxD,cAAc,mCAAmC,CAAC;AAClD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,2DAA2D,CAAC;AAC1E,cAAc,uDAAuD,CAAC"}
|
package/dist/public-api.js
CHANGED
|
@@ -12,6 +12,7 @@ export * from './lib/datepicker/datepicker.component';
|
|
|
12
12
|
export * from './lib/splitter/splitter.component';
|
|
13
13
|
export * from './lib/accordion/accordion.component';
|
|
14
14
|
export * from './lib/window/window.component';
|
|
15
|
+
export * from './lib/slide-panel/slide-panel.component';
|
|
15
16
|
export * from './lib/combobox/combobox.component';
|
|
16
17
|
export * from './lib/page-header/page-header.component';
|
|
17
18
|
export * from './lib/page-layout/page-layout.component';
|
package/dist/public-api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public-api.js","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,+DAA+D;AAE/D,cAAc,+BAA+B,CAAC;AAC9C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,mCAAmC,CAAC;AAClD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6CAA6C,CAAC;AAC5D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,+BAA+B,CAAC;AAC9C,cAAc,uCAAuC,CAAC;AACtD,cAAc,mCAAmC,CAAC;AAClD,cAAc,qCAAqC,CAAC;AACpD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,mCAAmC,CAAC;AAClD,cAAc,yCAAyC,CAAC;AACxD,cAAc,yCAAyC,CAAC;AACxD,cAAc,qCAAqC,CAAC;AACpD,cAAc,uCAAuC,CAAC;AACtD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,+CAA+C,CAAC;AAC9D,cAAc,yCAAyC,CAAC;AACxD,cAAc,yCAAyC,CAAC;AACxD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,iCAAiC,CAAC;AAChD,cAAc,yCAAyC,CAAC;AACxD,cAAc,mCAAmC,CAAC;AAClD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,2DAA2D,CAAC;AAC1E,cAAc,uDAAuD,CAAC","sourcesContent":["// @memberjunction/ng-ui-components\n// Reusable standalone Angular UI components for MemberJunction\n\nexport * from './lib/button/button.directive';\nexport * from './lib/dialog/dialog.component';\nexport * from './lib/dialog/dialog.service';\nexport * from './lib/dropdown/dropdown.component';\nexport * from './lib/switch/switch.component';\nexport * from './lib/numeric-input/numeric-input.component';\nexport * from './lib/progress-bar/progress-bar.component';\nexport * from './lib/calendar/calendar-utils';\nexport * from './lib/datepicker/datepicker.component';\nexport * from './lib/splitter/splitter.component';\nexport * from './lib/accordion/accordion.component';\nexport * from './lib/window/window.component';\nexport * from './lib/combobox/combobox.component';\nexport * from './lib/page-header/page-header.component';\nexport * from './lib/page-layout/page-layout.component';\nexport * from './lib/page-body/page-body.component';\nexport * from './lib/stat-badge/stat-badge.component';\nexport * from './lib/refresh-button/refresh-button.component';\nexport * from './lib/filter-popover/filter-popover.component';\nexport * from './lib/page-search/page-search.component';\nexport * from './lib/filter-chip/filter-chip.component';\nexport * from './lib/filter-field/filter-field.component';\nexport * from './lib/filter-panel/filter-panel.component';\nexport * from './lib/tab-nav/tab-nav.component';\nexport * from './lib/view-toggle/view-toggle.component';\nexport * from './lib/left-nav/left-nav.component';\nexport * from './lib/left-nav/left-nav-content.component';\nexport * from './lib/page-header-interior/page-header-interior.component';\nexport * from './lib/page-body-interior/page-body-interior.component';\n"]}
|
|
1
|
+
{"version":3,"file":"public-api.js","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,+DAA+D;AAE/D,cAAc,+BAA+B,CAAC;AAC9C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,mCAAmC,CAAC;AAClD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6CAA6C,CAAC;AAC5D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,+BAA+B,CAAC;AAC9C,cAAc,uCAAuC,CAAC;AACtD,cAAc,mCAAmC,CAAC;AAClD,cAAc,qCAAqC,CAAC;AACpD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,yCAAyC,CAAC;AACxD,cAAc,mCAAmC,CAAC;AAClD,cAAc,yCAAyC,CAAC;AACxD,cAAc,yCAAyC,CAAC;AACxD,cAAc,qCAAqC,CAAC;AACpD,cAAc,uCAAuC,CAAC;AACtD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,+CAA+C,CAAC;AAC9D,cAAc,yCAAyC,CAAC;AACxD,cAAc,yCAAyC,CAAC;AACxD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,iCAAiC,CAAC;AAChD,cAAc,yCAAyC,CAAC;AACxD,cAAc,mCAAmC,CAAC;AAClD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,2DAA2D,CAAC;AAC1E,cAAc,uDAAuD,CAAC","sourcesContent":["// @memberjunction/ng-ui-components\n// Reusable standalone Angular UI components for MemberJunction\n\nexport * from './lib/button/button.directive';\nexport * from './lib/dialog/dialog.component';\nexport * from './lib/dialog/dialog.service';\nexport * from './lib/dropdown/dropdown.component';\nexport * from './lib/switch/switch.component';\nexport * from './lib/numeric-input/numeric-input.component';\nexport * from './lib/progress-bar/progress-bar.component';\nexport * from './lib/calendar/calendar-utils';\nexport * from './lib/datepicker/datepicker.component';\nexport * from './lib/splitter/splitter.component';\nexport * from './lib/accordion/accordion.component';\nexport * from './lib/window/window.component';\nexport * from './lib/slide-panel/slide-panel.component';\nexport * from './lib/combobox/combobox.component';\nexport * from './lib/page-header/page-header.component';\nexport * from './lib/page-layout/page-layout.component';\nexport * from './lib/page-body/page-body.component';\nexport * from './lib/stat-badge/stat-badge.component';\nexport * from './lib/refresh-button/refresh-button.component';\nexport * from './lib/filter-popover/filter-popover.component';\nexport * from './lib/page-search/page-search.component';\nexport * from './lib/filter-chip/filter-chip.component';\nexport * from './lib/filter-field/filter-field.component';\nexport * from './lib/filter-panel/filter-panel.component';\nexport * from './lib/tab-nav/tab-nav.component';\nexport * from './lib/view-toggle/view-toggle.component';\nexport * from './lib/left-nav/left-nav.component';\nexport * from './lib/left-nav/left-nav-content.component';\nexport * from './lib/page-header-interior/page-header-interior.component';\nexport * from './lib/page-body-interior/page-body-interior.component';\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/ng-ui-components",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.40.0",
|
|
4
4
|
"description": "MemberJunction: Angular UI Components - reusable standalone components replacing Kendo UI dependencies.",
|
|
5
5
|
"main": "./dist/public-api.js",
|
|
6
6
|
"typings": "./dist/public-api.d.ts",
|