web/app/components/ui/dialog.tsxblame
View source
4dfd09b1"use client";
4dfd09b2
4dfd09b3import { useRef, useEffect } from "react";
4dfd09b4
4dfd09b5export interface DialogProps {
4dfd09b6 open: boolean;
4dfd09b7 onClose: () => void;
4dfd09b8 title: string;
4dfd09b9 children: React.ReactNode;
4dfd09b10 actions?: React.ReactNode;
4dfd09b11 className?: string;
4dfd09b12}
4dfd09b13
4dfd09b14export function Dialog({
4dfd09b15 open,
4dfd09b16 onClose,
4dfd09b17 title,
4dfd09b18 children,
4dfd09b19 actions,
4dfd09b20 className = "",
4dfd09b21}: DialogProps) {
4dfd09b22 const ref = useRef<HTMLDialogElement>(null);
4dfd09b23
4dfd09b24 useEffect(() => {
4dfd09b25 const dialog = ref.current;
4dfd09b26 if (!dialog) return;
4dfd09b27
4dfd09b28 if (open && !dialog.open) {
4dfd09b29 dialog.showModal();
4dfd09b30 } else if (!open && dialog.open) {
4dfd09b31 dialog.close();
4dfd09b32 }
4dfd09b33 }, [open]);
4dfd09b34
4dfd09b35 return (
4dfd09b36 <dialog
4dfd09b37 ref={ref}
4dfd09b38 onClose={onClose}
4dfd09b39 onClick={(e) => {
4dfd09b40 if (e.target === ref.current) onClose();
4dfd09b41 }}
ab61b9d42 className={className}
4dfd09b43 style={{
4dfd09b44 backgroundColor: "var(--bg-card)",
4dfd09b45 border: "1px solid var(--border-subtle)",
4dfd09b46 color: "var(--text-primary)",
ab61b9d47 width: "100%",
ab61b9d48 maxWidth: "28rem",
ab61b9d49 margin: "auto",
ab61b9d50 boxShadow: "0 8px 30px rgba(0, 0, 0, 0.12), 0 2px 8px rgba(0, 0, 0, 0.06)",
ab61b9d51 overflow: "hidden",
4dfd09b52 }}
4dfd09b53 >
ab61b9d54 <div
ab61b9d55 className="px-6 pt-6 pb-4"
ab61b9d56 style={{ borderBottom: "1px solid var(--border-subtle)" }}
ab61b9d57 >
ab61b9d58 <h2 className="text-lg">{title}</h2>
ab61b9d59 </div>
ab61b9d60 <div className="px-6 py-5">{children}</div>
4dfd09b61 {actions && (
ab61b9d62 <div
ab61b9d63 className="flex gap-3 px-6 py-4 justify-end"
ab61b9d64 style={{
ab61b9d65 borderTop: "1px solid var(--border-subtle)",
ab61b9d66 backgroundColor: "var(--bg-inset)",
ab61b9d67 }}
ab61b9d68 >
ab61b9d69 {actions}
ab61b9d70 </div>
4dfd09b71 )}
4dfd09b72 </dialog>
4dfd09b73 );
4dfd09b74}