import { AnimatePresence, motion } from 'framer-motion' import React, { useEffect, useState } from 'react' import { ModalStack, useModals } from '../src' export default { title: 'Animated', decorators: [ (Story) => ( ), ], } export const FramerMotion = () => { const { openModal } = useModals() return ( ) } function AnimatedModals({ stack }) { // the "displayed" stack which will be a lagged version of stack // in order to animate the transitions between modals const [displayedStack, setDisplayedStack] = useState(stack) // track the "open" state manually so we can dismiss the // top modal before popping it off the stack const [isOpen, setOpen] = useState(false) useEffect(() => { // we're opening the first modal, so update the stack right away if (stack.length === 1 && displayedStack.length === 0) { setOpen(true) setDisplayedStack(stack) } // stack updated, trigger a dismissal of the current modal else { setOpen(false) } }, [stack]) return ( <> {stack.length > 0 && ( )} {displayedStack.map((modal, index) => ( { // set open state for next modal if (stack.length > 0) { setOpen(true) } else { setOpen(false) } // update displayed stack // setTimeout is a hack to prevent a warning about updating state // in an unmounted component (I can't figure out why it happens, or why this fixes it) setTimeout(() => setDisplayedStack(stack)) modal.props?.onAnimationComplete?.() }} {...modal.props} /> ))} ) } type AnimatedModalProps = { open: boolean title?: string message?: string } function AnimatedModal({ open, message = `I'm modal #1`, title = 'Hello', ...props }: AnimatedModalProps) { const { stack, openModal, closeModal } = useModals() const [value, setValue] = useState('') return ( {open && (

{title}

{message}

setValue(e.currentTarget.value)} />

)}
) }