@praxisui/dialog 9.0.6 → 9.0.8
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/README.md +27 -5
- package/ai/component-registry.json +2 -2
- package/fesm2022/praxisui-dialog.mjs +160 -66
- package/package.json +2 -2
- package/types/praxisui-dialog.d.ts +20 -3
package/README.md
CHANGED
|
@@ -64,13 +64,33 @@ export class UsersComponent {
|
|
|
64
64
|
## Custom Content And Tag Mode
|
|
65
65
|
|
|
66
66
|
```ts
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
67
|
+
import { inject, Injector } from "@angular/core";
|
|
68
|
+
import { PraxisDialog } from "@praxisui/dialog";
|
|
69
|
+
|
|
70
|
+
export class CustomerPage {
|
|
71
|
+
private readonly dialog = inject(PraxisDialog);
|
|
72
|
+
private readonly featureInjector = inject(Injector);
|
|
73
|
+
|
|
74
|
+
openCustomer(customer: Customer): void {
|
|
75
|
+
this.dialog.open(CustomerFormComponent, {
|
|
76
|
+
title: "Edit customer",
|
|
77
|
+
width: "720px",
|
|
78
|
+
data: customer,
|
|
79
|
+
injector: this.featureInjector,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
72
83
|
```
|
|
73
84
|
|
|
85
|
+
Pass the feature `Injector` when the dynamic content depends on providers owned
|
|
86
|
+
by a lazy route or feature. If omitted, Dialog derives it from
|
|
87
|
+
`viewContainerRef` and then falls back to the injector that created
|
|
88
|
+
`PraxisDialog`. Metadata-driven `surface.open` dialogs forward their provider's
|
|
89
|
+
feature injector automatically.
|
|
90
|
+
|
|
91
|
+
`injector` and `viewContainerRef` are runtime-only integration fields. Do not
|
|
92
|
+
persist them in presets, AI-authored configuration or JSON documents.
|
|
93
|
+
|
|
74
94
|
Use `openByRegistry(id, config)` or `openTemplateById(id, config)` for governed registries. Use `<praxis-dialog>` when the host template controls the shell instead of the overlay service.
|
|
75
95
|
|
|
76
96
|
```html
|
|
@@ -134,6 +154,8 @@ Component-specific dialog variables remain available for deliberate local custom
|
|
|
134
154
|
|
|
135
155
|
`PraxisDialog` configures dialog roles, backdrop behavior, Escape handling, focus restoration and `aria-*` fields. Use `ariaRole: 'alertdialog'` for destructive or blocking confirmations, and always provide a visible title or accessible label.
|
|
136
156
|
|
|
157
|
+
Overlay sizing is applied to the CDK pane and to the dialog panel. `width` and `height` therefore remain centered when constrained by `minWidth`, `maxWidth`, `minHeight` or `maxHeight` on narrow viewports; hosts should not add local overlay-positioning CSS for this behavior.
|
|
158
|
+
|
|
137
159
|
Closable dialogs with role `dialog` also expose an accessible close button in the title bar. It follows the same `disableClose` policy as Escape and backdrop interactions. The runtime does not add this shortcut to `alertdialog`, whose explicit governed actions remain the required decision path. Hosts that override `PRAXIS_DIALOG_I18N` may provide `close`; older providers remain compatible and fall back to their localized `cancel` label.
|
|
138
160
|
|
|
139
161
|
## Official Links
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": "1.0.0",
|
|
3
|
-
"generatedAt": "2026-08-
|
|
3
|
+
"generatedAt": "2026-08-20T18:11:26.392Z",
|
|
4
4
|
"packageName": "@praxisui/dialog",
|
|
5
|
-
"packageVersion": "9.0.
|
|
5
|
+
"packageVersion": "9.0.8",
|
|
6
6
|
"sourceRegistry": "praxis-component-registry-ingestion",
|
|
7
7
|
"sourceRegistryVersion": "1.0.0",
|
|
8
8
|
"componentCount": 1,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, Directive, EventEmitter, inject, HostBinding, ContentChild, ViewChild, Output, Input, ViewEncapsulation, ChangeDetectionStrategy, Component, Injectable,
|
|
2
|
+
import { InjectionToken, Directive, EventEmitter, inject, HostBinding, ContentChild, ViewChild, Output, Input, ViewEncapsulation, ChangeDetectionStrategy, Component, Injectable, Injector, ApplicationRef, TemplateRef, ENVIRONMENT_INITIALIZER } from '@angular/core';
|
|
3
3
|
import { Subject, firstValueFrom } from 'rxjs';
|
|
4
4
|
import * as i1 from '@angular/common';
|
|
5
5
|
import { CommonModule } from '@angular/common';
|
|
@@ -61,6 +61,7 @@ class PraxisDialogRef {
|
|
|
61
61
|
this.overlayRef = overlayRef;
|
|
62
62
|
}
|
|
63
63
|
beforeCloseHandler;
|
|
64
|
+
closePromise;
|
|
64
65
|
setBeforeClose(handler) {
|
|
65
66
|
this.beforeCloseHandler = handler;
|
|
66
67
|
}
|
|
@@ -89,7 +90,13 @@ class PraxisDialogRef {
|
|
|
89
90
|
notifyKeydown(ev) {
|
|
90
91
|
this._keydownEvents.next(ev);
|
|
91
92
|
}
|
|
92
|
-
|
|
93
|
+
close(result) {
|
|
94
|
+
if (this.closePromise)
|
|
95
|
+
return this.closePromise;
|
|
96
|
+
this.closePromise = this.performClose(result);
|
|
97
|
+
return this.closePromise;
|
|
98
|
+
}
|
|
99
|
+
async performClose(result) {
|
|
93
100
|
this._beforeClosed.next(result);
|
|
94
101
|
this._beforeClosed.complete();
|
|
95
102
|
if (this.beforeCloseHandler) {
|
|
@@ -240,7 +247,6 @@ class PraxisDialogComponent {
|
|
|
240
247
|
if (!this.overlayMode)
|
|
241
248
|
this.opened.emit();
|
|
242
249
|
});
|
|
243
|
-
this.scheduleInitialFocus();
|
|
244
250
|
}
|
|
245
251
|
if (this.ariaRole === 'alertdialog') {
|
|
246
252
|
const hasLabel = !!(this.title || this.ariaLabel || this.ariaLabelledBy);
|
|
@@ -255,6 +261,10 @@ class PraxisDialogComponent {
|
|
|
255
261
|
catch { }
|
|
256
262
|
}
|
|
257
263
|
}
|
|
264
|
+
ngAfterViewInit() {
|
|
265
|
+
if (this.open)
|
|
266
|
+
this.scheduleInitialFocus();
|
|
267
|
+
}
|
|
258
268
|
ngOnChanges(changes) {
|
|
259
269
|
if (changes['open'] && this.open) {
|
|
260
270
|
this.isDisplayed = true;
|
|
@@ -330,32 +340,44 @@ class PraxisDialogComponent {
|
|
|
330
340
|
}
|
|
331
341
|
catch { }
|
|
332
342
|
}
|
|
343
|
+
/**
|
|
344
|
+
* Moves focus into the currently materialized panel. Overlay hosts call this
|
|
345
|
+
* after switching to the overlay template branch and attaching its content.
|
|
346
|
+
*/
|
|
347
|
+
focusInitialElement() {
|
|
348
|
+
this.captureFocusOrigin();
|
|
349
|
+
this.applyInitialFocus();
|
|
350
|
+
}
|
|
333
351
|
scheduleInitialFocus() {
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
352
|
+
this.captureFocusOrigin();
|
|
353
|
+
queueMicrotask(() => this.applyInitialFocus());
|
|
354
|
+
}
|
|
355
|
+
captureFocusOrigin() {
|
|
337
356
|
const prev = document.activeElement;
|
|
338
357
|
if (!this._previouslyFocused && this.restoreFocus)
|
|
339
358
|
this._previouslyFocused = prev;
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
el?.focus?.();
|
|
359
|
+
}
|
|
360
|
+
applyInitialFocus() {
|
|
361
|
+
const panel = this.panelEl?.nativeElement;
|
|
362
|
+
if (!panel || this.autoFocus === false)
|
|
363
|
+
return;
|
|
364
|
+
try {
|
|
365
|
+
if (this.autoFocus && this.ariaRole === 'alertdialog') {
|
|
366
|
+
// In alertdialog, focus the primary action if present
|
|
367
|
+
const focused = this.focusPrimaryAction();
|
|
368
|
+
if (focused)
|
|
351
369
|
return;
|
|
352
|
-
}
|
|
353
|
-
// focus first focusable
|
|
354
|
-
const focusable = panel.querySelector('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
|
|
355
|
-
(focusable || panel).focus?.();
|
|
356
370
|
}
|
|
357
|
-
|
|
358
|
-
|
|
371
|
+
if (this.autoFocusedElement) {
|
|
372
|
+
const el = panel.querySelector(this.autoFocusedElement);
|
|
373
|
+
el?.focus?.();
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
// focus first focusable
|
|
377
|
+
const focusable = panel.querySelector('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
|
|
378
|
+
(focusable || panel).focus?.();
|
|
379
|
+
}
|
|
380
|
+
catch { }
|
|
359
381
|
}
|
|
360
382
|
_previouslyFocused;
|
|
361
383
|
ngOnDestroy() {
|
|
@@ -527,7 +549,7 @@ class PraxisDialogComponent {
|
|
|
527
549
|
}
|
|
528
550
|
}
|
|
529
551
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
530
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PraxisDialogComponent, isStandalone: true, selector: "praxis-dialog", inputs: { title: "title", actions: "actions", actionsLayout: "actionsLayout", animation: "animation", open: "open", width: "width", height: "height", minWidth: "minWidth", maxWidth: "maxWidth", minHeight: "minHeight", maxHeight: "maxHeight", themeColor: "themeColor", disableClose: "disableClose", hasBackdrop: "hasBackdrop", closeOnBackdropClick: "closeOnBackdropClick", overlayMode: "overlayMode", zIndex: "zIndex", panelClass: "panelClass", backdropClass: "backdropClass", position: "position", autoFocusedElement: "autoFocusedElement", autoFocus: "autoFocus", restoreFocus: "restoreFocus", id: "id", ariaRole: "ariaRole", ariaLabel: "ariaLabel", ariaLabelledBy: "ariaLabelledBy", ariaDescribedBy: "ariaDescribedBy", styles: "styles", titleIcon: "titleIcon" }, outputs: { action: "action", close: "close", opened: "opened", afterClosed: "afterClosed" }, host: { properties: { "class": "this.hostClass", "attr.tabindex": "this.tabindex" } }, queries: [{ propertyName: "titleTpl", first: true, predicate: PraxisDialogTitleDirective, descendants: true, read: PraxisDialogTitleDirective }, { propertyName: "actionsTpl", first: true, predicate: PraxisDialogActionsDirective, descendants: true, read: PraxisDialogActionsDirective }, { propertyName: "contentTpl", first: true, predicate: PraxisDialogContentDirective, descendants: true, read: PraxisDialogContentDirective }], viewQueries: [{ propertyName: "contentHost", first: true, predicate: CdkPortalOutlet, descendants: true }, { propertyName: "panelEl", first: true, predicate: ["panel"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "@let _titleId = (id ?? \"praxis-dialog\") + \"-title\";\n\n<ng-template #panelHeader>\n @if (titleTpl?.templateRef || title || titleIcon || displaysCloseButton) {\n <div class=\"pdx-dialog__title\">\n <div class=\"pdx-dialog__title-row\">\n @if (titleTpl?.templateRef) {\n <div class=\"pdx-dialog__title-custom\">\n <ng-container\n [ngTemplateOutlet]=\"titleTpl!.templateRef\"\n ></ng-container>\n </div>\n } @else {\n @if (titleIcon) {\n <mat-icon\n class=\"pdx-dialog__title-icon\"\n [praxisIcon]=\"titleIcon\"\n aria-hidden=\"true\"\n ></mat-icon>\n }\n @if (title) {\n <h2 class=\"pdx-dialog__title-text\" [attr.id]=\"_titleId\">\n {{ title }}\n </h2>\n }\n }\n @if (displaysCloseButton) {\n <button\n type=\"button\"\n class=\"pdx-dialog__close-btn\"\n [attr.aria-label]=\"closeButtonLabel\"\n [attr.title]=\"closeButtonLabel\"\n data-testid=\"dialog-close\"\n (click)=\"requestClose()\"\n >\n <mat-icon praxisIcon=\"close\" aria-hidden=\"true\"></mat-icon>\n </button>\n }\n </div>\n </div>\n }\n</ng-template>\n\n<ng-template #panelActions>\n <div\n class=\"pdx-dialog__actions\"\n [class.is-stretched]=\"actionsLayout === 'stretched'\"\n >\n @if (actionsTpl?.templateRef) {\n <ng-container [ngTemplateOutlet]=\"actionsTpl!.templateRef\"></ng-container>\n } @else {\n @for (a of actions; track a?.id ?? a) {\n <button\n type=\"button\"\n class=\"pdx-dialog__action-btn\"\n [attr.data-testid]=\"a.id || null\"\n [attr.data-role]=\"a.role || null\"\n [attr.data-theme]=\"a.themeColor || null\"\n [attr.data-fill]=\"a.fillMode || null\"\n [ngClass]=\"a.cssClass\"\n (click)=\"onActionClick(a)\"\n [attr.cdkFocusInitial]=\"\n a.role === 'primary' && ariaRole === 'alertdialog' ? '' : null\n \"\n >\n @if (a.icon) {\n <mat-icon [praxisIcon]=\"a.icon\"></mat-icon>\n } @else if (a.svgIcon) {\n <mat-icon [svgIcon]=\"a.svgIcon\"></mat-icon>\n }\n {{ a.text }}\n </button>\n }\n }\n </div>\n</ng-template>\n\n@if (overlayMode) {\n <div\n #panel\n class=\"pdx-dialog pdx-dialog--{{ themeColor }} pdx-dialog--layout-{{\n actionsLayout\n }}\"\n [attr.role]=\"ariaRole\"\n [attr.id]=\"id || null\"\n [attr.aria-modal]=\"true\"\n [attr.aria-label]=\"ariaLabel || null\"\n [attr.aria-labelledby]=\"ariaLabelledBy || (title ? _titleId : null)\"\n [attr.aria-describedby]=\"ariaDescribedBy || null\"\n (keydown)=\"onKeydown($event)\"\n cdkTrapFocus\n [ngClass]=\"panelNgClass\"\n [style.width]=\"width\"\n [style.height]=\"height\"\n [style.min-width]=\"minWidth\"\n [style.max-width]=\"maxWidth\"\n [style.min-height]=\"minHeight\"\n [style.max-height]=\"maxHeight\"\n [class.has-actions]=\"(actions.length || 0) > 0 || !!actionsTpl?.templateRef\"\n >\n <ng-container [ngTemplateOutlet]=\"panelHeader\"></ng-container>\n <div class=\"pdx-dialog__content\">\n @if (contentTpl?.templateRef) {\n <ng-container\n [ngTemplateOutlet]=\"contentTpl!.templateRef\"\n ></ng-container>\n } @else {\n <ng-template cdkPortalOutlet></ng-template>\n }\n </div>\n <ng-container [ngTemplateOutlet]=\"panelActions\"></ng-container>\n </div>\n} @else {\n <div\n class=\"pdx-dialog-overlay\"\n [class.has-backdrop]=\"hasBackdrop\"\n [hidden]=\"!isDisplayed\"\n (click)=\"onBackdrop($event)\"\n [ngClass]=\"backdropClass\"\n [style.z-index]=\"zIndex\"\n >\n <div class=\"pdx-dialog-shell\" (click)=\"$event.stopPropagation()\">\n <div\n #panel\n class=\"pdx-dialog pdx-dialog--{{ themeColor }} pdx-dialog--layout-{{\n actionsLayout\n }}\"\n [attr.role]=\"ariaRole\"\n [attr.id]=\"id || null\"\n [attr.aria-modal]=\"true\"\n [attr.aria-label]=\"ariaLabel || null\"\n [attr.aria-labelledby]=\"ariaLabelledBy || (title ? _titleId : null)\"\n [attr.aria-describedby]=\"ariaDescribedBy || null\"\n (keydown)=\"onKeydown($event)\"\n cdkTrapFocus\n [ngClass]=\"panelNgClass\"\n [style.width]=\"width\"\n [style.height]=\"height\"\n [style.min-width]=\"minWidth\"\n [style.max-width]=\"maxWidth\"\n [style.min-height]=\"minHeight\"\n [style.max-height]=\"maxHeight\"\n [style.top]=\"position?.top || null\"\n [style.bottom]=\"position?.bottom || null\"\n [style.left]=\"position?.left || null\"\n [style.right]=\"position?.right || null\"\n [class.pdx-has-position]=\"position\"\n [class.has-actions]=\"\n (actions.length || 0) > 0 || !!actionsTpl?.templateRef\n \"\n >\n <ng-container [ngTemplateOutlet]=\"panelHeader\"></ng-container>\n <div class=\"pdx-dialog__content\">\n @if (contentTpl?.templateRef) {\n <ng-container\n [ngTemplateOutlet]=\"contentTpl!.templateRef\"\n ></ng-container>\n } @else {\n <ng-template cdkPortalOutlet></ng-template>\n }\n </div>\n <ng-container [ngTemplateOutlet]=\"panelActions\"></ng-container>\n </div>\n </div>\n </div>\n}\n", styles: ["@charset \"UTF-8\";.pdx-dialog-host{--pdx-dialog-bg: var(--praxis-theme-surface, var(--md-sys-color-surface));--pdx-dialog-surface: var( --praxis-theme-surface-overlay, var(--md-sys-color-surface-container-high) );--pdx-dialog-border: var( --praxis-theme-outline, var(--md-sys-color-outline-variant) );--pdx-dialog-title-fg: var( --praxis-theme-on-surface, var(--md-sys-color-on-surface) );--pdx-dialog-elevation: var( --praxis-theme-elevation, var(--mat-elevation-level4) )}.pdx-dialog-overlay{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;z-index:var(--praxis-layer-dialog, 1300);background:transparent}.pdx-dialog-overlay.has-backdrop{background:var(--pdx-dialog-backdrop, rgba(0, 0, 0, .6))}.pdx-dialog-shell{display:contents}.pdx-dialog.pdx-has-position{position:absolute}.pdx-dialog{background:var(--pdx-dialog-container-color, var(--pdx-dialog-surface));color:var(--praxis-theme-on-surface, var(--md-sys-color-on-surface, #111));border:1px solid var(--pdx-dialog-border);border-radius:var(--pdx-dialog-shape, 16px);box-shadow:var(--pdx-dialog-elevation-shadow, var(--pdx-dialog-elevation));max-width:var(--pdx-dialog-max-width, 90vw);max-height:var(--pdx-dialog-max-height, 80vh);display:flex;flex-direction:column;min-width:var(--pdx-dialog-min-width, 280px);outline:0}.pdx-dialog__title{padding:var(--pdx-dialog-headline-padding, 12px 24px 10px);border-bottom:1px solid var(--pdx-dialog-border);color:var(--pdx-dialog-subhead-color, var(--pdx-dialog-title-fg));background:var(--pdx-dialog-title-bg, transparent);flex:0 0 auto}.pdx-dialog__title-row{display:flex;align-items:center;gap:10px;min-height:40px}.pdx-dialog__title-custom,.pdx-dialog__title-text{min-width:0;flex:1 1 auto}.pdx-dialog__title-icon{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;flex:0 0 24px;font-size:20px;line-height:1;opacity:.87}.pdx-dialog__title-text{margin:0;font-family:var(--pdx-dialog-subhead-font, inherit);font-size:var(--pdx-dialog-subhead-size, 16px);letter-spacing:var(--pdx-dialog-subhead-tracking, normal);font-weight:var(--pdx-dialog-subhead-weight, 600);line-height:1.2}.pdx-dialog__close-btn{appearance:none;display:inline-flex;align-items:center;justify-content:center;flex:0 0 40px;width:40px;height:40px;margin:-4px -8px -4px 8px;padding:0;border:0;border-radius:999px;color:inherit;background:transparent;cursor:pointer;transition:background-color .16s ease,color .16s ease}.pdx-dialog__close-btn:hover{background:color-mix(in srgb,currentColor 10%,transparent)}.pdx-dialog__close-btn:focus-visible{outline:2px solid var(--praxis-theme-focus-outline, var(--md-sys-color-primary));outline-offset:2px}.pdx-dialog__close-btn .mat-icon{width:22px;height:22px;font-size:22px;line-height:1}.pdx-dialog__content{padding:var(--pdx-dialog-content-padding, 16px);overflow:auto;flex:1 1 auto;min-height:0;color:var(--pdx-dialog-supporting-text-color, inherit);font-family:var(--pdx-dialog-supporting-text-font, inherit);line-height:var(--pdx-dialog-supporting-text-line-height, 1.4);font-size:var(--pdx-dialog-supporting-text-size, 14px);letter-spacing:var(--pdx-dialog-supporting-text-tracking, normal);font-weight:var(--pdx-dialog-supporting-text-weight, 400)}.pdx-dialog.has-actions .pdx-dialog__content{padding-bottom:var(--pdx-dialog-with-actions-content-padding, var(--pdx-dialog-content-padding, 16px))}.pdx-dialog__actions{display:flex;gap:8px;padding:var(--pdx-dialog-actions-padding, 12px 24px 16px);border-top:1px solid var(--pdx-dialog-border);justify-content:flex-end;align-items:center;background:var(--pdx-dialog-actions-bg, transparent);flex:0 0 auto}.pdx-dialog__actions.is-stretched{justify-content:stretch}.pdx-dialog__actions.is-stretched .pdx-dialog__action-btn{flex:1 1 0;justify-content:center}.pdx-dialog__action-btn{appearance:none;border:1px solid var(--pdx-dialog-border);background:var(--praxis-theme-surface, var(--md-sys-color-surface-container-low));color:var(--praxis-theme-on-surface, var(--md-sys-color-on-surface));border-radius:var(--pdx-dialog-action-radius, 8px);padding:var(--pdx-dialog-action-padding, 0 14px);min-height:var(--pdx-dialog-action-min-height, 36px);cursor:pointer;display:inline-flex;align-items:center;gap:8px;line-height:1;transition:background-color .18s ease,border-color .18s ease,color .18s ease}.pdx-dialog__action-btn:hover{background:var(--praxis-theme-surface-raised, var(--md-sys-color-surface-container))}.pdx-dialog__action-btn:focus-visible{outline:2px solid var(--praxis-theme-focus-outline, var(--md-sys-color-primary));outline-offset:2px}.pdx-dialog__action-btn:disabled{opacity:.6;cursor:not-allowed}.pdx-dialog__action-btn[data-role=primary]:not([data-fill]),.pdx-dialog__action-btn[data-fill=solid]{background:var(--md-sys-color-primary);border-color:var(--md-sys-color-primary);color:var(--md-sys-color-on-primary)}.pdx-dialog__action-btn[data-role=primary]:not([data-fill]):hover,.pdx-dialog__action-btn[data-fill=solid]:hover{background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container);border-color:var(--md-sys-color-primary-container)}.pdx-dialog__action-btn[data-role=danger]:not([data-fill]),.pdx-dialog__action-btn[data-fill=solid][data-theme=warn],.pdx-dialog__action-btn[data-theme=warn][data-fill=solid]{background:var(--md-sys-color-error);border-color:var(--md-sys-color-error);color:var(--md-sys-color-on-error)}.pdx-dialog__action-btn[data-role=danger]:not([data-fill]):hover,.pdx-dialog__action-btn[data-fill=solid][data-theme=warn]:hover,.pdx-dialog__action-btn[data-theme=warn][data-fill=solid]:hover{background:var(--md-sys-color-error-container);color:var(--md-sys-color-on-error-container);border-color:var(--md-sys-color-error-container)}.pdx-dialog__action-btn[data-fill=solid][data-theme=accent],.pdx-dialog__action-btn[data-theme=accent][data-fill=solid]{background:var(--md-sys-color-secondary);border-color:var(--md-sys-color-secondary);color:var(--md-sys-color-on-secondary)}.pdx-dialog__action-btn[data-fill=solid][data-theme=accent]:hover,.pdx-dialog__action-btn[data-theme=accent][data-fill=solid]:hover{background:var(--md-sys-color-secondary-container);color:var(--md-sys-color-on-secondary-container);border-color:var(--md-sys-color-secondary-container)}.pdx-dialog__action-btn[data-fill=outline]{background:transparent;color:var(--praxis-theme-on-surface, var(--md-sys-color-on-surface))}.pdx-dialog__action-btn[data-fill=outline][data-theme=primary],.pdx-dialog__action-btn[data-fill=flat][data-theme=primary]{color:var(--md-sys-color-primary);border-color:var(--md-sys-color-primary)}.pdx-dialog__action-btn[data-fill=outline][data-theme=accent],.pdx-dialog__action-btn[data-fill=flat][data-theme=accent]{color:var(--md-sys-color-secondary);border-color:var(--md-sys-color-secondary)}.pdx-dialog__action-btn[data-fill=outline][data-theme=warn],.pdx-dialog__action-btn[data-fill=flat][data-theme=warn]{color:var(--md-sys-color-error);border-color:var(--md-sys-color-error)}.pdx-dialog__action-btn[data-fill=flat]{background:transparent;border-color:transparent;color:var(--md-sys-color-primary)}.pdx-dialog__action-btn .mat-icon{font-size:20px;width:20px;height:20px;line-height:1;display:inline-flex;align-items:center;justify-content:center}.pdx-dialog--primary .pdx-dialog__title{background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container);border-bottom-color:var(--praxis-theme-outline, var(--md-sys-color-outline-variant))}.pdx-dialog--dark{background:var(--praxis-theme-surface-raised, var(--md-sys-color-surface-container));color:var(--praxis-theme-on-surface, var(--md-sys-color-on-surface))}.pdx-dialog{transform-origin:center;transition-property:transform,opacity;transition-duration:var(--pdx-dialog-anim-duration, .3s);transition-timing-function:var(--pdx-dialog-anim-ease, cubic-bezier(.2, 0, 0, 1))}.pdx-dialog.pdx-anim-fade{opacity:1}.pdx-dialog.pdx-anim-zoom{transform:scale(1)}.pdx-dialog.pdx-anim-translate-up,.pdx-dialog.pdx-anim-translate-down{transform:translateY(0)}.pdx-dialog.pdx-anim-translate-left,.pdx-dialog.pdx-anim-translate-right{transform:translate(0)}.pdx-dialog.pdx-state-opening.pdx-anim-fade{opacity:0}.pdx-dialog.pdx-state-opening.pdx-anim-zoom{transform:scale(.96);opacity:0}.pdx-dialog.pdx-state-opening.pdx-anim-translate-up{transform:translateY(-16px);opacity:0}.pdx-dialog.pdx-state-opening.pdx-anim-translate-down{transform:translateY(16px);opacity:0}.pdx-dialog.pdx-state-opening.pdx-anim-translate-left{transform:translate(-16px);opacity:0}.pdx-dialog.pdx-state-opening.pdx-anim-translate-right{transform:translate(16px);opacity:0}.pdx-dialog.pdx-state-closing.pdx-anim-fade{opacity:0}.pdx-dialog.pdx-state-closing.pdx-anim-zoom{transform:scale(.96);opacity:0}.pdx-dialog.pdx-state-closing.pdx-anim-translate-up{transform:translateY(-16px);opacity:0}.pdx-dialog.pdx-state-closing.pdx-anim-translate-down{transform:translateY(16px);opacity:0}.pdx-dialog.pdx-state-closing.pdx-anim-translate-left{transform:translate(-16px);opacity:0}.pdx-dialog.pdx-state-closing.pdx-anim-translate-right{transform:translate(16px);opacity:0}@media(prefers-reduced-motion:reduce){.pdx-dialog{transition:none!important}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: PortalModule }, { kind: "directive", type: i2.CdkPortalOutlet, selector: "[cdkPortalOutlet]", inputs: ["cdkPortalOutlet"], outputs: ["attached"], exportAs: ["cdkPortalOutlet"] }, { kind: "ngmodule", type: A11yModule }, { kind: "directive", type: i3.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
552
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PraxisDialogComponent, isStandalone: true, selector: "praxis-dialog", inputs: { title: "title", actions: "actions", actionsLayout: "actionsLayout", animation: "animation", open: "open", width: "width", height: "height", minWidth: "minWidth", maxWidth: "maxWidth", minHeight: "minHeight", maxHeight: "maxHeight", themeColor: "themeColor", disableClose: "disableClose", hasBackdrop: "hasBackdrop", closeOnBackdropClick: "closeOnBackdropClick", overlayMode: "overlayMode", zIndex: "zIndex", panelClass: "panelClass", backdropClass: "backdropClass", position: "position", autoFocusedElement: "autoFocusedElement", autoFocus: "autoFocus", restoreFocus: "restoreFocus", id: "id", ariaRole: "ariaRole", ariaLabel: "ariaLabel", ariaLabelledBy: "ariaLabelledBy", ariaDescribedBy: "ariaDescribedBy", styles: "styles", titleIcon: "titleIcon" }, outputs: { action: "action", close: "close", opened: "opened", afterClosed: "afterClosed" }, host: { properties: { "class": "this.hostClass", "attr.tabindex": "this.tabindex" } }, queries: [{ propertyName: "titleTpl", first: true, predicate: PraxisDialogTitleDirective, descendants: true, read: PraxisDialogTitleDirective }, { propertyName: "actionsTpl", first: true, predicate: PraxisDialogActionsDirective, descendants: true, read: PraxisDialogActionsDirective }, { propertyName: "contentTpl", first: true, predicate: PraxisDialogContentDirective, descendants: true, read: PraxisDialogContentDirective }], viewQueries: [{ propertyName: "contentHost", first: true, predicate: CdkPortalOutlet, descendants: true }, { propertyName: "panelEl", first: true, predicate: ["panel"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "@let _titleId = (id ?? \"praxis-dialog\") + \"-title\";\n\n<ng-template #panelHeader>\n @if (titleTpl?.templateRef || title || titleIcon || displaysCloseButton) {\n <div class=\"pdx-dialog__title\">\n <div class=\"pdx-dialog__title-row\">\n @if (titleTpl?.templateRef) {\n <div class=\"pdx-dialog__title-custom\">\n <ng-container\n [ngTemplateOutlet]=\"titleTpl!.templateRef\"\n ></ng-container>\n </div>\n } @else {\n @if (titleIcon) {\n <mat-icon\n class=\"pdx-dialog__title-icon\"\n [praxisIcon]=\"titleIcon\"\n aria-hidden=\"true\"\n ></mat-icon>\n }\n @if (title) {\n <h2 class=\"pdx-dialog__title-text\" [attr.id]=\"_titleId\">\n {{ title }}\n </h2>\n }\n }\n @if (displaysCloseButton) {\n <button\n type=\"button\"\n class=\"pdx-dialog__close-btn\"\n [attr.aria-label]=\"closeButtonLabel\"\n [attr.title]=\"closeButtonLabel\"\n data-testid=\"dialog-close\"\n (click)=\"requestClose()\"\n >\n <mat-icon praxisIcon=\"close\" aria-hidden=\"true\"></mat-icon>\n </button>\n }\n </div>\n </div>\n }\n</ng-template>\n\n<ng-template #panelActions>\n <div\n class=\"pdx-dialog__actions\"\n [class.is-stretched]=\"actionsLayout === 'stretched'\"\n >\n @if (actionsTpl?.templateRef) {\n <ng-container [ngTemplateOutlet]=\"actionsTpl!.templateRef\"></ng-container>\n } @else {\n @for (a of actions; track a?.id ?? a) {\n <button\n type=\"button\"\n class=\"pdx-dialog__action-btn\"\n [attr.data-testid]=\"a.id || null\"\n [attr.data-role]=\"a.role || null\"\n [attr.data-theme]=\"a.themeColor || null\"\n [attr.data-fill]=\"a.fillMode || null\"\n [ngClass]=\"a.cssClass\"\n (click)=\"onActionClick(a)\"\n [attr.cdkFocusInitial]=\"\n a.role === 'primary' && ariaRole === 'alertdialog' ? '' : null\n \"\n >\n @if (a.icon) {\n <mat-icon [praxisIcon]=\"a.icon\"></mat-icon>\n } @else if (a.svgIcon) {\n <mat-icon [svgIcon]=\"a.svgIcon\"></mat-icon>\n }\n {{ a.text }}\n </button>\n }\n }\n </div>\n</ng-template>\n\n@if (overlayMode) {\n <div\n #panel\n class=\"pdx-dialog pdx-dialog--{{ themeColor }} pdx-dialog--layout-{{\n actionsLayout\n }}\"\n [attr.role]=\"ariaRole\"\n [attr.id]=\"id || null\"\n [attr.aria-modal]=\"true\"\n [attr.aria-label]=\"ariaLabel || null\"\n [attr.aria-labelledby]=\"ariaLabelledBy || (title ? _titleId : null)\"\n [attr.aria-describedby]=\"ariaDescribedBy || null\"\n (keydown)=\"onKeydown($event)\"\n cdkTrapFocus\n [ngClass]=\"panelNgClass\"\n [style.width]=\"width\"\n [style.height]=\"height\"\n [style.min-width]=\"minWidth\"\n [style.max-width]=\"maxWidth\"\n [style.min-height]=\"minHeight\"\n [style.max-height]=\"maxHeight\"\n [class.has-actions]=\"(actions.length || 0) > 0 || !!actionsTpl?.templateRef\"\n >\n <ng-container [ngTemplateOutlet]=\"panelHeader\"></ng-container>\n <div class=\"pdx-dialog__content\">\n @if (contentTpl?.templateRef) {\n <ng-container\n [ngTemplateOutlet]=\"contentTpl!.templateRef\"\n ></ng-container>\n } @else {\n <ng-template cdkPortalOutlet></ng-template>\n }\n </div>\n <ng-container [ngTemplateOutlet]=\"panelActions\"></ng-container>\n </div>\n} @else {\n <div\n class=\"pdx-dialog-overlay\"\n [class.has-backdrop]=\"hasBackdrop\"\n [hidden]=\"!isDisplayed\"\n (click)=\"onBackdrop($event)\"\n [ngClass]=\"backdropClass\"\n [style.z-index]=\"zIndex\"\n >\n <div class=\"pdx-dialog-shell\" (click)=\"$event.stopPropagation()\">\n <div\n #panel\n class=\"pdx-dialog pdx-dialog--{{ themeColor }} pdx-dialog--layout-{{\n actionsLayout\n }}\"\n [attr.role]=\"ariaRole\"\n [attr.id]=\"id || null\"\n [attr.aria-modal]=\"true\"\n [attr.aria-label]=\"ariaLabel || null\"\n [attr.aria-labelledby]=\"ariaLabelledBy || (title ? _titleId : null)\"\n [attr.aria-describedby]=\"ariaDescribedBy || null\"\n (keydown)=\"onKeydown($event)\"\n cdkTrapFocus\n [ngClass]=\"panelNgClass\"\n [style.width]=\"width\"\n [style.height]=\"height\"\n [style.min-width]=\"minWidth\"\n [style.max-width]=\"maxWidth\"\n [style.min-height]=\"minHeight\"\n [style.max-height]=\"maxHeight\"\n [style.top]=\"position?.top || null\"\n [style.bottom]=\"position?.bottom || null\"\n [style.left]=\"position?.left || null\"\n [style.right]=\"position?.right || null\"\n [class.pdx-has-position]=\"position\"\n [class.has-actions]=\"\n (actions.length || 0) > 0 || !!actionsTpl?.templateRef\n \"\n >\n <ng-container [ngTemplateOutlet]=\"panelHeader\"></ng-container>\n <div class=\"pdx-dialog__content\">\n @if (contentTpl?.templateRef) {\n <ng-container\n [ngTemplateOutlet]=\"contentTpl!.templateRef\"\n ></ng-container>\n } @else {\n <ng-template cdkPortalOutlet></ng-template>\n }\n </div>\n <ng-container [ngTemplateOutlet]=\"panelActions\"></ng-container>\n </div>\n </div>\n </div>\n}\n", styles: ["@charset \"UTF-8\";.pdx-dialog-host{--pdx-dialog-bg: var(--praxis-theme-surface, var(--md-sys-color-surface));--pdx-dialog-surface: var( --praxis-theme-surface-overlay, var(--md-sys-color-surface-container-high) );--pdx-dialog-border: var( --praxis-theme-outline, var(--md-sys-color-outline-variant) );--pdx-dialog-title-fg: var( --praxis-theme-on-surface, var(--md-sys-color-on-surface) );--pdx-dialog-elevation: var( --praxis-theme-elevation, var(--mat-elevation-level4) )}.pdx-dialog-overlay{position:fixed;inset:0;display:flex;align-items:center;justify-content:center;z-index:var(--praxis-layer-dialog, 1300);background:transparent}.pdx-dialog-overlay.has-backdrop{background:var(--pdx-dialog-backdrop, rgba(0, 0, 0, .6))}.pdx-dialog-shell{display:contents}.pdx-dialog.pdx-has-position{position:absolute}.pdx-dialog{background:var(--pdx-dialog-container-color, var(--pdx-dialog-surface));color:var(--praxis-theme-on-surface, var(--md-sys-color-on-surface, #111));border:1px solid var(--pdx-dialog-border);border-radius:var(--pdx-dialog-shape, 16px);box-shadow:var(--pdx-dialog-elevation-shadow, var(--pdx-dialog-elevation));max-width:var(--pdx-dialog-max-width, 90vw);max-height:var(--pdx-dialog-max-height, 80vh);display:flex;flex-direction:column;min-width:var(--pdx-dialog-min-width, 280px);outline:0}.pdx-dialog__title{padding:var(--pdx-dialog-headline-padding, 12px 24px 10px);border-bottom:1px solid var(--pdx-dialog-border);color:var(--pdx-dialog-subhead-color, var(--pdx-dialog-title-fg));background:var(--pdx-dialog-title-bg, transparent);flex:0 0 auto}.pdx-dialog__title-row{display:flex;align-items:center;gap:10px;min-height:40px}.pdx-dialog__title-custom,.pdx-dialog__title-text{min-width:0;flex:1 1 auto}.pdx-dialog__title-icon{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;flex:0 0 24px;font-size:20px;line-height:1;opacity:.87}.pdx-dialog__title-text{margin:0;font-family:var(--pdx-dialog-subhead-font, inherit);font-size:var(--pdx-dialog-subhead-size, 16px);letter-spacing:var(--pdx-dialog-subhead-tracking, normal);font-weight:var(--pdx-dialog-subhead-weight, 600);line-height:1.2}.pdx-dialog__close-btn{appearance:none;display:inline-flex;align-items:center;justify-content:center;flex:0 0 40px;width:40px;height:40px;margin:-4px -8px -4px 8px;padding:0;border:0;border-radius:999px;color:inherit;background:transparent;cursor:pointer;transition:background-color .16s ease,color .16s ease}.pdx-dialog__close-btn:hover{background:color-mix(in srgb,currentColor 10%,transparent)}.pdx-dialog__close-btn:focus-visible{outline:2px solid var(--praxis-theme-focus-outline, var(--md-sys-color-primary));outline-offset:2px}.pdx-dialog__close-btn .mat-icon{width:22px;height:22px;font-size:22px;line-height:1}.pdx-dialog__content{padding:var(--pdx-dialog-content-padding, 16px);overflow:auto;flex:1 1 auto;min-height:0;color:var(--pdx-dialog-supporting-text-color, inherit);font-family:var(--pdx-dialog-supporting-text-font, inherit);line-height:var(--pdx-dialog-supporting-text-line-height, 1.4);font-size:var(--pdx-dialog-supporting-text-size, 14px);letter-spacing:var(--pdx-dialog-supporting-text-tracking, normal);font-weight:var(--pdx-dialog-supporting-text-weight, 400)}.pdx-dialog.has-actions .pdx-dialog__content{padding-bottom:var(--pdx-dialog-with-actions-content-padding, var(--pdx-dialog-content-padding, 16px))}.pdx-dialog__actions{display:flex;gap:8px;padding:var(--pdx-dialog-actions-padding, 12px 24px 16px);border-top:1px solid var(--pdx-dialog-border);justify-content:flex-end;align-items:center;background:var(--pdx-dialog-actions-bg, transparent);flex:0 0 auto}.pdx-dialog__actions.is-stretched{justify-content:stretch}.pdx-dialog__actions.is-stretched .pdx-dialog__action-btn{flex:1 1 0;justify-content:center}.pdx-dialog__action-btn{appearance:none;border:1px solid var(--pdx-dialog-border);background:var(--praxis-theme-surface, var(--md-sys-color-surface-container-low));color:var(--praxis-theme-on-surface, var(--md-sys-color-on-surface));border-radius:var(--pdx-dialog-action-radius, 8px);padding:var(--pdx-dialog-action-padding, 0 14px);min-height:var(--pdx-dialog-action-min-height, 36px);cursor:pointer;display:inline-flex;align-items:center;gap:8px;line-height:1;transition:background-color .18s ease,border-color .18s ease,color .18s ease}.pdx-dialog__action-btn:hover{background:var(--praxis-theme-surface-raised, var(--md-sys-color-surface-container))}.pdx-dialog__action-btn:focus-visible{outline:2px solid var(--praxis-theme-focus-outline, var(--md-sys-color-primary));outline-offset:2px}.pdx-dialog__action-btn:disabled{opacity:.6;cursor:not-allowed}.pdx-dialog__action-btn[data-role=primary]:not([data-fill]),.pdx-dialog__action-btn[data-fill=solid]{background:var(--md-sys-color-primary);border-color:var(--md-sys-color-primary);color:var(--md-sys-color-on-primary)}.pdx-dialog__action-btn[data-role=primary]:not([data-fill]):hover,.pdx-dialog__action-btn[data-fill=solid]:hover{background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container);border-color:var(--md-sys-color-primary-container)}.pdx-dialog__action-btn[data-role=danger]:not([data-fill]),.pdx-dialog__action-btn[data-fill=solid][data-theme=warn],.pdx-dialog__action-btn[data-theme=warn][data-fill=solid]{background:var(--md-sys-color-error);border-color:var(--md-sys-color-error);color:var(--md-sys-color-on-error)}.pdx-dialog__action-btn[data-role=danger]:not([data-fill]):hover,.pdx-dialog__action-btn[data-fill=solid][data-theme=warn]:hover,.pdx-dialog__action-btn[data-theme=warn][data-fill=solid]:hover{background:var(--md-sys-color-error-container);color:var(--md-sys-color-on-error-container);border-color:var(--md-sys-color-error-container)}.pdx-dialog__action-btn[data-fill=solid][data-theme=accent],.pdx-dialog__action-btn[data-theme=accent][data-fill=solid]{background:var(--md-sys-color-secondary);border-color:var(--md-sys-color-secondary);color:var(--md-sys-color-on-secondary)}.pdx-dialog__action-btn[data-fill=solid][data-theme=accent]:hover,.pdx-dialog__action-btn[data-theme=accent][data-fill=solid]:hover{background:var(--md-sys-color-secondary-container);color:var(--md-sys-color-on-secondary-container);border-color:var(--md-sys-color-secondary-container)}.pdx-dialog__action-btn[data-fill=outline]{background:transparent;color:var(--praxis-theme-on-surface, var(--md-sys-color-on-surface))}.pdx-dialog__action-btn[data-fill=outline][data-theme=primary],.pdx-dialog__action-btn[data-fill=flat][data-theme=primary]{color:var(--md-sys-color-primary);border-color:var(--md-sys-color-primary)}.pdx-dialog__action-btn[data-fill=outline][data-theme=accent],.pdx-dialog__action-btn[data-fill=flat][data-theme=accent]{color:var(--md-sys-color-secondary);border-color:var(--md-sys-color-secondary)}.pdx-dialog__action-btn[data-fill=outline][data-theme=warn],.pdx-dialog__action-btn[data-fill=flat][data-theme=warn]{color:var(--md-sys-color-error);border-color:var(--md-sys-color-error)}.pdx-dialog__action-btn[data-fill=flat]{background:transparent;border-color:transparent;color:var(--md-sys-color-primary)}.pdx-dialog__action-btn .mat-icon{font-size:20px;width:20px;height:20px;line-height:1;display:inline-flex;align-items:center;justify-content:center}.pdx-dialog--primary .pdx-dialog__title{background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container);border-bottom-color:var(--praxis-theme-outline, var(--md-sys-color-outline-variant))}.pdx-dialog--dark{background:var(--praxis-theme-surface-raised, var(--md-sys-color-surface-container));color:var(--praxis-theme-on-surface, var(--md-sys-color-on-surface))}.pdx-dialog{transform-origin:center;transition-property:transform,opacity;transition-duration:var(--pdx-dialog-anim-duration, .3s);transition-timing-function:var(--pdx-dialog-anim-ease, cubic-bezier(.2, 0, 0, 1))}.pdx-dialog.pdx-anim-fade{opacity:1}.pdx-dialog.pdx-anim-zoom{transform:scale(1)}.pdx-dialog.pdx-anim-translate-up,.pdx-dialog.pdx-anim-translate-down{transform:translateY(0)}.pdx-dialog.pdx-anim-translate-left,.pdx-dialog.pdx-anim-translate-right{transform:translate(0)}.pdx-dialog.pdx-state-opening.pdx-anim-fade{opacity:0}.pdx-dialog.pdx-state-opening.pdx-anim-zoom{transform:scale(.96);opacity:0}.pdx-dialog.pdx-state-opening.pdx-anim-translate-up{transform:translateY(-16px);opacity:0}.pdx-dialog.pdx-state-opening.pdx-anim-translate-down{transform:translateY(16px);opacity:0}.pdx-dialog.pdx-state-opening.pdx-anim-translate-left{transform:translate(-16px);opacity:0}.pdx-dialog.pdx-state-opening.pdx-anim-translate-right{transform:translate(16px);opacity:0}.pdx-dialog.pdx-state-closing.pdx-anim-fade{opacity:0}.pdx-dialog.pdx-state-closing.pdx-anim-zoom{transform:scale(.96);opacity:0}.pdx-dialog.pdx-state-closing.pdx-anim-translate-up{transform:translateY(-16px);opacity:0}.pdx-dialog.pdx-state-closing.pdx-anim-translate-down{transform:translateY(16px);opacity:0}.pdx-dialog.pdx-state-closing.pdx-anim-translate-left{transform:translate(-16px);opacity:0}.pdx-dialog.pdx-state-closing.pdx-anim-translate-right{transform:translate(16px);opacity:0}@media(prefers-reduced-motion:reduce){.pdx-dialog{transition:none!important}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: PortalModule }, { kind: "directive", type: i2.CdkPortalOutlet, selector: "[cdkPortalOutlet]", inputs: ["cdkPortalOutlet"], outputs: ["attached"], exportAs: ["cdkPortalOutlet"] }, { kind: "ngmodule", type: A11yModule }, { kind: "directive", type: i3.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
531
553
|
}
|
|
532
554
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisDialogComponent, decorators: [{
|
|
533
555
|
type: Component,
|
|
@@ -611,7 +633,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
611
633
|
args: [CdkPortalOutlet, { static: false }]
|
|
612
634
|
}], panelEl: [{
|
|
613
635
|
type: ViewChild,
|
|
614
|
-
args: ['panel'
|
|
636
|
+
args: ['panel']
|
|
615
637
|
}], titleTpl: [{
|
|
616
638
|
type: ContentChild,
|
|
617
639
|
args: [PraxisDialogTitleDirective, {
|
|
@@ -638,13 +660,17 @@ const PraxisDialogDirectives = [];
|
|
|
638
660
|
|
|
639
661
|
class DialogOverlayService {
|
|
640
662
|
overlay = inject(Overlay);
|
|
641
|
-
|
|
663
|
+
defaults = inject(PRAXIS_DIALOG_DEFAULTS);
|
|
664
|
+
createOverlay(cfg) {
|
|
642
665
|
const overlayConfig = this.buildOverlayConfig(cfg);
|
|
643
666
|
return this.overlay.create(overlayConfig);
|
|
644
667
|
}
|
|
645
668
|
attachContainer(ref, injector) {
|
|
646
669
|
const portal = new ComponentPortal(PraxisDialogComponent, null, injector);
|
|
647
670
|
const compRef = ref.attach(portal);
|
|
671
|
+
// CDK 21 defers the first position calculation to afterNextRender. Apply the
|
|
672
|
+
// configured strategy now so dialogs never paint at the viewport origin.
|
|
673
|
+
ref.updatePosition();
|
|
648
674
|
return compRef;
|
|
649
675
|
}
|
|
650
676
|
buildOverlayConfig(cfg) {
|
|
@@ -684,6 +710,10 @@ class DialogOverlayService {
|
|
|
684
710
|
scrollStrategy,
|
|
685
711
|
width: coerceCssUnit(cfg?.width),
|
|
686
712
|
height: coerceCssUnit(cfg?.height),
|
|
713
|
+
minWidth: coerceCssUnit(cfg?.minWidth),
|
|
714
|
+
maxWidth: coerceCssUnit(cfg?.maxWidth ?? this.defaults.maxWidth),
|
|
715
|
+
minHeight: coerceCssUnit(cfg?.minHeight),
|
|
716
|
+
maxHeight: coerceCssUnit(cfg?.maxHeight ?? this.defaults.maxHeight),
|
|
687
717
|
});
|
|
688
718
|
if (cfg?.zIndex != null) {
|
|
689
719
|
overlayConfig.zIndex = cfg.zIndex;
|
|
@@ -706,6 +736,7 @@ const DialogOverlayImports = [OverlayModule, PortalModule];
|
|
|
706
736
|
|
|
707
737
|
class PraxisDialog {
|
|
708
738
|
overlay = inject(DialogOverlayService);
|
|
739
|
+
injector = inject(Injector);
|
|
709
740
|
layerScale = inject(PraxisLayerScaleStyleService);
|
|
710
741
|
appRef = inject(ApplicationRef);
|
|
711
742
|
registry = inject(PRAXIS_DIALOG_CONTENT_REGISTRY);
|
|
@@ -717,14 +748,18 @@ class PraxisDialog {
|
|
|
717
748
|
afterAllClosed = new Subject();
|
|
718
749
|
afterOpened = new Subject();
|
|
719
750
|
_openDialogs = [];
|
|
720
|
-
get openDialogs() {
|
|
751
|
+
get openDialogs() {
|
|
752
|
+
return this._openDialogs.slice();
|
|
753
|
+
}
|
|
721
754
|
_seq = 0;
|
|
722
755
|
open(content, config) {
|
|
723
756
|
this.layerScale.ensureInstalled();
|
|
757
|
+
const effectiveInjector = config?.injector ?? config?.viewContainerRef?.injector ?? this.injector;
|
|
724
758
|
const injector = Injector.create({
|
|
725
759
|
providers: [{ provide: PRAXIS_DIALOG_DATA, useValue: config?.data }],
|
|
760
|
+
parent: effectiveInjector,
|
|
726
761
|
});
|
|
727
|
-
const overlayRef = this.overlay.createOverlay(config ?? {}
|
|
762
|
+
const overlayRef = this.overlay.createOverlay(config ?? {});
|
|
728
763
|
const ref = new PraxisDialogRef(overlayRef);
|
|
729
764
|
// Auto-id fallback if not provided
|
|
730
765
|
let assignedId = config?.id ?? `praxis-dialog-${++this._seq}`;
|
|
@@ -739,10 +774,14 @@ class PraxisDialog {
|
|
|
739
774
|
// Set inputs before detectChanges so the correct branch/materialization occurs
|
|
740
775
|
container.overlayMode = true;
|
|
741
776
|
container.title = config?.title;
|
|
742
|
-
container.titleIcon =
|
|
777
|
+
container.titleIcon =
|
|
778
|
+
config?.icon ?? config?.titleIcon;
|
|
743
779
|
container.actions = config?.actions ?? [];
|
|
744
780
|
container.actionsLayout = config?.actionsLayout ?? 'stretched';
|
|
745
|
-
container.animation = config?.animation ?? {
|
|
781
|
+
container.animation = config?.animation ?? {
|
|
782
|
+
type: 'translate',
|
|
783
|
+
duration: 300,
|
|
784
|
+
};
|
|
746
785
|
container.width = config?.width;
|
|
747
786
|
container.height = config?.height;
|
|
748
787
|
container.minWidth = config?.minWidth;
|
|
@@ -758,7 +797,8 @@ class PraxisDialog {
|
|
|
758
797
|
container.backdropClass = config?.backdropClass;
|
|
759
798
|
container.position = config?.position;
|
|
760
799
|
container.autoFocusedElement = config?.autoFocusedElement;
|
|
761
|
-
container.autoFocus =
|
|
800
|
+
container.autoFocus =
|
|
801
|
+
config?.autoFocus ?? container.autoFocus;
|
|
762
802
|
container.restoreFocus = config?.restoreFocus ?? true;
|
|
763
803
|
container.id = assignedId;
|
|
764
804
|
container.ariaRole = config?.ariaRole ?? 'dialog';
|
|
@@ -813,16 +853,20 @@ class PraxisDialog {
|
|
|
813
853
|
return;
|
|
814
854
|
contentAttached = true;
|
|
815
855
|
if (content instanceof TemplateRef) {
|
|
816
|
-
const origin = config?.viewContainerRef ??
|
|
817
|
-
|
|
856
|
+
const origin = config?.viewContainerRef ??
|
|
857
|
+
null;
|
|
858
|
+
const portal = new TemplatePortal(content, origin, {
|
|
859
|
+
$implicit: config?.data,
|
|
860
|
+
});
|
|
818
861
|
container.contentHost.attachTemplatePortal(portal);
|
|
819
862
|
}
|
|
820
863
|
else {
|
|
821
|
-
const portal = new ComponentPortal(content);
|
|
864
|
+
const portal = new ComponentPortal(content, config?.viewContainerRef ?? null, injector);
|
|
822
865
|
const innerRef = container.contentHost.attachComponentPortal(portal);
|
|
823
866
|
ref.componentInstance = innerRef.instance;
|
|
824
867
|
ref.componentRef = innerRef;
|
|
825
868
|
}
|
|
869
|
+
container.focusInitialElement();
|
|
826
870
|
};
|
|
827
871
|
if (container.contentHost) {
|
|
828
872
|
doAttach();
|
|
@@ -864,8 +908,20 @@ class PraxisDialog {
|
|
|
864
908
|
confirm(cfg, variant) {
|
|
865
909
|
const merged = this.mergePresets('confirm', variant, cfg);
|
|
866
910
|
const actions = [
|
|
867
|
-
{
|
|
868
|
-
|
|
911
|
+
{
|
|
912
|
+
text: merged.cancelLabel ?? this.i18n.cancel,
|
|
913
|
+
role: 'secondary',
|
|
914
|
+
close: true,
|
|
915
|
+
id: 'cancel',
|
|
916
|
+
payload: false,
|
|
917
|
+
},
|
|
918
|
+
{
|
|
919
|
+
text: merged.confirmLabel ?? this.i18n.ok,
|
|
920
|
+
role: 'primary',
|
|
921
|
+
close: true,
|
|
922
|
+
id: 'confirm',
|
|
923
|
+
payload: true,
|
|
924
|
+
},
|
|
869
925
|
];
|
|
870
926
|
const Comp = SimpleDialogContentComponent;
|
|
871
927
|
return this.open(Comp, {
|
|
@@ -878,21 +934,53 @@ class PraxisDialog {
|
|
|
878
934
|
alert(cfg) {
|
|
879
935
|
const merged = this.mergePresets('alert', undefined, cfg);
|
|
880
936
|
const actions = [
|
|
881
|
-
{
|
|
937
|
+
{
|
|
938
|
+
text: merged.okLabel ?? this.i18n.ok,
|
|
939
|
+
role: 'primary',
|
|
940
|
+
close: true,
|
|
941
|
+
id: 'ok',
|
|
942
|
+
},
|
|
882
943
|
];
|
|
883
944
|
const Comp = SimpleDialogContentComponent;
|
|
884
|
-
return this.open(Comp, {
|
|
945
|
+
return this.open(Comp, {
|
|
946
|
+
...merged,
|
|
947
|
+
actions,
|
|
948
|
+
data: { message: merged.message, mode: 'alert' },
|
|
949
|
+
ariaRole: merged.ariaRole ?? 'alertdialog',
|
|
950
|
+
});
|
|
885
951
|
}
|
|
886
952
|
prompt(cfg) {
|
|
887
953
|
const merged = this.mergePresets('prompt', undefined, cfg);
|
|
888
954
|
const actions = [
|
|
889
|
-
{
|
|
890
|
-
|
|
955
|
+
{
|
|
956
|
+
text: merged.cancelLabel ?? this.i18n.cancel,
|
|
957
|
+
role: 'secondary',
|
|
958
|
+
close: true,
|
|
959
|
+
id: 'cancel',
|
|
960
|
+
payload: null,
|
|
961
|
+
},
|
|
962
|
+
{
|
|
963
|
+
text: merged.okLabel ?? this.i18n.ok,
|
|
964
|
+
role: 'primary',
|
|
965
|
+
close: false,
|
|
966
|
+
id: 'ok',
|
|
967
|
+
},
|
|
891
968
|
];
|
|
892
969
|
const Comp = SimpleDialogContentComponent;
|
|
893
|
-
const ref = this.open(Comp, {
|
|
970
|
+
const ref = this.open(Comp, {
|
|
971
|
+
...merged,
|
|
972
|
+
actions,
|
|
973
|
+
data: {
|
|
974
|
+
message: merged.message,
|
|
975
|
+
mode: 'prompt',
|
|
976
|
+
placeholder: merged.placeholder,
|
|
977
|
+
defaultValue: merged.defaultValue,
|
|
978
|
+
},
|
|
979
|
+
ariaRole: merged.ariaRole ?? 'dialog',
|
|
980
|
+
});
|
|
894
981
|
ref.afterOpened().subscribe(() => {
|
|
895
|
-
const inst = ref
|
|
982
|
+
const inst = ref
|
|
983
|
+
.componentInstance;
|
|
896
984
|
inst.submit = () => ref.close(inst.value ?? '');
|
|
897
985
|
});
|
|
898
986
|
return ref;
|
|
@@ -917,7 +1005,9 @@ class PraxisDialog {
|
|
|
917
1005
|
}
|
|
918
1006
|
mergePresets(type, variant, cfg) {
|
|
919
1007
|
const base = this.globalPresets?.[type] ?? {};
|
|
920
|
-
const variantCfg = variant
|
|
1008
|
+
const variantCfg = variant
|
|
1009
|
+
? (this.globalPresets?.variants?.[variant] ?? {})
|
|
1010
|
+
: {};
|
|
921
1011
|
return mergeDialogConfig(mergeDialogConfig(base, variantCfg), cfg);
|
|
922
1012
|
}
|
|
923
1013
|
closeAll() {
|
|
@@ -940,7 +1030,9 @@ class SimpleDialogContentComponent {
|
|
|
940
1030
|
placeholder;
|
|
941
1031
|
value;
|
|
942
1032
|
submit;
|
|
943
|
-
dialogData = inject(PRAXIS_DIALOG_DATA, {
|
|
1033
|
+
dialogData = inject(PRAXIS_DIALOG_DATA, {
|
|
1034
|
+
optional: true,
|
|
1035
|
+
});
|
|
944
1036
|
constructor() {
|
|
945
1037
|
const data = this.dialogData;
|
|
946
1038
|
try {
|
|
@@ -964,7 +1056,7 @@ class SimpleDialogContentComponent {
|
|
|
964
1056
|
</mat-form-field>
|
|
965
1057
|
}
|
|
966
1058
|
</div>
|
|
967
|
-
|
|
1059
|
+
`, isInline: true, styles: [".pdx-simple-dialog{display:grid;gap:12px}.pdx-simple-dialog__message{margin:0}.pdx-simple-dialog__field{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }] });
|
|
968
1060
|
}
|
|
969
1061
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: SimpleDialogContentComponent, decorators: [{
|
|
970
1062
|
type: Component,
|
|
@@ -980,7 +1072,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
980
1072
|
</mat-form-field>
|
|
981
1073
|
}
|
|
982
1074
|
</div>
|
|
983
|
-
|
|
1075
|
+
`, styles: [".pdx-simple-dialog{display:grid;gap:12px}.pdx-simple-dialog__message{margin:0}.pdx-simple-dialog__field{width:100%}\n"] }]
|
|
984
1076
|
}], ctorParameters: () => [] });
|
|
985
1077
|
class SimpleHtmlDialogContentComponent {
|
|
986
1078
|
safeHtml;
|
|
@@ -1156,7 +1248,7 @@ function providePraxisDialogGlobalActions() {
|
|
|
1156
1248
|
};
|
|
1157
1249
|
}
|
|
1158
1250
|
|
|
1159
|
-
function buildDialogConfig(payload) {
|
|
1251
|
+
function buildDialogConfig(payload, injector) {
|
|
1160
1252
|
return {
|
|
1161
1253
|
title: payload.title,
|
|
1162
1254
|
titleIcon: payload.icon,
|
|
@@ -1166,6 +1258,7 @@ function buildDialogConfig(payload) {
|
|
|
1166
1258
|
maxWidth: payload.size?.maxWidth,
|
|
1167
1259
|
minHeight: payload.size?.minHeight,
|
|
1168
1260
|
maxHeight: payload.size?.maxHeight,
|
|
1261
|
+
injector,
|
|
1169
1262
|
};
|
|
1170
1263
|
}
|
|
1171
1264
|
function buildHostInputs(payload, context, options) {
|
|
@@ -1194,7 +1287,9 @@ function buildDialogSurfaceRuntime(ref, resultSubject, complete) {
|
|
|
1194
1287
|
result$: resultSubject.asObservable(),
|
|
1195
1288
|
emitResult: (result) => resultSubject.next(result),
|
|
1196
1289
|
complete,
|
|
1197
|
-
close: (result) => {
|
|
1290
|
+
close: (result) => {
|
|
1291
|
+
void ref.close(result);
|
|
1292
|
+
},
|
|
1198
1293
|
updateSize: (preset) => {
|
|
1199
1294
|
const width = resolveDialogWidth(preset);
|
|
1200
1295
|
if (width) {
|
|
@@ -1248,7 +1343,8 @@ function bindSurfaceHostSelectionResults(instance, resultSubject) {
|
|
|
1248
1343
|
return () => subscriptions.forEach((unsubscribe) => unsubscribe());
|
|
1249
1344
|
}
|
|
1250
1345
|
function subscribeToOutput(output, handler) {
|
|
1251
|
-
if (!output ||
|
|
1346
|
+
if (!output ||
|
|
1347
|
+
typeof output.subscribe !== 'function') {
|
|
1252
1348
|
return null;
|
|
1253
1349
|
}
|
|
1254
1350
|
const subscription = output.subscribe(handler);
|
|
@@ -1263,9 +1359,9 @@ function toSurfaceSelectionResult(output, payload) {
|
|
|
1263
1359
|
};
|
|
1264
1360
|
}
|
|
1265
1361
|
function resolveParentSurfaceRuntime(context) {
|
|
1266
|
-
const runtime = context?.runtime?.state?.surfaceRuntime
|
|
1267
|
-
|
|
1268
|
-
|
|
1362
|
+
const runtime = context?.runtime?.state?.surfaceRuntime ||
|
|
1363
|
+
context?.payload?.surfaceContext?.surfaceRuntime ||
|
|
1364
|
+
context?.pageContext?.surfaceRuntime;
|
|
1269
1365
|
return runtime && typeof runtime === 'object'
|
|
1270
1366
|
? runtime
|
|
1271
1367
|
: null;
|
|
@@ -1276,11 +1372,10 @@ function resolveParentSurfaceRuntime(context) {
|
|
|
1276
1372
|
* control after the surface terminates.
|
|
1277
1373
|
*/
|
|
1278
1374
|
function resolveRuntimeFocusOrigin(context) {
|
|
1279
|
-
const candidate = context?.runtime
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
&& (candidate.isConnected || !!candidate.getAttribute('data-praxis-focus-key'))
|
|
1375
|
+
const candidate = context?.runtime?.focusOrigin;
|
|
1376
|
+
return candidate &&
|
|
1377
|
+
typeof candidate.focus === 'function' &&
|
|
1378
|
+
(candidate.isConnected || !!candidate.getAttribute('data-praxis-focus-key'))
|
|
1284
1379
|
? candidate
|
|
1285
1380
|
: null;
|
|
1286
1381
|
}
|
|
@@ -1292,9 +1387,7 @@ function resolveReplacementFocusOrigin(focusOrigin) {
|
|
|
1292
1387
|
if (!key || typeof document === 'undefined') {
|
|
1293
1388
|
return null;
|
|
1294
1389
|
}
|
|
1295
|
-
return Array.from(document.querySelectorAll('[data-praxis-focus-key]'))
|
|
1296
|
-
.find((candidate) => candidate.getAttribute('data-praxis-focus-key') === key)
|
|
1297
|
-
?? null;
|
|
1390
|
+
return (Array.from(document.querySelectorAll('[data-praxis-focus-key]')).find((candidate) => candidate.getAttribute('data-praxis-focus-key') === key) ?? null);
|
|
1298
1391
|
}
|
|
1299
1392
|
function restoreRuntimeFocusOnClose(closed$, focusOrigin) {
|
|
1300
1393
|
if (!focusOrigin || typeof closed$?.subscribe !== 'function')
|
|
@@ -1303,8 +1396,8 @@ function restoreRuntimeFocusOnClose(closed$, focusOrigin) {
|
|
|
1303
1396
|
const restore = (remainingAttempts) => {
|
|
1304
1397
|
const target = resolveReplacementFocusOrigin(focusOrigin);
|
|
1305
1398
|
const activeElement = typeof document !== 'undefined' ? document.activeElement : null;
|
|
1306
|
-
const focusWasLostToDocument = activeElement === document.body
|
|
1307
|
-
|
|
1399
|
+
const focusWasLostToDocument = activeElement === document.body ||
|
|
1400
|
+
activeElement === document.documentElement;
|
|
1308
1401
|
const targetAlreadyFocused = activeElement === target;
|
|
1309
1402
|
if (target && (focusWasLostToDocument || targetAlreadyFocused)) {
|
|
1310
1403
|
try {
|
|
@@ -1317,12 +1410,12 @@ function restoreRuntimeFocusOnClose(closed$, focusOrigin) {
|
|
|
1317
1410
|
catch { }
|
|
1318
1411
|
}
|
|
1319
1412
|
}
|
|
1320
|
-
if (remainingAttempts > 0
|
|
1321
|
-
|
|
1413
|
+
if (remainingAttempts > 0 &&
|
|
1414
|
+
typeof setTimeout !== 'undefined' &&
|
|
1322
1415
|
// A late overlay teardown can return focus to document.body after the
|
|
1323
1416
|
// first restore. Keep checking only while focus remains unowned (or
|
|
1324
1417
|
// on the restored target); never steal a user-initiated new focus.
|
|
1325
|
-
|
|
1418
|
+
(focusWasLostToDocument || targetAlreadyFocused)) {
|
|
1326
1419
|
setTimeout(() => restore(remainingAttempts - 1), 50);
|
|
1327
1420
|
}
|
|
1328
1421
|
};
|
|
@@ -1337,6 +1430,7 @@ function providePraxisSurfaceGlobalActions() {
|
|
|
1337
1430
|
provide: GLOBAL_SURFACE_SERVICE,
|
|
1338
1431
|
useFactory: () => {
|
|
1339
1432
|
const dialog = inject(PraxisDialog);
|
|
1433
|
+
const injector = inject(Injector);
|
|
1340
1434
|
const materializer = inject(SurfaceOpenMaterializerService);
|
|
1341
1435
|
const logger = inject(LoggerService, { optional: true });
|
|
1342
1436
|
const surfaceDrawer = inject(SURFACE_DRAWER_BRIDGE, {
|
|
@@ -1401,7 +1495,7 @@ function providePraxisSurfaceGlobalActions() {
|
|
|
1401
1495
|
restoreRuntimeFocusOnClose(ref.closed$, focusOrigin);
|
|
1402
1496
|
return ref;
|
|
1403
1497
|
}
|
|
1404
|
-
const ref = dialog.open(PraxisSurfaceHostComponent, buildDialogConfig(materializedPayload));
|
|
1498
|
+
const ref = dialog.open(PraxisSurfaceHostComponent, buildDialogConfig(materializedPayload, injector));
|
|
1405
1499
|
restoreRuntimeFocusOnClose(ref.afterClosed(), focusOrigin);
|
|
1406
1500
|
const resultSubject = new Subject();
|
|
1407
1501
|
let terminalOutcomeEmitted = false;
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@praxisui/dialog",
|
|
3
|
-
"version": "9.0.
|
|
3
|
+
"version": "9.0.8",
|
|
4
4
|
"description": "Dialog helpers and components for Praxis UI with Angular Material integration.",
|
|
5
5
|
"peerDependencies": {
|
|
6
6
|
"@angular/common": "^21.0.0",
|
|
7
7
|
"@angular/core": "^21.0.0",
|
|
8
8
|
"@angular/cdk": "^21.0.0",
|
|
9
9
|
"@angular/forms": "^21.0.0",
|
|
10
|
-
"@praxisui/core": "^9.0.
|
|
10
|
+
"@praxisui/core": "^9.0.8",
|
|
11
11
|
"@angular/material": "^21.0.0",
|
|
12
12
|
"@angular/platform-browser": "^21.0.0",
|
|
13
13
|
"rxjs": "~7.8.0"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, TemplateRef, ComponentRef, OnInit, OnChanges, OnDestroy, EventEmitter, ElementRef, SimpleChanges, Type, Provider } from '@angular/core';
|
|
2
|
+
import { Injector, ViewContainerRef, InjectionToken, TemplateRef, ComponentRef, OnInit, AfterViewInit, OnChanges, OnDestroy, EventEmitter, ElementRef, SimpleChanges, Type, Provider } from '@angular/core';
|
|
3
3
|
import { OverlayRef } from '@angular/cdk/overlay';
|
|
4
4
|
import { Observable, Subject } from 'rxjs';
|
|
5
5
|
import { CdkPortalOutlet } from '@angular/cdk/portal';
|
|
@@ -64,7 +64,13 @@ interface PraxisDialogConfig<D = any> {
|
|
|
64
64
|
ariaLabelledBy?: string;
|
|
65
65
|
ariaDescribedBy?: string;
|
|
66
66
|
appendTo?: Element | any;
|
|
67
|
-
|
|
67
|
+
/**
|
|
68
|
+
* Runtime-only injector used to create the dialog container and its dynamic
|
|
69
|
+
* content. It takes precedence over the injector derived from
|
|
70
|
+
* viewContainerRef and must not be persisted or authored as JSON.
|
|
71
|
+
*/
|
|
72
|
+
injector?: Injector;
|
|
73
|
+
viewContainerRef?: ViewContainerRef;
|
|
68
74
|
closeOnNavigation?: boolean;
|
|
69
75
|
zIndex?: number;
|
|
70
76
|
styles?: PraxisDialogStyleConfig;
|
|
@@ -166,6 +172,7 @@ declare class PraxisDialogRef<T = any, R = any> {
|
|
|
166
172
|
componentRef?: ComponentRef<T>;
|
|
167
173
|
constructor(overlayRef: OverlayRef);
|
|
168
174
|
private beforeCloseHandler?;
|
|
175
|
+
private closePromise?;
|
|
169
176
|
setBeforeClose(handler: (result?: R) => Promise<void> | void): void;
|
|
170
177
|
emitOpened(): void;
|
|
171
178
|
backdropClick(): Observable<MouseEvent>;
|
|
@@ -176,6 +183,7 @@ declare class PraxisDialogRef<T = any, R = any> {
|
|
|
176
183
|
notifyBackdropClick(ev: MouseEvent): void;
|
|
177
184
|
notifyKeydown(ev: KeyboardEvent): void;
|
|
178
185
|
close(result?: R): Promise<void>;
|
|
186
|
+
private performClose;
|
|
179
187
|
updateSize(width?: string | number, height?: string | number): this;
|
|
180
188
|
updatePosition(position?: PraxisDialogPosition): this;
|
|
181
189
|
}
|
|
@@ -201,7 +209,7 @@ declare class PraxisDialogContentDirective {
|
|
|
201
209
|
static ɵdir: i0.ɵɵDirectiveDeclaration<PraxisDialogContentDirective, "ng-template[praxisDialogContent]", never, {}, {}, never, never, true, never>;
|
|
202
210
|
}
|
|
203
211
|
|
|
204
|
-
declare class PraxisDialogComponent implements OnInit, OnChanges, OnDestroy {
|
|
212
|
+
declare class PraxisDialogComponent implements OnInit, AfterViewInit, OnChanges, OnDestroy {
|
|
205
213
|
title?: string;
|
|
206
214
|
actions: DialogAction[];
|
|
207
215
|
actionsLayout: ActionsLayout;
|
|
@@ -256,12 +264,20 @@ declare class PraxisDialogComponent implements OnInit, OnChanges, OnDestroy {
|
|
|
256
264
|
requestClose(): void;
|
|
257
265
|
isDisplayed: boolean;
|
|
258
266
|
ngOnInit(): void;
|
|
267
|
+
ngAfterViewInit(): void;
|
|
259
268
|
ngOnChanges(changes: SimpleChanges): void;
|
|
260
269
|
onKeydown(ev: KeyboardEvent): void;
|
|
261
270
|
onActionClick(a: DialogAction): void;
|
|
262
271
|
onBackdrop(ev: MouseEvent): void;
|
|
263
272
|
focus(): void;
|
|
273
|
+
/**
|
|
274
|
+
* Moves focus into the currently materialized panel. Overlay hosts call this
|
|
275
|
+
* after switching to the overlay template branch and attaching its content.
|
|
276
|
+
*/
|
|
277
|
+
focusInitialElement(): void;
|
|
264
278
|
private scheduleInitialFocus;
|
|
279
|
+
private captureFocusOrigin;
|
|
280
|
+
private applyInitialFocus;
|
|
265
281
|
private _previouslyFocused?;
|
|
266
282
|
ngOnDestroy(): void;
|
|
267
283
|
get animationClasses(): string[];
|
|
@@ -278,6 +294,7 @@ declare const PraxisDialogDirectives: readonly [];
|
|
|
278
294
|
|
|
279
295
|
declare class PraxisDialog {
|
|
280
296
|
private readonly overlay;
|
|
297
|
+
private readonly injector;
|
|
281
298
|
private readonly layerScale;
|
|
282
299
|
private readonly appRef;
|
|
283
300
|
private readonly registry;
|