UNPKG

@flanksource/clicky-ui

Version:

Flanksource Clicky UI — React component library built on shadcn/ui with light/dark and density theming.

92 lines (91 loc) 2.97 kB
import { jsx, jsxs } from "react/jsx-runtime"; import { useRef, useEffect } from "react"; import { cn } from "../lib/utils.js"; import { Icon } from "../data/Icon.js"; const sizeClass = { sm: "max-w-sm max-h-[90vh]", md: "max-w-md max-h-[90vh]", lg: "max-w-2xl max-h-[90vh]", xl: "max-w-4xl max-h-[90vh]", full: "max-w-[95vw] max-h-[95vh]" }; function Modal({ open, onClose, title, size = "md", closeOnBackdrop = true, closeOnEsc = true, hideClose = false, className, headerSlot, footer, children }) { const dialogRef = useRef(null); useEffect(() => { if (!open || !closeOnEsc) return; const onKey = (e) => { if (e.key === "Escape") onClose(); }; document.addEventListener("keydown", onKey); return () => document.removeEventListener("keydown", onKey); }, [open, closeOnEsc, onClose]); useEffect(() => { var _a; if (!open) return; const prev = document.activeElement; (_a = dialogRef.current) == null ? void 0 : _a.focus(); return () => { var _a2; return (_a2 = prev == null ? void 0 : prev.focus) == null ? void 0 : _a2.call(prev); }; }, [open]); if (!open) return null; return /* @__PURE__ */ jsx( "div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/40", onClick: closeOnBackdrop ? onClose : void 0, role: "presentation", children: /* @__PURE__ */ jsxs( "div", { ref: dialogRef, tabIndex: -1, role: "dialog", "aria-modal": "true", "aria-label": typeof title === "string" ? title : void 0, className: cn( "relative bg-background border border-border rounded-lg shadow-xl w-full flex flex-col", sizeClass[size], className ), onClick: (e) => e.stopPropagation(), children: [ (title || headerSlot || !hideClose) && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-density-2 px-density-4 py-density-3 border-b border-border", children: [ title && /* @__PURE__ */ jsx("h2", { className: "text-sm font-semibold flex-1", children: title }), headerSlot, !hideClose && /* @__PURE__ */ jsx( "button", { type: "button", onClick: onClose, "aria-label": "Close", className: "text-muted-foreground hover:text-foreground", children: /* @__PURE__ */ jsx(Icon, { name: "codicon:close" }) } ) ] }), /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-auto px-density-4 py-density-3", children }), footer && /* @__PURE__ */ jsx("div", { className: "px-density-4 py-density-3 border-t border-border", children: footer }) ] } ) } ); } export { Modal }; //# sourceMappingURL=Modal.js.map