Toast
Ephemeral notifications that slide in from the corner of the screen, auto-dismiss after a configurable duration, and pause on hover.
Installation
biji-ui = { version = "0.5.0", features = ["toast"] }
Usage
Wrap your app (or any subtree) with <Toaster>. This provides ToasterContext to all descendants. Access it anywhere with expect_context::<ToasterContext>() and call add() with your own type string to show a toast.
use leptos::prelude::*;
use biji_ui::components::toast::{Toaster, ToasterContext};
// 1. Wrap your app (or any subtree) with <Toaster>.
// This provides ToasterContext to all descendants.
#[component]
pub fn App() -> impl IntoView {
view! {
<Toaster>
<MyApp />
</Toaster>
}
}
// 2. Anywhere inside, grab the context and call add() with your own type string.
#[component]
pub fn SaveButton() -> impl IntoView {
let toaster = expect_context::<ToasterContext>();
view! {
<button on:click=move |_| {
toaster.add("Changes saved successfully.", None, Some("success".to_string()), None);
}>
"Save"
</button>
}
}
Styling
The component is fully headless — no styles are applied by default. Pass a toast_class string to <Toaster> and use data-[type=…], data-[entering=true], data-[dismissed=true], and data-[paused=true] Tailwind arbitrary-variant selectors to control each state. Enable the progress bar with show_progress=true and style it with progress_class.
// Pass a toast_class to style individual toasts.
// Use data-[type=…], data-[entering=…], data-[dismissed=…], data-[paused=…] selectors.
// The type value is whatever string you pass to add() — define your own vocabulary.
<Toaster
pause_on_hover=PauseOnHover::Single
show_progress=true
progress_class="absolute bottom-0 left-0 h-0.5 bg-current opacity-30 rounded-full"
toast_class="relative flex items-start gap-3 w-full rounded-lg border px-4 py-3 \
shadow-md text-sm font-medium bg-background border-border text-foreground \
overflow-hidden transition-all duration-300 ease-in-out \
data-[entering=true]:opacity-0 data-[entering=true]:translate-y-2 \
data-[dismissed=true]:opacity-0 data-[dismissed=true]:translate-x-[calc(100%+1rem)] \
data-[type=success]:border-green-500/30 data-[type=success]:bg-green-50 \
data-[type=success]:text-green-900 dark:data-[type=success]:bg-green-950/30 \
dark:data-[type=success]:text-green-100"
>
<MyApp />
</Toaster>
API Reference
Toaster
| Name | Type | Default | Description |
|---|---|---|---|
| children | Children | — | The app subtree. ToasterContext is available to all descendants. |
| default_duration | Option<Duration> | 4000 ms | How long a toast stays visible before auto-dismissing. |
| hide_delay | Option<Duration> | 300 ms | Time between data-dismissed="true" and the toast being removed from the DOM. Should match your CSS exit-animation duration. |
| position | ToastPosition | BottomRight | Viewport corner where the toast stack appears. One of TopLeft, TopCenter, TopRight, BottomLeft, BottomCenter, BottomRight. |
| max_toasts | usize | 5 | Maximum number of toasts shown at once. Toasts beyond this limit are immediately dismissed (and animate out). |
| pause_on_hover | PauseOnHover | Single | Single — only the hovered toast pauses. All — hovering any toast pauses all. Disable — hover has no effect. |
| show_progress | bool | false | When true, renders a countdown progress bar inside each toast. The bar's width transitions from 100% to 0% over the toast duration. Style it with progress_class. |
| progress_class | String | "" | CSS class for the progress bar element. Control height, color, and position here — the inline style handles width. |
| class | String | "" | Extra CSS class on the stack container div. |
| toast_class | String | "" | CSS class applied to every individual toast element. Style via data-[type=…], data-[entering=…], data-[dismissed=…], data-[paused=…] selectors. |
ToasterContext methods
| Name | Type | Default | Description |
|---|---|---|---|
| toast(title) | impl Into<String> | — | Add a toast with no type string. |
| add(title, description, toast_type, duration) | String, Option<String>, Option<String>, Option<Duration> | — | Full control: title, optional description, optional type string (emitted as data-type), and optional custom duration. |
| dismiss(id) | u32 | — | Start the exit animation for a specific toast. |
| dismiss_all() | — | — | Dismiss all active toasts. |
Data Attributes
| Attribute | Description |
|---|---|
| data-type | The user-supplied type string passed to add(). Absent when no type was given. Use any value you want — e.g. "success", "error", or your own custom variants. |
| data-entering | "true" for ~1 ms after mount so CSS transitions fire from the hidden state. Use data-[entering=true]:… to define your enter-from state. |
| data-dismissed | "true" once the toast starts its exit animation. Use data-[dismissed=true]:… to define your exit state. |
| data-paused | "true" while the toast's countdown is paused (e.g. on hover). Use data-[paused=true]:… to show a visual indicator. |
Keyboard Navigation
| Key | Description |
|---|---|
| Tab | Move focus to the dismiss button. |
| Enter / Space | Activate the focused dismiss button, triggering the exit animation. |