UNPKG

nextuiq

Version:

NextUIQ is a modern, lightweight, and developer-friendly UI component library for React and Next.js. Built with TypeScript and Tailwind CSS, it offers customizable, accessible, and performance-optimized components with built-in dark mode, theme customizat

126 lines (123 loc) 4.13 kB
import { j as jsxRuntimeExports } from './index46.mjs'; import { useRef, useEffect } from 'react'; import { FiX } from './index47.mjs'; import { cn } from './index38.mjs'; const Modal = ({ isOpen, onClose, children, className = "", showCloseButton = true, isFullscreen = false, size = "md", position = "center", title, description, initialFocus }) => { const modalRef = useRef(null); const previousActiveElement = useRef(null); useEffect(() => { if (isOpen) { previousActiveElement.current = document.activeElement; if (initialFocus?.current) { initialFocus.current.focus(); } else { modalRef.current?.focus(); } document.addEventListener("keydown", handleEscape); document.body.style.overflow = "hidden"; } else { document.body.style.overflow = "unset"; previousActiveElement.current?.focus(); } return () => { document.removeEventListener("keydown", handleEscape); document.body.style.overflow = "unset"; }; }, [isOpen, initialFocus]); const handleEscape = (event) => { if (event.key === "Escape") { onClose(); } }; if (!isOpen) return null; const sizeClasses = { sm: "max-w-sm", md: "max-w-md", lg: "max-w-lg", xl: "max-w-xl", full: "max-w-full" }; const positionClasses = { center: "items-center", top: "items-start mt-16" }; return /* @__PURE__ */ jsxRuntimeExports.jsxs( "div", { className: cn( "fixed inset-0 flex justify-center", positionClasses[position], "overflow-y-auto z-50", "animate-in fade-in duration-200" ), role: "presentation", children: [ /* @__PURE__ */ jsxRuntimeExports.jsx( "div", { className: "fixed inset-0 bg-[oklch(var(--theme-background)/0.8)] backdrop-blur-sm transition-opacity", onClick: onClose, "aria-hidden": "true" } ), /* @__PURE__ */ jsxRuntimeExports.jsxs( "div", { ref: modalRef, className: cn( "relative w-full m-4", !isFullscreen && [ sizeClasses[size], "rounded-lg bg-[oklch(var(--theme-background))]", "shadow-lg", "border border-[oklch(var(--theme-border))]" ], isFullscreen && "w-full h-full bg-[oklch(var(--theme-background))]", "animate-in zoom-in-95 duration-200", className ), onClick: (e) => e.stopPropagation(), role: "dialog", "aria-modal": "true", "aria-labelledby": title ? "modal-title" : void 0, "aria-describedby": description ? "modal-description" : void 0, tabIndex: -1, children: [ showCloseButton && /* @__PURE__ */ jsxRuntimeExports.jsx( "button", { onClick: onClose, className: cn( "absolute right-4 top-4 z-10 rounded-sm p-2", "text-[oklch(var(--theme-muted-foreground))] hover:text-[oklch(var(--theme-foreground))]", "transition-colors hover:bg-[oklch(var(--theme-muted))]" ), "aria-label": "Close modal", children: /* @__PURE__ */ jsxRuntimeExports.jsx(FiX, { className: "h-5 w-5", "aria-hidden": "true" }) } ), /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-6", children: [ title && /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { id: "modal-title", className: "text-xl font-semibold mb-2 text-[oklch(var(--theme-foreground))]", children: title }), description && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { id: "modal-description", className: "text-[oklch(var(--theme-muted-foreground))] mb-4", children: description }), children ] }) ] } ) ] } ); }; export { Modal };