@vsn-ux/ngx-gaia 0.9.17 → 0.10.0

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.
@@ -2940,6 +2940,68 @@ class GaModalRef {
2940
2940
 
2941
2941
  const GA_MODAL_DATA = new InjectionToken('GaModalData');
2942
2942
 
2943
+ class GaModalOptions {
2944
+ /**
2945
+ * Defines the predefined size of the modal.
2946
+ *
2947
+ * @default `md`
2948
+ */
2949
+ size;
2950
+ /**
2951
+ * Defines the type of the modal:
2952
+ * - `none` for no icon.
2953
+ * - `information` for info dialog.
2954
+ * - `danger` for danger dialog.
2955
+ * - `warning` for warning dialog.
2956
+ * - `success` for success dialog.
2957
+ */
2958
+ type;
2959
+ /**
2960
+ * The ARIA role of the dialog element.
2961
+ *
2962
+ * @default `dialog`
2963
+ */
2964
+ role;
2965
+ /**
2966
+ * Defines the vertical position of the modal.
2967
+ * - `center` centers the modal vertically in the viewport (default).
2968
+ * - `top` positions the modal at the top with a calculated offset.
2969
+ *
2970
+ * @default `center`
2971
+ */
2972
+ verticalPosition;
2973
+ /**
2974
+ * Defines if the modal should be closed when the escape key is pressed.
2975
+ *
2976
+ * @default `true`
2977
+ */
2978
+ closeOnEscape;
2979
+ /**
2980
+ * Defines if the modal should be closed when the backdrop is clicked.
2981
+ *
2982
+ * @default `true`
2983
+ */
2984
+ closeOnOutsideClick;
2985
+ /**
2986
+ * Defines if the modal should be closed when the route changes.
2987
+ *
2988
+ * @default `true`
2989
+ */
2990
+ closeOnNavigation;
2991
+ }
2992
+ const DEFAULT_MODAL_OPTIONS = {
2993
+ role: 'dialog',
2994
+ type: 'none',
2995
+ size: 'md',
2996
+ verticalPosition: 'center',
2997
+ closeOnEscape: true,
2998
+ closeOnOutsideClick: true,
2999
+ closeOnNavigation: true,
3000
+ };
3001
+ function provideGaModalOptions(options) {
3002
+ return { provide: GaModalOptions, useValue: options };
3003
+ }
3004
+
2943
3005
  class GaModalService {
2944
3006
  /** @ignore */
2945
3007
  overlay = inject(Overlay);
@@ -2952,6 +3014,8 @@ class GaModalService {
2952
3014
  });
2953
3015
  /** @ignore */
2954
3016
  openModalsAtThisLevel = signal([]);
3017
+ /** @ignore */
3018
+ positionStrategy;
2955
3019
  get activeModals() {
2956
3020
  if (this.parentModalService) {
2957
3021
  return this.parentModalService.activeModals;
@@ -2976,15 +3040,23 @@ class GaModalService {
2976
3040
  const modalRef = new GaModalRef();
2977
3041
  const injector = this.createInjector(this.injector, overlayRef, modalRef, data);
2978
3042
  const modalPortal = new ComponentPortal(component, null, injector);
2979
- const result = overlayRef.attach(modalPortal);
2980
- modalRef.instance = result.instance;
3043
+ const { instance: modalComponent } = overlayRef.attach(modalPortal);
3044
+ modalRef.instance = modalComponent;
3045
+ // Update position and size if verticalPosition is 'top'
3046
+ const verticalPosition = modalComponent.options.verticalPosition ??
3047
+ DEFAULT_MODAL_OPTIONS.verticalPosition;
3048
+ if (verticalPosition === 'top') {
3049
+ const modalStackIndex = this.activeModals().length + 1;
3050
+ this.positionStrategy?.top(`calc(4rem * var(--ga-base-scaling-factor, 1) * ${modalStackIndex})`);
3051
+ overlayRef.updateSize({
3052
+ maxHeight: `calc(100vh - 4rem * var(--ga-base-scaling-factor, 1) * (2 + ${modalStackIndex}))`,
3053
+ });
3054
+ }
2981
3055
  this.activeModals.update((modals) => {
2982
- modals.push(modalRef.instance);
3056
+ modals.push(modalComponent);
2983
3057
  return modals;
2984
3058
  });
2985
- modalRef.instance
2986
- .afterClosed({ closeOnUnsubscribe: false })
2987
- .subscribe(() => {
3059
+ modalComponent.afterClosed({ closeOnUnsubscribe: false }).subscribe(() => {
2988
3060
  const index = this.activeModals().indexOf(modalRef.instance);
2989
3061
  if (index > -1) {
2990
3062
  this.activeModals.update((modals) => {
@@ -2993,26 +3065,25 @@ class GaModalService {
2993
3065
  });
2994
3066
  }
2995
3067
  });
2996
- return result.instance;
3068
+ return modalComponent;
2997
3069
  }
2998
3070
  /** @ignore */
2999
3071
  createOverlay() {
3000
- const modalStackIndex = this.activeModals().length;
3001
- const positionStrategy = this.overlay
3072
+ this.positionStrategy = this.overlay
3002
3073
  .position()
3003
3074
  .global()
3004
3075
  .centerHorizontally()
3005
- .top(`calc(4rem * var(--ga-base-scaling-factor, 1) * ${modalStackIndex + 1})`);
3076
+ .centerVertically();
3006
3077
  const scrollStrategy = this.overlay.scrollStrategies.block();
3007
3078
  return this.overlay.create({
3008
- positionStrategy,
3079
+ positionStrategy: this.positionStrategy,
3009
3080
  scrollStrategy,
3010
3081
  hasBackdrop: true,
3011
3082
  backdropClass: 'ga-modal__backdrop',
3012
3083
  // NOTE: handled manually inside the modal component
3013
3084
  disposeOnNavigation: false,
3014
3085
  height: 'auto',
3015
- maxHeight: `calc(100vh - 4rem * var(--ga-base-scaling-factor, 1) * (2 + ${modalStackIndex}))`,
3086
+ maxHeight: `calc(100vh - 4rem * var(--ga-base-scaling-factor, 1) * 2)`,
3016
3087
  });
3017
3088
  }
3018
3089
  /** @ignore */
@@ -3034,59 +3105,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.4", ngImpor
3034
3105
  args: [{ providedIn: 'root' }]
3035
3106
  }] });
3036
3107
 
3037
- class GaModalOptions {
3038
- /**
3039
- * Defines the predefined size of the modal.
3040
- *
3041
- * @default `md`
3042
- */
3043
- size;
3044
- /**
3045
- * Defines the type of the modal:
3046
- * - `none` for no icon.
3047
- * - `information` for info dialog.
3048
- * - `danger` for danger dialog.
3049
- * - `warning` for warning dialog.
3050
- * - `success` for success dialog.
3051
- */
3052
- type;
3053
- /**
3054
- * The ARIA role of the dialog element.
3055
- *
3056
- * @default `dialog`
3057
- */
3058
- role;
3059
- /**
3060
- * Defines if the modal should be closed when the escape key is pressed.
3061
- *
3062
- * @default `true`
3063
- */
3064
- closeOnEscape;
3065
- /**
3066
- * Defines if the modal should be closed when the backdrop is clicked.
3067
- *
3068
- * @default `true`
3069
- */
3070
- closeOnOutsideClick;
3071
- /**
3072
- * Defines if the modal should be closed when the route changes.
3073
- *
3074
- * @default `true`
3075
- */
3076
- closeOnNavigation;
3077
- }
3078
- const DEFAULT_MODAL_OPTIONS = {
3079
- role: 'dialog',
3080
- type: 'none',
3081
- size: 'md',
3082
- closeOnEscape: true,
3083
- closeOnOutsideClick: true,
3084
- closeOnNavigation: true,
3085
- };
3086
- function provideGaModalOptions(options) {
3087
- return { provide: GaModalOptions, useValue: options };
3088
- }
3089
-
3090
3108
  class GaModalComponent {
3091
3109
  closeSubject = new Subject();
3092
3110
  overlayRef = inject(OverlayRef);