@tedi-design-system/angular 8.2.0-rc.4 → 8.2.0-rc.5

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,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, computed, ViewEncapsulation, ChangeDetectionStrategy, Component, signal, inject, ElementRef, Directive, booleanAttribute, output, ViewContainerRef, Renderer2, effect, HostListener, Injectable, InjectionToken, model, isDevMode, forwardRef, contentChild, DestroyRef, afterRenderEffect, contentChildren, PLATFORM_ID, REQUEST, isSignal, Pipe, Injector, HostAttributeToken, viewChild, NgZone, viewChildren, afterNextRender, Optional, SkipSelf, linkedSignal, untracked, ViewChild, TemplateRef, numberAttribute, HostBinding, runInInjectionContext, ContentChildren, RendererStyleFlags2, ContentChild, makeEnvironmentProviders } from '@angular/core';
2
+ import { input, computed, ViewEncapsulation, ChangeDetectionStrategy, Component, signal, inject, ElementRef, Directive, booleanAttribute, output, ViewContainerRef, Renderer2, effect, HostListener, Injectable, InjectionToken, model, isDevMode, forwardRef, contentChild, DestroyRef, afterRenderEffect, contentChildren, PLATFORM_ID, REQUEST, isSignal, Pipe, Injector, HostAttributeToken, viewChild, NgZone, viewChildren, afterNextRender, ErrorHandler, Optional, SkipSelf, linkedSignal, untracked, ViewChild, TemplateRef, numberAttribute, HostBinding, runInInjectionContext, ContentChildren, RendererStyleFlags2, ContentChild, makeEnvironmentProviders } from '@angular/core';
3
3
  import { BreakpointObserver } from '@angular/cdk/layout';
4
4
  import * as i1 from '@angular/cdk/overlay';
5
5
  import { CdkOverlayOrigin, OverlayContainer, OverlayModule, Overlay, OverlayConfig, CdkConnectedOverlay } from '@angular/cdk/overlay';
@@ -11,6 +11,7 @@ import * as i2 from '@angular/cdk/a11y';
11
11
  import { _IdGenerator, CdkTrapFocus, A11yModule, LiveAnnouncer, ActiveDescendantKeyManager } from '@angular/cdk/a11y';
12
12
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
13
13
  import { Dialog } from '@angular/cdk/dialog';
14
+ import { isObservable, firstValueFrom } from 'rxjs';
14
15
  import * as i1$2 from '@angular/cdk/scrolling';
15
16
  import { CdkScrollable, CdkVirtualScrollViewport, ScrollingModule } from '@angular/cdk/scrolling';
16
17
  import * as i3 from '@angular/cdk/listbox';
@@ -8691,15 +8692,50 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImpo
8691
8692
  /**
8692
8693
  * Reference to a modal opened via `ModalService`.
8693
8694
  * Provides methods to close the modal and observe its lifecycle.
8695
+ * The opener and the content share the same instance.
8694
8696
  */
8695
8697
  class ModalRef {
8696
8698
  dialogRef;
8697
- constructor(dialogRef) {
8699
+ errorHandler;
8700
+ /** Checked before every close, except `ModalService.closeAll()` and navigation. */
8701
+ canClose = null;
8702
+ pendingGuard = false;
8703
+ constructor(dialogRef, errorHandler = new ErrorHandler()) {
8698
8704
  this.dialogRef = dialogRef;
8705
+ this.errorHandler = errorHandler;
8699
8706
  }
8700
- /** Close the modal, optionally returning a result. */
8707
+ /** Close the modal, optionally returning a result. Subject to `canClose`. */
8701
8708
  close(result) {
8702
- this.dialogRef.close(result);
8709
+ this.requestClose("programmatic", result);
8710
+ }
8711
+ /** @internal */
8712
+ requestClose(reason, result) {
8713
+ if (this.pendingGuard)
8714
+ return;
8715
+ let verdict;
8716
+ try {
8717
+ verdict = this.canClose ? this.canClose(result, reason) : true;
8718
+ }
8719
+ catch (error) {
8720
+ this.errorHandler.handleError(error);
8721
+ return;
8722
+ }
8723
+ if (typeof verdict === "boolean") {
8724
+ if (verdict)
8725
+ this.dialogRef.close(result);
8726
+ return;
8727
+ }
8728
+ this.pendingGuard = true;
8729
+ const decision = isObservable(verdict)
8730
+ ? firstValueFrom(verdict, { defaultValue: false })
8731
+ : verdict;
8732
+ decision
8733
+ .then((allowed) => {
8734
+ if (allowed)
8735
+ this.dialogRef.close(result);
8736
+ })
8737
+ .catch((error) => this.errorHandler.handleError(error))
8738
+ .finally(() => (this.pendingGuard = false));
8703
8739
  }
8704
8740
  /** Observable that emits when the modal is closed, with the optional result value. */
8705
8741
  get closed() {
@@ -8755,6 +8791,7 @@ class ModalService {
8755
8791
  overlay = inject(Overlay);
8756
8792
  injector = inject(Injector);
8757
8793
  idGenerator = inject(_IdGenerator);
8794
+ errorHandler = inject(ErrorHandler);
8758
8795
  /**
8759
8796
  * Open a modal dialog with the given component as content.
8760
8797
  *
@@ -8777,6 +8814,7 @@ class ModalService {
8777
8814
  const { data, size = "default", width = "sm", position = "center", scrollBehavior = "content", closeOnBackdropClick = true, closeOnEscape = true, fullscreen = false, maxWidth, ariaLabel, ariaLabelledBy, } = config;
8778
8815
  const panelClasses = this.buildPanelClasses(size, width, position, scrollBehavior, fullscreen);
8779
8816
  const isPresetWidth = WIDTH_PRESETS.includes(width);
8817
+ let modalRef;
8780
8818
  const dialogRef = this.dialog.open(component, {
8781
8819
  data,
8782
8820
  panelClass: panelClasses,
@@ -8791,7 +8829,10 @@ class ModalService {
8791
8829
  positionStrategy: this.buildPositionStrategy(position, scrollBehavior),
8792
8830
  scrollStrategy: this.overlay.scrollStrategies.block(),
8793
8831
  providers: (ref) => [
8794
- { provide: ModalRef, useValue: new ModalRef(ref) },
8832
+ {
8833
+ provide: ModalRef,
8834
+ useValue: (modalRef = new ModalRef(ref, this.errorHandler)),
8835
+ },
8795
8836
  { provide: MODAL_DATA, useValue: data },
8796
8837
  { provide: MODAL_SIZE, useValue: signal(size) },
8797
8838
  ],
@@ -8802,13 +8843,13 @@ class ModalService {
8802
8843
  if (maxWidth) {
8803
8844
  dialogRef.overlayRef.overlayElement.style.setProperty("--_tedi-modal-max-width", maxWidth);
8804
8845
  }
8805
- this.setupDialogBehavior(dialogRef, scrollBehavior, closeOnBackdropClick, closeOnEscape);
8846
+ this.setupDialogBehavior(dialogRef, modalRef, scrollBehavior, closeOnBackdropClick, closeOnEscape);
8806
8847
  if (!ariaLabel && !ariaLabelledBy) {
8807
8848
  this.labelFromHeading(dialogRef);
8808
8849
  }
8809
- return new ModalRef(dialogRef);
8850
+ return modalRef;
8810
8851
  }
8811
- /** Close all open modals. */
8852
+ /** Close all open modals, ignoring `canClose`. */
8812
8853
  closeAll() {
8813
8854
  this.dialog.closeAll();
8814
8855
  }
@@ -8824,7 +8865,8 @@ class ModalService {
8824
8865
  labelFromHeading(dialogRef) {
8825
8866
  afterNextRender(() => {
8826
8867
  // The container, not the pane, is what carries role="dialog".
8827
- const container = dialogRef.overlayRef.overlayElement.querySelector("cdk-dialog-container");
8868
+ // The pane is null if the modal closed before rendering.
8869
+ const container = dialogRef.overlayRef.overlayElement?.querySelector("cdk-dialog-container");
8828
8870
  if (!container)
8829
8871
  return;
8830
8872
  const headingId = resolveModalHeadingId(container, this.idGenerator);
@@ -8855,19 +8897,19 @@ class ModalService {
8855
8897
  }
8856
8898
  return classes;
8857
8899
  }
8858
- setupDialogBehavior(dialogRef, scrollBehavior, closeOnBackdropClick, closeOnEscape) {
8900
+ setupDialogBehavior(dialogRef, modalRef, scrollBehavior, closeOnBackdropClick, closeOnEscape) {
8859
8901
  if (scrollBehavior === "page") {
8860
8902
  const host = dialogRef.overlayRef.hostElement;
8861
8903
  host.style.overflow = "auto";
8862
8904
  host.style.paddingBlock = "var(--layout-grid-gutters-16)";
8863
8905
  }
8864
8906
  if (closeOnBackdropClick) {
8865
- dialogRef.backdropClick.subscribe(() => dialogRef.close());
8907
+ dialogRef.backdropClick.subscribe(() => modalRef.requestClose("backdrop"));
8866
8908
  }
8867
8909
  if (closeOnEscape) {
8868
8910
  dialogRef.keydownEvents.subscribe((event) => {
8869
8911
  if (event.key === "Escape") {
8870
- dialogRef.close();
8912
+ modalRef.requestClose("escape");
8871
8913
  }
8872
8914
  });
8873
8915
  }
@@ -9123,7 +9165,7 @@ class ModalHeaderComponent {
9123
9165
  }, ...(ngDevMode ? [{ debugName: "effectiveCloseButtonSize" }] : []));
9124
9166
  closeModal() {
9125
9167
  if (this.modalRef) {
9126
- this.modalRef.close();
9168
+ this.modalRef.requestClose("close-button");
9127
9169
  }
9128
9170
  else if (this.modal) {
9129
9171
  this.modal.open.set(false);