diff --git a/core/src/components/modal/gestures/swipe-to-close.ts b/core/src/components/modal/gestures/swipe-to-close.ts index 1d9f2002fc..ef807937e1 100644 --- a/core/src/components/modal/gestures/swipe-to-close.ts +++ b/core/src/components/modal/gestures/swipe-to-close.ts @@ -9,6 +9,7 @@ import { import type { GestureDetail } from '../../../utils/gesture'; import { createGesture } from '../../../utils/gesture'; import { clamp, getElementRoot } from '../../../utils/helpers'; +import type { Style as StatusBarStyle } from '../../../utils/native/status-bar'; import { setCardStatusBarDark, setCardStatusBarDefault } from '../utils'; import { calculateSpringStep, handleCanDismiss } from './utils'; @@ -18,7 +19,12 @@ export const SwipeToCloseDefaults = { MIN_PRESENTING_SCALE: 0.93, }; -export const createSwipeToCloseGesture = (el: HTMLIonModalElement, animation: Animation, onDismiss: () => void) => { +export const createSwipeToCloseGesture = ( + el: HTMLIonModalElement, + animation: Animation, + statusBarStyle: StatusBarStyle, + onDismiss: () => void +) => { /** * The step value at which a card modal * is eligible for dismissing via gesture. @@ -173,14 +179,14 @@ export const createSwipeToCloseGesture = (el: HTMLIonModalElement, animation: An * should block the gesture from * proceeding, */ - const isAttempingDismissWithCanDismiss = step >= 0 && canDismissBlocksGesture; + const isAttemptingDismissWithCanDismiss = step >= 0 && canDismissBlocksGesture; /** * If we are blocking the gesture from dismissing, * set the max step value so that the sheet cannot be * completely hidden. */ - const maxStep = isAttempingDismissWithCanDismiss ? canDismissMaxStep : 0.9999; + const maxStep = isAttemptingDismissWithCanDismiss ? canDismissMaxStep : 0.9999; /** * If we are blocking the gesture from @@ -190,7 +196,7 @@ export const createSwipeToCloseGesture = (el: HTMLIonModalElement, animation: An * Note that the starting breakpoint is always 0, * so we omit adding 0 to the result. */ - const processedStep = isAttempingDismissWithCanDismiss ? calculateSpringStep(step / maxStep) : step; + const processedStep = isAttemptingDismissWithCanDismiss ? calculateSpringStep(step / maxStep) : step; const clampedStep = clamp(0.0001, processedStep, maxStep); @@ -205,7 +211,7 @@ export const createSwipeToCloseGesture = (el: HTMLIonModalElement, animation: An * crossed a certain threshold. */ if (clampedStep >= DISMISS_THRESHOLD && lastStep < DISMISS_THRESHOLD) { - setCardStatusBarDefault(); + setCardStatusBarDefault(statusBarStyle); /** * However, if we swipe back up, then the @@ -223,10 +229,10 @@ export const createSwipeToCloseGesture = (el: HTMLIonModalElement, animation: An const velocity = detail.velocityY; const step = detail.deltaY / height; - const isAttempingDismissWithCanDismiss = step >= 0 && canDismissBlocksGesture; - const maxStep = isAttempingDismissWithCanDismiss ? canDismissMaxStep : 0.9999; + const isAttemptingDismissWithCanDismiss = step >= 0 && canDismissBlocksGesture; + const maxStep = isAttemptingDismissWithCanDismiss ? canDismissMaxStep : 0.9999; - const processedStep = isAttempingDismissWithCanDismiss ? calculateSpringStep(step / maxStep) : step; + const processedStep = isAttemptingDismissWithCanDismiss ? calculateSpringStep(step / maxStep) : step; const clampedStep = clamp(0.0001, processedStep, maxStep); @@ -238,7 +244,7 @@ export const createSwipeToCloseGesture = (el: HTMLIonModalElement, animation: An * animation can never complete until * canDismiss is checked. */ - const shouldComplete = !isAttempingDismissWithCanDismiss && threshold >= DISMISS_THRESHOLD; + const shouldComplete = !isAttemptingDismissWithCanDismiss && threshold >= DISMISS_THRESHOLD; let newStepValue = shouldComplete ? -0.001 : 0.001; if (!shouldComplete) { @@ -280,7 +286,7 @@ export const createSwipeToCloseGesture = (el: HTMLIonModalElement, animation: An * check canDismiss. 25% was chosen * to avoid accidental swipes. */ - if (isAttempingDismissWithCanDismiss && clampedStep > maxStep / 4) { + if (isAttemptingDismissWithCanDismiss && clampedStep > maxStep / 4) { handleCanDismiss(el, animation); } else if (shouldComplete) { onDismiss(); diff --git a/core/src/components/modal/modal.tsx b/core/src/components/modal/modal.tsx index 804c803dc7..6f2353a975 100644 --- a/core/src/components/modal/modal.tsx +++ b/core/src/components/modal/modal.tsx @@ -22,6 +22,7 @@ import { raf, inheritAttributes } from '../../utils/helpers'; import type { Attributes } from '../../utils/helpers'; import { KEYBOARD_DID_OPEN } from '../../utils/keyboard/keyboard'; import { printIonWarning } from '../../utils/logging'; +import { Style as StatusBarStyle, StatusBar } from '../../utils/native/status-bar'; import { BACKDROP, activeAnimations, dismiss, eventMethod, prepareOverlay, present } from '../../utils/overlays'; import { getClassMap } from '../../utils/theme'; import { deepReady } from '../../utils/transition'; @@ -68,6 +69,7 @@ export class Modal implements ComponentInterface, OverlayInterface { private keyboardOpenCallback?: () => void; private moveSheetToBreakpoint?: (options: MoveSheetToBreakpointOptions) => Promise; private inheritedAttributes: Attributes = {}; + private statusBarStyle?: StatusBarStyle; private inline = false; private workingDelegate?: FrameworkDelegate; @@ -519,7 +521,7 @@ export class Modal implements ComponentInterface, OverlayInterface { * If we did not do this check, then not using swipeToClose would mean you could * not run canDismiss on swipe as there would be no swipe gesture created. */ - const hasCardModal = this.swipeToClose || (this.canDismiss !== undefined && this.presentingElement !== undefined); + const hasCardModal = this.presentingElement !== undefined && (this.swipeToClose || this.canDismiss !== undefined); /** * We need to change the status bar at the @@ -527,6 +529,8 @@ export class Modal implements ComponentInterface, OverlayInterface { * by the time the card animation is done. */ if (hasCardModal && getIonMode(this) === 'ios') { + // Cache the original status bar color before the modal is presented + this.statusBarStyle = await StatusBar.getStyle(); setCardStatusBarDark(); } @@ -584,7 +588,9 @@ export class Modal implements ComponentInterface, OverlayInterface { return; } - this.gesture = createSwipeToCloseGesture(el, ani, () => { + const statusBarStyle = this.statusBarStyle ?? StatusBarStyle.Default; + + this.gesture = createSwipeToCloseGesture(el, ani, statusBarStyle, () => { /** * While the gesture animation is finishing * it is possible for a user to tap the backdrop. @@ -691,9 +697,9 @@ export class Modal implements ComponentInterface, OverlayInterface { * finishes when the dismiss animation does. * TODO (FW-937) */ - const hasCardModal = this.swipeToClose || (this.canDismiss !== undefined && this.presentingElement !== undefined); + const hasCardModal = this.presentingElement !== undefined && (this.swipeToClose || this.canDismiss !== undefined); if (hasCardModal && getIonMode(this) === 'ios') { - setCardStatusBarDefault(); + setCardStatusBarDefault(this.statusBarStyle); } /* tslint:disable-next-line */ diff --git a/core/src/components/modal/utils.ts b/core/src/components/modal/utils.ts index 5a5ffc907d..99de3ba0e1 100644 --- a/core/src/components/modal/utils.ts +++ b/core/src/components/modal/utils.ts @@ -81,10 +81,10 @@ export const setCardStatusBarDark = () => { StatusBar.setStyle({ style: Style.Dark }); }; -export const setCardStatusBarDefault = () => { +export const setCardStatusBarDefault = (defaultStyle = Style.Default) => { if (!win || win.innerWidth >= 768 || !StatusBar.supportsDefaultStatusBarStyle()) { return; } - StatusBar.setStyle({ style: Style.Default }); + StatusBar.setStyle({ style: defaultStyle }); }; diff --git a/core/src/utils/native/status-bar.ts b/core/src/utils/native/status-bar.ts index ebe320de8a..a12dfc5d99 100644 --- a/core/src/utils/native/status-bar.ts +++ b/core/src/utils/native/status-bar.ts @@ -31,4 +31,12 @@ export const StatusBar = { engine.setStyle(options); }, + getStyle: async function (): Promise