webview-ui/src/components/Dialog.tsx (36 lines of code) (raw):

import { useEffect, useRef } from "react"; interface DialogProps { isShown: boolean; onCancel: () => void; } export function Dialog(props: React.PropsWithChildren<DialogProps>) { const dialogRef = useRef<HTMLDialogElement>(null); useEffect(() => { document.body.addEventListener("click", handleDocumentClick); return () => document.removeEventListener("click", handleDocumentClick); }); useEffect(() => { const elem = dialogRef.current; elem?.addEventListener("close", handleClose); return () => elem?.removeEventListener("close", handleClose); }); useEffect(() => { if (props.isShown && !dialogRef.current!.hasAttribute("open")) { dialogRef.current!.showModal(); } else if (!props.isShown && dialogRef.current!.hasAttribute("open")) { dialogRef.current!.close(); } }, [props.isShown, dialogRef]); function handleClose() { if (props.isShown) { props.onCancel(); } } function handleDocumentClick(e: MouseEvent) { if (e.target === dialogRef.current) { e.preventDefault(); e.stopPropagation(); dialogRef.current!.close(); } } return <dialog ref={dialogRef}>{props.children}</dialog>; }