Toast
A dismissible notification with no global provider.
Usage
'use client';
import { useState } from 'react';
import { Button } from '@fwenthehunter/friendly-ui';
import { Toast } from '@fwenthehunter/friendly-ui/client';
export function SaveNotice() {
const [open, setOpen] = useState(false);
return <>
<Button onClick={() => setOpen(true)}>Save</Button>
<Toast open={open} onOpenChange={setOpen} title="Changes saved"
variant="success" position="top-center" duration={8000} showTimer>
Your preferences are up to date.
</Toast>
</>;
}Keep Toast mounted in a client wrapper and control it with open and onOpenChange. Its live region announces newly inserted content. Error notifications use role="alert"; other variants use role="status". It never steals focus.
Dismisses after five seconds by default. The countdown pauses while hovered or focused and resumes with the remaining time. Set duration=0 to keep it until dismissed. Set showTimer to show a countdown bar, which pauses with the timer. A large close button is always available. Reduced-motion preferences hide the animated bar.
Error, warning, success, and info have default light and dark color palettes. Override --fui-toast-error-background, --fui-toast-error-foreground, and --fui-toast-error-border in your theme file, replacing error with any other variant. For a single notification, set these same variables through style or a className.
This is a single notification primitive, without a global queue. Mount near your app root, outside transformed or clipped containers; render one toast per position to avoid overlap. For critical errors, also show a persistent inline message.
Customize this component
- Choose a name.
- Add its CSS to your app’s theme.css, imported after the package styles.
- Pass the same name to the prop. No registration, provider, or package edits are needed. Built-in TypeScript suggestions remain available.
A custom name alone does not create styles: until its CSS is loaded, it inherits the component’s base appearance. The examples below are application styles, not additional package defaults.
Add a variant
Custom names use polite status announcements by default. The built-in error variant remains an alert. For built-in palettes, override --fui-toast-success-background (or another built-in name) instead. Toast has no size prop; use className or CSS for layout.
/* app/theme.css — import after @fwenthehunter/friendly-ui/styles.css */
@layer components {
.fui-toast[data-variant="brand"] {
--fui-toast-background: #312e81;
--fui-toast-foreground: #fff;
--fui-toast-border: #6366f1;
}
}"use client";
import { useState } from "react";
import { Button } from "@fwenthehunter/friendly-ui";
import { Toast } from "@fwenthehunter/friendly-ui/client";
export function BrandNotice() {
const [open, setOpen] = useState(false);
return <>
<Button onClick={() => setOpen(true)}>Show brand toast</Button>
<Toast variant="brand" open={open} onOpenChange={setOpen} title="Welcome">
Your brand colors, with the same toast behavior.
</Toast>
</>;
}Props
Components accept native HTML props, className, and style. Server-compatible primitives also forward React 19 refs; Modal manages its own dialog ref.
| Prop | Type | Default |
|---|---|---|
open / onOpenChange | boolean / (open: boolean) => void | required |
title | ReactNode | required |
duration | milliseconds, 0 disables timeout | 5000 |
showTimer | boolean, show animated countdown | false |
variant | default | success | error | warning | info | custom string | default |
position | bottom-right | bottom-center | bottom-left | top-right | top-center | top-left | bottom-right |
closeLabel | string | Dismiss notification |