import { type Accessor, createEffect, type JSX, type Setter, untrack } from "solid-js"; interface ModalProps { show: Accessor; setShow: Setter; //runs when the dialog opens, to reset whatever state it holds. untracked, so reading a store in //here cannot turn a later change to it into a second open onOpen?: () => void; //runs on every close path, including Escape and a backdrop click onClose?: () => void; style?: JSX.CSSProperties; //a function, so the content can close the dialog without needing its own ref to the element children: (close: () => void) => JSX.Element; } export function Modal(props: ModalProps) { let dialogElement!: HTMLDialogElement; createEffect(() => { if (!props.show()) return; dialogElement.showModal(); untrack(() => props.onOpen?.()); }); const close = () => dialogElement.close(); return ( { props.onClose?.(); props.setShow(false); }} onclick={(e) => e.target.nodeName === "DIALOG" && close()} > {props.children(close)} ); }