Skip to content
omaris

Communication

Toast

One toast card.

import { Toast } from 'omaris'
Learn

Examples

Kinds

toast() is a plain call from anywhere — no component, no context hook. OmarisProvider renders the stack these land in.

<script lang="ts">	import { Button, toast } from 'omaris';</script>​<Button variant="tonal" onclick={() => toast('Copied to clipboard')}>Plain</Button><Button variant="tonal" tone="success" onclick={() => toast.success('Invoice sent')}>Success</Button><Button variant="tonal" tone="destructive" onclick={() => toast.error('Upload failed')}>	Error</Button><Button variant="tonal" tone="warning" onclick={() => toast.warning('Card expires soon')}>	Warning</Button>

With an action

A toast can carry one action. Undo is what it is usually for.

Nothing deleted.

<script lang="ts">	import { Button, toast } from 'omaris';​	let deleted = $state(false);</script>​<Button	variant="outlined"	onclick={() => {		deleted = true;		toast('Message moved to trash', {			action: { label: 'Undo', onclick: () => (deleted = false) }		});	}}>	Delete a message</Button>​<p class="text-body-sm text-muted-foreground">	{deleted ? 'Deleted — press Undo in the toast.' : 'Nothing deleted.'}</p>

Following a promise

toast.promise shows a loading toast that becomes the success or the error one, so the three states are one call rather than three.

<script lang="ts">	import { Button, toast } from 'omaris';​	const save = (ok: boolean) =>		new Promise<string>((resolve, reject) =>			setTimeout(() => (ok ? resolve('storefront') : reject(new Error('timeout'))), 1500)		);</script>​<Button	variant="tonal"	onclick={() =>		toast.promise(save(true), {			loading: 'Deploying…',			success: (name) => `${name} is live`,			error: 'Deploy failed'		})}>	Deploy</Button>​<Button	variant="tonal"	tone="destructive"	onclick={() =>		toast.promise(save(false), {			loading: 'Deploying…',			success: 'Live',			error: 'Deploy failed'		})}>	Deploy, badly</Button>

When to use it

Use it for

  • Confirming something just happened: "Saved", "Invitation sent", "Copied". Call toast('Saved') from anywhere. OmarisProvider already renders the <Toaster />.
  • Undo. Put action: { label: 'Undo', onclick } on the toast that reports a delete or archive, instead of a confirm dialog before it.
  • A job the person can walk away from. toast.promise() with loading, success and error turns one card from spinner to result.
  • A failure that needs no decision: "Could not sync, retrying". toast.error stays six seconds instead of four.
  • A message that must stand out while the page is in use: variant="rich" tints the whole card.

Not for

  • A message that stays until the problem clears → Alert.
  • A decision, like "Delete 12 files?" → Dialog. A toast never blocks and leaves on its own.
  • Progress of the button just pressed → the Button's loading.
  • A count or a "new" mark → Badge.
  • Field validation → the field's supportingText. A toast is gone before it is read.

Do

  • Write one line with a verb: "Invoice sent", not "Success!". Put detail in description.
  • Keep to one action. Add cancel only for a destructive pair. Three buttons means you want a dialog.
  • Reuse an id to update a toast in place, for a changing count or a retry.
  • Let it close on its own. Use duration: 0 with closeButton only for a message that needs acknowledging, like a lost connection.
  • Set keepOpen on an action whose press does not finish the job.

Don't

  • Toast a result that is already on screen: the row is gone, the panel closed, the page moved. Most actions get no toast.
  • Toast every row in a bulk edit. Batch it: "12 rows updated".
  • Put the only way to reach something in a toast. A swipe throws it away.
  • Fire one on page load.
  • Mount a second <Toaster />. There is one stack; a message that belongs to a region is an Alert.

Quick reference

tone
  • primary (default)
  • secondary
  • tertiary
  • destructive
  • success
  • warning
  • info
variant
  • plain (default)
  • rich

API

Toast

One toast card.

Usually you don't render this yourself: call toast(...) and let <Toaster /> stack it. It's exported on its own for the cases where a message belongs to one part of the page rather than the app.

The card owns its swipe. The stack transform belongs to the <Toaster /> wrapper around it, so the two never fight over the same property.

import { Toast } from 'omaris'

Parts

Every element this renders is reachable from outside. Pass Tailwind for one part as classes={{ part: '…' }}; class covers the root and is merged last, so it always wins.

root
No description in the source yet.
icon
No description in the source yet.
body
No description in the source yet.
title
No description in the source yet.
description
No description in the source yet.
actions
Action and cancel sit on the trailing edge, action first.
action
No description in the source yet.
cancel
No description in the source yet.
close
The ×, revealed on hover so it doesn't clutter the resting card — except where there is no hover to reveal it with, on which devices a hidden control is simply a missing one. Same card, same size everywhere; only its resting opacity differs.

Props

toast required
ToastItem
variant

Defaults to 'plain'

ToastVariant
plain
Sonner's default: a neutral card, colour carried by the icon.
rich
The whole card takes the tone, for a message that must land.
swipe

Defaults to { x: 0, y: 1 }

ToastSwipe
closeButton

Defaults to false

boolean

Stack-wide default; the toast's own closeButton wins.

ondismiss
() => void
onhold
(held: boolean) => void

Held while a finger is on the card, so the timer can pause.

ontap
() => void

A press that turned out to be a press: it ended without becoming a swipe and did not land on a button. The stack uses it as "expand" on a touchscreen, where there is no hover to fan the deck with.

class
string
classes
ToastClasses

Per-part Tailwind overrides. class still covers the root.

Toaster

Where toasts appear. OmarisProvider renders one, so you only need this if you want them somewhere else or stacked differently.

import { Toaster } from 'omaris'

Props

position

Defaults to 'bottom-end'

ToastPosition
visible

Defaults to 3

number

How many are on screen at once. The rest wait in the deck.

variant

Defaults to 'plain'

ToastVariant

Fill style for every toast the stack renders.

closeButton

Defaults to false

boolean

Show the × on every toast.

expand

Defaults to false

boolean

Keep the deck fanned out instead of expanding on hover.

gap

Defaults to 14

number

Gap between toasts once expanded, in px.

class
string