Client component
Toast
Ephemeral notifications fired imperatively from anywhere: no context, no wiring.
"use client";
import { Button, HStack, Toaster, toast } from "astralis-ui";
export function ToastDemo() {
return (
<>
{/* Mount ONE Toaster near your app root. It catches toasts from anywhere. */}
<Toaster placement="bottom-end" />
<HStack gap="3" wrap="wrap">
<Button size="sm" colorScheme="blue" variant="subtle" onClick={() => toast.info("Heads up", { description: "A new version is available." })}>
Info
</Button>
<Button size="sm" colorScheme="green" variant="subtle" onClick={() => toast.success("Deploy complete", { description: "v0.2.0 is live." })}>
Success
</Button>
<Button size="sm" colorScheme="orange" variant="subtle" onClick={() => toast.warning("Approaching quota")}>
Warning
</Button>
<Button size="sm" colorScheme="red" variant="subtle" onClick={() => toast.error("Payment failed", { description: "Your card was declined." })}>
Error
</Button>
</HStack>
</>
);
}Import#
import { Toaster, toast } from "astralis-ui";Mount one <Toaster /> near your app root (inside AstralisProvider),
then call toast(...) from any event handler, effect, or async flow. The
store is module-level, so it works outside React trees too.
Options: actions, sticky toasts, dismiss#
"use client";
import { Button, HStack, toast } from "astralis-ui";
export function ToastOptions() {
return (
<HStack gap="3" wrap="wrap">
<Button
size="sm"
variant="outline"
onClick={() =>
toast({
title: "File deleted",
description: "report-final-v2.pdf was moved to trash.",
status: "info",
action: { label: "Undo", onClick: () => toast.success("Restored") },
})
}
>
With action
</Button>
<Button
size="sm"
variant="outline"
onClick={() =>
toast({
title: "Copies itself to your clipboard history",
duration: null,
status: "warning",
})
}
>
Sticky (duration: null)
</Button>
<Button size="sm" variant="text" colorScheme="gray" onClick={() => toast.dismiss()}>
Dismiss all
</Button>
</HStack>
);
}toast() API#
| Call | Returns | Description |
|---|---|---|
toast(options) | id | Full-control form. |
toast.info/success/warning/error(title, options?) | id | Status shorthands. |
toast.dismiss(id?) | None | Close one toast, or all when called with no id. |
Options#
| Prop | Type | Default | Description |
|---|---|---|---|
title | ReactNode | None | The headline. Required. |
description | ReactNode | None | Supporting copy. |
status | "info" | "success" | "warning" | "error" | "info" | Picks the icon and hue, and whether the announcement is polite or assertive. |
colorScheme | all 15 schemes | from status | Hue override. |
duration | number | null | 5000 | Auto-dismiss delay in ms; null keeps the toast until it's dismissed. |
closable | boolean | true | Shows the dismiss button and lets Escape dismiss the focused toast. |
action | { label: string; onClick: () => void } | None | A button after the text. |
<Toaster /> props#
| Prop | Type | Default | Description |
|---|---|---|---|
placement | "top-start" | "top-center" | "top-end" | "bottom-start" | "bottom-center" | "bottom-end" | "bottom-end" | The screen corner or edge the stack grows from. |
max | number | 5 | How many toasts show at once, newest first. The rest wait their turn. |
Keyboard#
Toasts never take focus when they appear, so they don't interrupt typing.
They sit in a "Notifications" region you can Tab into.
| Key | Action |
|---|---|
Tab | Move to a toast's action and dismiss buttons |
Enter / Space | Activate the focused button |
Esc | Dismiss the focused toast and return focus to where it was |
Esc only dismisses a closable toast, and it doesn't also close a Modal or
Popover open behind it.
Accessibility#
- Toasts are announced through two live regions the Toaster mounts empty:
polite for
infoandsuccess, assertive forwarninganderror. Regions that exist before their text arrives are announced reliably across screen readers, unlike one inserted already filled. - The toasts themselves sit in a
role="region"labelled "Notifications". - Hovering a toast, or moving focus into it, pauses the auto-dismiss timer, which resumes with the remaining time, so slow readers aren't raced.