import React, { CSSProperties, ReactElement } from 'react' import { useTransition } from '~/hooks' import { TransitionPrimitive } from './transitions' import { getTransitionStyles } from './utils' export interface GroupedTransitionItem { duration: number timingFunction?: CSSProperties['transitionTimingFunction'] transition: TransitionPrimitive } export interface GroupedTransitionProps { transitions: Record children(styles: Record): ReactElement duration?: number exitDuration?: number timingFunction?: string mounted: boolean onExited?: () => void onExit?: () => void onEnter?: () => void onEntered?: () => void } export function GroupedTransition({ transitions, duration = 250, exitDuration = duration, mounted, children, timingFunction, onExit, onEntered, onEnter, onExited, }: GroupedTransitionProps) { const { transitionDuration, transitionStatus, transitionTimingFunction } = useTransition({ mounted, duration, exitDuration, timingFunction, onExit, onEntered, onEnter, onExited, }) if (transitionDuration === 0) { return mounted ? <>{children({})} : null } if (transitionStatus === 'exited') { return null } const transitionsStyles = Object.keys(transitions).reduce( (accumulator, transition) => { accumulator[transition] = getTransitionStyles({ duration: transitions[transition].duration, transition: transitions[transition].transition, timingFunction: transitions[transition].timingFunction || transitionTimingFunction, state: transitionStatus, }) return accumulator }, {} ) return <>{children(transitionsStyles)} } GroupedTransition.displayName = 'GroupedTransition'