UNPKG

@mantine/modals

Version:

Modals manager based on Mantine components

200 lines (199 loc) 4.89 kB
"use client"; import { ModalsContext } from "./context.mjs"; import { ConfirmModal } from "./ConfirmModal.mjs"; import { useModalsEvents } from "./events.mjs"; import { handleCloseModal, modalsReducer } from "./reducer.mjs"; import { useCallback, useReducer, useRef } from "react"; import { Modal, getDefaultZIndex } from "@mantine/core"; import { randomId } from "@mantine/hooks"; import { jsx, jsxs } from "react/jsx-runtime"; //#region packages/@mantine/modals/src/ModalsProvider.tsx function separateConfirmModalProps(props) { if (!props) return { confirmProps: {}, modalProps: {} }; const { id, children, onCancel, onConfirm, closeOnConfirm, closeOnCancel, cancelProps, confirmProps, groupProps, labels, ...others } = props; return { confirmProps: { id, children, onCancel, onConfirm, closeOnConfirm, closeOnCancel, cancelProps, confirmProps, groupProps, labels }, modalProps: { id, ...others } }; } function ModalsProvider({ children, modalProps, labels, modals }) { const [state, dispatch] = useReducer(modalsReducer, { modals: [], current: null }); const stateRef = useRef(state); stateRef.current = state; const closingRef = useRef(false); const closeAll = useCallback((canceled) => { if (!closingRef.current) { closingRef.current = true; stateRef.current.modals.concat().reverse().forEach((modal) => { handleCloseModal(modal, canceled); }); closingRef.current = false; } dispatch({ type: "CLOSE_ALL", canceled }); }, [stateRef, dispatch]); const openModal = useCallback(({ modalId, ...props }) => { const id = modalId || randomId(); dispatch({ type: "OPEN", modal: { id, type: "content", props } }); return id; }, [dispatch]); const openConfirmModal = useCallback(({ modalId, ...props }) => { const id = modalId || randomId(); dispatch({ type: "OPEN", modal: { id, type: "confirm", props } }); return id; }, [dispatch]); const openContextModal = useCallback((modal, { modalId, ...props }) => { const id = modalId || randomId(); dispatch({ type: "OPEN", modal: { id, type: "context", props, ctx: modal } }); return id; }, [dispatch]); const closeModal = useCallback((id, canceled) => { if (!closingRef.current) { const modal = stateRef.current.modals.find((m) => m.id === id); if (modal) { closingRef.current = true; handleCloseModal(modal, canceled); closingRef.current = false; } } dispatch({ type: "CLOSE", modalId: id, canceled }); }, [stateRef, dispatch]); const updateModal = useCallback(({ modalId, ...newProps }) => { dispatch({ type: "UPDATE", modalId, newProps }); }, [dispatch]); const updateContextModal = useCallback(({ modalId, ...newProps }) => { dispatch({ type: "UPDATE", modalId, newProps }); }, [dispatch]); useModalsEvents({ openModal, openConfirmModal, openContextModal: ({ modal, ...payload }) => openContextModal(modal, payload), closeModal, closeContextModal: closeModal, closeAllModals: closeAll, updateModal, updateContextModal }); const ctx = { modalProps: modalProps || {}, modals: state.modals, openModal, openConfirmModal, openContextModal, closeModal, closeContextModal: closeModal, closeAll, updateModal, updateContextModal }; const getCurrentModal = () => { const currentModal = stateRef.current.current; switch (currentModal?.type) { case "context": { const { innerProps, ...rest } = currentModal.props; const ContextModal = modals[currentModal.ctx]; return { modalProps: rest, content: /* @__PURE__ */ jsx(ContextModal, { innerProps, context: ctx, id: currentModal.id }) }; } case "confirm": { const { modalProps: separatedModalProps, confirmProps: separatedConfirmProps } = separateConfirmModalProps(currentModal.props); return { modalProps: separatedModalProps, content: /* @__PURE__ */ jsx(ConfirmModal, { ...separatedConfirmProps, id: currentModal.id, labels: currentModal.props.labels || labels }) }; } case "content": { const { children: currentModalChildren, ...rest } = currentModal.props; return { modalProps: rest, content: currentModalChildren }; } default: return { modalProps: {}, content: null }; } }; const { modalProps: currentModalProps, content } = getCurrentModal(); return /* @__PURE__ */ jsxs(ModalsContext, { value: ctx, children: [/* @__PURE__ */ jsx(Modal, { zIndex: getDefaultZIndex("modal") + 1, ...modalProps, ...currentModalProps, opened: state.modals.length > 0, onClose: () => closeModal(state.current?.id), children: content }), children] }); } //#endregion export { ModalsProvider }; //# sourceMappingURL=ModalsProvider.mjs.map