@ng-nest/ui 20.2.0 → 20.2.1

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.
@@ -1,8 +1,8 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, input, model, output, Component, inject, ViewContainerRef, viewChild, signal, computed, DestroyRef, effect, HostBinding, ChangeDetectionStrategy, ViewEncapsulation, HostListener, Directive, Renderer2, ChangeDetectorRef, contentChildren, EventEmitter, NgModule, RendererFactory2, TemplateRef, Injectable } from '@angular/core';
3
- import { XPropertyFunction, XToCssPixelValue, XToBoolean, XToNumber, XProperty, XConfigService, XIsFunction, XMoveBoxAnimation, XOpacityAnimation, XFillDefault } from '@ng-nest/ui/core';
2
+ import { InjectionToken, input, model, output, Component, inject, ViewContainerRef, DOCUMENT, viewChild, signal, computed, DestroyRef, effect, HostBinding, ChangeDetectionStrategy, ViewEncapsulation, HostListener, Directive, Renderer2, ChangeDetectorRef, contentChildren, EventEmitter, NgModule, RendererFactory2, TemplateRef, Injectable } from '@angular/core';
3
+ import { XPropertyFunction, XToCssPixelValue, XToBoolean, XToNumber, XProperty, XConfigService, XIsFunction, XFillDefault } from '@ng-nest/ui/core';
4
4
  import { XPortalService, XPortalResizablePrefix } from '@ng-nest/ui/portal';
5
- import { Subject, filter, take } from 'rxjs';
5
+ import { Subject, fromEvent, filter, take, takeUntil as takeUntil$1 } from 'rxjs';
6
6
  import { Overlay } from '@angular/cdk/overlay';
7
7
  import { XI18nService, zh_CN } from '@ng-nest/ui/i18n';
8
8
  import { map, takeUntil } from 'rxjs/operators';
@@ -146,6 +146,11 @@ class XDialogProperty extends XPropertyFunction(X_DIALOG_CONFIG_NAME) {
146
146
  * @en_US Whether to display the background mask
147
147
  */
148
148
  this.hasBackdrop = input(this.config?.hasBackdrop ?? true, ...(ngDevMode ? [{ debugName: "hasBackdrop", transform: XToBoolean }] : [{ transform: XToBoolean }]));
149
+ /**
150
+ * @zh_CN 是否支持键盘 esc 关闭
151
+ * @en_US Whether to support keyboard esc to close
152
+ */
153
+ this.keyboard = input(this.config?.keyboard ?? true, ...(ngDevMode ? [{ debugName: "keyboard", transform: XToBoolean }] : [{ transform: XToBoolean }]));
149
154
  /**
150
155
  * @zh_CN 自定义样式名
151
156
  * @en_US Custom style name
@@ -198,12 +203,12 @@ class XDialogProperty extends XPropertyFunction(X_DIALOG_CONFIG_NAME) {
198
203
  this.closeDone = output();
199
204
  }
200
205
  /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.5", ngImport: i0, type: XDialogProperty, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
201
- /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.5", type: XDialogProperty, isStandalone: true, selector: "x-dialog-property", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null }, offset: { classPropertyName: "offset", publicName: "offset", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, hideClose: { classPropertyName: "hideClose", publicName: "hideClose", isSignal: true, isRequired: false, transformFunction: null }, closeText: { classPropertyName: "closeText", publicName: "closeText", isSignal: true, isRequired: false, transformFunction: null }, resizable: { classPropertyName: "resizable", publicName: "resizable", isSignal: true, isRequired: false, transformFunction: null }, offsetLeft: { classPropertyName: "offsetLeft", publicName: "offsetLeft", isSignal: true, isRequired: false, transformFunction: null }, offsetTop: { classPropertyName: "offsetTop", publicName: "offsetTop", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, minWidth: { classPropertyName: "minWidth", publicName: "minWidth", isSignal: true, isRequired: false, transformFunction: null }, minHeight: { classPropertyName: "minHeight", publicName: "minHeight", isSignal: true, isRequired: false, transformFunction: null }, effect: { classPropertyName: "effect", publicName: "effect", isSignal: true, isRequired: false, transformFunction: null }, footer: { classPropertyName: "footer", publicName: "footer", isSignal: true, isRequired: false, transformFunction: null }, showCancel: { classPropertyName: "showCancel", publicName: "showCancel", isSignal: true, isRequired: false, transformFunction: null }, cancelText: { classPropertyName: "cancelText", publicName: "cancelText", isSignal: true, isRequired: false, transformFunction: null }, showConfirm: { classPropertyName: "showConfirm", publicName: "showConfirm", isSignal: true, isRequired: false, transformFunction: null }, confirmText: { classPropertyName: "confirmText", publicName: "confirmText", isSignal: true, isRequired: false, transformFunction: null }, backdropClose: { classPropertyName: "backdropClose", publicName: "backdropClose", isSignal: true, isRequired: false, transformFunction: null }, hasBackdrop: { classPropertyName: "hasBackdrop", publicName: "hasBackdrop", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, buttonsCenter: { classPropertyName: "buttonsCenter", publicName: "buttonsCenter", isSignal: true, isRequired: false, transformFunction: null }, draggable: { classPropertyName: "draggable", publicName: "draggable", isSignal: true, isRequired: false, transformFunction: null }, maximize: { classPropertyName: "maximize", publicName: "maximize", isSignal: true, isRequired: false, transformFunction: null }, beforeClose: { classPropertyName: "beforeClose", publicName: "beforeClose", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { visible: "visibleChange", cancel: "cancel", confirm: "confirm", close: "close", showDone: "showDone", closeDone: "closeDone" }, usesInheritance: true, ngImport: i0, template: '', isInline: true }); }
206
+ /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.5", type: XDialogProperty, isStandalone: true, selector: "x-dialog-property", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null }, offset: { classPropertyName: "offset", publicName: "offset", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, hideClose: { classPropertyName: "hideClose", publicName: "hideClose", isSignal: true, isRequired: false, transformFunction: null }, closeText: { classPropertyName: "closeText", publicName: "closeText", isSignal: true, isRequired: false, transformFunction: null }, resizable: { classPropertyName: "resizable", publicName: "resizable", isSignal: true, isRequired: false, transformFunction: null }, offsetLeft: { classPropertyName: "offsetLeft", publicName: "offsetLeft", isSignal: true, isRequired: false, transformFunction: null }, offsetTop: { classPropertyName: "offsetTop", publicName: "offsetTop", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, minWidth: { classPropertyName: "minWidth", publicName: "minWidth", isSignal: true, isRequired: false, transformFunction: null }, minHeight: { classPropertyName: "minHeight", publicName: "minHeight", isSignal: true, isRequired: false, transformFunction: null }, effect: { classPropertyName: "effect", publicName: "effect", isSignal: true, isRequired: false, transformFunction: null }, footer: { classPropertyName: "footer", publicName: "footer", isSignal: true, isRequired: false, transformFunction: null }, showCancel: { classPropertyName: "showCancel", publicName: "showCancel", isSignal: true, isRequired: false, transformFunction: null }, cancelText: { classPropertyName: "cancelText", publicName: "cancelText", isSignal: true, isRequired: false, transformFunction: null }, showConfirm: { classPropertyName: "showConfirm", publicName: "showConfirm", isSignal: true, isRequired: false, transformFunction: null }, confirmText: { classPropertyName: "confirmText", publicName: "confirmText", isSignal: true, isRequired: false, transformFunction: null }, backdropClose: { classPropertyName: "backdropClose", publicName: "backdropClose", isSignal: true, isRequired: false, transformFunction: null }, hasBackdrop: { classPropertyName: "hasBackdrop", publicName: "hasBackdrop", isSignal: true, isRequired: false, transformFunction: null }, keyboard: { classPropertyName: "keyboard", publicName: "keyboard", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, buttonsCenter: { classPropertyName: "buttonsCenter", publicName: "buttonsCenter", isSignal: true, isRequired: false, transformFunction: null }, draggable: { classPropertyName: "draggable", publicName: "draggable", isSignal: true, isRequired: false, transformFunction: null }, maximize: { classPropertyName: "maximize", publicName: "maximize", isSignal: true, isRequired: false, transformFunction: null }, beforeClose: { classPropertyName: "beforeClose", publicName: "beforeClose", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { visible: "visibleChange", cancel: "cancel", confirm: "confirm", close: "close", showDone: "showDone", closeDone: "closeDone" }, usesInheritance: true, ngImport: i0, template: '', isInline: true }); }
202
207
  }
203
208
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.5", ngImport: i0, type: XDialogProperty, decorators: [{
204
209
  type: Component,
205
210
  args: [{ selector: `${XDialogPrefix}-property`, template: '' }]
206
- }], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], visible: [{ type: i0.Input, args: [{ isSignal: true, alias: "visible", required: false }] }, { type: i0.Output, args: ["visibleChange"] }], placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "placement", required: false }] }], offset: [{ type: i0.Input, args: [{ isSignal: true, alias: "offset", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], hideClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideClose", required: false }] }], closeText: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeText", required: false }] }], resizable: [{ type: i0.Input, args: [{ isSignal: true, alias: "resizable", required: false }] }], offsetLeft: [{ type: i0.Input, args: [{ isSignal: true, alias: "offsetLeft", required: false }] }], offsetTop: [{ type: i0.Input, args: [{ isSignal: true, alias: "offsetTop", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }], minWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "minWidth", required: false }] }], minHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "minHeight", required: false }] }], effect: [{ type: i0.Input, args: [{ isSignal: true, alias: "effect", required: false }] }], footer: [{ type: i0.Input, args: [{ isSignal: true, alias: "footer", required: false }] }], showCancel: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCancel", required: false }] }], cancelText: [{ type: i0.Input, args: [{ isSignal: true, alias: "cancelText", required: false }] }], showConfirm: [{ type: i0.Input, args: [{ isSignal: true, alias: "showConfirm", required: false }] }], confirmText: [{ type: i0.Input, args: [{ isSignal: true, alias: "confirmText", required: false }] }], backdropClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "backdropClose", required: false }] }], hasBackdrop: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasBackdrop", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], buttonsCenter: [{ type: i0.Input, args: [{ isSignal: true, alias: "buttonsCenter", required: false }] }], draggable: [{ type: i0.Input, args: [{ isSignal: true, alias: "draggable", required: false }] }], maximize: [{ type: i0.Input, args: [{ isSignal: true, alias: "maximize", required: false }] }], beforeClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "beforeClose", required: false }] }], cancel: [{ type: i0.Output, args: ["cancel"] }], confirm: [{ type: i0.Output, args: ["confirm"] }], close: [{ type: i0.Output, args: ["close"] }], showDone: [{ type: i0.Output, args: ["showDone"] }], closeDone: [{ type: i0.Output, args: ["closeDone"] }] } });
211
+ }], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], visible: [{ type: i0.Input, args: [{ isSignal: true, alias: "visible", required: false }] }, { type: i0.Output, args: ["visibleChange"] }], placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "placement", required: false }] }], offset: [{ type: i0.Input, args: [{ isSignal: true, alias: "offset", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], hideClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideClose", required: false }] }], closeText: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeText", required: false }] }], resizable: [{ type: i0.Input, args: [{ isSignal: true, alias: "resizable", required: false }] }], offsetLeft: [{ type: i0.Input, args: [{ isSignal: true, alias: "offsetLeft", required: false }] }], offsetTop: [{ type: i0.Input, args: [{ isSignal: true, alias: "offsetTop", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }], minWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "minWidth", required: false }] }], minHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "minHeight", required: false }] }], effect: [{ type: i0.Input, args: [{ isSignal: true, alias: "effect", required: false }] }], footer: [{ type: i0.Input, args: [{ isSignal: true, alias: "footer", required: false }] }], showCancel: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCancel", required: false }] }], cancelText: [{ type: i0.Input, args: [{ isSignal: true, alias: "cancelText", required: false }] }], showConfirm: [{ type: i0.Input, args: [{ isSignal: true, alias: "showConfirm", required: false }] }], confirmText: [{ type: i0.Input, args: [{ isSignal: true, alias: "confirmText", required: false }] }], backdropClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "backdropClose", required: false }] }], hasBackdrop: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasBackdrop", required: false }] }], keyboard: [{ type: i0.Input, args: [{ isSignal: true, alias: "keyboard", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], buttonsCenter: [{ type: i0.Input, args: [{ isSignal: true, alias: "buttonsCenter", required: false }] }], draggable: [{ type: i0.Input, args: [{ isSignal: true, alias: "draggable", required: false }] }], maximize: [{ type: i0.Input, args: [{ isSignal: true, alias: "maximize", required: false }] }], beforeClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "beforeClose", required: false }] }], cancel: [{ type: i0.Output, args: ["cancel"] }], confirm: [{ type: i0.Output, args: ["confirm"] }], close: [{ type: i0.Output, args: ["close"] }], showDone: [{ type: i0.Output, args: ["showDone"] }], closeDone: [{ type: i0.Output, args: ["closeDone"] }] } });
207
212
  /**
208
213
  * Dialog Container
209
214
  * @selector x-dialog-container
@@ -224,6 +229,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.5", ngImpor
224
229
  }] });
225
230
 
226
231
  class XDialogComponent extends XDialogProperty {
232
+ static { this.dialogOverlayRefs = []; }
227
233
  get getVisible() {
228
234
  return this.visible();
229
235
  }
@@ -234,6 +240,7 @@ class XDialogComponent extends XDialogProperty {
234
240
  this.overlay = inject(Overlay);
235
241
  this.i18n = inject(XI18nService);
236
242
  this.unSubject = new Subject();
243
+ this.document = inject(DOCUMENT);
237
244
  this.clsName = `${XDialogPrefix}-${this.placement()}`;
238
245
  this.dialogTpl = viewChild.required('dialogTpl');
239
246
  this.locale = toSignal(this.i18n.localeChange.pipe(map((x) => x.dialog)), { initialValue: zh_CN.dialog });
@@ -289,6 +296,7 @@ class XDialogComponent extends XDialogProperty {
289
296
  this.destroyRef.onDestroy(() => {
290
297
  this.destroy.set(true);
291
298
  this.backdropClick$?.unsubscribe();
299
+ this.keyboard$?.unsubscribe();
292
300
  this.unSubject.next();
293
301
  this.unSubject.complete();
294
302
  });
@@ -334,8 +342,22 @@ class XDialogComponent extends XDialogProperty {
334
342
  minWidth: this.minWidth(),
335
343
  minHeight: this.minHeight()
336
344
  });
345
+ XDialogComponent.dialogOverlayRefs.push(this.dialogRef);
337
346
  if (this.hasBackdrop() && this.backdropClose() && this.dialogRef?.overlayRef) {
338
- this.backdropClick$ = this.dialogRef.overlayRef.backdropClick().subscribe(() => this.onClose('close'));
347
+ this.backdropClick$ = this.dialogRef.overlayRef.backdropClick().subscribe(() => {
348
+ this.onClose('close');
349
+ this.keyboard$?.unsubscribe();
350
+ });
351
+ }
352
+ if (this.keyboard()) {
353
+ this.keyboard$ = fromEvent(this.document, 'keydown').subscribe((event) => {
354
+ if (event.key === 'Escape' || event.keyCode === 27) {
355
+ if (XDialogComponent.dialogOverlayRefs[XDialogComponent.dialogOverlayRefs.length - 1] === this.dialogRef) {
356
+ this.onClose('close');
357
+ this.keyboard$?.unsubscribe();
358
+ }
359
+ }
360
+ });
339
361
  }
340
362
  }
341
363
  setWidthHeight() {
@@ -434,11 +456,11 @@ class XDialogComponent extends XDialogProperty {
434
456
  }
435
457
  }
436
458
  /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.5", ngImport: i0, type: XDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
437
- /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.5", type: XDialogComponent, isStandalone: true, selector: "x-dialog", host: { properties: { "class.x-dialog-visible": "this.getVisible", "class": "this.clsName" } }, viewQueries: [{ propertyName: "dialogTpl", first: true, predicate: ["dialogTpl"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<ng-template #dialogTpl>\r\n @if (visible()) {\r\n @if (container && hasBackdrop()) {\r\n <div\r\n class=\"x-dialog-backdrop\"\r\n animate.enter=\"x-opacity-enter\"\r\n animate.leave=\"x-opacity-leave\"\r\n (click)=\"onClose('close')\"\r\n ></div>\r\n }\r\n <div\r\n class=\"x-dialog\"\r\n [animate.enter]=\"`x-move-${placement()}-enter`\"\r\n [animate.leave]=\"`x-move-${placement()}-leave`\"\r\n (animationend)=\"moveDone($event)\"\r\n [class.x-dialog-maximize]=\"isMaximize()\"\r\n [class.x-dialog-default-maximize]=\"isDefaultMaximize()\"\r\n [ngStyle]=\"getStyle()\"\r\n >\r\n <x-alert\r\n [draggable]=\"draggableSignal() && dialogBox['draggable']\"\r\n [dragFreeDragPosition]=\"dialogBox['distance']\"\r\n [minWidth]=\"dialogBox['minWidth']\"\r\n [minHeight]=\"dialogBox['minHeight']\"\r\n [dragBoundary]=\"'.cdk-overlay-container'\"\r\n [title]=\"title()\"\r\n [content]=\"contentTpl\"\r\n [type]=\"type()\"\r\n [effect]=\"effect()\"\r\n [hideClose]=\"hideClose()\"\r\n [closeText]=\"closeText()\"\r\n [operationTpl]=\"operationTpl\"\r\n (close)=\"onClose('close')\"\r\n (dragEnded)=\"onDragEnded($event)\"\r\n [showIcon]=\"false\"\r\n [duration]=\"0\"\r\n manual\r\n disabledAnimation\r\n ></x-alert>\r\n </div>\r\n }\r\n</ng-template>\r\n\r\n<ng-template #contentTpl>\r\n <div class=\"x-dialog-inner\">\r\n <div class=\"x-dialog-content\">\r\n <ng-content></ng-content>\r\n </div>\r\n <div class=\"x-dialog-buttons\" [class.x-dialog-buttons-center]=\"buttonsCenter()\">\r\n <ng-container *xOutlet=\"footer()\">\r\n @if (showCancel() || showConfirm()) {\r\n <x-buttons space=\"0.5rem\">\r\n @if (showCancel()) {\r\n <x-button class=\"x-dialog-cancel\" (click)=\"onClose('cancel')\" flat plain>{{ getCancelText() }}</x-button>\r\n }\r\n @if (showConfirm()) {\r\n <x-button class=\"x-dialog-confirm\" type=\"primary\" flat (click)=\"onClose('confirm')\">{{\r\n getConfirmText()\r\n }}</x-button>\r\n }\r\n </x-buttons>\r\n }\r\n </ng-container>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #operationTpl>\r\n @if (maximizeSignal()) {\r\n <x-button\r\n size=\"small\"\r\n flat\r\n [icon]=\"isMaximize() ? 'fto-minimize' : 'fto-maximize'\"\r\n [onlyIcon]=\"true\"\r\n (click)=\"onSize()\"\r\n class=\"x-dialog-maximize\"\r\n ></x-button>\r\n }\r\n</ng-template>\r\n\r\n@if (container) {\r\n <ng-container *ngTemplateOutlet=\"dialogTpl\"></ng-container>\r\n}\r\n", styles: [".x-dialog{margin:0;padding:0}.x-dialog{width:100%;height:100%}.x-dialog>x-alert{height:100%}.x-dialog>x-alert .x-alert{min-height:100%;height:fit-content;align-items:inherit;padding:0}.x-dialog>x-alert .x-alert-inner{min-height:100%;display:flex;flex-direction:column}.x-dialog>x-alert .x-alert-title{padding:1rem 1rem 0}.x-dialog>x-alert .x-alert-content{flex:1;display:flex;flex-direction:column;padding:0 1rem .5rem}.x-dialog-inner{display:flex;flex-direction:column;margin:.5rem 0;flex:1}.x-dialog-buttons{display:flex;justify-content:flex-end}.x-dialog-buttons>x-buttons{margin-top:1rem;align-self:flex-end}.x-dialog-buttons-center{justify-content:center}.x-dialog-content{display:inline-flex;flex-direction:column;flex:1;max-height:70vh;overflow:auto;min-height:2rem}.x-dialog-maximize>x-alert .x-alert{left:0!important;top:0!important;border-radius:0!important}.x-dialog-maximize .x-dialog-content{max-height:calc(100vh - 7.875rem)!important;height:calc(100vh - 7.875rem)!important}.x-dialog-default-maximize .x-dialog-content{max-height:calc(100vh - 7.875rem)!important;height:calc(100vh - 7.875rem)!important;flex:initial}.x-dialog-default-maximize>x-alert .x-alert{left:0!important;top:0!important;border-radius:0!important}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: XAlertComponent, selector: "x-alert" }, { kind: "component", type: XButtonComponent, selector: "x-button" }, { kind: "component", type: XButtonsComponent, selector: "x-buttons" }, { kind: "directive", type: XOutletDirective, selector: "[xOutlet]", inputs: ["xOutletContext", "xOutlet"] }], animations: [XMoveBoxAnimation, XOpacityAnimation], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
459
+ /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.5", type: XDialogComponent, isStandalone: true, selector: "x-dialog", host: { properties: { "class.x-dialog-visible": "this.getVisible", "class": "this.clsName" } }, viewQueries: [{ propertyName: "dialogTpl", first: true, predicate: ["dialogTpl"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<ng-template #dialogTpl>\r\n @if (visible()) {\r\n @if (container && hasBackdrop()) {\r\n <div\r\n class=\"x-dialog-backdrop\"\r\n animate.enter=\"x-opacity-enter\"\r\n animate.leave=\"x-opacity-leave\"\r\n (click)=\"onClose('close')\"\r\n ></div>\r\n }\r\n <div\r\n class=\"x-dialog\"\r\n [animate.enter]=\"`x-move-${placement()}-enter`\"\r\n [animate.leave]=\"`x-move-${placement()}-leave`\"\r\n (animationend)=\"moveDone($event)\"\r\n [class.x-dialog-maximize]=\"isMaximize()\"\r\n [class.x-dialog-default-maximize]=\"isDefaultMaximize()\"\r\n [ngStyle]=\"getStyle()\"\r\n >\r\n <x-alert\r\n [draggable]=\"draggableSignal() && dialogBox['draggable']\"\r\n [dragFreeDragPosition]=\"dialogBox['distance']\"\r\n [minWidth]=\"dialogBox['minWidth']\"\r\n [minHeight]=\"dialogBox['minHeight']\"\r\n [dragBoundary]=\"'.cdk-overlay-container'\"\r\n [title]=\"title()\"\r\n [content]=\"contentTpl\"\r\n [type]=\"type()\"\r\n [effect]=\"effect()\"\r\n [hideClose]=\"hideClose()\"\r\n [closeText]=\"closeText()\"\r\n [operationTpl]=\"operationTpl\"\r\n (close)=\"onClose('close')\"\r\n (dragEnded)=\"onDragEnded($event)\"\r\n [showIcon]=\"false\"\r\n [duration]=\"0\"\r\n manual\r\n disabledAnimation\r\n ></x-alert>\r\n </div>\r\n }\r\n</ng-template>\r\n\r\n<ng-template #contentTpl>\r\n <div class=\"x-dialog-inner\">\r\n <div class=\"x-dialog-content\">\r\n <ng-content></ng-content>\r\n </div>\r\n <div class=\"x-dialog-buttons\" [class.x-dialog-buttons-center]=\"buttonsCenter()\">\r\n <ng-container *xOutlet=\"footer()\">\r\n @if (showCancel() || showConfirm()) {\r\n <x-buttons space=\"0.5rem\">\r\n @if (showCancel()) {\r\n <x-button class=\"x-dialog-cancel\" (click)=\"onClose('cancel')\" flat plain>{{ getCancelText() }}</x-button>\r\n }\r\n @if (showConfirm()) {\r\n <x-button class=\"x-dialog-confirm\" type=\"primary\" flat (click)=\"onClose('confirm')\">{{\r\n getConfirmText()\r\n }}</x-button>\r\n }\r\n </x-buttons>\r\n }\r\n </ng-container>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #operationTpl>\r\n @if (maximizeSignal()) {\r\n <x-button\r\n size=\"small\"\r\n flat\r\n [icon]=\"isMaximize() ? 'fto-minimize' : 'fto-maximize'\"\r\n [onlyIcon]=\"true\"\r\n (click)=\"onSize()\"\r\n class=\"x-dialog-maximize\"\r\n ></x-button>\r\n }\r\n</ng-template>\r\n\r\n@if (container) {\r\n <ng-container *ngTemplateOutlet=\"dialogTpl\"></ng-container>\r\n}\r\n", styles: [".x-dialog{margin:0;padding:0}.x-dialog{width:100%;height:100%}.x-dialog>x-alert{height:100%}.x-dialog>x-alert .x-alert{min-height:100%;height:fit-content;align-items:inherit;padding:0}.x-dialog>x-alert .x-alert-inner{min-height:100%;display:flex;flex-direction:column}.x-dialog>x-alert .x-alert-title{padding:1rem 1rem 0}.x-dialog>x-alert .x-alert-content{flex:1;display:flex;flex-direction:column;padding:0 1rem .5rem}.x-dialog-inner{display:flex;flex-direction:column;margin:.5rem 0;flex:1}.x-dialog-buttons{display:flex;justify-content:flex-end}.x-dialog-buttons>x-buttons{margin-top:1rem;align-self:flex-end}.x-dialog-buttons-center{justify-content:center}.x-dialog-content{display:inline-flex;flex-direction:column;flex:1;max-height:70vh;overflow:auto;min-height:2rem}.x-dialog-maximize>x-alert .x-alert{left:0!important;top:0!important;border-radius:0!important}.x-dialog-maximize .x-dialog-content{max-height:calc(100vh - 7.875rem)!important;height:calc(100vh - 7.875rem)!important}.x-dialog-default-maximize .x-dialog-content{max-height:calc(100vh - 7.875rem)!important;height:calc(100vh - 7.875rem)!important;flex:initial}.x-dialog-default-maximize>x-alert .x-alert{left:0!important;top:0!important;border-radius:0!important}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: XAlertComponent, selector: "x-alert" }, { kind: "component", type: XButtonComponent, selector: "x-button" }, { kind: "component", type: XButtonsComponent, selector: "x-buttons" }, { kind: "directive", type: XOutletDirective, selector: "[xOutlet]", inputs: ["xOutletContext", "xOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
438
460
  }
439
461
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.5", ngImport: i0, type: XDialogComponent, decorators: [{
440
462
  type: Component,
441
- args: [{ selector: `${XDialogPrefix}`, imports: [NgStyle, NgTemplateOutlet, XAlertComponent, XButtonComponent, XButtonsComponent, XOutletDirective], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, animations: [XMoveBoxAnimation, XOpacityAnimation], template: "<ng-template #dialogTpl>\r\n @if (visible()) {\r\n @if (container && hasBackdrop()) {\r\n <div\r\n class=\"x-dialog-backdrop\"\r\n animate.enter=\"x-opacity-enter\"\r\n animate.leave=\"x-opacity-leave\"\r\n (click)=\"onClose('close')\"\r\n ></div>\r\n }\r\n <div\r\n class=\"x-dialog\"\r\n [animate.enter]=\"`x-move-${placement()}-enter`\"\r\n [animate.leave]=\"`x-move-${placement()}-leave`\"\r\n (animationend)=\"moveDone($event)\"\r\n [class.x-dialog-maximize]=\"isMaximize()\"\r\n [class.x-dialog-default-maximize]=\"isDefaultMaximize()\"\r\n [ngStyle]=\"getStyle()\"\r\n >\r\n <x-alert\r\n [draggable]=\"draggableSignal() && dialogBox['draggable']\"\r\n [dragFreeDragPosition]=\"dialogBox['distance']\"\r\n [minWidth]=\"dialogBox['minWidth']\"\r\n [minHeight]=\"dialogBox['minHeight']\"\r\n [dragBoundary]=\"'.cdk-overlay-container'\"\r\n [title]=\"title()\"\r\n [content]=\"contentTpl\"\r\n [type]=\"type()\"\r\n [effect]=\"effect()\"\r\n [hideClose]=\"hideClose()\"\r\n [closeText]=\"closeText()\"\r\n [operationTpl]=\"operationTpl\"\r\n (close)=\"onClose('close')\"\r\n (dragEnded)=\"onDragEnded($event)\"\r\n [showIcon]=\"false\"\r\n [duration]=\"0\"\r\n manual\r\n disabledAnimation\r\n ></x-alert>\r\n </div>\r\n }\r\n</ng-template>\r\n\r\n<ng-template #contentTpl>\r\n <div class=\"x-dialog-inner\">\r\n <div class=\"x-dialog-content\">\r\n <ng-content></ng-content>\r\n </div>\r\n <div class=\"x-dialog-buttons\" [class.x-dialog-buttons-center]=\"buttonsCenter()\">\r\n <ng-container *xOutlet=\"footer()\">\r\n @if (showCancel() || showConfirm()) {\r\n <x-buttons space=\"0.5rem\">\r\n @if (showCancel()) {\r\n <x-button class=\"x-dialog-cancel\" (click)=\"onClose('cancel')\" flat plain>{{ getCancelText() }}</x-button>\r\n }\r\n @if (showConfirm()) {\r\n <x-button class=\"x-dialog-confirm\" type=\"primary\" flat (click)=\"onClose('confirm')\">{{\r\n getConfirmText()\r\n }}</x-button>\r\n }\r\n </x-buttons>\r\n }\r\n </ng-container>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #operationTpl>\r\n @if (maximizeSignal()) {\r\n <x-button\r\n size=\"small\"\r\n flat\r\n [icon]=\"isMaximize() ? 'fto-minimize' : 'fto-maximize'\"\r\n [onlyIcon]=\"true\"\r\n (click)=\"onSize()\"\r\n class=\"x-dialog-maximize\"\r\n ></x-button>\r\n }\r\n</ng-template>\r\n\r\n@if (container) {\r\n <ng-container *ngTemplateOutlet=\"dialogTpl\"></ng-container>\r\n}\r\n", styles: [".x-dialog{margin:0;padding:0}.x-dialog{width:100%;height:100%}.x-dialog>x-alert{height:100%}.x-dialog>x-alert .x-alert{min-height:100%;height:fit-content;align-items:inherit;padding:0}.x-dialog>x-alert .x-alert-inner{min-height:100%;display:flex;flex-direction:column}.x-dialog>x-alert .x-alert-title{padding:1rem 1rem 0}.x-dialog>x-alert .x-alert-content{flex:1;display:flex;flex-direction:column;padding:0 1rem .5rem}.x-dialog-inner{display:flex;flex-direction:column;margin:.5rem 0;flex:1}.x-dialog-buttons{display:flex;justify-content:flex-end}.x-dialog-buttons>x-buttons{margin-top:1rem;align-self:flex-end}.x-dialog-buttons-center{justify-content:center}.x-dialog-content{display:inline-flex;flex-direction:column;flex:1;max-height:70vh;overflow:auto;min-height:2rem}.x-dialog-maximize>x-alert .x-alert{left:0!important;top:0!important;border-radius:0!important}.x-dialog-maximize .x-dialog-content{max-height:calc(100vh - 7.875rem)!important;height:calc(100vh - 7.875rem)!important}.x-dialog-default-maximize .x-dialog-content{max-height:calc(100vh - 7.875rem)!important;height:calc(100vh - 7.875rem)!important;flex:initial}.x-dialog-default-maximize>x-alert .x-alert{left:0!important;top:0!important;border-radius:0!important}\n"] }]
463
+ args: [{ selector: `${XDialogPrefix}`, imports: [NgStyle, NgTemplateOutlet, XAlertComponent, XButtonComponent, XButtonsComponent, XOutletDirective], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-template #dialogTpl>\r\n @if (visible()) {\r\n @if (container && hasBackdrop()) {\r\n <div\r\n class=\"x-dialog-backdrop\"\r\n animate.enter=\"x-opacity-enter\"\r\n animate.leave=\"x-opacity-leave\"\r\n (click)=\"onClose('close')\"\r\n ></div>\r\n }\r\n <div\r\n class=\"x-dialog\"\r\n [animate.enter]=\"`x-move-${placement()}-enter`\"\r\n [animate.leave]=\"`x-move-${placement()}-leave`\"\r\n (animationend)=\"moveDone($event)\"\r\n [class.x-dialog-maximize]=\"isMaximize()\"\r\n [class.x-dialog-default-maximize]=\"isDefaultMaximize()\"\r\n [ngStyle]=\"getStyle()\"\r\n >\r\n <x-alert\r\n [draggable]=\"draggableSignal() && dialogBox['draggable']\"\r\n [dragFreeDragPosition]=\"dialogBox['distance']\"\r\n [minWidth]=\"dialogBox['minWidth']\"\r\n [minHeight]=\"dialogBox['minHeight']\"\r\n [dragBoundary]=\"'.cdk-overlay-container'\"\r\n [title]=\"title()\"\r\n [content]=\"contentTpl\"\r\n [type]=\"type()\"\r\n [effect]=\"effect()\"\r\n [hideClose]=\"hideClose()\"\r\n [closeText]=\"closeText()\"\r\n [operationTpl]=\"operationTpl\"\r\n (close)=\"onClose('close')\"\r\n (dragEnded)=\"onDragEnded($event)\"\r\n [showIcon]=\"false\"\r\n [duration]=\"0\"\r\n manual\r\n disabledAnimation\r\n ></x-alert>\r\n </div>\r\n }\r\n</ng-template>\r\n\r\n<ng-template #contentTpl>\r\n <div class=\"x-dialog-inner\">\r\n <div class=\"x-dialog-content\">\r\n <ng-content></ng-content>\r\n </div>\r\n <div class=\"x-dialog-buttons\" [class.x-dialog-buttons-center]=\"buttonsCenter()\">\r\n <ng-container *xOutlet=\"footer()\">\r\n @if (showCancel() || showConfirm()) {\r\n <x-buttons space=\"0.5rem\">\r\n @if (showCancel()) {\r\n <x-button class=\"x-dialog-cancel\" (click)=\"onClose('cancel')\" flat plain>{{ getCancelText() }}</x-button>\r\n }\r\n @if (showConfirm()) {\r\n <x-button class=\"x-dialog-confirm\" type=\"primary\" flat (click)=\"onClose('confirm')\">{{\r\n getConfirmText()\r\n }}</x-button>\r\n }\r\n </x-buttons>\r\n }\r\n </ng-container>\r\n </div>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #operationTpl>\r\n @if (maximizeSignal()) {\r\n <x-button\r\n size=\"small\"\r\n flat\r\n [icon]=\"isMaximize() ? 'fto-minimize' : 'fto-maximize'\"\r\n [onlyIcon]=\"true\"\r\n (click)=\"onSize()\"\r\n class=\"x-dialog-maximize\"\r\n ></x-button>\r\n }\r\n</ng-template>\r\n\r\n@if (container) {\r\n <ng-container *ngTemplateOutlet=\"dialogTpl\"></ng-container>\r\n}\r\n", styles: [".x-dialog{margin:0;padding:0}.x-dialog{width:100%;height:100%}.x-dialog>x-alert{height:100%}.x-dialog>x-alert .x-alert{min-height:100%;height:fit-content;align-items:inherit;padding:0}.x-dialog>x-alert .x-alert-inner{min-height:100%;display:flex;flex-direction:column}.x-dialog>x-alert .x-alert-title{padding:1rem 1rem 0}.x-dialog>x-alert .x-alert-content{flex:1;display:flex;flex-direction:column;padding:0 1rem .5rem}.x-dialog-inner{display:flex;flex-direction:column;margin:.5rem 0;flex:1}.x-dialog-buttons{display:flex;justify-content:flex-end}.x-dialog-buttons>x-buttons{margin-top:1rem;align-self:flex-end}.x-dialog-buttons-center{justify-content:center}.x-dialog-content{display:inline-flex;flex-direction:column;flex:1;max-height:70vh;overflow:auto;min-height:2rem}.x-dialog-maximize>x-alert .x-alert{left:0!important;top:0!important;border-radius:0!important}.x-dialog-maximize .x-dialog-content{max-height:calc(100vh - 7.875rem)!important;height:calc(100vh - 7.875rem)!important}.x-dialog-default-maximize .x-dialog-content{max-height:calc(100vh - 7.875rem)!important;height:calc(100vh - 7.875rem)!important;flex:initial}.x-dialog-default-maximize>x-alert .x-alert{left:0!important;top:0!important;border-radius:0!important}\n"] }]
442
464
  }], ctorParameters: () => [], propDecorators: { getVisible: [{
443
465
  type: HostBinding,
444
466
  args: ['class.x-dialog-visible']
@@ -483,6 +505,7 @@ class XDialogRef {
483
505
  this.fullscreen = false;
484
506
  this.dragHandleRefs = [];
485
507
  this.afterClose = new Subject();
508
+ this.unsubject = new Subject();
486
509
  this._isFristFullscreen = true;
487
510
  }
488
511
  close(result) {
@@ -493,6 +516,8 @@ class XDialogRef {
493
516
  this.afterClose.next(result);
494
517
  });
495
518
  this.overlayRef.detach();
519
+ this.unsubject.next();
520
+ this.unsubject.complete();
496
521
  }
497
522
  onFullscreen() {
498
523
  let { dialogBox, dialogRef, overlayElement, distance, hostElement, defaultMaximize } = this.containerInstance;
@@ -814,13 +839,16 @@ class XDialogService {
814
839
  minHeight: '8rem',
815
840
  backdropClose: true,
816
841
  hasBackdrop: true,
842
+ keyboard: true,
817
843
  draggable: false
818
844
  };
819
845
  this.portalService = inject(XPortalService);
820
846
  this.configService = inject(XConfigService);
821
847
  this.overlay = inject(Overlay);
822
848
  this.rendererFactory = inject(RendererFactory2);
849
+ this.document = inject(DOCUMENT);
823
850
  this.renderer = this.rendererFactory.createRenderer(null, null);
851
+ this.dialogRefs = [];
824
852
  this.configDefault = this.configService.getConfigForComponent(X_DIALOG_CONFIG_NAME);
825
853
  Object.assign(this.default, this.configDefault);
826
854
  }
@@ -863,6 +891,7 @@ class XDialogService {
863
891
  instance.overlayElement = overlayElement;
864
892
  dialogRef.option = option;
865
893
  dialogRef.fullscreen = defaultMaximize;
894
+ dialogRef.unsubject = new Subject();
866
895
  if (defaultMaximize) {
867
896
  this.renderer.addClass(overlayElement, 'x-dialog-portal-fullscreen');
868
897
  }
@@ -877,9 +906,28 @@ class XDialogService {
877
906
  const comRef = instance.attachComponentPortal(new ComponentPortal(content, option.viewContainerRef, injector));
878
907
  dialogRef.componentInstance = comRef.instance;
879
908
  }
909
+ this.dialogRefs.push(dialogRef);
910
+ const close = () => {
911
+ dialogRef.close();
912
+ this.dialogRefs.splice(this.dialogRefs.indexOf(dialogRef), 1);
913
+ };
880
914
  if (option.hasBackdrop && option.backdropClose && overlayRef) {
881
- overlayRef.backdropClick().subscribe(() => {
882
- dialogRef.close();
915
+ overlayRef
916
+ .backdropClick()
917
+ .pipe(takeUntil$1(dialogRef.unsubject))
918
+ .subscribe(() => {
919
+ close();
920
+ });
921
+ }
922
+ if (option.keyboard) {
923
+ fromEvent(this.document, 'keydown')
924
+ .pipe(takeUntil$1(dialogRef.unsubject))
925
+ .subscribe((event) => {
926
+ if (event.key === 'Escape' || event.keyCode === 27) {
927
+ if (this.dialogRefs[this.dialogRefs.length - 1] === dialogRef) {
928
+ close();
929
+ }
930
+ }
883
931
  });
884
932
  }
885
933
  return dialogRef;