Toasts
const [open, setOpen] = useState(false);
useEffect(() => { if (!open) return; const timer = setTimeout(() => setOpen(false), 4000); return () => clearTimeout(timer);}, [open]);
<Sheet.Root modal={false} open={open} onOpenChange={setOpen} detents={['content']}>A toast is just modal={false} plus a plain timer closing it, the same controlled open any
other sheet uses.
Migrating an existing Sonner integration instead of writing this by hand?
import { toast, Toaster } from 'sonner';import { toast, Toaster } from 'scrollsheet';scrollsheet’s Sonner compat layer is a drop-in for toast()/Toaster that runs on this same
primitive. See Migrate from Sonner.
Migrate from SonnerDrop-in replacement for toast, useSonner, and Toaster, built on one non-modal Sheet.Root per Toaster instead of Sonner's DOM stack.