UNPKG

@easy-shadcn/react

Version:

Use shadcn/ui easy&enhance like component library

745 lines (735 loc) 24.2 kB
'use strict'; var chunkH2B2YIDE_js = require('./chunk-H2B2YIDE.js'); var chunkBTCOSRGV_js = require('./chunk-BTCOSRGV.js'); var chunkKRHWFZUK_js = require('./chunk-KRHWFZUK.js'); var chunkHKTXE4L5_js = require('./chunk-HKTXE4L5.js'); var React2 = require('react'); var utils = require('@easy-shadcn/utils'); var AlertDialogPrimitive2 = require('@radix-ui/react-alert-dialog'); var react = require('motion/react'); var jsxRuntime = require('react/jsx-runtime'); var DialogPrimitive = require('@radix-ui/react-dialog'); var reactIcons = require('@radix-ui/react-icons'); function _interopNamespace(e) { if (e && e.__esModule) return e; var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n.default = e; return Object.freeze(n); } var React2__namespace = /*#__PURE__*/_interopNamespace(React2); var AlertDialogPrimitive2__namespace = /*#__PURE__*/_interopNamespace(AlertDialogPrimitive2); var DialogPrimitive__namespace = /*#__PURE__*/_interopNamespace(DialogPrimitive); var AlertDialogAnimateContent = React2__namespace.forwardRef(({ className, children, open, onExitComplete, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { onExitComplete, children: open && /* @__PURE__ */ jsxRuntime.jsxs(AlertDialogPrimitive2__namespace.Portal, { forceMount: true, children: [ /* @__PURE__ */ jsxRuntime.jsx(AlertDialogPrimitive2__namespace.Overlay, { forceMount: true, asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx( react.motion.div, { className: utils.cn("fixed inset-0 z-50 bg-black/80"), exit: { opacity: 0 }, animate: { opacity: 1 }, initial: { opacity: 0 } } ) }), /* @__PURE__ */ jsxRuntime.jsx(AlertDialogPrimitive2__namespace.Content, { ref, forceMount: true, asChild: true, ...props, children: /* @__PURE__ */ jsxRuntime.jsx( react.motion.div, { className: utils.cn( "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg gap-4 border bg-background p-6 shadow-lg sm:rounded-lg", className ), initial: { opacity: 0, scale: 0.5, translateX: "-50%", translateY: "-50%" }, animate: { opacity: 1, scale: 1, translateX: "-50%", translateY: "-50%" }, exit: { opacity: 0, scale: 0.5, translateX: "-50%", translateY: "-50%" }, transition: { type: "spring", duration: 0.5, bounce: 0.3 }, children } ) }) ] }) })); AlertDialogAnimateContent.displayName = AlertDialogPrimitive2__namespace.Content.displayName; var AlertDialog = AlertDialogPrimitive2__namespace.Root; var AlertDialogTrigger = AlertDialogPrimitive2__namespace.Trigger; var AlertDialogPortal = AlertDialogPrimitive2__namespace.Portal; var AlertDialogOverlay = React2__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx( AlertDialogPrimitive2__namespace.Overlay, { className: utils.cn( "fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0", className ), ...props, ref } )); AlertDialogOverlay.displayName = AlertDialogPrimitive2__namespace.Overlay.displayName; var AlertDialogContent = React2__namespace.forwardRef(({ className, overlayProps, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(AlertDialogPortal, { children: [ /* @__PURE__ */ jsxRuntime.jsx(AlertDialogOverlay, { ...overlayProps }), /* @__PURE__ */ jsxRuntime.jsx( AlertDialogPrimitive2__namespace.Content, { ref, className: utils.cn( "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg", className ), ...props } ) ] })); AlertDialogContent.displayName = AlertDialogPrimitive2__namespace.Content.displayName; var AlertDialogHeader = ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx( "div", { className: utils.cn( "flex flex-col space-y-2 text-center sm:text-left", className ), ...props } ); AlertDialogHeader.displayName = "AlertDialogHeader"; var AlertDialogFooter = ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx( "div", { className: utils.cn( "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className ), ...props } ); AlertDialogFooter.displayName = "AlertDialogFooter"; var AlertDialogTitle = React2__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx( AlertDialogPrimitive2__namespace.Title, { ref, className: utils.cn("text-lg font-semibold", className), ...props } )); AlertDialogTitle.displayName = AlertDialogPrimitive2__namespace.Title.displayName; var AlertDialogDescription = React2__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx( AlertDialogPrimitive2__namespace.Description, { ref, className: utils.cn("text-sm text-muted-foreground", className), ...props } )); AlertDialogDescription.displayName = AlertDialogPrimitive2__namespace.Description.displayName; var AlertDialogAction = React2__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx( AlertDialogPrimitive2__namespace.Action, { ref, className: utils.cn(chunkHKTXE4L5_js.buttonVariants(), className), ...props } )); AlertDialogAction.displayName = AlertDialogPrimitive2__namespace.Action.displayName; var AlertDialogCancel = React2__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx( AlertDialogPrimitive2__namespace.Cancel, { ref, className: utils.cn( chunkHKTXE4L5_js.buttonVariants({ variant: "outline" }), "mt-2 sm:mt-0", className ), ...props } )); AlertDialogCancel.displayName = AlertDialogPrimitive2__namespace.Cancel.displayName; var AlertModal = ({ title, content, contentProps, children, cancelText, onCancel, cancelProps, confirmText, onConfirm, confirmProps, onOpenChange, afterClose, open, ...props }) => { const [innerOpen, setInnerOpen] = React2.useState(open || false); const [locale] = chunkBTCOSRGV_js.useLocale_default("AlertModal"); React2.useEffect(() => { setInnerOpen(open || false); }, [open]); const handleClose = () => { setInnerOpen(false); onOpenChange?.(false); }; return /* @__PURE__ */ jsxRuntime.jsxs( AlertDialog, { onOpenChange: (op) => { setInnerOpen(op); onOpenChange?.(op); }, open: innerOpen, ...props, children: [ children && /* @__PURE__ */ jsxRuntime.jsx(AlertDialogTrigger, { asChild: true, children }), /* @__PURE__ */ jsxRuntime.jsxs(AlertDialogAnimateContent, { open: innerOpen, onExitComplete: afterClose, ...contentProps, children: [ (title || content) && /* @__PURE__ */ jsxRuntime.jsxs(AlertDialogHeader, { className: "w-full overflow-auto whitespace-break-spaces", children: [ title && /* @__PURE__ */ jsxRuntime.jsx(AlertDialogTitle, { children: title }), content && /* @__PURE__ */ jsxRuntime.jsx(AlertDialogDescription, { children: content }) ] }), /* @__PURE__ */ jsxRuntime.jsxs(AlertDialogFooter, { children: [ /* @__PURE__ */ jsxRuntime.jsx( chunkKRHWFZUK_js.Button, { variant: "outline", onClick: async () => { await onCancel?.(); handleClose(); }, className: utils.cn("mt-2 sm:mt-0", cancelProps?.className), ...cancelProps, children: cancelText || locale.cancelText } ), /* @__PURE__ */ jsxRuntime.jsx( chunkKRHWFZUK_js.Button, { variant: "default", onClick: async () => { await onConfirm?.(); handleClose(); }, ...confirmProps, children: confirmText || locale.okText } ) ] }) ] }) ] } ); }; var DialogAnimateContent = React2__namespace.forwardRef(({ className, children, open, onExitComplete, ...props }, ref) => { return /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { onExitComplete, children: open && /* @__PURE__ */ jsxRuntime.jsxs(DialogPrimitive__namespace.Portal, { forceMount: true, children: [ /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Overlay, { forceMount: true, asChild: true, ...props, children: /* @__PURE__ */ jsxRuntime.jsx( react.motion.div, { className: utils.cn("fixed inset-0 z-50 bg-black/80"), exit: { opacity: 0 }, animate: { opacity: 1 }, initial: { opacity: 0 } } ) }), /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Content, { ref, forceMount: true, asChild: true, ...props, children: /* @__PURE__ */ jsxRuntime.jsxs( react.motion.div, { className: utils.cn( "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg gap-4 border bg-background p-6 shadow-lg sm:rounded-lg", className ), initial: { opacity: 0, scale: 0.5, translateX: "-50%", translateY: "-50%" }, animate: { opacity: 1, scale: 1, translateX: "-50%", translateY: "-50%" }, exit: { opacity: 0, scale: 0.5, translateX: "-50%", translateY: "-50%" }, transition: { type: "spring", duration: 0.5, bounce: 0.3 }, children: [ children, /* @__PURE__ */ jsxRuntime.jsxs(DialogPrimitive__namespace.Close, { tabIndex: -1, className: "absolute right-4 top-4 flex size-7 items-center justify-center rounded-sm text-muted-foreground opacity-70 ring-offset-background transition-opacity hover:bg-accent hover:opacity-100 disabled:pointer-events-none", children: [ /* @__PURE__ */ jsxRuntime.jsx(reactIcons.Cross2Icon, { className: "size-4" }), /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Close" }) ] }) ] } ) }) ] }) }); }); DialogAnimateContent.displayName = DialogPrimitive__namespace.Content.displayName; var Modal = ({ title, titleProps, description, descriptionProps, footer, footerProps, content, contentProps, children, open, afterClose, onOpenChange, ...restProps }) => { const [innerOpen, setInnerOpen] = React2.useState(open || false); React2.useEffect(() => { setInnerOpen(open || false); }, [open]); return /* @__PURE__ */ jsxRuntime.jsxs( chunkH2B2YIDE_js.Dialog, { open: innerOpen, onOpenChange: (op) => { setInnerOpen(op); onOpenChange?.(op); }, ...restProps, children: [ /* @__PURE__ */ jsxRuntime.jsx(chunkH2B2YIDE_js.DialogTrigger, { asChild: true, children }), /* @__PURE__ */ jsxRuntime.jsxs( DialogAnimateContent, { ...contentProps, open: innerOpen, className: utils.cn( "max-h-screen grid-rows-[auto_1fr_auto] gap-0 py-3 px-0", contentProps?.className ), onExitComplete: afterClose, children: [ /* @__PURE__ */ jsxRuntime.jsxs(chunkH2B2YIDE_js.DialogHeader, { className: "px-6 py-3", children: [ title && /* @__PURE__ */ jsxRuntime.jsx(chunkH2B2YIDE_js.DialogTitle, { ...titleProps, children: title }), description && /* @__PURE__ */ jsxRuntime.jsx(chunkH2B2YIDE_js.DialogDescription, { ...descriptionProps, children: description }) ] }), /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-auto px-6 py-3", children: content }), footer && /* @__PURE__ */ jsxRuntime.jsx( chunkH2B2YIDE_js.DialogFooter, { ...footerProps, className: utils.cn("px-6 py-3 space-x-2", footerProps?.className), children: footer } ) ] } ) ] } ); }; // src/modal/modal-helper/symbol.ts var symModalId = Symbol("ModalHelperId"); // src/modal/modal-helper/constants.ts var MODAL_REGISTRY = {}; var ALREADY_MOUNTED = {}; var uidSeed = 0; var getUid = () => `_nice_modal_${uidSeed++}`; var modalCallbacks = {}; var hideModalCallbacks = {}; function getModalId(modal) { if (typeof modal === "string") return modal; if (!modal[symModalId]) { modal[symModalId] = getUid(); } return modal[symModalId]; } var reducer = (state = initialState, action) => { switch (action.type) { case "modal-helper/show" /* showModal */: { const { modalId, args } = action.payload; return { ...state, [modalId]: { ...state[modalId], id: modalId, args, // If modal is not mounted, mount it first then make it visible. // There is logic inside HOC wrapper to make it visible after its first mount. // This mechanism ensures the entering transition. visible: !!ALREADY_MOUNTED[modalId], delayVisible: !ALREADY_MOUNTED[modalId] } }; } case "modal-helper/hide" /* hideModal */: { const { modalId } = action.payload; if (!state[modalId]) return state; return { ...state, [modalId]: { ...state[modalId], visible: false } }; } case "modal-helper/remove" /* removeModal */: { const { modalId } = action.payload; const newState = { ...state }; delete newState[modalId]; return newState; } case "modal-helper/set-flags" /* setModalFlags */: { const { modalId, flags } = action.payload; return { ...state, [modalId]: { ...state[modalId], ...flags } }; } default: return state; } }; var reducerDispatch = () => { throw new Error("No dispatch method detected, did you embed your app with ModalHelper.Provider?"); }; var reducerActions = { // action creator to show a modal showModal: (modalId, args) => { reducerDispatch({ type: "modal-helper/show" /* showModal */, payload: { modalId, args } }); }, // action creator to set flags of a modal setModalFlags: (modalId, flags) => { reducerDispatch({ type: "modal-helper/set-flags" /* setModalFlags */, payload: { modalId, flags } }); }, // action creator to hide a modal hideModal: (modalId) => { reducerDispatch({ type: "modal-helper/hide" /* hideModal */, payload: { modalId } }); }, // action creator to remove a modal removeModal: (modalId) => { reducerDispatch({ type: "modal-helper/remove" /* removeModal */, payload: { modalId } }); } }; var initialState = {}; var ModalHelperContext = React2.createContext(initialState); var ModalHelperIdContext = React2.createContext(null); var ModalHelperPlaceholder = () => { const modals = React2.useContext(ModalHelperContext); const visibleModalIds = Object.keys(modals).filter((id) => !!modals[id]); visibleModalIds.forEach((id) => { if (!MODAL_REGISTRY[id] && !ALREADY_MOUNTED[id]) { console.warn( `No modal found for id: ${id}. Please check the id or if it is registered or declared via JSX.` ); return; } }); const toRender = visibleModalIds.filter((id) => MODAL_REGISTRY[id]).map((id) => ({ id, ...MODAL_REGISTRY[id] })); return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: toRender.map((t) => /* @__PURE__ */ jsxRuntime.jsx(t.comp, { id: t.id, ...t.props }, t.id)) }); }; var Provider = ({ children }) => { const [modals, dispatch] = React2.useReducer(reducer, initialState); reducerDispatch = dispatch; return /* @__PURE__ */ jsxRuntime.jsxs(ModalHelperContext.Provider, { value: modals, children: [ children, /* @__PURE__ */ jsxRuntime.jsx(ModalHelperPlaceholder, {}) ] }); }; function ModalHolder({ modal, handler, ...restProps }) { const mid = React2.useMemo(() => getUid(), []); const ModalComp = typeof modal === "string" ? MODAL_REGISTRY[modal]?.comp : modal; if (!ModalComp && typeof modal === "string") { throw new Error(`No modal found for id: ${modal} in ModalHelper.ModalHolder.`); } handler.show = React2.useCallback((args) => show(mid, args), [mid]); handler.hide = React2.useCallback(() => hide(mid), [mid]); return /* @__PURE__ */ jsxRuntime.jsx(ModalComp, { id: mid, ...restProps }); } function useModal(modal, args) { const modals = React2.useContext(ModalHelperContext); const contextModalId = React2.useContext(ModalHelperIdContext); let modalId = null; const isUseComponent = modal && typeof modal !== "string"; if (!modal) { modalId = contextModalId; } else { modalId = getModalId(modal); } if (!modalId) throw new Error("No modal id found in ModalHelper.useModal."); const mid = modalId; React2.useEffect(() => { if (isUseComponent && !MODAL_REGISTRY[mid]) { register(mid, modal, args); } }, [isUseComponent, mid, modal, args]); const modalInfo = modals[mid]; const showCallback = React2.useCallback((args2) => show(mid, args2), [mid]); const hideCallback = React2.useCallback(() => hide(mid), [mid]); const removeCallback = React2.useCallback(() => remove(mid), [mid]); const resolveCallback = React2.useCallback( (args2) => { modalCallbacks[mid]?.resolve(args2); delete modalCallbacks[mid]; }, [mid] ); const rejectCallback = React2.useCallback( (args2) => { modalCallbacks[mid]?.reject(args2); delete modalCallbacks[mid]; }, [mid] ); const resolveHide = React2.useCallback( (args2) => { hideModalCallbacks[mid]?.resolve(args2); delete hideModalCallbacks[mid]; }, [mid] ); return React2.useMemo( () => ({ id: mid, args: modalInfo?.args, visible: !!modalInfo?.visible, keepMounted: !!modalInfo?.keepMounted, show: showCallback, hide: hideCallback, remove: removeCallback, resolve: resolveCallback, reject: rejectCallback, resolveHide, modalProps: { open: modalInfo?.visible, onOpenChange: (open) => { if (open) { void showCallback(); } else { void hideCallback(); } }, afterClose: () => { resolveHide(); if (!modalInfo?.keepMounted) removeCallback(); } } }), [ mid, modalInfo?.args, modalInfo?.visible, modalInfo?.keepMounted, showCallback, hideCallback, removeCallback, resolveCallback, rejectCallback, resolveHide ] ); } function useModalHolder(modal) { const handler = React2.useMemo(() => ({}), []); const ModalHolderCallback = React2.useCallback( (props) => /* @__PURE__ */ jsxRuntime.jsx(ModalHolder, { modal, ...props, handler }), [modal, handler] ); return [handler, ModalHolderCallback]; } function show(modal, args) { const modalId = getModalId(modal); if (typeof modal !== "string" && !MODAL_REGISTRY[modalId]) { register(modalId, modal); } reducerActions.showModal(modalId, args); if (!modalCallbacks[modalId]) { let theResolve; let theReject; const promise = new Promise((resolve, reject) => { theResolve = resolve; theReject = reject; }); modalCallbacks[modalId] = { resolve: theResolve, reject: theReject, promise }; } return modalCallbacks[modalId].promise; } function hide(modal) { const modalId = getModalId(modal); reducerActions.hideModal(modalId); delete modalCallbacks[modalId]; if (!hideModalCallbacks[modalId]) { let theResolve; let theReject; const promise = new Promise((resolve, reject) => { theResolve = resolve; theReject = reject; }); hideModalCallbacks[modalId] = { resolve: theResolve, reject: theReject, promise }; } return hideModalCallbacks[modalId].promise; } var remove = (modal) => { const modalId = getModalId(modal); reducerActions.removeModal(modalId); delete modalCallbacks[modalId]; delete hideModalCallbacks[modalId]; }; var create = (Comp) => { const HocComp = ({ defaultVisible, keepMounted, id, ...props }) => { const { args, show: show2 } = useModal(id); const modals = React2.useContext(ModalHelperContext); const shouldMount = !!modals[id]; React2.useEffect(() => { if (defaultVisible) { void show2(); } ALREADY_MOUNTED[id] = true; return () => { delete ALREADY_MOUNTED[id]; }; }, [id, show2, defaultVisible]); React2.useEffect(() => { if (keepMounted) { reducerActions.setModalFlags(id, { keepMounted: true }); } }, [id, keepMounted]); const delayVisible = modals[id]?.delayVisible; React2.useEffect(() => { if (delayVisible) { void show2(args); } }, [delayVisible, args, show2]); if (!shouldMount) return null; return /* @__PURE__ */ jsxRuntime.jsx(ModalHelperIdContext.Provider, { value: id, children: /* @__PURE__ */ jsxRuntime.jsx(Comp, { ...props, ...args }) }); }; return HocComp; }; var register = (id, comp, props) => { if (!MODAL_REGISTRY[id]) { MODAL_REGISTRY[id] = { comp, props }; } else { MODAL_REGISTRY[id].props = props; } }; // src/modal/modal-helper/index.tsx var modalProps = (modal) => { return { open: modal.visible, onOpenChange: (open) => { if (open) { void modal.show(); } else { void modal.hide(); } }, afterClose: () => { modal.resolveHide(); if (!modal.keepMounted) modal.remove(); } }; }; var ModalHelper = { Provider, ModalHelperContext, create, register, show, hide, remove, useModal, useModalHolder, reducer, modalProps }; var modal_helper_default = ModalHelper; var alert = (props) => { const AlertModalHelper = modal_helper_default.create(() => { const { modalProps: modalProps2, resolve } = modal_helper_default.useModal(); return /* @__PURE__ */ jsxRuntime.jsx( AlertModal, { ...props, ...modalProps2, cancelProps: { className: "hidden" }, onConfirm: async () => { await props.onConfirm?.(); resolve(); } } ); }); return modal_helper_default.show(AlertModalHelper); }; var confirm = (props) => { const AlertModalHelper = modal_helper_default.create(() => { const { modalProps: modalProps2, resolve, reject } = modal_helper_default.useModal(); return /* @__PURE__ */ jsxRuntime.jsx( AlertModal, { ...props, ...modalProps2, onConfirm: async () => { await props.onConfirm?.(); resolve(); }, onCancel: async () => { await props.onCancel?.(); reject(); } } ); }); return modal_helper_default.show(AlertModalHelper); }; var alert_modal_helper_default = { alert, confirm }; // src/modal/index.tsx var AlertModal2 = Object.assign( AlertModal, alert_modal_helper_default ); var Modal2 = Object.assign( Modal, modal_helper_default ); exports.AlertModal = AlertModal2; exports.Modal = Modal2;