Skip to content

Commit

Permalink
fix: fully animate last modal out before closing the stack
Browse files Browse the repository at this point in the history
This issue was happening because as soon as we were triggering the close of a modal, we were *also* animating the backdrop out, resulting in the last modal being "closed" before its out animation. Now, the backdrop will wait for that last modal stack item to be fully finished with its out animation, *before* checking if it should animate out itself.

Closes #96
  • Loading branch information
CharlesMangwa committed Mar 14, 2023
1 parent 7015a2e commit 34879fb
Show file tree
Hide file tree
Showing 2 changed files with 4 additions and 27 deletions.
3 changes: 0 additions & 3 deletions src/lib/ModalStack.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ const ModalStack = <P extends ModalfyParams>(props: Props<P>) => {
props.openModal(...args)
setOpenActionCallbacks(state => [...state, stackItem.hash])
}}
hideBackdrop={hideBackdrop}
wasOpenCallbackCalled={openActionCallbacks.includes(stackItem.hash)}
wasClosedByBackdropPress={backdropClosedItems.includes(stackItem.hash)}
pendingClosingAction={hasPendingClosingAction ? pendingClosingAction : undefined}
Expand All @@ -99,8 +98,6 @@ const ModalStack = <P extends ModalfyParams>(props: Props<P>) => {

const currentItem = [...stack.openedItems].slice(-1)[0]

if (stack.openedItemsSize === 1) hideBackdrop()

setBackdropClosedItems([...backdropClosedItems, currentItem?.hash])
}

Expand Down
28 changes: 4 additions & 24 deletions src/lib/StackItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import { getStackItemOptions, vh } from '../utils'
type Props<P> = SharedProps<P> & {
zIndex: number
position: number
hideBackdrop: () => void
stackItem: ModalStackItem<P>
wasOpenCallbackCalled: boolean
wasClosedByBackdropPress: boolean
Expand All @@ -35,7 +34,6 @@ const StackItem = <P extends ModalfyParams>({
openModal,
closeModal,
closeModals,
hideBackdrop,
currentModal,
closeAllModals,
eventListeners,
Expand Down Expand Up @@ -144,16 +142,13 @@ const StackItem = <P extends ModalfyParams>({
callback?.()
}

if (stack.openedItemsSize === 1) hideBackdrop()

if (!modalName || modalName === currentModal) {
updateAnimatedValue(position - 1, onCloseFns)
} else onCloseFns()
},
[
currentModal,
closeModal,
hideBackdrop,
onCloseListener,
position,
stack.openedItemsSize,
Expand All @@ -171,35 +166,29 @@ const StackItem = <P extends ModalfyParams>({
return output
}

if (stack.openedItemsSize === 1) hideBackdrop()

if (closingElement === currentModal && position === 1) {
return updateAnimatedValue(position - 1, onCloseFns)
} else return onCloseFns()
},
[closeModals, currentModal, hideBackdrop, position, stack.openedItemsSize, updateAnimatedValue],
[closeModals, currentModal, position, stack.openedItemsSize, updateAnimatedValue],
)

const closeAllStackItems = useCallback(
(callback?: () => void) => {
if (stack.openedItemsSize === 1) hideBackdrop()

updateAnimatedValue(position - 1, () => {
onCloseListener.current({ type: 'closeAllModals', origin: wasClosedByBackdropPress ? 'backdrop' : 'default' })
closeAllModals()
callback?.()
})
},
[closeAllModals, hideBackdrop, position, stack.openedItemsSize, updateAnimatedValue, wasClosedByBackdropPress],
[closeAllModals, position, stack.openedItemsSize, updateAnimatedValue, wasClosedByBackdropPress],
)

const onFling = useCallback(
({ nativeEvent }) => {
if (!disableFlingGesture && nativeEvent.oldState === State.ACTIVE) {
const toValue = verticalPosition === 'top' ? vh(-100) : vh(100)

if (stack.openedItemsSize === 1) hideBackdrop()

Animated.timing(translateY, {
toValue,
useNativeDriver: true,
Expand All @@ -212,23 +201,14 @@ const StackItem = <P extends ModalfyParams>({
})
}
},
[
animateOutConfig,
closeModal,
disableFlingGesture,
hideBackdrop,
stack.openedItemsSize,
stackItem,
translateY,
verticalPosition,
],
[animateOutConfig, closeModal, disableFlingGesture, stack.openedItemsSize, stackItem, translateY, verticalPosition],
)

const pointerEvents = useMemo((): ViewProps['pointerEvents'] => {
/**
* NOTE: Using `box-only` instead of `none` here so that the modal would catch the event and not dispatch it to the backdrop.
* If there's only 1 modal in the stack for instance, by using `none` and touching anywhere on the modal, the event
* would be propagated to the backdrop which would close the modal, which is a pretty counterintuitive UX.
* would be propagated to the backdrop which would close the modal, which is a pretty counterintuitive UX.
*/
switch (pointerEventsBehavior) {
case 'none':
Expand Down

0 comments on commit 34879fb

Please sign in to comment.