import React, { createContext, useContext, useMemo, useState } from 'react'; import type { DialogProps } from './core/Dialog'; import { Dialog } from './core/Dialog'; type DialogEntry = { id: string; render: ({ hide }: { hide: () => void }) => React.ReactNode; } & Pick; type DialogEntryOptionalId = Omit & { id?: string }; interface State { dialogs: DialogEntry[]; actions: Actions; } interface Actions { show: (d: DialogEntryOptionalId) => void; hide: (id: string) => void; } // eslint-disable-next-line @typescript-eslint/no-explicit-any const DialogContext = createContext({} as any); export const DialogProvider = ({ children }: { children: React.ReactNode }) => { const [dialogs, setDialogs] = useState([]); const actions = useMemo( () => ({ show: ({ id: oid, ...props }: DialogEntryOptionalId) => { const id = oid ?? Math.random().toString(36).slice(2); setDialogs((a) => [...a.filter((d) => d.id !== id), { id, ...props }]); }, hide: (id: string) => { setDialogs((a) => a.filter((d) => d.id !== id)); }, }), [], ); const state: State = { dialogs, actions, }; return ( {children} {dialogs.map((props: DialogEntry) => ( ))} ); }; function DialogInstance({ id, render, ...props }: DialogEntry) { const { actions } = useContext(DialogContext); const children = render({ hide: () => actions.hide(id) }); return ( actions.hide(id)} {...props}> {children} ); } export const useDialog = () => useContext(DialogContext).actions;