@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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"confirm-dialog.service.js","sourceRoot":"","sources":["../../../src/lib/confirm-dialog/confirm-dialog.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { ApplicationRef, ComponentRef, Injectable, createComponent, inject } from '@angular/core';\nimport { MJConfirmDialogComponent, MJConfirmDialogType } from './confirm-dialog.component';\n\n/**\n * Options for {@link MJConfirmService.Confirm}. Mirror the `<mj-confirm-dialog>`\n * inputs, but in a flat options bag suited to an imperative call.\n */\nexport interface MJConfirmOptions {\n /** Primary prompt text. */\n message: string;\n /** Title-bar heading. Defaults to 'Confirm'. */\n title?: string;\n /** Optional secondary line, rendered smaller/muted beneath the message. */\n detail?: string;\n /** Visual intent — drives the header icon + confirm button color. Defaults to 'default'. */\n type?: MJConfirmDialogType;\n /** Affirmative button label. Defaults to 'Confirm'. */\n confirmText?: string;\n /** Dismiss button label. Defaults to 'Cancel'. */\n cancelText?: string;\n /** Font Awesome icon override (e.g. \"fa-solid fa-trash\"). `''` suppresses the icon. */\n icon?: string;\n}\n\n/**\n * MJConfirmService — Imperative, Promise-based confirmation prompts.\n *\n * The one-liner replacement for native `window.confirm()` (an anti-pattern this\n * codebase bans) and for the boilerplate of wiring `<mj-confirm-dialog>` into a\n * template just to ask a yes/no question. It dynamically mounts an\n * `MJConfirmDialogComponent` to `document.body`, shows it, and resolves a\n * `Promise<boolean>` — `true` on confirm, `false` on cancel/backdrop/Esc — then\n * tears the component down.\n *\n * @example\n * ```typescript\n * private confirm = inject(MJConfirmService);\n *\n * // Simplest — replaces `if (window.confirm('Discard changes?')) { ... }`\n * if (await this.confirm.Confirm('Discard unsaved changes?')) {\n * this.discard();\n * }\n *\n * // Destructive delete with a detail line\n * if (await this.confirm.ConfirmDelete({\n * message: 'Delete this user?',\n * detail: 'This action cannot be undone.',\n * })) {\n * await this.deleteUser();\n * }\n * ```\n *\n * **Async work after confirm:** because this resolves a boolean, the dialog has\n * already closed by the time your `await` continues — there's no in-dialog\n * spinner. When you need a \"keep open + spinner while I save\" UX, use the\n * `<mj-confirm-dialog>` component directly with its `Processing` input instead.\n *\n * **Synchronous guards:** `window.confirm` blocks the thread; a synchronous\n * `CanClose`/`beforeunload` guard that must return a boolean *immediately*\n * cannot use this async service. Those rare cases stay on `window.confirm` as a\n * documented exception.\n */\n@Injectable({ providedIn: 'root' })\nexport class MJConfirmService {\n private appRef = inject(ApplicationRef);\n\n /**\n * Ask the user to confirm. Pass a bare string for the simplest case, or an\n * options bag for control over title/type/labels/detail.\n * @returns a Promise resolving `true` if confirmed, `false` otherwise.\n */\n Confirm(options: MJConfirmOptions | string): Promise<boolean> {\n const opts: MJConfirmOptions = typeof options === 'string' ? { message: options } : options;\n\n return new Promise<boolean>((resolve) => {\n const ref = createComponent(MJConfirmDialogComponent, {\n environmentInjector: this.appRef.injector,\n });\n this.applyInputs(ref, opts);\n // An imperative confirm must layer above whatever surface launched it —\n // bespoke drawers/panels go up to ~1101 and mj-window sits at 10000,\n // all above the shared mj-dialog backdrop (1000). Without this, a\n // confirm opened from such an overlay renders UNDER its backdrop:\n // unclickable, and each swallowed click can re-trigger the caller and\n // stack another dialog. position:relative + z-index forms a stacking\n // context on the host that lifts the fixed backdrop/dialog inside it\n // to this level (20000 — above mj-window, below toasts at 100000)\n // without touching the fixed element's viewport-relative geometry.\n const host = ref.location.nativeElement as HTMLElement;\n host.style.position = 'relative';\n host.style.zIndex = '20000';\n document.body.appendChild(host);\n this.appRef.attachView(ref.hostView);\n\n let settled = false;\n const finish = (result: boolean): void => {\n if (settled) {\n return;\n }\n settled = true;\n confirmedSub.unsubscribe();\n cancelledSub.unsubscribe();\n this.appRef.detachView(ref.hostView);\n ref.location.nativeElement.remove();\n ref.destroy();\n resolve(result);\n };\n\n const confirmedSub = ref.instance.Confirmed.subscribe(() => finish(true));\n const cancelledSub = ref.instance.Cancelled.subscribe(() => finish(false));\n\n ref.instance.Visible = true;\n ref.changeDetectorRef.detectChanges();\n });\n }\n\n /**\n * Convenience for destructive deletes — `type: 'danger'` and a 'Delete'\n * confirm label by default (both overridable via `options`).\n */\n ConfirmDelete(options: Omit<MJConfirmOptions, 'type'>): Promise<boolean> {\n return this.Confirm({ confirmText: 'Delete', ...options, type: 'danger' });\n }\n\n private applyInputs(ref: ComponentRef<MJConfirmDialogComponent>, opts: MJConfirmOptions): void {\n const i = ref.instance;\n i.Message = opts.message;\n if (opts.title != null) {\n i.Title = opts.title;\n }\n if (opts.detail != null) {\n i.DetailMessage = opts.detail;\n }\n if (opts.type != null) {\n i.Type = opts.type;\n }\n if (opts.confirmText != null) {\n i.ConfirmText = opts.confirmText;\n }\n if (opts.cancelText != null) {\n i.CancelText = opts.cancelText;\n }\n if (opts.icon != null) {\n i.Icon = opts.icon;\n }\n }\n}\n"]}
|
|
@@ -31,6 +31,13 @@ export declare class MJDialogComponent implements OnDestroy {
|
|
|
31
31
|
Size: MjDialogSize;
|
|
32
32
|
Closeable: boolean;
|
|
33
33
|
MinWidth: number | null;
|
|
34
|
+
/**
|
|
35
|
+
* ARIA role for the dialog container. Defaults to `'dialog'`; pass
|
|
36
|
+
* `'alertdialog'` for confirmation / destructive prompts that interrupt the
|
|
37
|
+
* user (per WAI-ARIA, an alertdialog conveys an urgent message requiring a
|
|
38
|
+
* response). Backward compatible — existing callers keep `'dialog'`.
|
|
39
|
+
*/
|
|
40
|
+
Role: 'dialog' | 'alertdialog';
|
|
34
41
|
Close: EventEmitter<void>;
|
|
35
42
|
DialogId: number;
|
|
36
43
|
get dialogId(): number;
|
|
@@ -43,7 +50,7 @@ export declare class MJDialogComponent implements OnDestroy {
|
|
|
43
50
|
private onCloseInternal;
|
|
44
51
|
ngOnDestroy(): void;
|
|
45
52
|
static ɵfac: i0.ɵɵFactoryDeclaration<MJDialogComponent, never>;
|
|
46
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<MJDialogComponent, "mj-dialog", never, { "Visible": { "alias": "Visible"; "required": false; }; "Title": { "alias": "Title"; "required": false; }; "Width": { "alias": "Width"; "required": false; }; "Height": { "alias": "Height"; "required": false; }; "Size": { "alias": "Size"; "required": false; }; "Closeable": { "alias": "Closeable"; "required": false; }; "MinWidth": { "alias": "MinWidth"; "required": false; }; }, { "Close": "Close"; }, never, ["mj-dialog-titlebar", "*", "mj-dialog-actions"], true, never>;
|
|
53
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<MJDialogComponent, "mj-dialog", never, { "Visible": { "alias": "Visible"; "required": false; }; "Title": { "alias": "Title"; "required": false; }; "Width": { "alias": "Width"; "required": false; }; "Height": { "alias": "Height"; "required": false; }; "Size": { "alias": "Size"; "required": false; }; "Closeable": { "alias": "Closeable"; "required": false; }; "MinWidth": { "alias": "MinWidth"; "required": false; }; "Role": { "alias": "Role"; "required": false; }; }, { "Close": "Close"; }, never, ["mj-dialog-titlebar", "*", "mj-dialog-actions"], true, never>;
|
|
47
54
|
}
|
|
48
55
|
/**
|
|
49
56
|
* mj-dialog-titlebar — Custom titlebar content for mj-dialog.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dialog.component.d.ts","sourceRoot":"","sources":["../../../src/lib/dialog/dialog.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,YAAY,EAKZ,SAAS,EAEV,MAAM,eAAe,CAAC;;AAEvB,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC;AAU9D;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBA2Ca,iBAAkB,YAAW,SAAS;IACjD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAAC,MAAM,CAAK;IAE1B,IACI,OAAO,CAAC,KAAK,EAAE,OAAO,EASzB;IACD,IAAI,OAAO,IAAI,OAAO,CAErB;IAEQ,KAAK,SAAM;IACX,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAQ;IACrC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAQ;IACtC,IAAI,EAAE,YAAY,CAAU;IAC5B,SAAS,UAAQ;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;
|
|
1
|
+
{"version":3,"file":"dialog.component.d.ts","sourceRoot":"","sources":["../../../src/lib/dialog/dialog.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,YAAY,EAKZ,SAAS,EAEV,MAAM,eAAe,CAAC;;AAEvB,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC;AAU9D;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBA2Ca,iBAAkB,YAAW,SAAS;IACjD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAAC,MAAM,CAAK;IAE1B,IACI,OAAO,CAAC,KAAK,EAAE,OAAO,EASzB;IACD,IAAI,OAAO,IAAI,OAAO,CAErB;IAEQ,KAAK,SAAM;IACX,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAQ;IACrC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAQ;IACtC,IAAI,EAAE,YAAY,CAAU;IAC5B,SAAS,UAAQ;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAExC;;;;;OAKG;IACM,IAAI,EAAE,QAAQ,GAAG,aAAa,CAAY;IAEzC,KAAK,qBAA4B;IAE3C,QAAQ,SAA8B;IAEtC,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,IAAI,aAAa,IAAI,MAAM,CAK1B;IAED,IAAI,cAAc,IAAI,MAAM,CAK3B;IAGD,WAAW,IAAI,IAAI;IAMnB,eAAe,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAMnC,YAAY,IAAI,IAAI;IAIpB,OAAO,CAAC,MAAM;IAId,OAAO,CAAC,eAAe;IAIvB,WAAW,IAAI,IAAI;yCAjFR,iBAAiB;2CAAjB,iBAAiB;CAoF7B;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAKa,yBAAyB;yCAAzB,yBAAyB;2CAAzB,yBAAyB;CAAG;AAEzC;;;;;;;;;;;;GAYG;AACH,qBASa,wBAAwB;yCAAxB,wBAAwB;2CAAxB,wBAAwB;CAAG"}
|
|
@@ -48,7 +48,7 @@ function MJDialogComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
|
48
48
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
49
49
|
i0.ɵɵadvance();
|
|
50
50
|
i0.ɵɵstyleProp("width", ctx_r1.resolvedWidth)("height", ctx_r1.resolvedHeight)("max-width", "90vw")("max-height", "90vh");
|
|
51
|
-
i0.ɵɵattribute("aria-labelledby", ctx_r1.Title ? "mj-dialog-title-" + ctx_r1.dialogId : null);
|
|
51
|
+
i0.ɵɵattribute("role", ctx_r1.Role)("aria-labelledby", ctx_r1.Title ? "mj-dialog-title-" + ctx_r1.dialogId : null);
|
|
52
52
|
i0.ɵɵadvance();
|
|
53
53
|
i0.ɵɵconditional(ctx_r1.Title || ctx_r1.Closeable ? 2 : -1);
|
|
54
54
|
} }
|
|
@@ -101,6 +101,13 @@ export class MJDialogComponent {
|
|
|
101
101
|
Size = 'auto';
|
|
102
102
|
Closeable = true;
|
|
103
103
|
MinWidth = null;
|
|
104
|
+
/**
|
|
105
|
+
* ARIA role for the dialog container. Defaults to `'dialog'`; pass
|
|
106
|
+
* `'alertdialog'` for confirmation / destructive prompts that interrupt the
|
|
107
|
+
* user (per WAI-ARIA, an alertdialog conveys an urgent message requiring a
|
|
108
|
+
* response). Backward compatible — existing callers keep `'dialog'`.
|
|
109
|
+
*/
|
|
110
|
+
Role = 'dialog';
|
|
104
111
|
Close = new EventEmitter();
|
|
105
112
|
DialogId = MJDialogComponent.nextId++;
|
|
106
113
|
get dialogId() {
|
|
@@ -143,9 +150,9 @@ export class MJDialogComponent {
|
|
|
143
150
|
static ɵfac = function MJDialogComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || MJDialogComponent)(); };
|
|
144
151
|
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MJDialogComponent, selectors: [["mj-dialog"]], hostBindings: function MJDialogComponent_HostBindings(rf, ctx) { if (rf & 1) {
|
|
145
152
|
i0.ɵɵlistener("keydown.escape", function MJDialogComponent_keydown_escape_HostBindingHandler() { return ctx.OnEscapeKey(); }, i0.ɵɵresolveDocument);
|
|
146
|
-
} }, inputs: { Visible: "Visible", Title: "Title", Width: "Width", Height: "Height", Size: "Size", Closeable: "Closeable", MinWidth: "MinWidth" }, outputs: { Close: "Close" }, ngContentSelectors: _c1, decls: 1, vars: 1, consts: [[1, "mj-dialog-backdrop"], [1, "mj-dialog-backdrop", 3, "click"], ["
|
|
153
|
+
} }, inputs: { Visible: "Visible", Title: "Title", Width: "Width", Height: "Height", Size: "Size", Closeable: "Closeable", MinWidth: "MinWidth", Role: "Role" }, outputs: { Close: "Close" }, ngContentSelectors: _c1, decls: 1, vars: 1, consts: [[1, "mj-dialog-backdrop"], [1, "mj-dialog-backdrop", 3, "click"], ["aria-modal", "true", 1, "mj-dialog-container", 3, "click"], [1, "mj-dialog-titlebar"], [1, "mj-dialog-body"], [1, "mj-dialog-title", 3, "id"], ["aria-label", "Close dialog", 1, "mj-dialog-close"], ["aria-label", "Close dialog", 1, "mj-dialog-close", 3, "click"], [1, "fa-solid", "fa-times"]], template: function MJDialogComponent_Template(rf, ctx) { if (rf & 1) {
|
|
147
154
|
i0.ɵɵprojectionDef(_c0);
|
|
148
|
-
i0.ɵɵconditionalCreate(0, MJDialogComponent_Conditional_0_Template, 6,
|
|
155
|
+
i0.ɵɵconditionalCreate(0, MJDialogComponent_Conditional_0_Template, 6, 11, "div", 0);
|
|
149
156
|
} if (rf & 2) {
|
|
150
157
|
i0.ɵɵconditional(ctx.Visible ? 0 : -1);
|
|
151
158
|
} }, encapsulation: 2 });
|
|
@@ -159,7 +166,7 @@ export class MJDialogComponent {
|
|
|
159
166
|
@if (Visible) {
|
|
160
167
|
<div class="mj-dialog-backdrop" (click)="OnBackdropClick($event)">
|
|
161
168
|
<div class="mj-dialog-container"
|
|
162
|
-
role="
|
|
169
|
+
[attr.role]="Role"
|
|
163
170
|
aria-modal="true"
|
|
164
171
|
[attr.aria-labelledby]="Title ? 'mj-dialog-title-' + dialogId : null"
|
|
165
172
|
[style.width]="resolvedWidth"
|
|
@@ -209,6 +216,8 @@ export class MJDialogComponent {
|
|
|
209
216
|
type: Input
|
|
210
217
|
}], MinWidth: [{
|
|
211
218
|
type: Input
|
|
219
|
+
}], Role: [{
|
|
220
|
+
type: Input
|
|
212
221
|
}], Close: [{
|
|
213
222
|
type: Output
|
|
214
223
|
}], OnEscapeKey: [{
|
|
@@ -246,7 +255,7 @@ export class MJDialogTitlebarComponent {
|
|
|
246
255
|
template: `<ng-content></ng-content>`
|
|
247
256
|
}]
|
|
248
257
|
}], null, null); })();
|
|
249
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJDialogTitlebarComponent, { className: "MJDialogTitlebarComponent", filePath: "lib/dialog/dialog.component.ts", lineNumber:
|
|
258
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJDialogTitlebarComponent, { className: "MJDialogTitlebarComponent", filePath: "lib/dialog/dialog.component.ts", lineNumber: 192 }); })();
|
|
250
259
|
/**
|
|
251
260
|
* mj-dialog-actions — Footer action bar for mj-dialog.
|
|
252
261
|
*
|
|
@@ -281,5 +290,5 @@ export class MJDialogActionsComponent {
|
|
|
281
290
|
`
|
|
282
291
|
}]
|
|
283
292
|
}], null, null); })();
|
|
284
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJDialogActionsComponent, { className: "MJDialogActionsComponent", filePath: "lib/dialog/dialog.component.ts", lineNumber:
|
|
293
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJDialogActionsComponent, { className: "MJDialogActionsComponent", filePath: "lib/dialog/dialog.component.ts", lineNumber: 216 }); })();
|
|
285
294
|
//# sourceMappingURL=dialog.component.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dialog.component.js","sourceRoot":"","sources":["../../../src/lib/dialog/dialog.component.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,KAAK,EACL,MAAM,EACN,YAAY,EACZ,YAAY,EAMb,MAAM,eAAe,CAAC;;;;;IAmDP,gCAAiE;IAAA,YAAW;IAAA,oBAAK;;;IAArD,4DAAoC;IAAC,cAAW;IAAX,kCAAW;;;;IAI5E,oCAAmF;IAAnD,qNAAS,qBAAc,KAAC;IACtD,0BAAiC;IACnC,oBAAS;;;IARb,iCAAgC;IAC9B,8GAAa;IAGb,qBAAqD;IACrD,kHAAiB;IAKnB,oBAAM;;;IATJ,cAEC;IAFD,uCAEC;IAED,eAIC;IAJD,2CAIC;;;;IAtBT,iCAAkE;IAAlC,2LAAS,8BAAuB,KAAC;IAC/D,iCAQqC;IAAnC,wJAAS,wBAAwB,KAAC;IAGlC,iGAA0B;IAe1B,iCAA4B;IAC1B,kBAAyB;IAC3B,oBAAM;IAGN,qBAAoD;IAExD,AADE,oBAAM,EACF;;;IA7BF,cAA6B;IAG7B,AADA,AADA,AADA,6CAA6B,iCACE,qBACL,sBACC;;IAI3B,cAYC;IAZD,2DAYC;;;AAxDX,MAAM,QAAQ,GAAiC;IAC7C,EAAE,EAAE,OAAO;IACX,EAAE,EAAE,OAAO;IACX,EAAE,EAAE,OAAO;IACX,EAAE,EAAE,QAAQ;IACZ,IAAI,EAAE,MAAM;CACb,CAAC;AAEF;;;;;;;;;;;;;;;;;;GAkBG;AA4CH,MAAM,OAAO,iBAAiB;IACpB,QAAQ,GAAG,KAAK,CAAC;IACjB,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;IAE1B,IACI,OAAO,CAAC,KAAc;QACxB,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC;QACjC,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QACtB,IAAI,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,CAAC;QACD,IAAI,CAAC,KAAK,IAAI,UAAU,EAAE,CAAC;YACzB,IAAI,CAAC,eAAe,EAAE,CAAC;QACzB,CAAC;IACH,CAAC;IACD,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAEQ,KAAK,GAAG,EAAE,CAAC;IACX,KAAK,GAA2B,IAAI,CAAC;IACrC,MAAM,GAA2B,IAAI,CAAC;IACtC,IAAI,GAAiB,MAAM,CAAC;IAC5B,SAAS,GAAG,IAAI,CAAC;IACjB,QAAQ,GAAkB,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"dialog.component.js","sourceRoot":"","sources":["../../../src/lib/dialog/dialog.component.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n Input,\n Output,\n EventEmitter,\n HostListener,\n ElementRef,\n ViewChild,\n AfterViewInit,\n OnDestroy,\n inject\n} from '@angular/core';\n\nexport type MjDialogSize = 'sm' | 'md' | 'lg' | 'xl' | 'auto';\n\nconst SIZE_MAP: Record<MjDialogSize, string> = {\n sm: '400px',\n md: '600px',\n lg: '800px',\n xl: '1000px',\n auto: 'auto'\n};\n\n/**\n * mj-dialog — Modal dialog component using native `<dialog>` element.\n *\n * Replaces `<kendo-dialog>`.\n *\n * Supports both explicit width/height and size presets.\n * Content is projected, with an optional `<mj-dialog-actions>` for the footer.\n *\n * @example\n * ```html\n * <mj-dialog [Visible]=\"showDialog\" Title=\"Confirm\" (Close)=\"onClose()\">\n * <p>Are you sure?</p>\n * <mj-dialog-actions>\n * <button mjButton variant=\"primary\" (click)=\"onConfirm()\">Yes</button>\n * <button mjButton (click)=\"onClose()\">No</button>\n * </mj-dialog-actions>\n * </mj-dialog>\n * ```\n */\n@Component({\n selector: 'mj-dialog',\n standalone: true,\n template: `\n @if (Visible) {\n <div class=\"mj-dialog-backdrop\" (click)=\"OnBackdropClick($event)\">\n <div class=\"mj-dialog-container\"\n [attr.role]=\"Role\"\n aria-modal=\"true\"\n [attr.aria-labelledby]=\"Title ? 'mj-dialog-title-' + dialogId : null\"\n [style.width]=\"resolvedWidth\"\n [style.height]=\"resolvedHeight\"\n [style.max-width]=\"'90vw'\"\n [style.max-height]=\"'90vh'\"\n (click)=\"$event.stopPropagation()\">\n\n <!-- Title bar -->\n @if (Title || Closeable) {\n <div class=\"mj-dialog-titlebar\">\n @if (Title) {\n <h2 class=\"mj-dialog-title\" [id]=\"'mj-dialog-title-' + dialogId\">{{ Title }}</h2>\n }\n <ng-content select=\"mj-dialog-titlebar\"></ng-content>\n @if (Closeable) {\n <button class=\"mj-dialog-close\" (click)=\"OnCloseClick()\" aria-label=\"Close dialog\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n }\n </div>\n }\n\n <!-- Body -->\n <div class=\"mj-dialog-body\">\n <ng-content></ng-content>\n </div>\n\n <!-- Actions (projected) -->\n <ng-content select=\"mj-dialog-actions\"></ng-content>\n </div>\n </div>\n }\n `\n})\nexport class MJDialogComponent implements OnDestroy {\n private _visible = false;\n private static nextId = 0;\n\n @Input()\n set Visible(value: boolean) {\n const wasVisible = this._visible;\n this._visible = value;\n if (value && !wasVisible) {\n this.onOpen();\n }\n if (!value && wasVisible) {\n this.onCloseInternal();\n }\n }\n get Visible(): boolean {\n return this._visible;\n }\n\n @Input() Title = '';\n @Input() Width: number | string | null = null;\n @Input() Height: number | string | null = null;\n @Input() Size: MjDialogSize = 'auto';\n @Input() Closeable = true;\n @Input() MinWidth: number | null = null;\n\n /**\n * ARIA role for the dialog container. Defaults to `'dialog'`; pass\n * `'alertdialog'` for confirmation / destructive prompts that interrupt the\n * user (per WAI-ARIA, an alertdialog conveys an urgent message requiring a\n * response). Backward compatible — existing callers keep `'dialog'`.\n */\n @Input() Role: 'dialog' | 'alertdialog' = 'dialog';\n\n @Output() Close = new EventEmitter<void>();\n\n DialogId = MJDialogComponent.nextId++;\n\n get dialogId(): number {\n return this.DialogId;\n }\n\n get resolvedWidth(): string {\n if (this.Width) {\n return typeof this.Width === 'number' ? `${this.Width}px` : this.Width;\n }\n return SIZE_MAP[this.Size] ?? 'auto';\n }\n\n get resolvedHeight(): string {\n if (this.Height) {\n return typeof this.Height === 'number' ? `${this.Height}px` : this.Height;\n }\n return 'auto';\n }\n\n @HostListener('document:keydown.escape')\n OnEscapeKey(): void {\n if (this.Visible && this.Closeable) {\n this.OnCloseClick();\n }\n }\n\n OnBackdropClick(event: Event): void {\n if (this.Closeable) {\n this.OnCloseClick();\n }\n }\n\n OnCloseClick(): void {\n this.Close.emit();\n }\n\n private onOpen(): void {\n document.body.style.overflow = 'hidden';\n }\n\n private onCloseInternal(): void {\n document.body.style.overflow = '';\n }\n\n ngOnDestroy(): void {\n document.body.style.overflow = '';\n }\n}\n\n/**\n * mj-dialog-titlebar — Custom titlebar content for mj-dialog.\n *\n * Replaces `<kendo-dialog-titlebar>`.\n *\n * @example\n * ```html\n * <mj-dialog [Visible]=\"show\" (Close)=\"onClose()\">\n * <mj-dialog-titlebar>\n * <i class=\"fa-solid fa-save\"></i> Custom Title\n * </mj-dialog-titlebar>\n * <p>Dialog content</p>\n * </mj-dialog>\n * ```\n */\n@Component({\n selector: 'mj-dialog-titlebar',\n standalone: true,\n template: `<ng-content></ng-content>`\n})\nexport class MJDialogTitlebarComponent {}\n\n/**\n * mj-dialog-actions — Footer action bar for mj-dialog.\n *\n * Replaces `<kendo-dialog-actions>`.\n *\n * @example\n * ```html\n * <mj-dialog-actions>\n * <button mjButton variant=\"primary\">Save</button>\n * <button mjButton>Cancel</button>\n * </mj-dialog-actions>\n * ```\n */\n@Component({\n selector: 'mj-dialog-actions',\n standalone: true,\n template: `\n <div class=\"mj-dialog-actions\">\n <ng-content></ng-content>\n </div>\n `\n})\nexport class MJDialogActionsComponent {}\n"]}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { EventEmitter } from '@angular/core';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
/**
|
|
4
|
+
* Visual intent of an `<mj-empty-state>`. Drives the default icon and the icon's
|
|
5
|
+
* color treatment so callers don't restate either for the common cases.
|
|
6
|
+
*
|
|
7
|
+
* - `empty` — nothing exists yet (default). Neutral/disabled icon tone.
|
|
8
|
+
* - `no-results` — a search/filter matched nothing. Muted icon tone, magnifier default.
|
|
9
|
+
* - `success` — a positive "all clear" empty (e.g. "No Errors Found"). Success icon tone, check default.
|
|
10
|
+
* - `warning` — a non-error blocking condition (disabled/misconfigured feature). Warning icon tone.
|
|
11
|
+
* - `error` — a load/operation failed. Error icon tone, triangle default.
|
|
12
|
+
*/
|
|
13
|
+
export type MJEmptyStateVariant = 'empty' | 'no-results' | 'success' | 'warning' | 'error';
|
|
14
|
+
/** Density of an `<mj-empty-state>` — controls padding and icon size. */
|
|
15
|
+
export type MJEmptyStateSize = 'compact' | 'default' | 'large';
|
|
16
|
+
/**
|
|
17
|
+
* mj-empty-state — Canonical centered empty/no-results/error placeholder.
|
|
18
|
+
*
|
|
19
|
+
* Replaces the ~213 inline empty-state `<div>`s that pages were each hand-rolling
|
|
20
|
+
* (icon + title + message, optionally a CTA), e.g.:
|
|
21
|
+
* ```html
|
|
22
|
+
* <div class="empty-state">
|
|
23
|
+
* <i class="fa-solid fa-inbox"></i>
|
|
24
|
+
* <h3>No Permissions Found</h3>
|
|
25
|
+
* <p>Try adjusting your filters or refresh the data.</p>
|
|
26
|
+
* <button mjButton variant="primary" (click)="refreshData()">Refresh</button>
|
|
27
|
+
* </div>
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* Usage:
|
|
31
|
+
* ```html
|
|
32
|
+
* <!-- Simplest: nothing-here placeholder -->
|
|
33
|
+
* <mj-empty-state Title="No runs found" Message="No runs match the selected filters." />
|
|
34
|
+
*
|
|
35
|
+
* <!-- Search/filter produced nothing -->
|
|
36
|
+
* <mj-empty-state Variant="no-results" Title="No icons found" Message="Try a different search term." />
|
|
37
|
+
*
|
|
38
|
+
* <!-- Load failed, retry CTA -->
|
|
39
|
+
* <mj-empty-state Variant="error" Title="Couldn't load permissions" [Message]="error"
|
|
40
|
+
* ActionText="Try Again" ActionIcon="fa-solid fa-rotate-right" (Action)="loadData()" />
|
|
41
|
+
*
|
|
42
|
+
* <!-- Invitation to create the first record -->
|
|
43
|
+
* <mj-empty-state Icon="fa-solid fa-key" Title="No API keys yet"
|
|
44
|
+
* Message="Generate a key to start calling the API."
|
|
45
|
+
* ActionText="Generate Your First Key" ActionIcon="fa-solid fa-plus"
|
|
46
|
+
* (Action)="requestCreate()" />
|
|
47
|
+
*
|
|
48
|
+
* <!-- Multiple / bespoke CTAs: project them into the [actions] slot -->
|
|
49
|
+
* <mj-empty-state Title="No pinned items yet" Message="Pin dashboards for quick access.">
|
|
50
|
+
* <button mjButton variant="primary" (click)="addPin()">Add your first pin</button>
|
|
51
|
+
* <button mjButton variant="flat" (click)="dismiss()">Don't show again</button>
|
|
52
|
+
* </mj-empty-state>
|
|
53
|
+
* ```
|
|
54
|
+
*
|
|
55
|
+
* For dynamic messages (e.g. "No keys matching X" vs "No keys yet"), compute the
|
|
56
|
+
* string in the parent and bind it to `[Message]`, or project richer body content
|
|
57
|
+
* as default `<ng-content>` (rendered between the message and the actions).
|
|
58
|
+
*/
|
|
59
|
+
export declare class MJEmptyStateComponent {
|
|
60
|
+
/**
|
|
61
|
+
* Font Awesome icon class string (e.g. "fa-solid fa-key"). When omitted, a
|
|
62
|
+
* sensible default is chosen from `Variant`. Pass an empty string AND no
|
|
63
|
+
* variant default applies — set this explicitly to "" to render no icon.
|
|
64
|
+
*/
|
|
65
|
+
Icon: string | null;
|
|
66
|
+
/** Bold heading line (e.g. "No API keys yet"). */
|
|
67
|
+
Title: string;
|
|
68
|
+
/** Supporting/help text below the title. */
|
|
69
|
+
Message: string;
|
|
70
|
+
/** When set, renders a primary CTA button with this label. */
|
|
71
|
+
ActionText: string;
|
|
72
|
+
/** Optional Font Awesome icon shown inside the CTA button. */
|
|
73
|
+
ActionIcon: string;
|
|
74
|
+
/** mjButton variant for the built-in CTA. Defaults to 'primary'. */
|
|
75
|
+
ActionVariant: 'primary' | 'secondary' | 'outline' | 'flat';
|
|
76
|
+
/** Visual intent — drives the default icon and icon color. Defaults to 'empty'. */
|
|
77
|
+
Variant: MJEmptyStateVariant;
|
|
78
|
+
/** Density — controls padding and icon size. Defaults to 'default'. */
|
|
79
|
+
Size: MJEmptyStateSize;
|
|
80
|
+
/**
|
|
81
|
+
* ARIA live-region role on the host. When unset, it defaults from `Variant`:
|
|
82
|
+
* `error` → `'alert'` (assertive), everything else → `'status'` (polite). This
|
|
83
|
+
* makes a dynamically-appearing empty state announce itself to screen readers —
|
|
84
|
+
* the title + message are read together via the role's implicit
|
|
85
|
+
* `aria-live`/`aria-atomic`. (Empty states present at page load are not
|
|
86
|
+
* announced, per the live-region spec, so static placeholders stay quiet.)
|
|
87
|
+
* Pass an explicit role to override, or `''` to opt out of the live region.
|
|
88
|
+
*/
|
|
89
|
+
Role: string | null;
|
|
90
|
+
/** Emitted when the built-in CTA button is clicked. */
|
|
91
|
+
Action: EventEmitter<MouseEvent>;
|
|
92
|
+
get IsCompact(): boolean;
|
|
93
|
+
get IsLarge(): boolean;
|
|
94
|
+
get IsNoResults(): boolean;
|
|
95
|
+
get IsSuccess(): boolean;
|
|
96
|
+
get IsWarning(): boolean;
|
|
97
|
+
get IsError(): boolean;
|
|
98
|
+
/**
|
|
99
|
+
* Live-region role applied to the host. Explicit `Role` wins (`''` ⇒ no role);
|
|
100
|
+
* otherwise an error state is an assertive `alert`, everything else a polite `status`.
|
|
101
|
+
*/
|
|
102
|
+
get HostRole(): string | null;
|
|
103
|
+
/**
|
|
104
|
+
* Icon actually rendered: the explicit `Icon` when provided (including ""
|
|
105
|
+
* to suppress the icon), otherwise the per-variant default.
|
|
106
|
+
*/
|
|
107
|
+
get ResolvedIcon(): string;
|
|
108
|
+
/** Default Font Awesome icon for each variant. */
|
|
109
|
+
static DefaultIconForVariant(variant: MJEmptyStateVariant): string;
|
|
110
|
+
OnAction(event: MouseEvent): void;
|
|
111
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<MJEmptyStateComponent, never>;
|
|
112
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<MJEmptyStateComponent, "mj-empty-state", never, { "Icon": { "alias": "Icon"; "required": false; }; "Title": { "alias": "Title"; "required": false; }; "Message": { "alias": "Message"; "required": false; }; "ActionText": { "alias": "ActionText"; "required": false; }; "ActionIcon": { "alias": "ActionIcon"; "required": false; }; "ActionVariant": { "alias": "ActionVariant"; "required": false; }; "Variant": { "alias": "Variant"; "required": false; }; "Size": { "alias": "Size"; "required": false; }; "Role": { "alias": "Role"; "required": false; }; }, { "Action": "Action"; }, never, ["*", "[actions]"], true, never>;
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=empty-state.component.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"empty-state.component.d.ts","sourceRoot":"","sources":["../../../src/lib/empty-state/empty-state.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,YAAY,EAA8B,MAAM,eAAe,CAAC;;AAGpF;;;;;;;;;GASG;AACH,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AAE3F,yEAAyE;AACzE,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AAE/D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,qBA6Ga,qBAAqB;IAChC;;;;OAIG;IACM,IAAI,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEpC,kDAAkD;IACzC,KAAK,EAAE,MAAM,CAAM;IAE5B,4CAA4C;IACnC,OAAO,EAAE,MAAM,CAAM;IAE9B,8DAA8D;IACrD,UAAU,EAAE,MAAM,CAAM;IAEjC,8DAA8D;IACrD,UAAU,EAAE,MAAM,CAAM;IAEjC,oEAAoE;IAC3D,aAAa,EAAE,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,MAAM,CAAa;IAEjF,mFAAmF;IAC1E,OAAO,EAAE,mBAAmB,CAAW;IAEhD,uEAAuE;IAC9D,IAAI,EAAE,gBAAgB,CAAa;IAE5C;;;;;;;;OAQG;IACM,IAAI,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEpC,uDAAuD;IAC7C,MAAM,2BAAkC;IAElD,IACI,SAAS,IAAI,OAAO,CAAoC;IAE5D,IACI,OAAO,IAAI,OAAO,CAAkC;IAExD,IACI,WAAW,IAAI,OAAO,CAA0C;IAEpE,IACI,SAAS,IAAI,OAAO,CAAuC;IAE/D,IACI,SAAS,IAAI,OAAO,CAAuC;IAE/D,IACI,OAAO,IAAI,OAAO,CAAqC;IAE3D;;;OAGG;IACH,IACI,QAAQ,IAAI,MAAM,GAAG,IAAI,CAK5B;IAED;;;OAGG;IACH,IAAI,YAAY,IAAI,MAAM,CAKzB;IAED,kDAAkD;IAClD,MAAM,CAAC,qBAAqB,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM;IAelE,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;yCApGtB,qBAAqB;2CAArB,qBAAqB;CAuGjC"}
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
import { Component, EventEmitter, HostBinding, Input, Output } from '@angular/core';
|
|
2
|
+
import { MJButtonDirective } from '../button/button.directive';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
const _c0 = ["*", [["", "actions", ""]]];
|
|
5
|
+
const _c1 = ["*", "[actions]"];
|
|
6
|
+
function MJEmptyStateComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
7
|
+
i0.ɵɵelement(0, "i", 5);
|
|
8
|
+
} if (rf & 2) {
|
|
9
|
+
const ctx_r0 = i0.ɵɵnextContext();
|
|
10
|
+
i0.ɵɵclassMap(i0.ɵɵinterpolate1("mj-empty-state__icon ", ctx_r0.ResolvedIcon));
|
|
11
|
+
} }
|
|
12
|
+
function MJEmptyStateComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
13
|
+
i0.ɵɵelementStart(0, "h3", 1);
|
|
14
|
+
i0.ɵɵtext(1);
|
|
15
|
+
i0.ɵɵelementEnd();
|
|
16
|
+
} if (rf & 2) {
|
|
17
|
+
const ctx_r0 = i0.ɵɵnextContext();
|
|
18
|
+
i0.ɵɵadvance();
|
|
19
|
+
i0.ɵɵtextInterpolate(ctx_r0.Title);
|
|
20
|
+
} }
|
|
21
|
+
function MJEmptyStateComponent_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
22
|
+
i0.ɵɵelementStart(0, "p", 2);
|
|
23
|
+
i0.ɵɵtext(1);
|
|
24
|
+
i0.ɵɵelementEnd();
|
|
25
|
+
} if (rf & 2) {
|
|
26
|
+
const ctx_r0 = i0.ɵɵnextContext();
|
|
27
|
+
i0.ɵɵadvance();
|
|
28
|
+
i0.ɵɵtextInterpolate(ctx_r0.Message);
|
|
29
|
+
} }
|
|
30
|
+
function MJEmptyStateComponent_Conditional_5_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
31
|
+
i0.ɵɵelement(0, "i", 5);
|
|
32
|
+
} if (rf & 2) {
|
|
33
|
+
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
34
|
+
i0.ɵɵclassMap(ctx_r0.ActionIcon);
|
|
35
|
+
} }
|
|
36
|
+
function MJEmptyStateComponent_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
37
|
+
const _r2 = i0.ɵɵgetCurrentView();
|
|
38
|
+
i0.ɵɵelementStart(0, "button", 6);
|
|
39
|
+
i0.ɵɵlistener("click", function MJEmptyStateComponent_Conditional_5_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnAction($event)); });
|
|
40
|
+
i0.ɵɵconditionalCreate(1, MJEmptyStateComponent_Conditional_5_Conditional_1_Template, 1, 2, "i", 0);
|
|
41
|
+
i0.ɵɵtext(2);
|
|
42
|
+
i0.ɵɵelementEnd();
|
|
43
|
+
} if (rf & 2) {
|
|
44
|
+
const ctx_r0 = i0.ɵɵnextContext();
|
|
45
|
+
i0.ɵɵproperty("variant", ctx_r0.ActionVariant);
|
|
46
|
+
i0.ɵɵadvance();
|
|
47
|
+
i0.ɵɵconditional(ctx_r0.ActionIcon ? 1 : -1);
|
|
48
|
+
i0.ɵɵadvance();
|
|
49
|
+
i0.ɵɵtextInterpolate1(" ", ctx_r0.ActionText, " ");
|
|
50
|
+
} }
|
|
51
|
+
/**
|
|
52
|
+
* mj-empty-state — Canonical centered empty/no-results/error placeholder.
|
|
53
|
+
*
|
|
54
|
+
* Replaces the ~213 inline empty-state `<div>`s that pages were each hand-rolling
|
|
55
|
+
* (icon + title + message, optionally a CTA), e.g.:
|
|
56
|
+
* ```html
|
|
57
|
+
* <div class="empty-state">
|
|
58
|
+
* <i class="fa-solid fa-inbox"></i>
|
|
59
|
+
* <h3>No Permissions Found</h3>
|
|
60
|
+
* <p>Try adjusting your filters or refresh the data.</p>
|
|
61
|
+
* <button mjButton variant="primary" (click)="refreshData()">Refresh</button>
|
|
62
|
+
* </div>
|
|
63
|
+
* ```
|
|
64
|
+
*
|
|
65
|
+
* Usage:
|
|
66
|
+
* ```html
|
|
67
|
+
* <!-- Simplest: nothing-here placeholder -->
|
|
68
|
+
* <mj-empty-state Title="No runs found" Message="No runs match the selected filters." />
|
|
69
|
+
*
|
|
70
|
+
* <!-- Search/filter produced nothing -->
|
|
71
|
+
* <mj-empty-state Variant="no-results" Title="No icons found" Message="Try a different search term." />
|
|
72
|
+
*
|
|
73
|
+
* <!-- Load failed, retry CTA -->
|
|
74
|
+
* <mj-empty-state Variant="error" Title="Couldn't load permissions" [Message]="error"
|
|
75
|
+
* ActionText="Try Again" ActionIcon="fa-solid fa-rotate-right" (Action)="loadData()" />
|
|
76
|
+
*
|
|
77
|
+
* <!-- Invitation to create the first record -->
|
|
78
|
+
* <mj-empty-state Icon="fa-solid fa-key" Title="No API keys yet"
|
|
79
|
+
* Message="Generate a key to start calling the API."
|
|
80
|
+
* ActionText="Generate Your First Key" ActionIcon="fa-solid fa-plus"
|
|
81
|
+
* (Action)="requestCreate()" />
|
|
82
|
+
*
|
|
83
|
+
* <!-- Multiple / bespoke CTAs: project them into the [actions] slot -->
|
|
84
|
+
* <mj-empty-state Title="No pinned items yet" Message="Pin dashboards for quick access.">
|
|
85
|
+
* <button mjButton variant="primary" (click)="addPin()">Add your first pin</button>
|
|
86
|
+
* <button mjButton variant="flat" (click)="dismiss()">Don't show again</button>
|
|
87
|
+
* </mj-empty-state>
|
|
88
|
+
* ```
|
|
89
|
+
*
|
|
90
|
+
* For dynamic messages (e.g. "No keys matching X" vs "No keys yet"), compute the
|
|
91
|
+
* string in the parent and bind it to `[Message]`, or project richer body content
|
|
92
|
+
* as default `<ng-content>` (rendered between the message and the actions).
|
|
93
|
+
*/
|
|
94
|
+
export class MJEmptyStateComponent {
|
|
95
|
+
/**
|
|
96
|
+
* Font Awesome icon class string (e.g. "fa-solid fa-key"). When omitted, a
|
|
97
|
+
* sensible default is chosen from `Variant`. Pass an empty string AND no
|
|
98
|
+
* variant default applies — set this explicitly to "" to render no icon.
|
|
99
|
+
*/
|
|
100
|
+
Icon = null;
|
|
101
|
+
/** Bold heading line (e.g. "No API keys yet"). */
|
|
102
|
+
Title = '';
|
|
103
|
+
/** Supporting/help text below the title. */
|
|
104
|
+
Message = '';
|
|
105
|
+
/** When set, renders a primary CTA button with this label. */
|
|
106
|
+
ActionText = '';
|
|
107
|
+
/** Optional Font Awesome icon shown inside the CTA button. */
|
|
108
|
+
ActionIcon = '';
|
|
109
|
+
/** mjButton variant for the built-in CTA. Defaults to 'primary'. */
|
|
110
|
+
ActionVariant = 'primary';
|
|
111
|
+
/** Visual intent — drives the default icon and icon color. Defaults to 'empty'. */
|
|
112
|
+
Variant = 'empty';
|
|
113
|
+
/** Density — controls padding and icon size. Defaults to 'default'. */
|
|
114
|
+
Size = 'default';
|
|
115
|
+
/**
|
|
116
|
+
* ARIA live-region role on the host. When unset, it defaults from `Variant`:
|
|
117
|
+
* `error` → `'alert'` (assertive), everything else → `'status'` (polite). This
|
|
118
|
+
* makes a dynamically-appearing empty state announce itself to screen readers —
|
|
119
|
+
* the title + message are read together via the role's implicit
|
|
120
|
+
* `aria-live`/`aria-atomic`. (Empty states present at page load are not
|
|
121
|
+
* announced, per the live-region spec, so static placeholders stay quiet.)
|
|
122
|
+
* Pass an explicit role to override, or `''` to opt out of the live region.
|
|
123
|
+
*/
|
|
124
|
+
Role = null;
|
|
125
|
+
/** Emitted when the built-in CTA button is clicked. */
|
|
126
|
+
Action = new EventEmitter();
|
|
127
|
+
get IsCompact() { return this.Size === 'compact'; }
|
|
128
|
+
get IsLarge() { return this.Size === 'large'; }
|
|
129
|
+
get IsNoResults() { return this.Variant === 'no-results'; }
|
|
130
|
+
get IsSuccess() { return this.Variant === 'success'; }
|
|
131
|
+
get IsWarning() { return this.Variant === 'warning'; }
|
|
132
|
+
get IsError() { return this.Variant === 'error'; }
|
|
133
|
+
/**
|
|
134
|
+
* Live-region role applied to the host. Explicit `Role` wins (`''` ⇒ no role);
|
|
135
|
+
* otherwise an error state is an assertive `alert`, everything else a polite `status`.
|
|
136
|
+
*/
|
|
137
|
+
get HostRole() {
|
|
138
|
+
if (this.Role != null) {
|
|
139
|
+
return this.Role || null;
|
|
140
|
+
}
|
|
141
|
+
return this.Variant === 'error' ? 'alert' : 'status';
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Icon actually rendered: the explicit `Icon` when provided (including ""
|
|
145
|
+
* to suppress the icon), otherwise the per-variant default.
|
|
146
|
+
*/
|
|
147
|
+
get ResolvedIcon() {
|
|
148
|
+
if (this.Icon != null) {
|
|
149
|
+
return this.Icon;
|
|
150
|
+
}
|
|
151
|
+
return MJEmptyStateComponent.DefaultIconForVariant(this.Variant);
|
|
152
|
+
}
|
|
153
|
+
/** Default Font Awesome icon for each variant. */
|
|
154
|
+
static DefaultIconForVariant(variant) {
|
|
155
|
+
switch (variant) {
|
|
156
|
+
case 'no-results':
|
|
157
|
+
return 'fa-solid fa-magnifying-glass';
|
|
158
|
+
case 'success':
|
|
159
|
+
return 'fa-solid fa-circle-check';
|
|
160
|
+
case 'warning':
|
|
161
|
+
case 'error':
|
|
162
|
+
return 'fa-solid fa-triangle-exclamation';
|
|
163
|
+
case 'empty':
|
|
164
|
+
default:
|
|
165
|
+
return 'fa-solid fa-inbox';
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
OnAction(event) {
|
|
169
|
+
this.Action.emit(event);
|
|
170
|
+
}
|
|
171
|
+
static ɵfac = function MJEmptyStateComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || MJEmptyStateComponent)(); };
|
|
172
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MJEmptyStateComponent, selectors: [["mj-empty-state"]], hostVars: 13, hostBindings: function MJEmptyStateComponent_HostBindings(rf, ctx) { if (rf & 2) {
|
|
173
|
+
i0.ɵɵattribute("role", ctx.HostRole);
|
|
174
|
+
i0.ɵɵclassProp("mj-empty-state--compact", ctx.IsCompact)("mj-empty-state--large", ctx.IsLarge)("mj-empty-state--no-results", ctx.IsNoResults)("mj-empty-state--success", ctx.IsSuccess)("mj-empty-state--warning", ctx.IsWarning)("mj-empty-state--error", ctx.IsError);
|
|
175
|
+
} }, inputs: { Icon: "Icon", Title: "Title", Message: "Message", ActionText: "ActionText", ActionIcon: "ActionIcon", ActionVariant: "ActionVariant", Variant: "Variant", Size: "Size", Role: "Role" }, outputs: { Action: "Action" }, ngContentSelectors: _c1, decls: 7, vars: 4, consts: [["aria-hidden", "true", 3, "class"], [1, "mj-empty-state__title"], [1, "mj-empty-state__message"], [1, "mj-empty-state__actions"], ["type", "button", "mjButton", "", 3, "variant"], ["aria-hidden", "true"], ["type", "button", "mjButton", "", 3, "click", "variant"]], template: function MJEmptyStateComponent_Template(rf, ctx) { if (rf & 1) {
|
|
176
|
+
i0.ɵɵprojectionDef(_c0);
|
|
177
|
+
i0.ɵɵconditionalCreate(0, MJEmptyStateComponent_Conditional_0_Template, 1, 3, "i", 0);
|
|
178
|
+
i0.ɵɵconditionalCreate(1, MJEmptyStateComponent_Conditional_1_Template, 2, 1, "h3", 1);
|
|
179
|
+
i0.ɵɵconditionalCreate(2, MJEmptyStateComponent_Conditional_2_Template, 2, 1, "p", 2);
|
|
180
|
+
i0.ɵɵprojection(3);
|
|
181
|
+
i0.ɵɵelementStart(4, "div", 3);
|
|
182
|
+
i0.ɵɵconditionalCreate(5, MJEmptyStateComponent_Conditional_5_Template, 3, 3, "button", 4);
|
|
183
|
+
i0.ɵɵprojection(6, 1);
|
|
184
|
+
i0.ɵɵelementEnd();
|
|
185
|
+
} if (rf & 2) {
|
|
186
|
+
i0.ɵɵconditional(ctx.ResolvedIcon ? 0 : -1);
|
|
187
|
+
i0.ɵɵadvance();
|
|
188
|
+
i0.ɵɵconditional(ctx.Title ? 1 : -1);
|
|
189
|
+
i0.ɵɵadvance();
|
|
190
|
+
i0.ɵɵconditional(ctx.Message ? 2 : -1);
|
|
191
|
+
i0.ɵɵadvance(3);
|
|
192
|
+
i0.ɵɵconditional(ctx.ActionText ? 5 : -1);
|
|
193
|
+
} }, dependencies: [MJButtonDirective], styles: ["[_nghost-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n text-align: center;\n padding: var(--mj-space-12);\n color: var(--mj-text-secondary);\n }\n\n .mj-empty-state__icon[_ngcontent-%COMP%] {\n font-size: 3rem;\n line-height: 1;\n margin-bottom: var(--mj-space-4);\n color: var(--mj-text-disabled);\n }\n\n .mj-empty-state__title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: var(--mj-text-lg);\n font-weight: 600;\n color: var(--mj-text-primary);\n }\n\n .mj-empty-state__message[_ngcontent-%COMP%] {\n margin: var(--mj-space-2) 0 0;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-muted);\n max-width: 420px;\n }\n\n .mj-empty-state__actions[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: center;\n gap: var(--mj-space-2);\n margin-top: var(--mj-space-6);\n }\n \n\n\n .mj-empty-state__actions[_ngcontent-%COMP%]:empty {\n display: none;\n }\n\n \n\n .mj-empty-state--compact[_nghost-%COMP%] {\n padding: var(--mj-space-8);\n }\n .mj-empty-state--compact[_nghost-%COMP%] .mj-empty-state__icon[_ngcontent-%COMP%] {\n font-size: 2rem;\n margin-bottom: var(--mj-space-3);\n }\n\n .mj-empty-state--large[_nghost-%COMP%] {\n padding: var(--mj-space-16) var(--mj-space-10);\n }\n .mj-empty-state--large[_nghost-%COMP%] .mj-empty-state__icon[_ngcontent-%COMP%] {\n font-size: 4rem;\n }\n\n \n\n .mj-empty-state--no-results[_nghost-%COMP%] .mj-empty-state__icon[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n }\n .mj-empty-state--success[_nghost-%COMP%] .mj-empty-state__icon[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n }\n .mj-empty-state--warning[_nghost-%COMP%] .mj-empty-state__icon[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n }\n .mj-empty-state--error[_nghost-%COMP%] .mj-empty-state__icon[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n }"] });
|
|
194
|
+
}
|
|
195
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJEmptyStateComponent, [{
|
|
196
|
+
type: Component,
|
|
197
|
+
args: [{ selector: 'mj-empty-state', standalone: true, imports: [MJButtonDirective], template: `
|
|
198
|
+
@if (ResolvedIcon) {
|
|
199
|
+
<i class="mj-empty-state__icon {{ ResolvedIcon }}" aria-hidden="true"></i>
|
|
200
|
+
}
|
|
201
|
+
@if (Title) {
|
|
202
|
+
<h3 class="mj-empty-state__title">{{ Title }}</h3>
|
|
203
|
+
}
|
|
204
|
+
@if (Message) {
|
|
205
|
+
<p class="mj-empty-state__message">{{ Message }}</p>
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
<!-- Optional richer body content (feature lists, dynamic text, links) -->
|
|
209
|
+
<ng-content></ng-content>
|
|
210
|
+
|
|
211
|
+
<!-- Actions: the built-in single CTA and/or projected [actions] buttons.
|
|
212
|
+
Hidden via :empty when neither is present. -->
|
|
213
|
+
<div class="mj-empty-state__actions">
|
|
214
|
+
@if (ActionText) {
|
|
215
|
+
<button type="button" mjButton [variant]="ActionVariant" (click)="OnAction($event)">
|
|
216
|
+
@if (ActionIcon) {
|
|
217
|
+
<i class="{{ ActionIcon }}" aria-hidden="true"></i>
|
|
218
|
+
}
|
|
219
|
+
{{ ActionText }}
|
|
220
|
+
</button>
|
|
221
|
+
}
|
|
222
|
+
<ng-content select="[actions]"></ng-content>
|
|
223
|
+
</div>
|
|
224
|
+
`, styles: ["\n :host {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n text-align: center;\n padding: var(--mj-space-12);\n color: var(--mj-text-secondary);\n }\n\n .mj-empty-state__icon {\n font-size: 3rem;\n line-height: 1;\n margin-bottom: var(--mj-space-4);\n color: var(--mj-text-disabled);\n }\n\n .mj-empty-state__title {\n margin: 0;\n font-size: var(--mj-text-lg);\n font-weight: 600;\n color: var(--mj-text-primary);\n }\n\n .mj-empty-state__message {\n margin: var(--mj-space-2) 0 0;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-muted);\n max-width: 420px;\n }\n\n .mj-empty-state__actions {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: center;\n gap: var(--mj-space-2);\n margin-top: var(--mj-space-6);\n }\n /* Collapse the actions row entirely when no CTA is rendered (modern browsers\n treat an element containing only Angular's @if comment-anchors as :empty). */\n .mj-empty-state__actions:empty {\n display: none;\n }\n\n /* \u2500\u2500 Sizes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n :host(.mj-empty-state--compact) {\n padding: var(--mj-space-8);\n }\n :host(.mj-empty-state--compact) .mj-empty-state__icon {\n font-size: 2rem;\n margin-bottom: var(--mj-space-3);\n }\n\n :host(.mj-empty-state--large) {\n padding: var(--mj-space-16) var(--mj-space-10);\n }\n :host(.mj-empty-state--large) .mj-empty-state__icon {\n font-size: 4rem;\n }\n\n /* \u2500\u2500 Variants (icon tone) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n :host(.mj-empty-state--no-results) .mj-empty-state__icon {\n color: var(--mj-text-muted);\n }\n :host(.mj-empty-state--success) .mj-empty-state__icon {\n color: var(--mj-status-success);\n }\n :host(.mj-empty-state--warning) .mj-empty-state__icon {\n color: var(--mj-status-warning);\n }\n :host(.mj-empty-state--error) .mj-empty-state__icon {\n color: var(--mj-status-error);\n }\n "] }]
|
|
225
|
+
}], null, { Icon: [{
|
|
226
|
+
type: Input
|
|
227
|
+
}], Title: [{
|
|
228
|
+
type: Input
|
|
229
|
+
}], Message: [{
|
|
230
|
+
type: Input
|
|
231
|
+
}], ActionText: [{
|
|
232
|
+
type: Input
|
|
233
|
+
}], ActionIcon: [{
|
|
234
|
+
type: Input
|
|
235
|
+
}], ActionVariant: [{
|
|
236
|
+
type: Input
|
|
237
|
+
}], Variant: [{
|
|
238
|
+
type: Input
|
|
239
|
+
}], Size: [{
|
|
240
|
+
type: Input
|
|
241
|
+
}], Role: [{
|
|
242
|
+
type: Input
|
|
243
|
+
}], Action: [{
|
|
244
|
+
type: Output
|
|
245
|
+
}], IsCompact: [{
|
|
246
|
+
type: HostBinding,
|
|
247
|
+
args: ['class.mj-empty-state--compact']
|
|
248
|
+
}], IsLarge: [{
|
|
249
|
+
type: HostBinding,
|
|
250
|
+
args: ['class.mj-empty-state--large']
|
|
251
|
+
}], IsNoResults: [{
|
|
252
|
+
type: HostBinding,
|
|
253
|
+
args: ['class.mj-empty-state--no-results']
|
|
254
|
+
}], IsSuccess: [{
|
|
255
|
+
type: HostBinding,
|
|
256
|
+
args: ['class.mj-empty-state--success']
|
|
257
|
+
}], IsWarning: [{
|
|
258
|
+
type: HostBinding,
|
|
259
|
+
args: ['class.mj-empty-state--warning']
|
|
260
|
+
}], IsError: [{
|
|
261
|
+
type: HostBinding,
|
|
262
|
+
args: ['class.mj-empty-state--error']
|
|
263
|
+
}], HostRole: [{
|
|
264
|
+
type: HostBinding,
|
|
265
|
+
args: ['attr.role']
|
|
266
|
+
}] }); })();
|
|
267
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJEmptyStateComponent, { className: "MJEmptyStateComponent", filePath: "lib/empty-state/empty-state.component.ts", lineNumber: 171 }); })();
|
|
268
|
+
//# sourceMappingURL=empty-state.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"empty-state.component.js","sourceRoot":"","sources":["../../../src/lib/empty-state/empty-state.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, EventEmitter, HostBinding, Input, Output } from '@angular/core';\nimport { MJButtonDirective } from '../button/button.directive';\n\n/**\n * Visual intent of an `<mj-empty-state>`. Drives the default icon and the icon's\n * color treatment so callers don't restate either for the common cases.\n *\n * - `empty` — nothing exists yet (default). Neutral/disabled icon tone.\n * - `no-results` — a search/filter matched nothing. Muted icon tone, magnifier default.\n * - `success` — a positive \"all clear\" empty (e.g. \"No Errors Found\"). Success icon tone, check default.\n * - `warning` — a non-error blocking condition (disabled/misconfigured feature). Warning icon tone.\n * - `error` — a load/operation failed. Error icon tone, triangle default.\n */\nexport type MJEmptyStateVariant = 'empty' | 'no-results' | 'success' | 'warning' | 'error';\n\n/** Density of an `<mj-empty-state>` — controls padding and icon size. */\nexport type MJEmptyStateSize = 'compact' | 'default' | 'large';\n\n/**\n * mj-empty-state — Canonical centered empty/no-results/error placeholder.\n *\n * Replaces the ~213 inline empty-state `<div>`s that pages were each hand-rolling\n * (icon + title + message, optionally a CTA), e.g.:\n * ```html\n * <div class=\"empty-state\">\n * <i class=\"fa-solid fa-inbox\"></i>\n * <h3>No Permissions Found</h3>\n * <p>Try adjusting your filters or refresh the data.</p>\n * <button mjButton variant=\"primary\" (click)=\"refreshData()\">Refresh</button>\n * </div>\n * ```\n *\n * Usage:\n * ```html\n * <!-- Simplest: nothing-here placeholder -->\n * <mj-empty-state Title=\"No runs found\" Message=\"No runs match the selected filters.\" />\n *\n * <!-- Search/filter produced nothing -->\n * <mj-empty-state Variant=\"no-results\" Title=\"No icons found\" Message=\"Try a different search term.\" />\n *\n * <!-- Load failed, retry CTA -->\n * <mj-empty-state Variant=\"error\" Title=\"Couldn't load permissions\" [Message]=\"error\"\n * ActionText=\"Try Again\" ActionIcon=\"fa-solid fa-rotate-right\" (Action)=\"loadData()\" />\n *\n * <!-- Invitation to create the first record -->\n * <mj-empty-state Icon=\"fa-solid fa-key\" Title=\"No API keys yet\"\n * Message=\"Generate a key to start calling the API.\"\n * ActionText=\"Generate Your First Key\" ActionIcon=\"fa-solid fa-plus\"\n * (Action)=\"requestCreate()\" />\n *\n * <!-- Multiple / bespoke CTAs: project them into the [actions] slot -->\n * <mj-empty-state Title=\"No pinned items yet\" Message=\"Pin dashboards for quick access.\">\n * <button mjButton variant=\"primary\" (click)=\"addPin()\">Add your first pin</button>\n * <button mjButton variant=\"flat\" (click)=\"dismiss()\">Don't show again</button>\n * </mj-empty-state>\n * ```\n *\n * For dynamic messages (e.g. \"No keys matching X\" vs \"No keys yet\"), compute the\n * string in the parent and bind it to `[Message]`, or project richer body content\n * as default `<ng-content>` (rendered between the message and the actions).\n */\n@Component({\n selector: 'mj-empty-state',\n standalone: true,\n imports: [MJButtonDirective],\n template: `\n @if (ResolvedIcon) {\n <i class=\"mj-empty-state__icon {{ ResolvedIcon }}\" aria-hidden=\"true\"></i>\n }\n @if (Title) {\n <h3 class=\"mj-empty-state__title\">{{ Title }}</h3>\n }\n @if (Message) {\n <p class=\"mj-empty-state__message\">{{ Message }}</p>\n }\n\n <!-- Optional richer body content (feature lists, dynamic text, links) -->\n <ng-content></ng-content>\n\n <!-- Actions: the built-in single CTA and/or projected [actions] buttons.\n Hidden via :empty when neither is present. -->\n <div class=\"mj-empty-state__actions\">\n @if (ActionText) {\n <button type=\"button\" mjButton [variant]=\"ActionVariant\" (click)=\"OnAction($event)\">\n @if (ActionIcon) {\n <i class=\"{{ ActionIcon }}\" aria-hidden=\"true\"></i>\n }\n {{ ActionText }}\n </button>\n }\n <ng-content select=\"[actions]\"></ng-content>\n </div>\n `,\n styles: [`\n :host {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n text-align: center;\n padding: var(--mj-space-12);\n color: var(--mj-text-secondary);\n }\n\n .mj-empty-state__icon {\n font-size: 3rem;\n line-height: 1;\n margin-bottom: var(--mj-space-4);\n color: var(--mj-text-disabled);\n }\n\n .mj-empty-state__title {\n margin: 0;\n font-size: var(--mj-text-lg);\n font-weight: 600;\n color: var(--mj-text-primary);\n }\n\n .mj-empty-state__message {\n margin: var(--mj-space-2) 0 0;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-muted);\n max-width: 420px;\n }\n\n .mj-empty-state__actions {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: center;\n gap: var(--mj-space-2);\n margin-top: var(--mj-space-6);\n }\n /* Collapse the actions row entirely when no CTA is rendered (modern browsers\n treat an element containing only Angular's @if comment-anchors as :empty). */\n .mj-empty-state__actions:empty {\n display: none;\n }\n\n /* ── Sizes ────────────────────────────────────────────────── */\n :host(.mj-empty-state--compact) {\n padding: var(--mj-space-8);\n }\n :host(.mj-empty-state--compact) .mj-empty-state__icon {\n font-size: 2rem;\n margin-bottom: var(--mj-space-3);\n }\n\n :host(.mj-empty-state--large) {\n padding: var(--mj-space-16) var(--mj-space-10);\n }\n :host(.mj-empty-state--large) .mj-empty-state__icon {\n font-size: 4rem;\n }\n\n /* ── Variants (icon tone) ─────────────────────────────────── */\n :host(.mj-empty-state--no-results) .mj-empty-state__icon {\n color: var(--mj-text-muted);\n }\n :host(.mj-empty-state--success) .mj-empty-state__icon {\n color: var(--mj-status-success);\n }\n :host(.mj-empty-state--warning) .mj-empty-state__icon {\n color: var(--mj-status-warning);\n }\n :host(.mj-empty-state--error) .mj-empty-state__icon {\n color: var(--mj-status-error);\n }\n `]\n})\nexport class MJEmptyStateComponent {\n /**\n * Font Awesome icon class string (e.g. \"fa-solid fa-key\"). When omitted, a\n * sensible default is chosen from `Variant`. Pass an empty string AND no\n * variant default applies — set this explicitly to \"\" to render no icon.\n */\n @Input() Icon: string | null = null;\n\n /** Bold heading line (e.g. \"No API keys yet\"). */\n @Input() Title: string = '';\n\n /** Supporting/help text below the title. */\n @Input() Message: string = '';\n\n /** When set, renders a primary CTA button with this label. */\n @Input() ActionText: string = '';\n\n /** Optional Font Awesome icon shown inside the CTA button. */\n @Input() ActionIcon: string = '';\n\n /** mjButton variant for the built-in CTA. Defaults to 'primary'. */\n @Input() ActionVariant: 'primary' | 'secondary' | 'outline' | 'flat' = 'primary';\n\n /** Visual intent — drives the default icon and icon color. Defaults to 'empty'. */\n @Input() Variant: MJEmptyStateVariant = 'empty';\n\n /** Density — controls padding and icon size. Defaults to 'default'. */\n @Input() Size: MJEmptyStateSize = 'default';\n\n /**\n * ARIA live-region role on the host. When unset, it defaults from `Variant`:\n * `error` → `'alert'` (assertive), everything else → `'status'` (polite). This\n * makes a dynamically-appearing empty state announce itself to screen readers —\n * the title + message are read together via the role's implicit\n * `aria-live`/`aria-atomic`. (Empty states present at page load are not\n * announced, per the live-region spec, so static placeholders stay quiet.)\n * Pass an explicit role to override, or `''` to opt out of the live region.\n */\n @Input() Role: string | null = null;\n\n /** Emitted when the built-in CTA button is clicked. */\n @Output() Action = new EventEmitter<MouseEvent>();\n\n @HostBinding('class.mj-empty-state--compact')\n get IsCompact(): boolean { return this.Size === 'compact'; }\n\n @HostBinding('class.mj-empty-state--large')\n get IsLarge(): boolean { return this.Size === 'large'; }\n\n @HostBinding('class.mj-empty-state--no-results')\n get IsNoResults(): boolean { return this.Variant === 'no-results'; }\n\n @HostBinding('class.mj-empty-state--success')\n get IsSuccess(): boolean { return this.Variant === 'success'; }\n\n @HostBinding('class.mj-empty-state--warning')\n get IsWarning(): boolean { return this.Variant === 'warning'; }\n\n @HostBinding('class.mj-empty-state--error')\n get IsError(): boolean { return this.Variant === 'error'; }\n\n /**\n * Live-region role applied to the host. Explicit `Role` wins (`''` ⇒ no role);\n * otherwise an error state is an assertive `alert`, everything else a polite `status`.\n */\n @HostBinding('attr.role')\n get HostRole(): string | null {\n if (this.Role != null) {\n return this.Role || null;\n }\n return this.Variant === 'error' ? 'alert' : 'status';\n }\n\n /**\n * Icon actually rendered: the explicit `Icon` when provided (including \"\"\n * to suppress the icon), otherwise the per-variant default.\n */\n get ResolvedIcon(): string {\n if (this.Icon != null) {\n return this.Icon;\n }\n return MJEmptyStateComponent.DefaultIconForVariant(this.Variant);\n }\n\n /** Default Font Awesome icon for each variant. */\n static DefaultIconForVariant(variant: MJEmptyStateVariant): string {\n switch (variant) {\n case 'no-results':\n return 'fa-solid fa-magnifying-glass';\n case 'success':\n return 'fa-solid fa-circle-check';\n case 'warning':\n case 'error':\n return 'fa-solid fa-triangle-exclamation';\n case 'empty':\n default:\n return 'fa-solid fa-inbox';\n }\n }\n\n OnAction(event: MouseEvent): void {\n this.Action.emit(event);\n }\n}\n"]}
|