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:

  • onAutoClose fires once the toast finishes its timer-based exit.
  • onDismiss runs 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,
});