import { popoverTransitionClasses } from "@thorium/ui/Dropdown"; import { cn } from "@thorium/utils/cn"; import * as React from "react"; import { Dialog, Heading, Modal, ModalOverlay } from "react-aria-components"; import Button from "./Button"; interface DialogI { header: React.ReactNode; body?: string; defaultValue?: string; type: "alert" | "confirm" | "prompt"; inputProps?: React.DetailedHTMLProps< React.InputHTMLAttributes, HTMLInputElement >; } const DialogContext = React.createContext< ({ header, body, defaultValue, type, inputProps }: DialogI) => Promise >(async () => false); export const AlertDialog = ({ children }: { children: React.ReactNode }) => { const [isOpen, setIsOpen] = React.useState(false); const [header, setHeader] = React.useState(""); const [body, setBody] = React.useState(""); const [type, setType] = React.useState<"alert" | "confirm" | "prompt">("alert"); const [input, setInput] = React.useState(""); const [inputProps, setInputProps] = React.useState, HTMLInputElement > | null>(null); const cancelRef = React.useRef(null); const resolveRef = React.useRef<(tf: boolean | string) => void>(undefined); const openConfirm = React.useCallback( ({ header, body, defaultValue, type, inputProps }: DialogI) => { if (isOpen) return Promise.resolve(false); if (resolveRef.current) { resolveRef.current(false); } setIsOpen(true); setHeader(header); setBody(body || ""); setType(type); setInput(defaultValue || ""); setInputProps(inputProps || null); return new Promise((resolve) => { resolveRef.current = resolve; }); }, [isOpen], ); // const [inputEl, setInputEl] = React.useState(); // const inputRef = React.useCallback(node => { // if (node !== null) { // setInputEl(node); // } // }, []); // React.useEffect(() => { // if (isOpen && type === "prompt" && inputEl) { // inputEl.setSelectionRange(0, inputEl.value.length); // } // }, [inputEl, isOpen, type]); React.useEffect(() => { function handleReturn(e: KeyboardEvent) { if (e.key === "Enter") { e.preventDefault(); if (type === "confirm") { resolveRef.current?.(true); } else if (type === "prompt") { resolveRef.current?.(input); } else { resolveRef.current?.(false); } setIsOpen(false); } } if (isOpen) { document.addEventListener("keydown", handleReturn); return () => document.removeEventListener("keydown", handleReturn); } }, [isOpen, input, type]); const inputEl = React.useRef(null); const okayButton = React.useRef(null); React.useEffect(() => { const ref = inputEl.current; ref?.focus(); ref?.select(); }, []); return ( {children} setIsOpen(isOpen)} className={cn( "fixed inset-0 z-10 overflow-y-auto bg-black/40 flex min-h-full w-full items-center justify-center p-4 backdrop-blur", "transition-all duration-200 data-[entering]:opacity-0 data-[exiting]:opacity-0", )} > {({ close }) => ( <> {header} {type === "prompt" ? (
) : (

{body}

)}
{type !== "alert" && ( )}
)}
// // {children} // // close()} // className="theme-container fixed z-10 inset-0 overflow-y-auto" // > //
// // // // //
// {header} // //
//
//
//
); }; export function useConfirm() { const dialog = React.useContext(DialogContext); return React.useCallback( (input: string | { header: string; body?: string }, bodyInput?: string) => { if (typeof input === "string") { return dialog({ header: input, body: bodyInput, type: "confirm" }); } const { header, body } = input; return dialog({ header, body, type: "confirm" }); }, [dialog], ); } export function usePrompt() { const dialog = React.useContext(DialogContext); return ( input: | string | { header: React.ReactNode; body?: string; defaultValue?: string; inputProps?: React.DetailedHTMLProps< React.InputHTMLAttributes, HTMLInputElement >; }, ) => { if (typeof input === "string") { return dialog({ header: input, type: "prompt" }) as Promise; } const { header, body, defaultValue, inputProps } = input; return dialog({ header, body, defaultValue, type: "prompt", inputProps, }) as Promise; }; } export function useAlert() { const dialog = React.useContext(DialogContext); return ({ header, body }: { header: string; body?: string }): Promise => dialog({ header, body, type: "alert" }) as Promise; }