@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 CHANGED
@@ -64,13 +64,33 @@ export class UsersComponent {
64
64
  ## Custom Content And Tag Mode
65
65
 
66
66
  ```ts
67
- this.dialog.open(CustomerFormComponent, {
68
- title: "Edit customer",
69
- width: "720px",
70
- data: customer,
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-19T23:21:15.260Z",
3
+ "generatedAt": "2026-08-20T18:11:26.392Z",
4
4
  "packageName": "@praxisui/dialog",
5
- "packageVersion": "9.0.6",
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, ApplicationRef, Injector, TemplateRef, ENVIRONMENT_INITIALIZER } from '@angular/core';
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
- async close(result) {
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
- const panel = this.panelEl?.nativeElement;
335
- if (!panel)
336
- return;
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
- queueMicrotask(() => {
341
- try {
342
- if (this.autoFocus && this.ariaRole === 'alertdialog') {
343
- // In alertdialog, focus the primary action if present
344
- const focused = this.focusPrimaryAction();
345
- if (focused)
346
- return;
347
- }
348
- if (this.autoFocusedElement) {
349
- const el = panel.querySelector(this.autoFocusedElement);
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
- catch { }
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', { static: true }]
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
- createOverlay(cfg, injector) {
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() { return this._openDialogs.slice(); }
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 ?? {}, injector);
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 = config?.icon ?? config?.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 ?? { type: 'translate', duration: 300 };
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 = config?.autoFocus ?? 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 ?? null;
817
- const portal = new TemplatePortal(content, origin, { $implicit: config?.data });
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
- { text: merged.cancelLabel ?? this.i18n.cancel, role: 'secondary', close: true, id: 'cancel', payload: false },
868
- { text: merged.confirmLabel ?? this.i18n.ok, role: 'primary', close: true, id: 'confirm', payload: true },
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
- { text: merged.okLabel ?? this.i18n.ok, role: 'primary', close: true, id: 'ok' },
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, { ...merged, actions, data: { message: merged.message, mode: 'alert' }, ariaRole: merged.ariaRole ?? 'alertdialog' });
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
- { text: merged.cancelLabel ?? this.i18n.cancel, role: 'secondary', close: true, id: 'cancel', payload: null },
890
- { text: merged.okLabel ?? this.i18n.ok, role: 'primary', close: false, id: 'ok' },
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, { ...merged, actions, data: { message: merged.message, mode: 'prompt', placeholder: merged.placeholder, defaultValue: merged.defaultValue }, ariaRole: merged.ariaRole ?? 'dialog' });
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.componentInstance;
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 ? (this.globalPresets?.variants?.[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, { optional: true });
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
- `, 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"] }] });
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
- `, styles: [".pdx-simple-dialog{display:grid;gap:12px}.pdx-simple-dialog__message{margin:0}.pdx-simple-dialog__field{width:100%}\n"] }]
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) => { void ref.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 || typeof output.subscribe !== 'function') {
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
- || context?.payload?.surfaceContext?.surfaceRuntime
1268
- || context?.pageContext?.surfaceRuntime;
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
- ?.focusOrigin;
1281
- return candidate
1282
- && typeof candidate.focus === 'function'
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
- || activeElement === document.documentElement;
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
- && typeof setTimeout !== 'undefined'
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
- && (focusWasLostToDocument || targetAlreadyFocused)) {
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.6",
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.6",
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
- viewContainerRef?: i0.ViewContainerRef;
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;