import { Dispatch, SetStateAction, useMemo, useState } from "react"; import { ModalOptions } from "./interface"; import { useClick, useDismiss, useFloating, UseFloatingReturn, useInteractions, UseInteractionsReturn, useRole, } from "@floating-ui/react"; import { ThemeBaseColor } from "../../types"; export type UseModalReturn = { open: boolean; setOpen: Dispatch>; color?: ThemeBaseColor; labelId?: string; descriptionId?: string; setLabelId: Dispatch>; setDescriptionId: Dispatch>; } & UseInteractionsReturn & UseFloatingReturn; export function useModal({ initialOpen = false, open: controlledOpen, onOpen: setControlledOpen, color, }: ModalOptions = {}): UseModalReturn { const [uncontrolledOpen, setUncontrolledOpen] = useState(initialOpen); const [labelId, setLabelId] = useState(); const [descriptionId, setDescriptionId] = useState(); const isUncontrolled = controlledOpen === null || controlledOpen === undefined; const open = isUncontrolled ? uncontrolledOpen : controlledOpen; const setOpen = isUncontrolled ? setUncontrolledOpen : (setControlledOpen as Dispatch>); const data = useFloating({ open, onOpenChange: setOpen, }); const { context } = data; const click = useClick(context); const dismiss = useDismiss(context); const role = useRole(context); const interactions = useInteractions([click, dismiss, role]); return useMemo( () => ({ open, setOpen, ...interactions, ...data, color, labelId, descriptionId, setLabelId, setDescriptionId, }), [open, setOpen, interactions, data, color, labelId, descriptionId], ); }