@memberjunction/ng-ui-components 5.43.0 → 5.45.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/accordion/accordion.component.d.ts +137 -2
- package/dist/lib/accordion/accordion.component.d.ts.map +1 -1
- package/dist/lib/accordion/accordion.component.js +300 -43
- package/dist/lib/accordion/accordion.component.js.map +1 -1
- package/dist/lib/accordion/accordion.scss +256 -13
- package/dist/lib/alert/alert.component.d.ts +97 -0
- package/dist/lib/alert/alert.component.d.ts.map +1 -0
- package/dist/lib/alert/alert.component.js +235 -0
- package/dist/lib/alert/alert.component.js.map +1 -0
- package/dist/lib/confirm-dialog/confirm-dialog.component.d.ts +102 -0
- package/dist/lib/confirm-dialog/confirm-dialog.component.d.ts.map +1 -0
- package/dist/lib/confirm-dialog/confirm-dialog.component.js +259 -0
- package/dist/lib/confirm-dialog/confirm-dialog.component.js.map +1 -0
- package/dist/lib/confirm-dialog/confirm-dialog.service.d.ts +78 -0
- package/dist/lib/confirm-dialog/confirm-dialog.service.d.ts.map +1 -0
- package/dist/lib/confirm-dialog/confirm-dialog.service.js +125 -0
- package/dist/lib/confirm-dialog/confirm-dialog.service.js.map +1 -0
- package/dist/lib/dialog/dialog.component.d.ts +8 -1
- package/dist/lib/dialog/dialog.component.d.ts.map +1 -1
- package/dist/lib/dialog/dialog.component.js +15 -6
- package/dist/lib/dialog/dialog.component.js.map +1 -1
- package/dist/lib/empty-state/empty-state.component.d.ts +114 -0
- package/dist/lib/empty-state/empty-state.component.d.ts.map +1 -0
- package/dist/lib/empty-state/empty-state.component.js +268 -0
- package/dist/lib/empty-state/empty-state.component.js.map +1 -0
- package/dist/lib/slide-panel/slide-panel.component.js +2 -2
- package/dist/public-api.d.ts +4 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +4 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +2 -2
|
@@ -21,6 +21,55 @@ export declare class MJAccordionTitleDirective {
|
|
|
21
21
|
static ɵfac: i0.ɵɵFactoryDeclaration<MJAccordionTitleDirective, never>;
|
|
22
22
|
static ɵdir: i0.ɵɵDirectiveDeclaration<MJAccordionTitleDirective, "[mjAccordionTitle]", never, {}, {}, never, never, true, never>;
|
|
23
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Directive to mark a template as the accordion header **actions** — interactive
|
|
26
|
+
* controls (edit / copy / run / checkbox, etc.) that sit in the header row but
|
|
27
|
+
* are NOT the expand/collapse toggle. Rendered as a sibling of the toggle
|
|
28
|
+
* `<button>`, so there's no button-in-button and the toggle stays a clean,
|
|
29
|
+
* accessible control.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```html
|
|
33
|
+
* <mj-accordion-panel>
|
|
34
|
+
* <ng-template mjAccordionTitle>Connection</ng-template>
|
|
35
|
+
* <ng-template mjAccordionActions>
|
|
36
|
+
* <button mjButton variant="icon" (click)="edit()"><i class="fa fa-pen"></i></button>
|
|
37
|
+
* </ng-template>
|
|
38
|
+
* …body…
|
|
39
|
+
* </mj-accordion-panel>
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export declare class MJAccordionActionsDirective {
|
|
43
|
+
templateRef: TemplateRef<unknown>;
|
|
44
|
+
constructor(templateRef: TemplateRef<unknown>);
|
|
45
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<MJAccordionActionsDirective, never>;
|
|
46
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<MJAccordionActionsDirective, "[mjAccordionActions]", never, {}, {}, never, never, true, never>;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Directive to mark a template as the accordion **body** — the panel's collapsible
|
|
50
|
+
* content. Use this INSTEAD of placing content directly in the panel when the body
|
|
51
|
+
* may be expensive (code editors, grids, large lists) OR just to be future-proof:
|
|
52
|
+
* the accordion instantiates the template **lazily on first expand** and then keeps
|
|
53
|
+
* it alive, so nothing is created until the user opens the panel, while later
|
|
54
|
+
* open/close still animates. Consumers never have to reason about content weight or
|
|
55
|
+
* write `@if (expanded)` themselves.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```html
|
|
59
|
+
* <mj-accordion-panel [Expanded]="open" (ExpandedChange)="open = $event">
|
|
60
|
+
* <ng-template mjAccordionTitle>Configuration</ng-template>
|
|
61
|
+
* <ng-template mjAccordionBody>
|
|
62
|
+
* <mj-code-editor ...></mj-code-editor> <!-- not created until first opened -->
|
|
63
|
+
* </ng-template>
|
|
64
|
+
* </mj-accordion-panel>
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
export declare class MJAccordionBodyDirective {
|
|
68
|
+
templateRef: TemplateRef<unknown>;
|
|
69
|
+
constructor(templateRef: TemplateRef<unknown>);
|
|
70
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<MJAccordionBodyDirective, never>;
|
|
71
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<MJAccordionBodyDirective, "[mjAccordionBody]", never, {}, {}, never, never, true, never>;
|
|
72
|
+
}
|
|
24
73
|
/**
|
|
25
74
|
* mj-accordion-panel — Collapsible panel. Replaces `<kendo-panelbar-item>` and `<kendo-expansionpanel>`.
|
|
26
75
|
*
|
|
@@ -46,13 +95,99 @@ export declare class MJAccordionTitleDirective {
|
|
|
46
95
|
*/
|
|
47
96
|
export declare class MJAccordionPanelComponent {
|
|
48
97
|
Title: string;
|
|
49
|
-
|
|
98
|
+
private _expanded;
|
|
99
|
+
/** Latches true the first time the panel is expanded; never resets. Lets a
|
|
100
|
+
* [mjAccordionBody] template instantiate lazily on first open and then stay
|
|
101
|
+
* alive so subsequent open/close still animates. */
|
|
102
|
+
private _everExpanded;
|
|
103
|
+
set Expanded(value: boolean);
|
|
104
|
+
get Expanded(): boolean;
|
|
105
|
+
protected get hasBeenExpanded(): boolean;
|
|
50
106
|
Disabled: boolean;
|
|
107
|
+
/**
|
|
108
|
+
* Emphasis variant for visual hierarchy:
|
|
109
|
+
* - `primary` — bold, solid brand-colored header (use to make a panel stand out)
|
|
110
|
+
* - `secondary` — subtle brand tint
|
|
111
|
+
* - `default` — standard neutral header
|
|
112
|
+
* All brand-token-driven, so dark-mode-safe and themeable.
|
|
113
|
+
*/
|
|
114
|
+
Variant: 'default' | 'primary' | 'secondary';
|
|
115
|
+
/**
|
|
116
|
+
* Render icons projected into the title slot in the muted color instead of the
|
|
117
|
+
* header's primary text color. Lets consumers get the common "quiet icon" look
|
|
118
|
+
* without writing CSS. Status/brand-colored icons can still be colored inline.
|
|
119
|
+
*/
|
|
120
|
+
TitleIconMuted: boolean;
|
|
121
|
+
/**
|
|
122
|
+
* Density. `md` (default) is the standard size; `sm` tightens header padding and
|
|
123
|
+
* font for dense contexts (sidebars, flyouts, nested panels).
|
|
124
|
+
*/
|
|
125
|
+
Size: 'sm' | 'md';
|
|
126
|
+
/**
|
|
127
|
+
* Bare chrome — drop the panel's own border and header background so the panel
|
|
128
|
+
* sits cleanly inside a host that already provides chrome (e.g. an expandable
|
|
129
|
+
* card). The toggle/title/chevron/body still work; only the box styling is removed.
|
|
130
|
+
*/
|
|
131
|
+
Bare: boolean;
|
|
132
|
+
/**
|
|
133
|
+
* Remove the body's default padding, for bodies that manage their own spacing
|
|
134
|
+
* (code editors, full-bleed grids, custom forms).
|
|
135
|
+
*/
|
|
136
|
+
FlushBody: boolean;
|
|
137
|
+
/**
|
|
138
|
+
* Fill mode — for "rail section that owns the leftover height" cases (e.g. an
|
|
139
|
+
* entity tree or grid that should consume all remaining vertical space and
|
|
140
|
+
* scroll *internally*), rather than the default "reveal stacked content"
|
|
141
|
+
* disclosure. When set AND expanded, the panel becomes a flex column that
|
|
142
|
+
* fills its flex parent and its body becomes a `flex:1; min-height:0` region —
|
|
143
|
+
* the projected content is expected to provide its own scroll child. While
|
|
144
|
+
* collapsed, the panel behaves exactly like a normal panel (header only,
|
|
145
|
+
* natural height) and does NOT claim the leftover space.
|
|
146
|
+
*
|
|
147
|
+
* Requires the panel's parent to be a flex column with `min-height:0`.
|
|
148
|
+
* Note: the open/close height animation is skipped in fill mode (the body
|
|
149
|
+
* fills rather than animating to content height).
|
|
150
|
+
*/
|
|
151
|
+
Fill: boolean;
|
|
51
152
|
ExpandedChange: EventEmitter<boolean>;
|
|
52
153
|
titleTemplate: MJAccordionTitleDirective | null;
|
|
154
|
+
actionsTemplate: MJAccordionActionsDirective | null;
|
|
155
|
+
bodyTemplate: MJAccordionBodyDirective | null;
|
|
53
156
|
readonly hostClass = true;
|
|
157
|
+
/** Host claims flex:1 of its parent ONLY while a Fill panel is expanded —
|
|
158
|
+
* so a collapsed Fill panel sits at natural (header) height like any other. */
|
|
159
|
+
get fillActive(): boolean;
|
|
160
|
+
/** Stable per-instance ids that programmatically associate the header
|
|
161
|
+
* `<button>` with its body region (`aria-controls` ↔ `aria-labelledby`),
|
|
162
|
+
* completing the WAI-ARIA accordion pattern so screen readers announce the
|
|
163
|
+
* region with the header's name. */
|
|
164
|
+
private readonly _uid;
|
|
165
|
+
readonly HeaderId: string;
|
|
166
|
+
readonly BodyId: string;
|
|
54
167
|
Toggle(): void;
|
|
55
168
|
static ɵfac: i0.ɵɵFactoryDeclaration<MJAccordionPanelComponent, never>;
|
|
56
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<MJAccordionPanelComponent, "mj-accordion-panel", never, { "Title": { "alias": "Title"; "required": false; }; "Expanded": { "alias": "Expanded"; "required": false; }; "Disabled": { "alias": "Disabled"; "required": false; }; }, { "ExpandedChange": "ExpandedChange"; }, ["titleTemplate"], ["*"], true, never>;
|
|
169
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<MJAccordionPanelComponent, "mj-accordion-panel", never, { "Title": { "alias": "Title"; "required": false; }; "Expanded": { "alias": "Expanded"; "required": false; }; "Disabled": { "alias": "Disabled"; "required": false; }; "Variant": { "alias": "Variant"; "required": false; }; "TitleIconMuted": { "alias": "TitleIconMuted"; "required": false; }; "Size": { "alias": "Size"; "required": false; }; "Bare": { "alias": "Bare"; "required": false; }; "FlushBody": { "alias": "FlushBody"; "required": false; }; "Fill": { "alias": "Fill"; "required": false; }; }, { "ExpandedChange": "ExpandedChange"; }, ["titleTemplate", "actionsTemplate", "bodyTemplate"], ["*"], true, never>;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Convenience module bundling the accordion panel + all of its slot directives.
|
|
173
|
+
* Import this ONE symbol instead of listing the component and each directive
|
|
174
|
+
* separately:
|
|
175
|
+
*
|
|
176
|
+
* ```ts
|
|
177
|
+
* import { MJAccordionModule } from '@memberjunction/ng-ui-components';
|
|
178
|
+
* @NgModule({ imports: [MJAccordionModule, ...] }) // or @Component standalone imports
|
|
179
|
+
* ```
|
|
180
|
+
*
|
|
181
|
+
* Why a module (not a bare `const [...]` array): Angular's AOT compiler can't
|
|
182
|
+
* statically expand a value-array imported across a compiled-package boundary in
|
|
183
|
+
* an `imports` array (NG1010), and `as const` makes it a readonly tuple the
|
|
184
|
+
* `imports` type rejects (TS2322). An NgModule is always a valid `imports` entry
|
|
185
|
+
* in both NgModule and standalone consumers. Adding a future accordion directive
|
|
186
|
+
* here makes it available to every consumer automatically — no per-module churn.
|
|
187
|
+
*/
|
|
188
|
+
export declare class MJAccordionModule {
|
|
189
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<MJAccordionModule, never>;
|
|
190
|
+
static ɵmod: i0.ɵɵNgModuleDeclaration<MJAccordionModule, never, [typeof MJAccordionPanelComponent, typeof MJAccordionTitleDirective, typeof MJAccordionActionsDirective, typeof MJAccordionBodyDirective], [typeof MJAccordionPanelComponent, typeof MJAccordionTitleDirective, typeof MJAccordionActionsDirective, typeof MJAccordionBodyDirective]>;
|
|
191
|
+
static ɵinj: i0.ɵɵInjectorDeclaration<MJAccordionModule>;
|
|
57
192
|
}
|
|
58
193
|
//# sourceMappingURL=accordion.component.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accordion.component.d.ts","sourceRoot":"","sources":["../../../src/lib/accordion/accordion.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAA6B,WAAW,
|
|
1
|
+
{"version":3,"file":"accordion.component.d.ts","sourceRoot":"","sources":["../../../src/lib/accordion/accordion.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAA6B,WAAW,EAAuB,MAAM,eAAe,CAAC;;AAOpI;;;;;;;;;;;;;;GAcG;AACH,qBAIa,yBAAyB;IACjB,WAAW,EAAE,WAAW,CAAC,OAAO,CAAC;gBAAjC,WAAW,EAAE,WAAW,CAAC,OAAO,CAAC;yCADzC,yBAAyB;2CAAzB,yBAAyB;CAErC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAIa,2BAA2B;IACnB,WAAW,EAAE,WAAW,CAAC,OAAO,CAAC;gBAAjC,WAAW,EAAE,WAAW,CAAC,OAAO,CAAC;yCADzC,2BAA2B;2CAA3B,2BAA2B;CAEvC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAIa,wBAAwB;IAChB,WAAW,EAAE,WAAW,CAAC,OAAO,CAAC;gBAAjC,WAAW,EAAE,WAAW,CAAC,OAAO,CAAC;yCADzC,wBAAwB;2CAAxB,wBAAwB;CAEpC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAwDa,yBAAyB;IAC3B,KAAK,SAAM;IACpB,OAAO,CAAC,SAAS,CAAS;IAC1B;;yDAEqD;IACrD,OAAO,CAAC,aAAa,CAAS;IAC9B,IACI,QAAQ,CAAC,KAAK,EAAE,OAAO,EAG1B;IACD,IAAI,QAAQ,IAAI,OAAO,CAA2B;IAClD,SAAS,KAAK,eAAe,IAAI,OAAO,CAA+B;IAC9D,QAAQ,UAAS;IAC1B;;;;;;OAMG;IACM,OAAO,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,CAAa;IAClE;;;;OAIG;IACM,cAAc,UAAS;IAChC;;;OAGG;IACM,IAAI,EAAE,IAAI,GAAG,IAAI,CAAQ;IAClC;;;;OAIG;IACM,IAAI,UAAS;IACtB;;;OAGG;IACM,SAAS,UAAS;IAC3B;;;;;;;;;;;;;OAaG;IACM,IAAI,UAAS;IACZ,cAAc,wBAA+B;IACd,aAAa,EAAE,yBAAyB,GAAG,IAAI,CAAQ;IACrD,eAAe,EAAE,2BAA2B,GAAG,IAAI,CAAQ;IAC9D,YAAY,EAAE,wBAAwB,GAAG,IAAI,CAAQ;IAC/C,QAAQ,CAAC,SAAS,QAAQ;IACxE;oFACgF;IAChF,IAAmD,UAAU,IAAI,OAAO,CAEvE;IAED;;;yCAGqC;IACrC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAsB;IAC3C,QAAQ,CAAC,QAAQ,SAAsC;IACvD,QAAQ,CAAC,MAAM,SAAoC;IAEnD,MAAM,IAAI,IAAI;yCA/EH,yBAAyB;2CAAzB,yBAAyB;CAoFrC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAca,iBAAiB;yCAAjB,iBAAiB;0CAAjB,iBAAiB,iBArHjB,yBAAyB,SAxIzB,yBAAyB,SA0BzB,2BAA2B,SA2B3B,wBAAwB,WAmFxB,yBAAyB,SAxIzB,yBAAyB,SA0BzB,2BAA2B,SA2B3B,wBAAwB;0CAwMxB,iBAAiB;CAAG"}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { Component, Input, Output, EventEmitter, HostBinding, ContentChild, Directive } from '@angular/core';
|
|
1
|
+
import { Component, Input, Output, EventEmitter, HostBinding, ContentChild, Directive, NgModule } from '@angular/core';
|
|
2
2
|
import { NgTemplateOutlet } from '@angular/common';
|
|
3
3
|
import * as i0 from "@angular/core";
|
|
4
4
|
const _c0 = ["*"];
|
|
5
|
-
function
|
|
6
|
-
i0.ɵɵelementContainer(0,
|
|
5
|
+
function MJAccordionPanelComponent_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
6
|
+
i0.ɵɵelementContainer(0, 4);
|
|
7
7
|
} if (rf & 2) {
|
|
8
8
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
9
9
|
i0.ɵɵproperty("ngTemplateOutlet", ctx_r0.titleTemplate.templateRef);
|
|
10
10
|
} }
|
|
11
|
-
function
|
|
11
|
+
function MJAccordionPanelComponent_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
12
12
|
i0.ɵɵtext(0);
|
|
13
13
|
} if (rf & 2) {
|
|
14
14
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
@@ -16,9 +16,22 @@ function MJAccordionPanelComponent_Conditional_4_Template(rf, ctx) { if (rf & 1)
|
|
|
16
16
|
} }
|
|
17
17
|
function MJAccordionPanelComponent_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
18
18
|
i0.ɵɵelementStart(0, "div", 5);
|
|
19
|
-
i0.ɵɵ
|
|
19
|
+
i0.ɵɵelementContainer(1, 4);
|
|
20
20
|
i0.ɵɵelementEnd();
|
|
21
|
+
} if (rf & 2) {
|
|
22
|
+
const ctx_r0 = i0.ɵɵnextContext();
|
|
23
|
+
i0.ɵɵadvance();
|
|
24
|
+
i0.ɵɵproperty("ngTemplateOutlet", ctx_r0.actionsTemplate.templateRef);
|
|
21
25
|
} }
|
|
26
|
+
function MJAccordionPanelComponent_Conditional_13_Template(rf, ctx) { if (rf & 1) {
|
|
27
|
+
i0.ɵɵelementContainer(0, 4);
|
|
28
|
+
} if (rf & 2) {
|
|
29
|
+
const ctx_r0 = i0.ɵɵnextContext();
|
|
30
|
+
i0.ɵɵproperty("ngTemplateOutlet", ctx_r0.bodyTemplate.templateRef);
|
|
31
|
+
} }
|
|
32
|
+
/** Process-wide counter for generating unique, stable accordion element ids
|
|
33
|
+
* (used to wire `aria-controls` / `aria-labelledby` between header and body). */
|
|
34
|
+
let nextAccordionUid = 0;
|
|
22
35
|
/**
|
|
23
36
|
* Directive to mark a template as the accordion panel title.
|
|
24
37
|
* Supports rich HTML content (icons, badges, dynamic text).
|
|
@@ -49,6 +62,73 @@ export class MJAccordionTitleDirective {
|
|
|
49
62
|
standalone: true
|
|
50
63
|
}]
|
|
51
64
|
}], () => [{ type: i0.TemplateRef }], null); })();
|
|
65
|
+
/**
|
|
66
|
+
* Directive to mark a template as the accordion header **actions** — interactive
|
|
67
|
+
* controls (edit / copy / run / checkbox, etc.) that sit in the header row but
|
|
68
|
+
* are NOT the expand/collapse toggle. Rendered as a sibling of the toggle
|
|
69
|
+
* `<button>`, so there's no button-in-button and the toggle stays a clean,
|
|
70
|
+
* accessible control.
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```html
|
|
74
|
+
* <mj-accordion-panel>
|
|
75
|
+
* <ng-template mjAccordionTitle>Connection</ng-template>
|
|
76
|
+
* <ng-template mjAccordionActions>
|
|
77
|
+
* <button mjButton variant="icon" (click)="edit()"><i class="fa fa-pen"></i></button>
|
|
78
|
+
* </ng-template>
|
|
79
|
+
* …body…
|
|
80
|
+
* </mj-accordion-panel>
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
export class MJAccordionActionsDirective {
|
|
84
|
+
templateRef;
|
|
85
|
+
constructor(templateRef) {
|
|
86
|
+
this.templateRef = templateRef;
|
|
87
|
+
}
|
|
88
|
+
static ɵfac = function MJAccordionActionsDirective_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || MJAccordionActionsDirective)(i0.ɵɵdirectiveInject(i0.TemplateRef)); };
|
|
89
|
+
static ɵdir = /*@__PURE__*/ i0.ɵɵdefineDirective({ type: MJAccordionActionsDirective, selectors: [["", "mjAccordionActions", ""]] });
|
|
90
|
+
}
|
|
91
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJAccordionActionsDirective, [{
|
|
92
|
+
type: Directive,
|
|
93
|
+
args: [{
|
|
94
|
+
selector: '[mjAccordionActions]',
|
|
95
|
+
standalone: true
|
|
96
|
+
}]
|
|
97
|
+
}], () => [{ type: i0.TemplateRef }], null); })();
|
|
98
|
+
/**
|
|
99
|
+
* Directive to mark a template as the accordion **body** — the panel's collapsible
|
|
100
|
+
* content. Use this INSTEAD of placing content directly in the panel when the body
|
|
101
|
+
* may be expensive (code editors, grids, large lists) OR just to be future-proof:
|
|
102
|
+
* the accordion instantiates the template **lazily on first expand** and then keeps
|
|
103
|
+
* it alive, so nothing is created until the user opens the panel, while later
|
|
104
|
+
* open/close still animates. Consumers never have to reason about content weight or
|
|
105
|
+
* write `@if (expanded)` themselves.
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* ```html
|
|
109
|
+
* <mj-accordion-panel [Expanded]="open" (ExpandedChange)="open = $event">
|
|
110
|
+
* <ng-template mjAccordionTitle>Configuration</ng-template>
|
|
111
|
+
* <ng-template mjAccordionBody>
|
|
112
|
+
* <mj-code-editor ...></mj-code-editor> <!-- not created until first opened -->
|
|
113
|
+
* </ng-template>
|
|
114
|
+
* </mj-accordion-panel>
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
export class MJAccordionBodyDirective {
|
|
118
|
+
templateRef;
|
|
119
|
+
constructor(templateRef) {
|
|
120
|
+
this.templateRef = templateRef;
|
|
121
|
+
}
|
|
122
|
+
static ɵfac = function MJAccordionBodyDirective_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || MJAccordionBodyDirective)(i0.ɵɵdirectiveInject(i0.TemplateRef)); };
|
|
123
|
+
static ɵdir = /*@__PURE__*/ i0.ɵɵdefineDirective({ type: MJAccordionBodyDirective, selectors: [["", "mjAccordionBody", ""]] });
|
|
124
|
+
}
|
|
125
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJAccordionBodyDirective, [{
|
|
126
|
+
type: Directive,
|
|
127
|
+
args: [{
|
|
128
|
+
selector: '[mjAccordionBody]',
|
|
129
|
+
standalone: true
|
|
130
|
+
}]
|
|
131
|
+
}], () => [{ type: i0.TemplateRef }], null); })();
|
|
52
132
|
/**
|
|
53
133
|
* mj-accordion-panel — Collapsible panel. Replaces `<kendo-panelbar-item>` and `<kendo-expansionpanel>`.
|
|
54
134
|
*
|
|
@@ -74,11 +154,81 @@ export class MJAccordionTitleDirective {
|
|
|
74
154
|
*/
|
|
75
155
|
export class MJAccordionPanelComponent {
|
|
76
156
|
Title = '';
|
|
77
|
-
|
|
157
|
+
_expanded = false;
|
|
158
|
+
/** Latches true the first time the panel is expanded; never resets. Lets a
|
|
159
|
+
* [mjAccordionBody] template instantiate lazily on first open and then stay
|
|
160
|
+
* alive so subsequent open/close still animates. */
|
|
161
|
+
_everExpanded = false;
|
|
162
|
+
set Expanded(value) {
|
|
163
|
+
this._expanded = value;
|
|
164
|
+
if (value)
|
|
165
|
+
this._everExpanded = true;
|
|
166
|
+
}
|
|
167
|
+
get Expanded() { return this._expanded; }
|
|
168
|
+
get hasBeenExpanded() { return this._everExpanded; }
|
|
78
169
|
Disabled = false;
|
|
170
|
+
/**
|
|
171
|
+
* Emphasis variant for visual hierarchy:
|
|
172
|
+
* - `primary` — bold, solid brand-colored header (use to make a panel stand out)
|
|
173
|
+
* - `secondary` — subtle brand tint
|
|
174
|
+
* - `default` — standard neutral header
|
|
175
|
+
* All brand-token-driven, so dark-mode-safe and themeable.
|
|
176
|
+
*/
|
|
177
|
+
Variant = 'default';
|
|
178
|
+
/**
|
|
179
|
+
* Render icons projected into the title slot in the muted color instead of the
|
|
180
|
+
* header's primary text color. Lets consumers get the common "quiet icon" look
|
|
181
|
+
* without writing CSS. Status/brand-colored icons can still be colored inline.
|
|
182
|
+
*/
|
|
183
|
+
TitleIconMuted = false;
|
|
184
|
+
/**
|
|
185
|
+
* Density. `md` (default) is the standard size; `sm` tightens header padding and
|
|
186
|
+
* font for dense contexts (sidebars, flyouts, nested panels).
|
|
187
|
+
*/
|
|
188
|
+
Size = 'md';
|
|
189
|
+
/**
|
|
190
|
+
* Bare chrome — drop the panel's own border and header background so the panel
|
|
191
|
+
* sits cleanly inside a host that already provides chrome (e.g. an expandable
|
|
192
|
+
* card). The toggle/title/chevron/body still work; only the box styling is removed.
|
|
193
|
+
*/
|
|
194
|
+
Bare = false;
|
|
195
|
+
/**
|
|
196
|
+
* Remove the body's default padding, for bodies that manage their own spacing
|
|
197
|
+
* (code editors, full-bleed grids, custom forms).
|
|
198
|
+
*/
|
|
199
|
+
FlushBody = false;
|
|
200
|
+
/**
|
|
201
|
+
* Fill mode — for "rail section that owns the leftover height" cases (e.g. an
|
|
202
|
+
* entity tree or grid that should consume all remaining vertical space and
|
|
203
|
+
* scroll *internally*), rather than the default "reveal stacked content"
|
|
204
|
+
* disclosure. When set AND expanded, the panel becomes a flex column that
|
|
205
|
+
* fills its flex parent and its body becomes a `flex:1; min-height:0` region —
|
|
206
|
+
* the projected content is expected to provide its own scroll child. While
|
|
207
|
+
* collapsed, the panel behaves exactly like a normal panel (header only,
|
|
208
|
+
* natural height) and does NOT claim the leftover space.
|
|
209
|
+
*
|
|
210
|
+
* Requires the panel's parent to be a flex column with `min-height:0`.
|
|
211
|
+
* Note: the open/close height animation is skipped in fill mode (the body
|
|
212
|
+
* fills rather than animating to content height).
|
|
213
|
+
*/
|
|
214
|
+
Fill = false;
|
|
79
215
|
ExpandedChange = new EventEmitter();
|
|
80
216
|
titleTemplate = null;
|
|
217
|
+
actionsTemplate = null;
|
|
218
|
+
bodyTemplate = null;
|
|
81
219
|
hostClass = true;
|
|
220
|
+
/** Host claims flex:1 of its parent ONLY while a Fill panel is expanded —
|
|
221
|
+
* so a collapsed Fill panel sits at natural (header) height like any other. */
|
|
222
|
+
get fillActive() {
|
|
223
|
+
return this.Fill && this.Expanded;
|
|
224
|
+
}
|
|
225
|
+
/** Stable per-instance ids that programmatically associate the header
|
|
226
|
+
* `<button>` with its body region (`aria-controls` ↔ `aria-labelledby`),
|
|
227
|
+
* completing the WAI-ARIA accordion pattern so screen readers announce the
|
|
228
|
+
* region with the header's name. */
|
|
229
|
+
_uid = nextAccordionUid++;
|
|
230
|
+
HeaderId = `mj-accordion-header-${this._uid}`;
|
|
231
|
+
BodyId = `mj-accordion-body-${this._uid}`;
|
|
82
232
|
Toggle() {
|
|
83
233
|
if (this.Disabled)
|
|
84
234
|
return;
|
|
@@ -87,32 +237,49 @@ export class MJAccordionPanelComponent {
|
|
|
87
237
|
}
|
|
88
238
|
static ɵfac = function MJAccordionPanelComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || MJAccordionPanelComponent)(); };
|
|
89
239
|
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MJAccordionPanelComponent, selectors: [["mj-accordion-panel"]], contentQueries: function MJAccordionPanelComponent_ContentQueries(rf, ctx, dirIndex) { if (rf & 1) {
|
|
90
|
-
i0.ɵɵcontentQuery(dirIndex, MJAccordionTitleDirective, 5);
|
|
240
|
+
i0.ɵɵcontentQuery(dirIndex, MJAccordionTitleDirective, 5)(dirIndex, MJAccordionActionsDirective, 5)(dirIndex, MJAccordionBodyDirective, 5);
|
|
91
241
|
} if (rf & 2) {
|
|
92
242
|
let _t;
|
|
93
243
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.titleTemplate = _t.first);
|
|
94
|
-
|
|
95
|
-
i0.ɵɵ
|
|
96
|
-
} },
|
|
244
|
+
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.actionsTemplate = _t.first);
|
|
245
|
+
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.bodyTemplate = _t.first);
|
|
246
|
+
} }, hostVars: 4, hostBindings: function MJAccordionPanelComponent_HostBindings(rf, ctx) { if (rf & 2) {
|
|
247
|
+
i0.ɵɵclassProp("mj-accordion-panel-host", ctx.hostClass)("mj-accordion-fill-active", ctx.fillActive);
|
|
248
|
+
} }, inputs: { Title: "Title", Expanded: "Expanded", Disabled: "Disabled", Variant: "Variant", TitleIconMuted: "TitleIconMuted", Size: "Size", Bare: "Bare", FlushBody: "FlushBody", Fill: "Fill" }, outputs: { ExpandedChange: "ExpandedChange" }, ngContentSelectors: _c0, decls: 14, vars: 26, consts: [[1, "mj-accordion-panel"], [1, "mj-accordion-header-row"], ["type", "button", 1, "mj-accordion-header", 3, "click", "id", "disabled"], [1, "mj-accordion-title"], [3, "ngTemplateOutlet"], [1, "mj-accordion-actions"], ["type", "button", "tabindex", "-1", "aria-hidden", "true", 1, "mj-accordion-chevron", 3, "click", "disabled"], [1, "fa-solid", "fa-chevron-down", "mj-accordion-icon"], [1, "mj-accordion-body-outer"], [1, "mj-accordion-body-clip"], ["role", "region", 1, "mj-accordion-body", 3, "id"]], template: function MJAccordionPanelComponent_Template(rf, ctx) { if (rf & 1) {
|
|
97
249
|
i0.ɵɵprojectionDef();
|
|
98
|
-
i0.ɵɵelementStart(0, "div", 0)(1, "
|
|
99
|
-
i0.ɵɵlistener("click", function
|
|
100
|
-
i0.ɵɵelementStart(
|
|
101
|
-
i0.ɵɵconditionalCreate(
|
|
102
|
-
i0.ɵɵelementEnd();
|
|
103
|
-
i0.ɵɵ
|
|
104
|
-
i0.ɵɵ
|
|
105
|
-
i0.ɵɵ
|
|
106
|
-
i0.ɵɵ
|
|
250
|
+
i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "button", 2);
|
|
251
|
+
i0.ɵɵlistener("click", function MJAccordionPanelComponent_Template_button_click_2_listener() { return ctx.Toggle(); });
|
|
252
|
+
i0.ɵɵelementStart(3, "span", 3);
|
|
253
|
+
i0.ɵɵconditionalCreate(4, MJAccordionPanelComponent_Conditional_4_Template, 1, 1, "ng-container", 4)(5, MJAccordionPanelComponent_Conditional_5_Template, 1, 1);
|
|
254
|
+
i0.ɵɵelementEnd()();
|
|
255
|
+
i0.ɵɵconditionalCreate(6, MJAccordionPanelComponent_Conditional_6_Template, 2, 1, "div", 5);
|
|
256
|
+
i0.ɵɵelementStart(7, "button", 6);
|
|
257
|
+
i0.ɵɵlistener("click", function MJAccordionPanelComponent_Template_button_click_7_listener() { return ctx.Toggle(); });
|
|
258
|
+
i0.ɵɵelement(8, "i", 7);
|
|
259
|
+
i0.ɵɵelementEnd()();
|
|
260
|
+
i0.ɵɵelementStart(9, "div", 8)(10, "div", 9)(11, "div", 10);
|
|
261
|
+
i0.ɵɵprojection(12);
|
|
262
|
+
i0.ɵɵconditionalCreate(13, MJAccordionPanelComponent_Conditional_13_Template, 1, 1, "ng-container", 4);
|
|
263
|
+
i0.ɵɵelementEnd()()()();
|
|
107
264
|
} if (rf & 2) {
|
|
108
|
-
i0.ɵɵclassProp("mj-accordion-panel--expanded", ctx.Expanded)("mj-accordion-panel--disabled", ctx.Disabled);
|
|
265
|
+
i0.ɵɵclassProp("mj-accordion-panel--expanded", ctx.Expanded)("mj-accordion-panel--disabled", ctx.Disabled)("mj-accordion-panel--muted-icon", ctx.TitleIconMuted)("mj-accordion-panel--sm", ctx.Size === "sm")("mj-accordion-panel--bare", ctx.Bare)("mj-accordion-panel--flush-body", ctx.FlushBody)("mj-accordion-panel--fill", ctx.Fill);
|
|
266
|
+
i0.ɵɵattribute("data-variant", ctx.Variant !== "default" ? ctx.Variant : null);
|
|
267
|
+
i0.ɵɵadvance(2);
|
|
268
|
+
i0.ɵɵproperty("id", ctx.HeaderId)("disabled", ctx.Disabled);
|
|
269
|
+
i0.ɵɵattribute("aria-expanded", ctx.Expanded)("aria-controls", ctx.BodyId);
|
|
270
|
+
i0.ɵɵadvance(2);
|
|
271
|
+
i0.ɵɵconditional(ctx.titleTemplate ? 4 : 5);
|
|
272
|
+
i0.ɵɵadvance(2);
|
|
273
|
+
i0.ɵɵconditional(ctx.actionsTemplate ? 6 : -1);
|
|
109
274
|
i0.ɵɵadvance();
|
|
110
275
|
i0.ɵɵproperty("disabled", ctx.Disabled);
|
|
111
|
-
i0.ɵɵattribute("aria-expanded", ctx.Expanded);
|
|
112
276
|
i0.ɵɵadvance(2);
|
|
113
|
-
i0.ɵɵ
|
|
114
|
-
i0.ɵɵadvance(
|
|
115
|
-
i0.ɵɵ
|
|
277
|
+
i0.ɵɵattribute("inert", ctx.Expanded ? null : "");
|
|
278
|
+
i0.ɵɵadvance(2);
|
|
279
|
+
i0.ɵɵproperty("id", ctx.BodyId);
|
|
280
|
+
i0.ɵɵattribute("aria-labelledby", ctx.HeaderId);
|
|
281
|
+
i0.ɵɵadvance(2);
|
|
282
|
+
i0.ɵɵconditional(ctx.bodyTemplate && (ctx.Expanded || ctx.hasBeenExpanded) ? 13 : -1);
|
|
116
283
|
} }, dependencies: [NgTemplateOutlet], encapsulation: 2 });
|
|
117
284
|
}
|
|
118
285
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJAccordionPanelComponent, [{
|
|
@@ -122,25 +289,54 @@ export class MJAccordionPanelComponent {
|
|
|
122
289
|
standalone: true,
|
|
123
290
|
imports: [NgTemplateOutlet],
|
|
124
291
|
template: `
|
|
125
|
-
<div class="mj-accordion-panel" [class.mj-accordion-panel--expanded]="Expanded" [class.mj-accordion-panel--disabled]="Disabled"
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
292
|
+
<div class="mj-accordion-panel" [class.mj-accordion-panel--expanded]="Expanded" [class.mj-accordion-panel--disabled]="Disabled"
|
|
293
|
+
[class.mj-accordion-panel--muted-icon]="TitleIconMuted"
|
|
294
|
+
[class.mj-accordion-panel--sm]="Size === 'sm'"
|
|
295
|
+
[class.mj-accordion-panel--bare]="Bare"
|
|
296
|
+
[class.mj-accordion-panel--flush-body]="FlushBody"
|
|
297
|
+
[class.mj-accordion-panel--fill]="Fill"
|
|
298
|
+
[attr.data-variant]="Variant !== 'default' ? Variant : null">
|
|
299
|
+
<div class="mj-accordion-header-row">
|
|
300
|
+
<button class="mj-accordion-header" type="button"
|
|
301
|
+
[id]="HeaderId"
|
|
302
|
+
[attr.aria-expanded]="Expanded"
|
|
303
|
+
[attr.aria-controls]="BodyId"
|
|
304
|
+
[disabled]="Disabled"
|
|
305
|
+
(click)="Toggle()">
|
|
306
|
+
<span class="mj-accordion-title">
|
|
307
|
+
@if (titleTemplate) {
|
|
308
|
+
<ng-container [ngTemplateOutlet]="titleTemplate.templateRef"></ng-container>
|
|
309
|
+
} @else {
|
|
310
|
+
{{ Title }}
|
|
311
|
+
}
|
|
312
|
+
</span>
|
|
313
|
+
</button>
|
|
314
|
+
@if (actionsTemplate) {
|
|
315
|
+
<div class="mj-accordion-actions">
|
|
316
|
+
<ng-container [ngTemplateOutlet]="actionsTemplate.templateRef"></ng-container>
|
|
317
|
+
</div>
|
|
318
|
+
}
|
|
319
|
+
<!-- The chevron is ALWAYS the rightmost element of the header row (after any
|
|
320
|
+
actions). It's a secondary, a11y-hidden toggle affordance — the primary
|
|
321
|
+
disclosure control is the title button above (which owns aria-expanded). -->
|
|
322
|
+
<button class="mj-accordion-chevron" type="button" tabindex="-1" aria-hidden="true"
|
|
323
|
+
[disabled]="Disabled" (click)="Toggle()">
|
|
324
|
+
<i class="fa-solid fa-chevron-down mj-accordion-icon"></i>
|
|
325
|
+
</button>
|
|
326
|
+
</div>
|
|
327
|
+
<div class="mj-accordion-body-outer" [attr.inert]="Expanded ? null : ''">
|
|
328
|
+
<div class="mj-accordion-body-clip">
|
|
329
|
+
<div class="mj-accordion-body" role="region" [id]="BodyId" [attr.aria-labelledby]="HeaderId">
|
|
330
|
+
<!-- Legacy: content placed directly in the panel (eager). -->
|
|
331
|
+
<ng-content></ng-content>
|
|
332
|
+
<!-- Preferred: [mjAccordionBody] template — instantiated lazily on first
|
|
333
|
+
expand, then kept alive so later toggles still animate. -->
|
|
334
|
+
@if (bodyTemplate && (Expanded || hasBeenExpanded)) {
|
|
335
|
+
<ng-container [ngTemplateOutlet]="bodyTemplate.templateRef"></ng-container>
|
|
336
|
+
}
|
|
337
|
+
</div>
|
|
142
338
|
</div>
|
|
143
|
-
|
|
339
|
+
</div>
|
|
144
340
|
</div>
|
|
145
341
|
`
|
|
146
342
|
}]
|
|
@@ -150,14 +346,75 @@ export class MJAccordionPanelComponent {
|
|
|
150
346
|
type: Input
|
|
151
347
|
}], Disabled: [{
|
|
152
348
|
type: Input
|
|
349
|
+
}], Variant: [{
|
|
350
|
+
type: Input
|
|
351
|
+
}], TitleIconMuted: [{
|
|
352
|
+
type: Input
|
|
353
|
+
}], Size: [{
|
|
354
|
+
type: Input
|
|
355
|
+
}], Bare: [{
|
|
356
|
+
type: Input
|
|
357
|
+
}], FlushBody: [{
|
|
358
|
+
type: Input
|
|
359
|
+
}], Fill: [{
|
|
360
|
+
type: Input
|
|
153
361
|
}], ExpandedChange: [{
|
|
154
362
|
type: Output
|
|
155
363
|
}], titleTemplate: [{
|
|
156
364
|
type: ContentChild,
|
|
157
365
|
args: [MJAccordionTitleDirective]
|
|
366
|
+
}], actionsTemplate: [{
|
|
367
|
+
type: ContentChild,
|
|
368
|
+
args: [MJAccordionActionsDirective]
|
|
369
|
+
}], bodyTemplate: [{
|
|
370
|
+
type: ContentChild,
|
|
371
|
+
args: [MJAccordionBodyDirective]
|
|
158
372
|
}], hostClass: [{
|
|
159
373
|
type: HostBinding,
|
|
160
374
|
args: ['class.mj-accordion-panel-host']
|
|
375
|
+
}], fillActive: [{
|
|
376
|
+
type: HostBinding,
|
|
377
|
+
args: ['class.mj-accordion-fill-active']
|
|
161
378
|
}] }); })();
|
|
162
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJAccordionPanelComponent, { className: "MJAccordionPanelComponent", filePath: "lib/accordion/accordion.component.ts", lineNumber:
|
|
379
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJAccordionPanelComponent, { className: "MJAccordionPanelComponent", filePath: "lib/accordion/accordion.component.ts", lineNumber: 163 }); })();
|
|
380
|
+
/**
|
|
381
|
+
* Convenience module bundling the accordion panel + all of its slot directives.
|
|
382
|
+
* Import this ONE symbol instead of listing the component and each directive
|
|
383
|
+
* separately:
|
|
384
|
+
*
|
|
385
|
+
* ```ts
|
|
386
|
+
* import { MJAccordionModule } from '@memberjunction/ng-ui-components';
|
|
387
|
+
* @NgModule({ imports: [MJAccordionModule, ...] }) // or @Component standalone imports
|
|
388
|
+
* ```
|
|
389
|
+
*
|
|
390
|
+
* Why a module (not a bare `const [...]` array): Angular's AOT compiler can't
|
|
391
|
+
* statically expand a value-array imported across a compiled-package boundary in
|
|
392
|
+
* an `imports` array (NG1010), and `as const` makes it a readonly tuple the
|
|
393
|
+
* `imports` type rejects (TS2322). An NgModule is always a valid `imports` entry
|
|
394
|
+
* in both NgModule and standalone consumers. Adding a future accordion directive
|
|
395
|
+
* here makes it available to every consumer automatically — no per-module churn.
|
|
396
|
+
*/
|
|
397
|
+
export class MJAccordionModule {
|
|
398
|
+
static ɵfac = function MJAccordionModule_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || MJAccordionModule)(); };
|
|
399
|
+
static ɵmod = /*@__PURE__*/ i0.ɵɵdefineNgModule({ type: MJAccordionModule });
|
|
400
|
+
static ɵinj = /*@__PURE__*/ i0.ɵɵdefineInjector({});
|
|
401
|
+
}
|
|
402
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJAccordionModule, [{
|
|
403
|
+
type: NgModule,
|
|
404
|
+
args: [{
|
|
405
|
+
imports: [
|
|
406
|
+
MJAccordionPanelComponent,
|
|
407
|
+
MJAccordionTitleDirective,
|
|
408
|
+
MJAccordionActionsDirective,
|
|
409
|
+
MJAccordionBodyDirective,
|
|
410
|
+
],
|
|
411
|
+
exports: [
|
|
412
|
+
MJAccordionPanelComponent,
|
|
413
|
+
MJAccordionTitleDirective,
|
|
414
|
+
MJAccordionActionsDirective,
|
|
415
|
+
MJAccordionBodyDirective,
|
|
416
|
+
],
|
|
417
|
+
}]
|
|
418
|
+
}], null, null); })();
|
|
419
|
+
(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MJAccordionModule, { imports: [MJAccordionPanelComponent, MJAccordionTitleDirective, MJAccordionActionsDirective, MJAccordionBodyDirective], exports: [MJAccordionPanelComponent, MJAccordionTitleDirective, MJAccordionActionsDirective, MJAccordionBodyDirective] }); })();
|
|
163
420
|
//# sourceMappingURL=accordion.component.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accordion.component.js","sourceRoot":"","sources":["../../../src/lib/accordion/accordion.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAe,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1H,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;;;;IA4DvC,2BAA4E;;;IAA9D,mEAA8C;;;IAE5D,YACF;;;IADE,6CACF;;;IAKF,8BAA6C;IAC3C,kBAAyB;IAC3B,iBAAM;;AApEd;;;;;;;;;;;;;;GAcG;AAKH,MAAM,OAAO,yBAAyB;IACjB;IAAnB,YAAmB,WAAiC;QAAjC,gBAAW,GAAX,WAAW,CAAsB;IAAG,CAAC;mHAD7C,yBAAyB;6DAAzB,yBAAyB;;iFAAzB,yBAAyB;cAJrC,SAAS;eAAC;gBACT,QAAQ,EAAE,oBAAoB;gBAC9B,UAAU,EAAE,IAAI;aACjB;;AAKD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AA4BH,MAAM,OAAO,yBAAyB;IAC3B,KAAK,GAAG,EAAE,CAAC;IACX,QAAQ,GAAG,KAAK,CAAC;IACjB,QAAQ,GAAG,KAAK,CAAC;IAChB,cAAc,GAAG,IAAI,YAAY,EAAW,CAAC;IACd,aAAa,GAAqC,IAAI,CAAC;IACzC,SAAS,GAAG,IAAI,CAAC;IAExE,MAAM;QACJ,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO;QAC1B,IAAI,CAAC,QAAQ,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC;QAC/B,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1C,CAAC;mHAZU,yBAAyB;6DAAzB,yBAAyB;wCAKtB,yBAAyB;;;;;YAL5B,wDAAyB;;;YArBhC,AADF,8BAAgI,gBAIzG;YAAnB,sGAAS,YAAQ,IAAC;YAClB,+BAAiC;YAG7B,AAFF,oGAAqB,2DAEZ;YAGX,iBAAO;YACP,uBAA0D;YAC5D,iBAAS;YACT,2FAAgB;YAKlB,iBAAM;;YAnB0E,AAAhD,4DAA+C,8CAAgD;YAG3H,cAAqB;YAArB,uCAAqB;;YAGnB,eAIC;YAJD,2CAIC;YAIL,eAIC;YAJD,uCAIC;4BApBK,gBAAgB;;iFAwBf,yBAAyB;cA3BrC,SAAS;eAAC;gBACT,QAAQ,EAAE,oBAAoB;gBAC9B,UAAU,EAAE,IAAI;gBAChB,OAAO,EAAE,CAAC,gBAAgB,CAAC;gBAC3B,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;GAqBT;aACF;;kBAEE,KAAK;;kBACL,KAAK;;kBACL,KAAK;;kBACL,MAAM;;kBACN,YAAY;mBAAC,yBAAyB;;kBACtC,WAAW;mBAAC,+BAA+B;;kFANjC,yBAAyB","sourcesContent":["import { Component, Input, Output, EventEmitter, HostBinding, ContentChild, TemplateRef, Directive } from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\n\n/**\n * Directive to mark a template as the accordion panel title.\n * Supports rich HTML content (icons, badges, dynamic text).\n *\n * @example\n * ```html\n * <mj-accordion-panel [Expanded]=\"true\">\n * <ng-template mjAccordionTitle>\n * <i class=\"fa-solid fa-code\"></i> Template Editor\n * <span class=\"badge\">3</span>\n * </ng-template>\n * <p>Panel content here</p>\n * </mj-accordion-panel>\n * ```\n */\n@Directive({\n selector: '[mjAccordionTitle]',\n standalone: true\n})\nexport class MJAccordionTitleDirective {\n constructor(public templateRef: TemplateRef<unknown>) {}\n}\n\n/**\n * mj-accordion-panel — Collapsible panel. Replaces `<kendo-panelbar-item>` and `<kendo-expansionpanel>`.\n *\n * Supports two title modes:\n * - Simple string: `[Title]=\"'Details'\"` — plain text title\n * - Rich template: `<ng-template mjAccordionTitle>` — HTML with icons, badges, etc.\n *\n * @example\n * ```html\n * <!-- Simple string title -->\n * <mj-accordion-panel Title=\"Details\" [Expanded]=\"true\">\n * <p>Panel content here</p>\n * </mj-accordion-panel>\n *\n * <!-- Rich HTML title -->\n * <mj-accordion-panel [Expanded]=\"true\">\n * <ng-template mjAccordionTitle>\n * <i class=\"fa-solid fa-code\"></i> Template Editor\n * </ng-template>\n * <p>Panel content here</p>\n * </mj-accordion-panel>\n * ```\n */\n@Component({\n selector: 'mj-accordion-panel',\n standalone: true,\n imports: [NgTemplateOutlet],\n template: `\n <div class=\"mj-accordion-panel\" [class.mj-accordion-panel--expanded]=\"Expanded\" [class.mj-accordion-panel--disabled]=\"Disabled\">\n <button class=\"mj-accordion-header\" type=\"button\"\n [attr.aria-expanded]=\"Expanded\"\n [disabled]=\"Disabled\"\n (click)=\"Toggle()\">\n <span class=\"mj-accordion-title\">\n @if (titleTemplate) {\n <ng-container [ngTemplateOutlet]=\"titleTemplate.templateRef\"></ng-container>\n } @else {\n {{ Title }}\n }\n </span>\n <i class=\"fa-solid fa-chevron-down mj-accordion-icon\"></i>\n </button>\n @if (Expanded) {\n <div class=\"mj-accordion-body\" role=\"region\">\n <ng-content></ng-content>\n </div>\n }\n </div>\n `\n})\nexport class MJAccordionPanelComponent {\n @Input() Title = '';\n @Input() Expanded = false;\n @Input() Disabled = false;\n @Output() ExpandedChange = new EventEmitter<boolean>();\n @ContentChild(MJAccordionTitleDirective) titleTemplate: MJAccordionTitleDirective | null = null;\n @HostBinding('class.mj-accordion-panel-host') readonly hostClass = true;\n\n Toggle(): void {\n if (this.Disabled) return;\n this.Expanded = !this.Expanded;\n this.ExpandedChange.emit(this.Expanded);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"accordion.component.js","sourceRoot":"","sources":["../../../src/lib/accordion/accordion.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, HostBinding, ContentChild, TemplateRef, Directive, NgModule } from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\n\n/** Process-wide counter for generating unique, stable accordion element ids\n * (used to wire `aria-controls` / `aria-labelledby` between header and body). */\nlet nextAccordionUid = 0;\n\n/**\n * Directive to mark a template as the accordion panel title.\n * Supports rich HTML content (icons, badges, dynamic text).\n *\n * @example\n * ```html\n * <mj-accordion-panel [Expanded]=\"true\">\n * <ng-template mjAccordionTitle>\n * <i class=\"fa-solid fa-code\"></i> Template Editor\n * <span class=\"badge\">3</span>\n * </ng-template>\n * <p>Panel content here</p>\n * </mj-accordion-panel>\n * ```\n */\n@Directive({\n selector: '[mjAccordionTitle]',\n standalone: true\n})\nexport class MJAccordionTitleDirective {\n constructor(public templateRef: TemplateRef<unknown>) {}\n}\n\n/**\n * Directive to mark a template as the accordion header **actions** — interactive\n * controls (edit / copy / run / checkbox, etc.) that sit in the header row but\n * are NOT the expand/collapse toggle. Rendered as a sibling of the toggle\n * `<button>`, so there's no button-in-button and the toggle stays a clean,\n * accessible control.\n *\n * @example\n * ```html\n * <mj-accordion-panel>\n * <ng-template mjAccordionTitle>Connection</ng-template>\n * <ng-template mjAccordionActions>\n * <button mjButton variant=\"icon\" (click)=\"edit()\"><i class=\"fa fa-pen\"></i></button>\n * </ng-template>\n * …body…\n * </mj-accordion-panel>\n * ```\n */\n@Directive({\n selector: '[mjAccordionActions]',\n standalone: true\n})\nexport class MJAccordionActionsDirective {\n constructor(public templateRef: TemplateRef<unknown>) {}\n}\n\n/**\n * Directive to mark a template as the accordion **body** — the panel's collapsible\n * content. Use this INSTEAD of placing content directly in the panel when the body\n * may be expensive (code editors, grids, large lists) OR just to be future-proof:\n * the accordion instantiates the template **lazily on first expand** and then keeps\n * it alive, so nothing is created until the user opens the panel, while later\n * open/close still animates. Consumers never have to reason about content weight or\n * write `@if (expanded)` themselves.\n *\n * @example\n * ```html\n * <mj-accordion-panel [Expanded]=\"open\" (ExpandedChange)=\"open = $event\">\n * <ng-template mjAccordionTitle>Configuration</ng-template>\n * <ng-template mjAccordionBody>\n * <mj-code-editor ...></mj-code-editor> <!-- not created until first opened -->\n * </ng-template>\n * </mj-accordion-panel>\n * ```\n */\n@Directive({\n selector: '[mjAccordionBody]',\n standalone: true\n})\nexport class MJAccordionBodyDirective {\n constructor(public templateRef: TemplateRef<unknown>) {}\n}\n\n/**\n * mj-accordion-panel — Collapsible panel. Replaces `<kendo-panelbar-item>` and `<kendo-expansionpanel>`.\n *\n * Supports two title modes:\n * - Simple string: `[Title]=\"'Details'\"` — plain text title\n * - Rich template: `<ng-template mjAccordionTitle>` — HTML with icons, badges, etc.\n *\n * @example\n * ```html\n * <!-- Simple string title -->\n * <mj-accordion-panel Title=\"Details\" [Expanded]=\"true\">\n * <p>Panel content here</p>\n * </mj-accordion-panel>\n *\n * <!-- Rich HTML title -->\n * <mj-accordion-panel [Expanded]=\"true\">\n * <ng-template mjAccordionTitle>\n * <i class=\"fa-solid fa-code\"></i> Template Editor\n * </ng-template>\n * <p>Panel content here</p>\n * </mj-accordion-panel>\n * ```\n */\n@Component({\n selector: 'mj-accordion-panel',\n standalone: true,\n imports: [NgTemplateOutlet],\n template: `\n <div class=\"mj-accordion-panel\" [class.mj-accordion-panel--expanded]=\"Expanded\" [class.mj-accordion-panel--disabled]=\"Disabled\"\n [class.mj-accordion-panel--muted-icon]=\"TitleIconMuted\"\n [class.mj-accordion-panel--sm]=\"Size === 'sm'\"\n [class.mj-accordion-panel--bare]=\"Bare\"\n [class.mj-accordion-panel--flush-body]=\"FlushBody\"\n [class.mj-accordion-panel--fill]=\"Fill\"\n [attr.data-variant]=\"Variant !== 'default' ? Variant : null\">\n <div class=\"mj-accordion-header-row\">\n <button class=\"mj-accordion-header\" type=\"button\"\n [id]=\"HeaderId\"\n [attr.aria-expanded]=\"Expanded\"\n [attr.aria-controls]=\"BodyId\"\n [disabled]=\"Disabled\"\n (click)=\"Toggle()\">\n <span class=\"mj-accordion-title\">\n @if (titleTemplate) {\n <ng-container [ngTemplateOutlet]=\"titleTemplate.templateRef\"></ng-container>\n } @else {\n {{ Title }}\n }\n </span>\n </button>\n @if (actionsTemplate) {\n <div class=\"mj-accordion-actions\">\n <ng-container [ngTemplateOutlet]=\"actionsTemplate.templateRef\"></ng-container>\n </div>\n }\n <!-- The chevron is ALWAYS the rightmost element of the header row (after any\n actions). It's a secondary, a11y-hidden toggle affordance — the primary\n disclosure control is the title button above (which owns aria-expanded). -->\n <button class=\"mj-accordion-chevron\" type=\"button\" tabindex=\"-1\" aria-hidden=\"true\"\n [disabled]=\"Disabled\" (click)=\"Toggle()\">\n <i class=\"fa-solid fa-chevron-down mj-accordion-icon\"></i>\n </button>\n </div>\n <div class=\"mj-accordion-body-outer\" [attr.inert]=\"Expanded ? null : ''\">\n <div class=\"mj-accordion-body-clip\">\n <div class=\"mj-accordion-body\" role=\"region\" [id]=\"BodyId\" [attr.aria-labelledby]=\"HeaderId\">\n <!-- Legacy: content placed directly in the panel (eager). -->\n <ng-content></ng-content>\n <!-- Preferred: [mjAccordionBody] template — instantiated lazily on first\n expand, then kept alive so later toggles still animate. -->\n @if (bodyTemplate && (Expanded || hasBeenExpanded)) {\n <ng-container [ngTemplateOutlet]=\"bodyTemplate.templateRef\"></ng-container>\n }\n </div>\n </div>\n </div>\n </div>\n `\n})\nexport class MJAccordionPanelComponent {\n @Input() Title = '';\n private _expanded = false;\n /** Latches true the first time the panel is expanded; never resets. Lets a\n * [mjAccordionBody] template instantiate lazily on first open and then stay\n * alive so subsequent open/close still animates. */\n private _everExpanded = false;\n @Input()\n set Expanded(value: boolean) {\n this._expanded = value;\n if (value) this._everExpanded = true;\n }\n get Expanded(): boolean { return this._expanded; }\n protected get hasBeenExpanded(): boolean { return this._everExpanded; }\n @Input() Disabled = false;\n /**\n * Emphasis variant for visual hierarchy:\n * - `primary` — bold, solid brand-colored header (use to make a panel stand out)\n * - `secondary` — subtle brand tint\n * - `default` — standard neutral header\n * All brand-token-driven, so dark-mode-safe and themeable.\n */\n @Input() Variant: 'default' | 'primary' | 'secondary' = 'default';\n /**\n * Render icons projected into the title slot in the muted color instead of the\n * header's primary text color. Lets consumers get the common \"quiet icon\" look\n * without writing CSS. Status/brand-colored icons can still be colored inline.\n */\n @Input() TitleIconMuted = false;\n /**\n * Density. `md` (default) is the standard size; `sm` tightens header padding and\n * font for dense contexts (sidebars, flyouts, nested panels).\n */\n @Input() Size: 'sm' | 'md' = 'md';\n /**\n * Bare chrome — drop the panel's own border and header background so the panel\n * sits cleanly inside a host that already provides chrome (e.g. an expandable\n * card). The toggle/title/chevron/body still work; only the box styling is removed.\n */\n @Input() Bare = false;\n /**\n * Remove the body's default padding, for bodies that manage their own spacing\n * (code editors, full-bleed grids, custom forms).\n */\n @Input() FlushBody = false;\n /**\n * Fill mode — for \"rail section that owns the leftover height\" cases (e.g. an\n * entity tree or grid that should consume all remaining vertical space and\n * scroll *internally*), rather than the default \"reveal stacked content\"\n * disclosure. When set AND expanded, the panel becomes a flex column that\n * fills its flex parent and its body becomes a `flex:1; min-height:0` region —\n * the projected content is expected to provide its own scroll child. While\n * collapsed, the panel behaves exactly like a normal panel (header only,\n * natural height) and does NOT claim the leftover space.\n *\n * Requires the panel's parent to be a flex column with `min-height:0`.\n * Note: the open/close height animation is skipped in fill mode (the body\n * fills rather than animating to content height).\n */\n @Input() Fill = false;\n @Output() ExpandedChange = new EventEmitter<boolean>();\n @ContentChild(MJAccordionTitleDirective) titleTemplate: MJAccordionTitleDirective | null = null;\n @ContentChild(MJAccordionActionsDirective) actionsTemplate: MJAccordionActionsDirective | null = null;\n @ContentChild(MJAccordionBodyDirective) bodyTemplate: MJAccordionBodyDirective | null = null;\n @HostBinding('class.mj-accordion-panel-host') readonly hostClass = true;\n /** Host claims flex:1 of its parent ONLY while a Fill panel is expanded —\n * so a collapsed Fill panel sits at natural (header) height like any other. */\n @HostBinding('class.mj-accordion-fill-active') get fillActive(): boolean {\n return this.Fill && this.Expanded;\n }\n\n /** Stable per-instance ids that programmatically associate the header\n * `<button>` with its body region (`aria-controls` ↔ `aria-labelledby`),\n * completing the WAI-ARIA accordion pattern so screen readers announce the\n * region with the header's name. */\n private readonly _uid = nextAccordionUid++;\n readonly HeaderId = `mj-accordion-header-${this._uid}`;\n readonly BodyId = `mj-accordion-body-${this._uid}`;\n\n Toggle(): void {\n if (this.Disabled) return;\n this.Expanded = !this.Expanded;\n this.ExpandedChange.emit(this.Expanded);\n }\n}\n\n/**\n * Convenience module bundling the accordion panel + all of its slot directives.\n * Import this ONE symbol instead of listing the component and each directive\n * separately:\n *\n * ```ts\n * import { MJAccordionModule } from '@memberjunction/ng-ui-components';\n * @NgModule({ imports: [MJAccordionModule, ...] }) // or @Component standalone imports\n * ```\n *\n * Why a module (not a bare `const [...]` array): Angular's AOT compiler can't\n * statically expand a value-array imported across a compiled-package boundary in\n * an `imports` array (NG1010), and `as const` makes it a readonly tuple the\n * `imports` type rejects (TS2322). An NgModule is always a valid `imports` entry\n * in both NgModule and standalone consumers. Adding a future accordion directive\n * here makes it available to every consumer automatically — no per-module churn.\n */\n@NgModule({\n imports: [\n MJAccordionPanelComponent,\n MJAccordionTitleDirective,\n MJAccordionActionsDirective,\n MJAccordionBodyDirective,\n ],\n exports: [\n MJAccordionPanelComponent,\n MJAccordionTitleDirective,\n MJAccordionActionsDirective,\n MJAccordionBodyDirective,\n ],\n})\nexport class MJAccordionModule {}\n"]}
|