import { ANIMATED_COMPONENT_TRANSITION_MS } from 'components/core/transitions' ; import { ReactElement , ReactNode , createContext , useContext , memo , useState , useCallback , useMemo , } from 'react' ; import AnimatedModal from './AnimatedModal' ; type ModalActions = { showModal : ( content : ReactElement ) => void ; hideModal : ( ) => void ; } ; const ModalContext = createContext < ModalActions | undefined > ( undefined ) ; export const useModal = ( ) : ModalActions => { const context = useContext ( ModalContext ) ; if ( ! context ) { throw new Error ( 'Attempted to use ModalContext without a provider!' ) ; } return context ; } ; type Props = { children : ReactNode ; } ; function ModalProvider ( { children } ) { const [ isMounted , setIsMounted ] = useState ( false ) ; const [ isActive , setIsActive ] = useState ( false ) ; const [ content , setContent ] = useState < ReactElement | null > ( null ) ; const showModal = useCallback ( ( providedContent ) => { setIsActive ( true ) ; setIsMounted ( true ) ; setContent ( providedContent ) ; } , [ ] ) ; const hideModal = useCallback ( ( ) => { setIsActive ( false ) ; setTimeout ( ( ) => { setIsMounted ( false ) ; setContent ( null ) ; } , ANIMATED_COMPONENT_TRANSITION_MS - 30 ) ; } , [ ] ) ; const actions = useMemo ( ( ) => ( { showModal , hideModal , } ) , [ showModal , hideModal ] ) ; return ( < ModalContext . Provider value = { actions } > { children } { isMounted && content && ( < AnimatedModal isActive = { isActive } hideModal = { hideModal } content = { content } / > ) } < /ModalContext.Provider>); } export default memo ( ModalProvider ) ;