UNPKG

mui-modal-provider

Version:

[![codecov](https://codecov.io/gh/Quernest/mui-modal-provider/branch/master/graph/badge.svg?token=AL2WK480NF)](https://codecov.io/gh/Quernest/mui-modal-provider) [![package version](https://img.shields.io/npm/v/mui-modal-provider.svg?style=flat-square)](h

355 lines (344 loc) 10.3 kB
import React, { createContext, Suspense, Fragment, useContext, useRef, useEffect, useCallback } from 'react'; function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; } var modalContextFallback = { state: {}, updateModal: function updateModal() { return undefined; }, hideModal: function hideModal() { return undefined; }, destroyModal: function destroyModal() { return undefined; }, destroyModalsByRootId: function destroyModalsByRootId() { return undefined; }, showModal: function showModal() { return { id: 'id', hide: function hide() { return undefined; }, destroy: function destroy() { return undefined; }, update: function update() { return undefined; } }; } }; var ModalContext = /*#__PURE__*/createContext(undefined); var Types; (function (Types) { Types["SHOW"] = "SHOW"; Types["HIDE"] = "HIDE"; Types["UPDATE"] = "UPDATE"; Types["DESTROY"] = "DESTROY"; Types["DESTROY_BY_ROOT_ID"] = "DESTROY_BY_ROOT_ID"; Types["UNKNOWN"] = "UNKNOWN"; })(Types || (Types = {})); var initialState = {}; function reducer(state, action) { switch (action.type) { case Types.SHOW: { var _extends2; var _action$payload = action.payload, id = _action$payload.id, component = _action$payload.component, props = _action$payload.props, options = _action$payload.options; return _extends({}, state, (_extends2 = {}, _extends2[id] = { component: component, props: _extends({}, props, { open: true }), options: options }, _extends2)); } case Types.HIDE: { var _extends3; var _id = action.payload.id; if (!state[_id]) { return state; } return _extends({}, state, (_extends3 = {}, _extends3[_id] = _extends({}, state[_id], { props: _extends({}, state[_id].props, { open: false }) }), _extends3)); } case Types.UPDATE: { var _extends4; var _action$payload2 = action.payload, _id2 = _action$payload2.id, _props = _action$payload2.props; if (!state[_id2]) { return state; } return _extends({}, state, (_extends4 = {}, _extends4[_id2] = _extends({}, state[_id2], { props: _extends({}, state[_id2].props, _props) }), _extends4)); } case Types.DESTROY: { var _id3 = action.payload.id; var newState = _extends({}, state); delete newState[_id3]; return newState; } case Types.DESTROY_BY_ROOT_ID: { var rootId = action.payload.rootId; return Object.keys(state).filter(function (key) { return key.split('.')[0] !== rootId; }).reduce(function (acc, key) { var _extends5; return _extends({}, acc, (_extends5 = {}, _extends5[key] = state[key], _extends5)); }, {}); } default: throw new Error('Unexpected action'); } } var MISSED_MODAL_ID_ERROR_MESSAGE = '[ERROR]: Modal ID is missing'; var MISSED_MODAL_ROOT_ID_ERROR_MESSAGE = '[ERROR]: Modal root ID is missing'; var uid = function uid(len) { if (len === void 0) { len = 8; } var buf = []; var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; var charlen = chars.length; for (var i = 0; i < len; i++) { buf[i] = chars.charAt(Math.floor(Math.random() * charlen)); } return buf.join(''); }; var _excluded = ["open"]; function ModalProvider(_ref) { var children = _ref.children, _ref$legacy = _ref.legacy, legacy = _ref$legacy === void 0 ? false : _ref$legacy, _ref$suspense = _ref.suspense, suspense = _ref$suspense === void 0 ? true : _ref$suspense, _ref$fallback = _ref.fallback, fallback = _ref$fallback === void 0 ? null : _ref$fallback; var _React$useReducer = React.useReducer(reducer, initialState), state = _React$useReducer[0], dispatch = _React$useReducer[1]; var _update = React.useCallback(function (id, _ref2) { var props = _objectWithoutPropertiesLoose(_ref2, _excluded); if (!id) { console.error(MISSED_MODAL_ID_ERROR_MESSAGE); return; } dispatch({ type: Types.UPDATE, payload: { id: id, props: props } }); }, [dispatch]); var _hide = React.useCallback(function (id) { if (!id) { console.error(MISSED_MODAL_ID_ERROR_MESSAGE); return; } dispatch({ type: Types.HIDE, payload: { id: id } }); }, [dispatch]); var _destroy = React.useCallback(function (id) { if (!id) { console.error(MISSED_MODAL_ID_ERROR_MESSAGE); return; } dispatch({ type: Types.DESTROY, payload: { id: id } }); }, [dispatch]); var destroyByRootId = React.useCallback(function (rootId) { if (!rootId) { console.error(MISSED_MODAL_ROOT_ID_ERROR_MESSAGE); return; } dispatch({ type: Types.DESTROY_BY_ROOT_ID, payload: { rootId: rootId } }); }, [dispatch]); var show = React.useCallback(function (component, props, options) { var id = uid(8); if (options && options.rootId) { id = options.rootId + "." + id; } dispatch({ type: Types.SHOW, payload: { id: id, component: component, props: props, options: options } }); return { id: id, hide: function hide() { return _hide(id); }, destroy: function destroy() { return _destroy(id); }, update: function update(newProps) { return _update(id, newProps); } }; }, [dispatch, _hide, _destroy, _update]); var renderState = function renderState() { return Object.keys(state).map(function (id) { var _state$id = state[id], Component = _state$id.component, props = _state$id.props, options = _state$id.options; var handleClose = function handleClose() { if (options && options.hideOnClose) { _hide(id); } if (options && options.destroyOnClose && options.hideOnClose) { _destroy(id); } if (props && props.onClose) { props.onClose.apply(props, arguments); } }; var handleExited = function handleExited() { var _props$TransitionProp; if (props != null && props.onExited) { props.onExited.apply(props, arguments); } if (props != null && (_props$TransitionProp = props.TransitionProps) != null && _props$TransitionProp.onExited) { var _props$TransitionProp2; (_props$TransitionProp2 = props.TransitionProps).onExited.apply(_props$TransitionProp2, arguments); } _destroy(id); }; var extraProps = {}; if (!legacy) { extraProps = { TransitionProps: _extends({}, props == null ? void 0 : props.TransitionProps, { onExited: handleExited }) }; } else { extraProps = { onExited: handleExited }; } return React.createElement(Component, Object.assign({}, props, { key: id, onClose: handleClose }, options && !options.destroyOnClose && extraProps)); }); }; var SuspenseWrapper = suspense ? Suspense : Fragment; return React.createElement(ModalContext.Provider, { value: { state: state, updateModal: _update, hideModal: _hide, destroyModal: _destroy, showModal: show, destroyModalsByRootId: destroyByRootId } }, children, React.createElement(SuspenseWrapper, Object.assign({}, suspense && { fallback: fallback }), renderState())); } var config = { /** * If set to `true` you will get an error when trying to access * a context without the `ModalProvider` declared above. */ enforceProvider: false }; function setModalConfig(newConfig) { Object.assign(config, newConfig); } function getModalConfig() { return config; } function useModalContext() { var context = useContext(ModalContext); var _getModalConfig = getModalConfig(), enforceProvider = _getModalConfig.enforceProvider; if (enforceProvider && context === undefined) { throw new Error('useModalContext must be used within a ModalProvider'); } return context || modalContextFallback; } var _excluded$1 = ["showModal", "destroyModalsByRootId"]; var defaultOptions = { disableAutoDestroy: false }; function useModal(options) { if (options === void 0) { options = defaultOptions; } var _defaultOptions$optio = _extends({}, defaultOptions, options), disableAutoDestroy = _defaultOptions$optio.disableAutoDestroy; var _useModalContext = useModalContext(), showModal = _useModalContext.showModal, destroyModalsByRootId = _useModalContext.destroyModalsByRootId, otherModalContextProps = _objectWithoutPropertiesLoose(_useModalContext, _excluded$1); var rootId = useRef(uid(6)); useEffect(function () { return function () { if (!disableAutoDestroy && destroyModalsByRootId) { destroyModalsByRootId(rootId.current); } }; }, [disableAutoDestroy, destroyModalsByRootId]); return _extends({ showModal: useCallback(function (component, props, options) { return showModal(component, props, _extends({ rootId: rootId.current, hideOnClose: true }, options)); }, [showModal]), destroyModalsByRootId: destroyModalsByRootId }, otherModalContextProps); } export default ModalProvider; export { ModalProvider, getModalConfig, setModalConfig, useModal }; //# sourceMappingURL=mui-modal-provider.esm.js.map