"use client" import { cx } from "class-variance-authority" import { AnimatePresence, motion } from "motion/react" import { type PropsWithChildren, useEffect, useState } from "react" import { Modal as AriaModal, Dialog, DialogTrigger, ModalOverlay, } from "react-aria-components" import { useIntl } from "react-intl" import { type AnimationState, AnimationStateEnum, type InnerModalProps, type ModalProps, } from "./modal" import { fade, slideInOut } from "./motionVariants" import { modalContentVariants } from "./variants" import { IconButton } from "../IconButton" import { Typography } from "../Typography" import styles from "./modal.module.css" const MotionOverlay = motion.create(ModalOverlay) const MotionModal = motion.create(AriaModal) function InnerModal({ animation, onAnimationComplete = () => undefined, setAnimation, onToggle, isOpen, children, title, subtitle, withActions, hideHeader, className, contentClassName, }: PropsWithChildren) { const intl = useIntl() const contentClassNames = modalContentVariants({ withActions, className: contentClassName, }) function modalStateHandler(newAnimationState: AnimationState) { setAnimation((currentAnimationState) => newAnimationState === AnimationStateEnum.hidden && currentAnimationState === AnimationStateEnum.hidden ? AnimationStateEnum.unmounted : currentAnimationState ) if (newAnimationState === AnimationStateEnum.visible) { onAnimationComplete() } } function onOpenChange(state: boolean) { onToggle!(state) } return ( {({ close }) => ( <> {!hideHeader && (
{title && (

{title}

)} {subtitle && ( {subtitle} )}
)}
{children}
)}
) } export default function Modal({ onAnimationComplete = () => undefined, trigger, isOpen, onToggle, onOpenChange, title, subtitle, children, withActions = false, hideHeader = false, className = "", contentClassName = "", }: PropsWithChildren) { const [animation, setAnimation] = useState( AnimationStateEnum.visible ) useEffect(() => { if (typeof isOpen === "boolean") { setAnimation( isOpen ? AnimationStateEnum.visible : AnimationStateEnum.hidden ) } if (isOpen === undefined) { setAnimation(AnimationStateEnum.unmounted) } }, [isOpen]) const shouldRender = isOpen || animation !== AnimationStateEnum.unmounted if (!trigger) { return ( {shouldRender && ( {children} )} ) } return ( { setAnimation( isOpen ? AnimationStateEnum.visible : AnimationStateEnum.hidden ) onOpenChange?.(isOpen) }} > {trigger} {shouldRender && ( {children} )} ) }