Patterns
Common modal usage patterns that fit the current API.
Patterns
Stable id closing
Because children is plain ReactNode, the most reliable pattern is to generate a stable id at the call site and pass close callbacks down into your content.
function ConfirmPanel({
onConfirm,
onCancel,
}: {
onConfirm: () => void;
onCancel: () => void;
}) {
return (
<div>
<button onClick={onCancel}>Cancel</button>
<button onClick={onConfirm}>Confirm</button>
</div>
);
}
const modalId = 'archive-item';
await display<boolean>({
id: modalId,
children: (
<ConfirmPanel
onConfirm={() => close(modalId, true)}
onCancel={() => close(modalId, false)}
/>
),
});Global facade with one default provider
If you want module-level commands, mount one default ModalProvider near the root and use modal.display() from elsewhere.
<ModalProvider>{children}</ModalProvider>const result = await modal.display<boolean>({
id: 'global-delete',
children: <DeletePanel />,
});Use transport deliberately
- use
inlinefor the best animation control and app-owned backdrop styling - use
top-layerwhen browser top-layer behavior matters more than styling freedom
Treat display() as the safest continuation point
Because the promise resolves after removal, await display() is the safest place to continue with navigation, destructive writes, or follow-up UI.
const confirmed = await display<boolean>({ id: 'delete-item', children: <DeletePanel /> });
if (confirmed) {
await api.delete();
}