Actions & callbacks
Some events deserve more than a static status message. Varsel lets you attach a single action button plus lifecycle callbacks so people can immediately respond.
Action buttons
Provide an action object with a label and an onClick handler. The handler receives no arguments, so close over whatever data you need. Varsel automatically focuses the button after the toast animates in, and closes the toast after the action fires.
<script lang="ts">
import { toast } from "varsel";
const undo = () => {
toast({
title: "Email scheduled",
description: "Will send in ten minutes.",
action: {
label: "Undo",
onClick: () => {
console.log("Email cancelled");
},
},
});
};
</script>
<button class="rounded-md bg-foreground h-9 px-4 py-2 text-sm font-medium text-foreground-invert hover:bg-foreground/80 transition-[background-color,scale] duration-150 ease-out active:scale-[0.975]" onclick={undo}>
Show action toast
</button>Lifecycle hooks
Two callbacks help you distinguish why a toast disappeared:
onAutoClosefires once the toast finishes its timer-based exit.onDismissruns when the toast is closed manually (close button, swipe,toast.dismiss,toast.dismissAll, etc.).
Both callbacks run after the exit animation completes, so follow-up work can assume the toast has already left the DOM.
const id = toast({
title: "Export ready",
description: "Opening the download dialog...",
onAutoClose: () => {
console.log(`Toast ${id} closed on its own`);
},
onDismiss: () => {
console.log(`Toast ${id} was dismissed manually`);
}
});Toggle the close button
The close button is enabled by default for regular toasts, but you can disable it with the showClose prop. When showClose is false, Varsel hides the “X” button and also disables the swipe-to-dismiss gesture, which is useful for blocking manual dismissal while a task is in progress. toast.promise follows this pattern automatically—its loading toast hides the close button unless you override the flag.
toast({
title: "Sync in progress",
description: "We will close this when the job finishes.",
showClose: false,
});