Toast

Brief confirmation for a completed background action.

import { Toast } from "@sagui/ui";
Markdown
Loading demo

When to use

  • A single success confirmation, like Changes saved, controlled with local state.
  • Demos or small apps that do not need a toast queue.

When not to use

  • Use alert for persistent messages that should stay in the page flow.

Installation

Install the package and import the styles once. The installation guide covers the Tailwind setup.

$ npm install @sagui/ui

Usage

example.tsx
import Toast from "@sagui/ui";

export function SavedToast() {
  const [open, setOpen] = useState(false);
  return (
    <>
      <button type="button" onClick={() => setOpen(true)}>Save</button>
      <Toast open={open} onOpenChange={setOpen} title="Changes saved" description="Synced to all devices." />
    </>
  );
}

Examples

Title only

Loading demo

Copy that changes

Loading demo

API reference

Toast

A single swipeable notification with a drawn check, auto-dismiss, and morphing copy.

Prop Type Default Description
title (required) string – Headline. Changes crossfade while shown.
description string – Supporting line.
open boolean true Whether the toast is shown. Setting it true again after a dismiss re-raises it.
onOpenChange (open: boolean) => void – Called with false on close, swipe, or timeout. Auto-dismiss only runs when this is provided.
duration number 4500 Milliseconds before auto-dismiss. 0 or less disables it.
className string – Added to the toast surface.

Keyboard interactions

Keys Action
TabthenEnter Reaches and activates the dismiss button.

Accessibility

  • Renders role="status" with aria-live="polite" and aria-atomic, so new content is announced without stealing focus.
  • The dismiss button is labelled "Dismiss notification"; the check icon is aria-hidden.
  • Positioning is up to the caller; the auto-dismiss timer does not pause on hover, so keep messages short.

Motion

  • Enters rising 16px from 0.96 scale on a morph spring while the check draws in; a swipe past 80px or 480px/s throws it off with its release velocity.
  • Closing sinks it 8px and fades. Copy changes rise in while the height springs to fit.
  • Reduced motion uses opacity fades and disables dragging.

Responsive behavior

  • The toast is min(100%, 26rem) wide and the title ellipsizes on one line.
  • Positioning is up to you; fix it to the bottom center on phones so it clears the thumb zone edges.
  • It swipes horizontally on touch and mouse; drag is disabled under reduced motion.

Performance

  • Drag and throw run on motion values, and a ResizeObserver springs the height when copy changes.
  • The auto-dismiss timer does not pause on hover, so keep messages short.

Notes

  • Use for a single success confirmation you control with local state.
  • Import as a default export. Position it yourself, for example fixed to the bottom of the viewport.

Also in messages