@praxisui/dialog 9.0.4-rc.8 → 9.0.4

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
@@ -25,11 +25,11 @@ Peer dependencies:
25
25
  ## Use The Service API
26
26
 
27
27
  ```ts
28
- import { Component } from '@angular/core';
29
- import { PraxisDialog } from '@praxisui/dialog';
28
+ import { Component } from "@angular/core";
29
+ import { PraxisDialog } from "@praxisui/dialog";
30
30
 
31
31
  @Component({
32
- selector: 'app-users',
32
+ selector: "app-users",
33
33
  standalone: true,
34
34
  template: `<button type="button" (click)="deleteUser()">Delete</button>`,
35
35
  })
@@ -39,13 +39,13 @@ export class UsersComponent {
39
39
  deleteUser(): void {
40
40
  const ref = this.dialog.confirm(
41
41
  {
42
- title: 'Delete user',
43
- message: 'This action cannot be undone.',
44
- confirmLabel: 'Delete',
45
- cancelLabel: 'Cancel',
42
+ title: "Delete user",
43
+ message: "This action cannot be undone.",
44
+ confirmLabel: "Delete",
45
+ cancelLabel: "Cancel",
46
46
  disableClose: true,
47
47
  },
48
- 'destructive',
48
+ "destructive",
49
49
  );
50
50
 
51
51
  ref.afterClosed().subscribe((confirmed) => {
@@ -65,8 +65,8 @@ export class UsersComponent {
65
65
 
66
66
  ```ts
67
67
  this.dialog.open(CustomerFormComponent, {
68
- title: 'Edit customer',
69
- width: '720px',
68
+ title: "Edit customer",
69
+ width: "720px",
70
70
  data: customer,
71
71
  });
72
72
  ```
@@ -90,8 +90,8 @@ Use `openByRegistry(id, config)` or `openTemplateById(id, config)` for governed
90
90
  Register the global dialog bridge when metadata-driven surfaces need to open alerts, confirmations, prompts or registered component dialogs through `GLOBAL_DIALOG_SERVICE`.
91
91
 
92
92
  ```ts
93
- import { ApplicationConfig } from '@angular/core';
94
- import { providePraxisDialogGlobalActions } from '@praxisui/dialog';
93
+ import { ApplicationConfig } from "@angular/core";
94
+ import { providePraxisDialogGlobalActions } from "@praxisui/dialog";
95
95
 
96
96
  export const appConfig: ApplicationConfig = {
97
97
  providers: [providePraxisDialogGlobalActions()],
@@ -103,15 +103,15 @@ For `dialog.open`, provide `componentId`, optional `inputs`, `data`, and `size`.
103
103
  ## Presets And Host Policy
104
104
 
105
105
  ```ts
106
- import { PRAXIS_DIALOG_GLOBAL_PRESETS } from '@praxisui/dialog';
106
+ import { PRAXIS_DIALOG_GLOBAL_PRESETS } from "@praxisui/dialog";
107
107
 
108
108
  providers: [
109
109
  {
110
110
  provide: PRAXIS_DIALOG_GLOBAL_PRESETS,
111
111
  useValue: {
112
- confirm: { themeColor: 'light', animation: { type: 'translate', duration: 200 } },
112
+ confirm: { themeColor: "light", animation: { type: "translate", duration: 200 } },
113
113
  variants: {
114
- destructive: { ariaRole: 'alertdialog', themeColor: 'primary', disableClose: true },
114
+ destructive: { ariaRole: "alertdialog", themeColor: "primary", disableClose: true },
115
115
  },
116
116
  },
117
117
  },
@@ -134,6 +134,8 @@ Component-specific dialog variables remain available for deliberate local custom
134
134
 
135
135
  `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
136
 
137
+ 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
+
137
139
  ## Official Links
138
140
 
139
141
  - Documentation: https://praxisui.dev/components/dialog
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": "1.0.0",
3
- "generatedAt": "2026-08-02T14:11:23.065Z",
3
+ "generatedAt": "2026-08-11T17:36:05.628Z",
4
4
  "packageName": "@praxisui/dialog",
5
- "packageVersion": "9.0.4-rc.8",
5
+ "packageVersion": "9.0.4",
6
6
  "sourceRegistry": "praxis-component-registry-ingestion",
7
7
  "sourceRegistryVersion": "1.0.0",
8
8
  "componentCount": 1,
@@ -9,7 +9,7 @@ import * as i3 from '@angular/cdk/a11y';
9
9
  import { A11yModule } from '@angular/cdk/a11y';
10
10
  import * as i4 from '@angular/material/icon';
11
11
  import { MatIconModule } from '@angular/material/icon';
12
- import { PraxisIconDirective, PraxisLayerScaleStyleService, GlobalConfigService, GLOBAL_DIALOG_SERVICE, ComponentMetadataRegistry, GLOBAL_SURFACE_SERVICE, SurfaceOpenMaterializerService, SURFACE_DRAWER_BRIDGE, PraxisSurfaceHostComponent } from '@praxisui/core';
12
+ import { PraxisIconDirective, PraxisLayerScaleStyleService, GlobalConfigService, GLOBAL_DIALOG_SERVICE, ComponentMetadataRegistry, GLOBAL_SURFACE_SERVICE, SurfaceOpenMaterializerService, LoggerService, SURFACE_DRAWER_BRIDGE, PraxisSurfaceHostComponent, SurfaceNavigationError } from '@praxisui/core';
13
13
  import { Overlay, OverlayConfig, OverlayModule } from '@angular/cdk/overlay';
14
14
  import * as i1$1 from '@angular/forms';
15
15
  import { FormsModule } from '@angular/forms';
@@ -22,7 +22,13 @@ import { MatInputModule } from '@angular/material/input';
22
22
  const PRAXIS_DIALOG_DATA = new InjectionToken('PRAXIS_DIALOG_DATA');
23
23
  const PRAXIS_DIALOG_I18N = new InjectionToken('PRAXIS_DIALOG_I18N', {
24
24
  providedIn: 'root',
25
- factory: () => ({ ok: 'OK', cancel: 'Cancelar', yes: 'Sim', no: 'Não' }),
25
+ factory: () => ({
26
+ ok: 'OK',
27
+ cancel: 'Cancelar',
28
+ yes: 'Sim',
29
+ no: 'Não',
30
+ close: 'Fechar',
31
+ }),
26
32
  });
27
33
  const PRAXIS_DIALOG_DEFAULTS = new InjectionToken('PRAXIS_DIALOG_DEFAULTS', {
28
34
  providedIn: 'root',
@@ -210,7 +216,20 @@ class PraxisDialogComponent {
210
216
  hostClass = 'pdx-dialog-host';
211
217
  tabindex = '-1';
212
218
  data = inject(PRAXIS_DIALOG_DATA, { optional: true });
213
- get titleId() { return (this.id ?? 'praxis-dialog') + '-title'; }
219
+ i18n = inject(PRAXIS_DIALOG_I18N);
220
+ get titleId() {
221
+ return (this.id ?? 'praxis-dialog') + '-title';
222
+ }
223
+ get displaysCloseButton() {
224
+ return this.ariaRole === 'dialog' && !this.disableClose;
225
+ }
226
+ get closeButtonLabel() {
227
+ return this.i18n.close ?? this.i18n.cancel;
228
+ }
229
+ requestClose() {
230
+ if (!this.disableClose)
231
+ this.close.emit();
232
+ }
214
233
  isDisplayed = false; // controls DOM visibility for animation in tag mode
215
234
  ngOnInit() {
216
235
  if (this.open) {
@@ -226,7 +245,9 @@ class PraxisDialogComponent {
226
245
  if (this.ariaRole === 'alertdialog') {
227
246
  const hasLabel = !!(this.title || this.ariaLabel || this.ariaLabelledBy);
228
247
  try {
229
- const isDev = typeof globalThis.ngDevMode !== 'undefined' ? !!globalThis.ngDevMode : true;
248
+ const isDev = typeof globalThis.ngDevMode !== 'undefined'
249
+ ? !!globalThis.ngDevMode
250
+ : true;
230
251
  if (isDev && !hasLabel) {
231
252
  console.warn('[PraxisDialog] alertdialog requires a title or aria label.');
232
253
  }
@@ -245,12 +266,17 @@ class PraxisDialogComponent {
245
266
  });
246
267
  this.scheduleInitialFocus();
247
268
  }
248
- if (changes['open'] && !this.open && !this.overlayMode && this.isDisplayed) {
269
+ if (changes['open'] &&
270
+ !this.open &&
271
+ !this.overlayMode &&
272
+ this.isDisplayed) {
249
273
  // animate close then hide
250
274
  this.beginCloseAnimation().then(() => {
251
275
  this.isDisplayed = false;
252
276
  this.afterClosed.emit();
253
- if (this.restoreFocus && this._previouslyFocused && typeof this._previouslyFocused.focus === 'function') {
277
+ if (this.restoreFocus &&
278
+ this._previouslyFocused &&
279
+ typeof this._previouslyFocused.focus === 'function') {
254
280
  try {
255
281
  this._previouslyFocused.focus();
256
282
  }
@@ -333,7 +359,9 @@ class PraxisDialogComponent {
333
359
  }
334
360
  _previouslyFocused;
335
361
  ngOnDestroy() {
336
- if (this.restoreFocus && this._previouslyFocused && typeof this._previouslyFocused.focus === 'function') {
362
+ if (this.restoreFocus &&
363
+ this._previouslyFocused &&
364
+ typeof this._previouslyFocused.focus === 'function') {
337
365
  try {
338
366
  this._previouslyFocused.focus();
339
367
  }
@@ -375,7 +403,9 @@ class PraxisDialogComponent {
375
403
  if (!this.panelEl)
376
404
  return;
377
405
  const anim = this.animation;
378
- const conf = anim === true || anim == null ? { type: 'translate', duration: 300 } : anim;
406
+ const conf = anim === true || anim == null
407
+ ? { type: 'translate', duration: 300 }
408
+ : anim;
379
409
  const dur = (conf.duration ?? 300);
380
410
  try {
381
411
  this.panelEl.nativeElement.style.setProperty('--pdx-dialog-anim-duration', `${dur}ms`);
@@ -456,10 +486,16 @@ class PraxisDialogComponent {
456
486
  panel.classList.add('pdx-state-closing');
457
487
  return new Promise((resolve) => {
458
488
  let done = false;
459
- const finish = () => { if (done)
460
- return; done = true; panel.removeEventListener('transitionend', onEnd); resolve(); };
489
+ const finish = () => {
490
+ if (done)
491
+ return;
492
+ done = true;
493
+ panel.removeEventListener('transitionend', onEnd);
494
+ resolve();
495
+ };
461
496
  const onEnd = (ev) => {
462
- if (ev.propertyName === 'opacity' || ev.propertyName === 'transform')
497
+ if (ev.propertyName === 'opacity' ||
498
+ ev.propertyName === 'transform')
463
499
  finish();
464
500
  };
465
501
  panel.addEventListener('transitionend', onEnd);
@@ -491,11 +527,17 @@ class PraxisDialogComponent {
491
527
  }
492
528
  }
493
529
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
494
- 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) {\n <div class=\"pdx-dialog__title\">\n @if (titleTpl?.templateRef) {\n <ng-container [ngTemplateOutlet]=\"titleTpl!.templateRef\"></ng-container>\n } @else {\n <div class=\"pdx-dialog__title-row\">\n @if (titleIcon) {\n <mat-icon class=\"pdx-dialog__title-icon\" [praxisIcon]=\"titleIcon\" aria-hidden=\"true\"></mat-icon>\n }\n <h2 class=\"pdx-dialog__title-text\" [attr.id]=\"_titleId\">{{ title }}</h2>\n </div>\n }\n </div>\n }\n</ng-template>\n\n<ng-template #panelActions>\n <div class=\"pdx-dialog__actions\" [class.is-stretched]=\"actionsLayout==='stretched'\">\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]=\"a.role==='primary' && ariaRole==='alertdialog' ? '' : null\"\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-{{ actionsLayout }}\"\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 [ngTemplateOutlet]=\"contentTpl!.templateRef\"></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 class=\"pdx-dialog-overlay\" [class.has-backdrop]=\"hasBackdrop\" [hidden]=\"!isDisplayed\" (click)=\"onBackdrop($event)\" [ngClass]=\"backdropClass\" [style.z-index]=\"zIndex\">\n <div class=\"pdx-dialog-shell\" (click)=\"$event.stopPropagation()\">\n <div\n #panel\n class=\"pdx-dialog pdx-dialog--{{ themeColor }} pdx-dialog--layout-{{ actionsLayout }}\"\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]=\"(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 [ngTemplateOutlet]=\"contentTpl!.templateRef\"></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;gap:10px}.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__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 });
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 });
495
531
  }
496
532
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisDialogComponent, decorators: [{
497
533
  type: Component,
498
- args: [{ selector: 'praxis-dialog', standalone: true, imports: [CommonModule, PortalModule, A11yModule, MatIconModule, PraxisIconDirective], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "@let _titleId = (id ?? 'praxis-dialog') + '-title';\n\n<ng-template #panelHeader>\n @if (titleTpl?.templateRef || title || titleIcon) {\n <div class=\"pdx-dialog__title\">\n @if (titleTpl?.templateRef) {\n <ng-container [ngTemplateOutlet]=\"titleTpl!.templateRef\"></ng-container>\n } @else {\n <div class=\"pdx-dialog__title-row\">\n @if (titleIcon) {\n <mat-icon class=\"pdx-dialog__title-icon\" [praxisIcon]=\"titleIcon\" aria-hidden=\"true\"></mat-icon>\n }\n <h2 class=\"pdx-dialog__title-text\" [attr.id]=\"_titleId\">{{ title }}</h2>\n </div>\n }\n </div>\n }\n</ng-template>\n\n<ng-template #panelActions>\n <div class=\"pdx-dialog__actions\" [class.is-stretched]=\"actionsLayout==='stretched'\">\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]=\"a.role==='primary' && ariaRole==='alertdialog' ? '' : null\"\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-{{ actionsLayout }}\"\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 [ngTemplateOutlet]=\"contentTpl!.templateRef\"></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 class=\"pdx-dialog-overlay\" [class.has-backdrop]=\"hasBackdrop\" [hidden]=\"!isDisplayed\" (click)=\"onBackdrop($event)\" [ngClass]=\"backdropClass\" [style.z-index]=\"zIndex\">\n <div class=\"pdx-dialog-shell\" (click)=\"$event.stopPropagation()\">\n <div\n #panel\n class=\"pdx-dialog pdx-dialog--{{ themeColor }} pdx-dialog--layout-{{ actionsLayout }}\"\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]=\"(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 [ngTemplateOutlet]=\"contentTpl!.templateRef\"></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;gap:10px}.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__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"] }]
534
+ args: [{ selector: 'praxis-dialog', standalone: true, imports: [
535
+ CommonModule,
536
+ PortalModule,
537
+ A11yModule,
538
+ MatIconModule,
539
+ PraxisIconDirective,
540
+ ], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, 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"] }]
499
541
  }], propDecorators: { title: [{
500
542
  type: Input
501
543
  }], actions: [{
@@ -572,13 +614,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
572
614
  args: ['panel', { static: true }]
573
615
  }], titleTpl: [{
574
616
  type: ContentChild,
575
- args: [PraxisDialogTitleDirective, { read: PraxisDialogTitleDirective }]
617
+ args: [PraxisDialogTitleDirective, {
618
+ read: PraxisDialogTitleDirective,
619
+ }]
576
620
  }], actionsTpl: [{
577
621
  type: ContentChild,
578
- args: [PraxisDialogActionsDirective, { read: PraxisDialogActionsDirective }]
622
+ args: [PraxisDialogActionsDirective, {
623
+ read: PraxisDialogActionsDirective,
624
+ }]
579
625
  }], contentTpl: [{
580
626
  type: ContentChild,
581
- args: [PraxisDialogContentDirective, { read: PraxisDialogContentDirective }]
627
+ args: [PraxisDialogContentDirective, {
628
+ read: PraxisDialogContentDirective,
629
+ }]
582
630
  }], hostClass: [{
583
631
  type: HostBinding,
584
632
  args: ['class']
@@ -1214,43 +1262,147 @@ function toSurfaceSelectionResult(output, payload) {
1214
1262
  payload,
1215
1263
  };
1216
1264
  }
1265
+ function resolveParentSurfaceRuntime(context) {
1266
+ const runtime = context?.runtime?.state?.surfaceRuntime
1267
+ || context?.payload?.surfaceContext?.surfaceRuntime
1268
+ || context?.pageContext?.surfaceRuntime;
1269
+ return runtime && typeof runtime === 'object'
1270
+ ? runtime
1271
+ : null;
1272
+ }
1273
+ /**
1274
+ * The action origin is runtime-only: persisted surface payloads remain JSON
1275
+ * safe, while the visual host can return keyboard focus to the invoking
1276
+ * control after the surface terminates.
1277
+ */
1278
+ 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'))
1284
+ ? candidate
1285
+ : null;
1286
+ }
1287
+ function resolveReplacementFocusOrigin(focusOrigin) {
1288
+ if (focusOrigin.isConnected) {
1289
+ return focusOrigin;
1290
+ }
1291
+ const key = focusOrigin.getAttribute('data-praxis-focus-key');
1292
+ if (!key || typeof document === 'undefined') {
1293
+ return null;
1294
+ }
1295
+ return Array.from(document.querySelectorAll('[data-praxis-focus-key]'))
1296
+ .find((candidate) => candidate.getAttribute('data-praxis-focus-key') === key)
1297
+ ?? null;
1298
+ }
1299
+ function restoreRuntimeFocusOnClose(closed$, focusOrigin) {
1300
+ if (!focusOrigin || typeof closed$?.subscribe !== 'function')
1301
+ return;
1302
+ closed$.subscribe(() => {
1303
+ const restore = (remainingAttempts) => {
1304
+ const target = resolveReplacementFocusOrigin(focusOrigin);
1305
+ const activeElement = typeof document !== 'undefined' ? document.activeElement : null;
1306
+ const focusWasLostToDocument = activeElement === document.body
1307
+ || activeElement === document.documentElement;
1308
+ const targetAlreadyFocused = activeElement === target;
1309
+ if (target && (focusWasLostToDocument || targetAlreadyFocused)) {
1310
+ try {
1311
+ target.focus({ preventScroll: true });
1312
+ }
1313
+ catch {
1314
+ try {
1315
+ target.focus();
1316
+ }
1317
+ catch { }
1318
+ }
1319
+ }
1320
+ if (remainingAttempts > 0
1321
+ && typeof setTimeout !== 'undefined'
1322
+ // A late overlay teardown can return focus to document.body after the
1323
+ // first restore. Keep checking only while focus remains unowned (or
1324
+ // on the restored target); never steal a user-initiated new focus.
1325
+ && (focusWasLostToDocument || targetAlreadyFocused)) {
1326
+ setTimeout(() => restore(remainingAttempts - 1), 50);
1327
+ }
1328
+ };
1329
+ // The host can recreate a responsive control only after its close and
1330
+ // change-detection queue settles. Three seconds is the bounded recovery
1331
+ // window; the loop stops immediately if the user focuses elsewhere.
1332
+ queueMicrotask(() => restore(60));
1333
+ });
1334
+ }
1217
1335
  function providePraxisSurfaceGlobalActions() {
1218
1336
  return {
1219
1337
  provide: GLOBAL_SURFACE_SERVICE,
1220
1338
  useFactory: () => {
1221
1339
  const dialog = inject(PraxisDialog);
1222
1340
  const materializer = inject(SurfaceOpenMaterializerService);
1341
+ const logger = inject(LoggerService, { optional: true });
1223
1342
  const surfaceDrawer = inject(SURFACE_DRAWER_BRIDGE, {
1224
1343
  optional: true,
1225
1344
  });
1226
1345
  return {
1227
1346
  open: async (payload, context) => {
1228
1347
  const materializedPayload = await materializer.materialize(payload, context);
1348
+ const focusOrigin = resolveRuntimeFocusOrigin(context);
1229
1349
  if (materializedPayload.presentation === 'drawer') {
1230
1350
  if (!surfaceDrawer) {
1231
1351
  throw new Error('Drawer surface service not available');
1232
1352
  }
1233
- const ref = surfaceDrawer.open({
1353
+ const frame = {
1234
1354
  id: `surface:${materializedPayload.widget.id}`,
1235
1355
  title: materializedPayload.title || materializedPayload.widget.id,
1236
1356
  titleIcon: materializedPayload.icon,
1237
1357
  subtitle: materializedPayload.subtitle,
1238
- width: materializedPayload.size?.width,
1239
- minWidth: materializedPayload.size?.minWidth,
1240
- maxWidth: materializedPayload.size?.maxWidth,
1241
- height: materializedPayload.size?.height,
1242
- minHeight: materializedPayload.size?.minHeight,
1243
- maxHeight: materializedPayload.size?.maxHeight,
1358
+ ...(focusOrigin ? { returnFocusTo: focusOrigin } : {}),
1244
1359
  content: {
1245
1360
  component: PraxisSurfaceHostComponent,
1246
1361
  inputs: buildHostInputs(materializedPayload, context, {
1247
1362
  includeSubtitle: false,
1248
1363
  }),
1249
1364
  },
1365
+ };
1366
+ const parentRuntime = resolveParentSurfaceRuntime(context);
1367
+ if (typeof parentRuntime?.['push'] === 'function') {
1368
+ const frameRef = await parentRuntime['push'](frame);
1369
+ if (!frameRef) {
1370
+ const error = new SurfaceNavigationError('SURFACE_SESSION_NAVIGATION_REJECTED', 'push', frame.id);
1371
+ logger?.warn('Surface session rejected nested navigation frame.', {
1372
+ context: {
1373
+ lib: '@praxisui/dialog',
1374
+ component: 'SurfaceGlobalActionsProvider',
1375
+ actionId: 'surface.open',
1376
+ correlationId: typeof context?.meta?.['correlationId'] === 'string'
1377
+ ? context.meta['correlationId']
1378
+ : undefined,
1379
+ },
1380
+ data: {
1381
+ code: error.code,
1382
+ operation: error.operation,
1383
+ frameId: error.frameId,
1384
+ widgetId: materializedPayload.widget.id,
1385
+ },
1386
+ throttleKey: `${error.code}:dialog:${frame.id}`,
1387
+ });
1388
+ throw error;
1389
+ }
1390
+ return frameRef;
1391
+ }
1392
+ const ref = surfaceDrawer.open({
1393
+ ...frame,
1394
+ width: materializedPayload.size?.width,
1395
+ minWidth: materializedPayload.size?.minWidth,
1396
+ maxWidth: materializedPayload.size?.maxWidth,
1397
+ height: materializedPayload.size?.height,
1398
+ minHeight: materializedPayload.size?.minHeight,
1399
+ maxHeight: materializedPayload.size?.maxHeight,
1250
1400
  });
1401
+ restoreRuntimeFocusOnClose(ref.closed$, focusOrigin);
1251
1402
  return ref;
1252
1403
  }
1253
1404
  const ref = dialog.open(PraxisSurfaceHostComponent, buildDialogConfig(materializedPayload));
1405
+ restoreRuntimeFocusOnClose(ref.afterClosed(), focusOrigin);
1254
1406
  const resultSubject = new Subject();
1255
1407
  let terminalOutcomeEmitted = false;
1256
1408
  const complete = (outcome) => {
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@praxisui/dialog",
3
- "version": "9.0.4-rc.8",
3
+ "version": "9.0.4",
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.4-rc.8",
10
+ "@praxisui/core": "^9.0.4",
11
11
  "@angular/material": "^21.0.0",
12
12
  "@angular/platform-browser": "^21.0.0",
13
13
  "rxjs": "~7.8.0"
@@ -135,6 +135,7 @@ declare const PRAXIS_DIALOG_I18N: InjectionToken<Readonly<{
135
135
  cancel: string;
136
136
  yes: string;
137
137
  no: string;
138
+ close?: string;
138
139
  }>>;
139
140
  declare const PRAXIS_DIALOG_DEFAULTS: InjectionToken<Readonly<{
140
141
  maxWidth: string | number;
@@ -248,7 +249,11 @@ declare class PraxisDialogComponent implements OnInit, OnChanges, OnDestroy {
248
249
  hostClass: string;
249
250
  tabindex: string;
250
251
  readonly data: unknown;
252
+ private readonly i18n;
251
253
  get titleId(): string;
254
+ get displaysCloseButton(): boolean;
255
+ get closeButtonLabel(): string;
256
+ requestClose(): void;
252
257
  isDisplayed: boolean;
253
258
  ngOnInit(): void;
254
259
  ngOnChanges(changes: SimpleChanges): void;