Skip to content

Undo with a toast

.md

Delete optimistically, offer Undo for six seconds with a draining progress bar, and only send the real request when nothing took the deletion back. Built from Toast and Button.

Preview

Release checklist
Meeting notes
Launch copy

Deleted for real: 0

Steps

  1. Remove the item from the list right away and raise a toast with `duration: 6000`, `progress: true` and an `Undo` action.
  2. In the action handler, restore the item at its old position and dismiss the toast. Pressing the action settles `onClose` with `action` before the handler runs.
  3. Commit the deletion from `onClose` for every reason except `action`: `timeout` (the time ran out), `dismiss` (the user closed it), and `evicted` (newer toasts pushed it out of the stack).
  4. Raise one toast per deletion. Each has its own timer and its own `onClose`, so two quick deletions are two independent undo windows.

Pitfalls

  • Committing only on `timeout`: closing the toast or deleting four more items would then silently cancel a deletion the user confirmed by moving on.
  • Committing on every reason including `action`: Undo would restore the item locally and still delete it on the server.
  • Mounting the Toaster per page: when it unmounts, pending timers are dropped without firing `onClose`, so a deletion still waiting on its undo window is never committed. Mount one Toaster at the app level.
  • Expecting hover to restart the clock: pausing keeps what was left, so hovering at 5.9 s of 6 s and leaving still gives the remaining 0.1 s, not a fresh window.

Components used