import { createContext, JSX, ParentProps, useContext } from "solid-js" import { StandardSchemaV1 } from "@standard-schema/spec" import { createStore } from "solid-js/store" import { Dialog } from "./dialog" const Context = createContext() type DialogControl = { open>( component: DialogComponent, input: StandardSchemaV1.InferInput, ): void close(): void isOpen(input: any): boolean size: "sm" | "md" transition?: boolean input?: any } type DialogProps> = { input: StandardSchemaV1.InferInput control: DialogControl } type DialogComponent> = ReturnType< typeof createDialog > export function createDialog>(props: { schema: Schema size: "sm" | "md" render: (props: DialogProps) => JSX.Element }) { const result = () => { const dialog = useDialog() return ( { if (!val) dialog.close() }} > {props.render({ input: dialog.input, control: dialog, })} ) } result.schema = props.schema result.size = props.size return result } export function DialogProvider(props: ParentProps) { const [store, setStore] = createStore<{ dialog?: DialogComponent input?: any transition?: boolean size: "sm" | "md" }>({ size: "sm", }) const control: DialogControl = { get input() { return store.input }, get size() { return store.size }, get transition() { return store.transition }, isOpen(input) { return store.dialog === input }, open(component, input) { setStore({ dialog: component, input: input, size: store.dialog !== undefined ? store.size : component.size, transition: store.dialog !== undefined, }) setTimeout(() => { setStore({ size: component.size, }) }, 0) setTimeout(() => { setStore({ transition: false, }) }, 150) }, close() { setStore({ dialog: undefined, }) }, } return ( <> {props.children} ) } export function useDialog() { const ctx = useContext(Context) if (!ctx) { throw new Error("useDialog must be used within a DialogProvider") } return ctx }