import * as Ariakit from '@ariakit/react'; import { getClassNames } from '@websolutespa/bom-core'; import { forwardRef, useContext, useEffect, useState } from 'react'; import styled from 'styled-components'; import { getVariantKey } from '../../variants'; import { Role } from '../role/role'; import { UIStyledComponentProps } from '../types'; import { getCssResponsive } from '../utils'; import { ModalDialogContext, ModalForceMountContext } from './modal-dialog.context'; import { ModalContext } from './modal.context'; import { IModalVariants, modalVariants } from './modal.variants'; const StyledBackdrop = styled(Ariakit.DisclosureContent) ` ${props => getVariantKey('backdrop', props.variant, props.variants)} ${props => getCssResponsive(props)} `; export type ModalBackdropProps = UIStyledComponentProps<{ className?: string; variant?: keyof typeof modalVariants | (string & {}); variants?: IModalVariants; asChild?: boolean; forceMount?: boolean; }>; export const ModalBackdrop = forwardRef( function ModalBackdrop({ asChild, forceMount, className, variant, variants, ...props }, ref) { const { store } = useContext(ModalDialogContext)!; const forceMountContext = useContext(ModalForceMountContext); forceMount = forceMount ?? forceMountContext; const mounted = Ariakit.useStoreState(store, (state) => forceMount || state.mounted); const open = Ariakit.useStoreState(store, 'open'); const [state, setState] = useState('closed'); // Sets the state on the next animation frame so that the transition can be // triggered. useEffect(() => { const raf = requestAnimationFrame(() => { setState(open ? 'open' : 'closed'); }); return () => cancelAnimationFrame(raf); }, [open]); const disclosure = Ariakit.useDisclosureStore({ open, setOpen: store.setOpen, }); const classNames = getClassNames('modal__backdrop', className); const context = useContext(ModalContext); if (!mounted) { return null; } return ( : undefined} /> ); });