UNPKG

@chakra-ui/modal

Version:

An accessible dialog (modal) component for React & Chakra UI

126 lines (124 loc) 3.5 kB
'use client' import { modalManager, useModalManager } from "./chunk-CYRBRIA2.mjs"; // src/use-modal.ts import { callAllHandlers } from "@chakra-ui/shared-utils"; import { mergeRefs } from "@chakra-ui/react-use-merge-refs"; import { hideOthers } from "aria-hidden"; import { useCallback, useEffect, useId, useMemo, useRef, useState } from "react"; function useModal(props) { const { isOpen, onClose, id, closeOnOverlayClick = true, closeOnEsc = true, useInert = true, onOverlayClick: onOverlayClickProp, onEsc } = props; const dialogRef = useRef(null); const overlayRef = useRef(null); const [dialogId, headerId, bodyId] = useIds( id, `chakra-modal`, `chakra-modal--header`, `chakra-modal--body` ); useAriaHidden(dialogRef, isOpen && useInert); const index = useModalManager(dialogRef, isOpen); const mouseDownTarget = useRef(null); const onMouseDown = useCallback((event) => { mouseDownTarget.current = event.target; }, []); const onKeyDown = useCallback( (event) => { if (event.key === "Escape") { event.stopPropagation(); if (closeOnEsc) { onClose == null ? void 0 : onClose(); } onEsc == null ? void 0 : onEsc(); } }, [closeOnEsc, onClose, onEsc] ); const [headerMounted, setHeaderMounted] = useState(false); const [bodyMounted, setBodyMounted] = useState(false); const getDialogProps = useCallback( (props2 = {}, ref = null) => ({ role: "dialog", ...props2, ref: mergeRefs(ref, dialogRef), id: dialogId, tabIndex: -1, "aria-modal": true, "aria-labelledby": headerMounted ? headerId : void 0, "aria-describedby": bodyMounted ? bodyId : void 0, onClick: callAllHandlers( props2.onClick, (event) => event.stopPropagation() ) }), [bodyId, bodyMounted, dialogId, headerId, headerMounted] ); const onOverlayClick = useCallback( (event) => { event.stopPropagation(); if (mouseDownTarget.current !== event.target) return; if (!modalManager.isTopModal(dialogRef.current)) return; if (closeOnOverlayClick) { onClose == null ? void 0 : onClose(); } onOverlayClickProp == null ? void 0 : onOverlayClickProp(); }, [onClose, closeOnOverlayClick, onOverlayClickProp] ); const getDialogContainerProps = useCallback( (props2 = {}, ref = null) => ({ ...props2, ref: mergeRefs(ref, overlayRef), onClick: callAllHandlers(props2.onClick, onOverlayClick), onKeyDown: callAllHandlers(props2.onKeyDown, onKeyDown), onMouseDown: callAllHandlers(props2.onMouseDown, onMouseDown) }), [onKeyDown, onMouseDown, onOverlayClick] ); return { isOpen, onClose, headerId, bodyId, setBodyMounted, setHeaderMounted, dialogRef, overlayRef, getDialogProps, getDialogContainerProps, index }; } function useAriaHidden(ref, shouldHide) { const currentElement = ref.current; useEffect(() => { if (!ref.current || !shouldHide) return void 0; return hideOthers(ref.current); }, [shouldHide, ref, currentElement]); } function useIds(idProp, ...prefixes) { const reactId = useId(); const id = idProp || reactId; return useMemo(() => { return prefixes.map((prefix) => `${prefix}-${id}`); }, [id, prefixes]); } export { useModal, useAriaHidden }; //# sourceMappingURL=chunk-TJ2Q5ITW.mjs.map