UNPKG

dynamic-modal

Version:

The dynamic-modal is a solution of creation different modals into project using a json configuration file

178 lines (177 loc) 9.62 kB
"use strict"; 'use client'; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Modal = void 0; const react_1 = __importStar(require("react")); const react_hook_form_1 = require("react-hook-form"); const portal_1 = require("./components/portal/portal"); const make_toggle_1 = __importDefault(require("./components/make-toggle/make-toggle")); const make_input_1 = __importDefault(require("./components/make-input/make-input")); const make_select_1 = __importDefault(require("./components/make-select/make-select")); const make_textarea_1 = __importDefault(require("./components/make-textarea/make-textarea")); const make_description_1 = __importDefault(require("./components/make-description/make-description")); const make_upload_1 = __importDefault(require("./components/make-upload/make-upload")); const make_button_1 = __importDefault(require("./components/make-button/make-button")); const component_state_1 = require("./context/component/component-state"); const Modal = ({ open, close, config }) => { const { ModalButtonAction, ModalButtonCancel } = (0, react_1.useContext)(component_state_1.ComponentStateContext); const [modalReady, setModalReady] = (0, react_1.useState)(undefined); const [defaultLoaded, setDefaultLoaded] = (0, react_1.useState)(false); const { control, handleSubmit, getValues, unregister, setValue, watch, trigger, reset, getFieldState, } = (0, react_hook_form_1.useForm)(); const formValueHandler = (element) => { if (['group', 'upload', 'text'].includes(element.elementType)) return; if (!element.defaultValue && element.renderIf) { unregister(element.name); return; } const defaultValue = element.defaultValue ?? ''; const parsedValue = defaultValue === 'true' ? true : defaultValue === 'false' ? false : defaultValue; setValue(element.name, parsedValue ?? ''); }; const autoLoadGroup = (groupFields) => { groupFields.forEach((element) => { formValueHandler(element); }); }; const autoLoadField = (modalFields) => { if (defaultLoaded) return; modalFields.forEach((element) => { if (element.elementType === 'group') { autoLoadGroup(element.groups); return; } formValueHandler(element); }); setDefaultLoaded(true); }; const getUseSubmit = (modalConfig) => { const useSubmit = modalConfig.useSubmit === undefined ? true : modalConfig.useSubmit === false ? false : true; return useSubmit; }; const getRender = ({ elementType, ...element }, index, isEndOfRender = false) => { if (isEndOfRender && modalReady) setTimeout(() => autoLoadField(modalReady.fields), 200); const props = { control, watch, setValue, unregister, }; return elementType === 'input' ? (react_1.default.createElement(make_input_1.default, { ...props, key: `modal-input-${index}`, element: element })) : elementType === 'select' ? (react_1.default.createElement(make_select_1.default, { ...props, key: `modal-select-${index}`, element: element })) : elementType === 'textarea' ? (react_1.default.createElement(make_textarea_1.default, { ...props, key: `modal-textarea-${index}`, element: element })) : elementType === 'toggle' ? (react_1.default.createElement(make_toggle_1.default, { ...props, key: `modal-toggle-${index}`, element: element })) : elementType === 'text' ? (react_1.default.createElement(make_description_1.default, { ...props, key: `modal-text-${index}`, element: element })) : elementType === 'upload' ? (react_1.default.createElement(make_upload_1.default, { ...props, key: `modal-upload-${index}`, element: element })) : elementType === 'button' ? (react_1.default.createElement(make_button_1.default, { ...props, key: `modal-button-${index}`, element: element })) : null; }; const closeHandler = () => { if (modalReady?.onClose) modalReady.onClose(); setTimeout(() => { setModalReady(undefined); setDefaultLoaded(false); reset(); close(); }, 200); }; const manualSubmit = async () => { const form = getValues(); const fields = Object.keys(form); await trigger(fields); const validations = fields.map((field) => { const { invalid } = getFieldState(field); return invalid; }); const result = validations.some((isInvalid) => isInvalid) ? undefined : form; if (!result) return; actionHandler({ ...(modalReady?.reservedData ?? {}), ...form }); }; const actionHandler = (data) => { modalReady?.out({ ...(modalReady?.reservedData ?? {}), ...data }); closeHandler(); }; (0, react_1.useEffect)(() => { if (open && !modalReady) setModalReady(config); }, [config, modalReady, open]); if (!modalReady) return null; return (react_1.default.createElement(portal_1.Portal, { closeTime: 200, portalOpen: open, portalTag: '#modal-portal' }, react_1.default.createElement("div", { className: "rounded bg-white relative w-auto h-auto min-h-[200px] min-w-[500px]", style: modalReady.style }, react_1.default.createElement("form", { className: "flex flex-col p-4 gap-4", autoComplete: "off", onSubmit: handleSubmit(actionHandler) }, react_1.default.createElement("h2", { className: "text-bold text-center border-b pb-4 font-semibold" }, modalReady.title), react_1.default.createElement("div", { className: "flex flex-col gap-4 py-4", style: { overflowY: modalReady.overFlowBody ? 'auto' : undefined, height: modalReady.overFlowBody, minHeight: modalReady.minHeightBody, } }, modalReady.fields.map((element, index) => { const isEndOfRender = index + 1 === modalReady.fields.length; if (element.elementType === 'group') { return (react_1.default.createElement("div", { key: `modal-group-${index}`, className: "flex flex-col w-full gap-2" }, element.title && (react_1.default.createElement("h3", { className: "font-bold border-b-2 pb-2 mb-2" }, element.title)), react_1.default.createElement("div", { key: `modal-group-${index}`, className: "flex gap-4 w-full", style: element.style }, element.groups .filter((sub) => [ 'input', 'select', 'toggle', 'multiselect', 'upload', 'button', 'autocomplete', ].includes(sub.elementType)) .map((sub, subIndex) => getRender(sub, index + subIndex, isEndOfRender))))); } else { return getRender(element, index, isEndOfRender); } })), react_1.default.createElement("div", { className: "flex gap-4 items-center justify-center border-t p-2", style: modalReady?.actions.containerStyle }, modalReady.actions.cancel && (react_1.default.createElement(ModalButtonCancel, { ...modalReady.actions.cancel, onClick: closeHandler })), getUseSubmit(modalReady) ? (react_1.default.createElement(ModalButtonAction, { ...modalReady.actions.action, type: "submit" })) : (react_1.default.createElement(ModalButtonAction, { ...modalReady.actions.action, onClick: manualSubmit, type: "button" }))))))); }; exports.Modal = Modal; exports.default = exports.Modal;