From f08456700246e7b14ef9eb2354bfdd9499a76d74 Mon Sep 17 00:00:00 2001 From: Sean Perkins Date: Wed, 30 Mar 2022 13:14:45 -0400 Subject: [PATCH] feat(modal): dynamic breakpoints --- core/src/components/modal/modal.tsx | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/core/src/components/modal/modal.tsx b/core/src/components/modal/modal.tsx index 180c2ad1b0..c281a9bf89 100644 --- a/core/src/components/modal/modal.tsx +++ b/core/src/components/modal/modal.tsx @@ -5,7 +5,7 @@ import { config } from '../../global/config'; import { getIonMode } from '../../global/ionic-global'; import { Animation, AnimationBuilder, ComponentProps, ComponentRef, FrameworkDelegate, Gesture, ModalAttributes, ModalBreakpointChangeEventDetail, OverlayEventDetail, OverlayInterface } from '../../interface'; import { CoreDelegate, attachComponent, detachComponent } from '../../utils/framework-delegate'; -import { raf } from '../../utils/helpers'; +import { clamp, raf } from '../../utils/helpers'; import { KEYBOARD_DID_OPEN } from '../../utils/keyboard/keyboard'; import { BACKDROP, activeAnimations, dismiss, eventMethod, prepareOverlay, present } from '../../utils/overlays'; import { getClassMap } from '../../utils/theme'; @@ -98,7 +98,7 @@ export class Modal implements ComponentInterface, OverlayInterface { * array must be the value of the `initialBreakpoint` property. * For example: [0, .25, .5, 1] */ - @Prop() breakpoints?: number[]; + @Prop({ mutable: true }) breakpoints?: number[]; /** * A decimal value between 0 and 1 that indicates the @@ -278,9 +278,27 @@ export class Modal implements ComponentInterface, OverlayInterface { } } - breakpointsChanged(breakpoints: number[] | undefined) { + @Watch('breakpoints') + breakpointsChanged(breakpoints: number[] | undefined, previousBreakpoints?: number[]) { if (breakpoints !== undefined) { this.sortedBreakpoints = breakpoints.sort((a, b) => a - b); + + if (previousBreakpoints) { + /** + * If the new breakpoints are different from the previous ones, we need to + * re-initialize the gesture. + */ + if (breakpoints.length !== previousBreakpoints.length || !breakpoints.every((v, i) => v === previousBreakpoints[i])) { + const { currentBreakpoint, sortedBreakpoints } = this; + // Calculate the initial breakpoint by comparing the current breakpoint vs. the min/max breakpoints. + const newBreakpoint = clamp(sortedBreakpoints[0], currentBreakpoint!, sortedBreakpoints[sortedBreakpoints.length - 1]); + this.initSheetGesture(newBreakpoint); + if (currentBreakpoint && !breakpoints.includes(currentBreakpoint)) { + // Current breakpoint is not within the new breakpoints, so we need to update the current breakpoint. + this.setCurrentBreakpoint(newBreakpoint); + } + } + } } } @@ -514,8 +532,8 @@ export class Modal implements ComponentInterface, OverlayInterface { this.gesture.enable(true); } - private initSheetGesture() { - const { wrapperEl, initialBreakpoint, backdropBreakpoint } = this; + private initSheetGesture(initialBreakpoint = this.initialBreakpoint) { + const { wrapperEl, backdropBreakpoint } = this; if (!wrapperEl || initialBreakpoint === undefined) { return;