Alert dialog
A one-button notice. The caller awaits acknowledgement; the response type is void — the act of closing is the value.
→ awaiting click…
The Callable
declared once, mounted in the React treeimport { createCallable } from 'react-call'
interface Props { title: string message: string}
export const Alert = createCallable<Props, void>(({ call, title, message }) => ( <div role="alertdialog" aria-modal="true" aria-labelledby="alert-title" className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm" > <div className="w-full max-w-sm rounded-lg border border-[var(--color-border)] bg-[var(--color-bg)] p-6 shadow-2xl"> <p id="alert-title" className="text-base font-medium text-[var(--color-fg)]" > {title} </p> <p className="mt-2 text-sm text-[var(--color-fg-muted)]">{message}</p> <div className="mt-6 flex justify-end"> <button type="button" onClick={() => call.end()} className="rounded-md bg-[var(--color-accent)] px-4 py-2 text-sm font-medium text-[var(--color-accent-fg)] transition-colors hover:bg-[var(--color-accent-hover)]" > OK </button> </div> </div> </div>))Alert.displayName = 'Alert'The Root
mounted in your app tree, onceimport { Alert } from './Alert'import { ShowAlertButton } from './ShowAlertButton'
export default function App() { return ( <> <Alert /> <ShowAlertButton /> </> )}The caller
anywhere in your app, imperativeimport { useState } from 'react'import { Alert } from './Alert'
export const ShowAlertButton = () => { const [acked, setAcked] = useState(false)
const handleClick = async () => { await Alert.call({ title: 'Heads up', message: 'Your session will expire in 5 minutes. Save your work to keep it.', }) setAcked(true) }
return ( <div className="flex flex-col items-center gap-3"> <button type="button" onClick={handleClick} className="rounded-md bg-[var(--color-accent)] px-4 py-2 text-sm font-medium text-[var(--color-accent-fg)] transition-colors hover:bg-[var(--color-accent-hover)]" > Show alert </button> <span className="font-mono text-xs text-[var(--color-fg-subtle)]"> {acked ? '→ acknowledged' : '→ awaiting click…'} </span> </div> )}