Toast
A notification region for temporary messages, actions, and contextual feedback.
API Reference
Original primitive API
Behavior, accessibility details, and low-level props are documented by Base UI.
Basic
Mount one ToastProvider near the application root. Any component inside it can call
useToastManager() for stacked toasts or useAnchoredToastManager() for anchored toasts.
ToastRegion and ToastAnchoredRegion render their portals and viewports automatically; use
classNames.portal and classNames.viewport only when those infrastructure slots need custom
styling.
import { Button, ToastProvider, ToastRegion, useToastManager,} from "moduix";export function App() { return ( <ToastProvider> <AppShell /> <ToastRegion /> </ToastProvider> );}function AppShell() { const toastManager = useToastManager(); function showToast() { toastManager.add({ title: "Saved", description: "Changes were saved successfully.", }); } return <Button onClick={showToast}>Save changes</Button>;}Full list of component variables available for project-level overrides.
| Property | Default | Description |
|---|---|---|
| --toast-action-bg | var(--color-background) | Controls action button background. |
| --toast-action-bg-hover | var(--color-accent) | Controls action hover background. |
| --toast-action-border-color | var(--color-border) | Controls action border color. |
| --toast-action-border-width | var(--toast-border-width, var(--border-width-sm)) | Controls action button border width. |
| --toast-action-color | var(--color-foreground) | Controls action text color. |
| --toast-action-font-size | var(--text-xs) | Controls action font size. |
| --toast-action-font-weight | var(--weight-medium) | Controls action font weight. |
| --toast-action-line-height | var(--line-height-text-xs) | Controls action line height. |
| --toast-action-margin-top | 0.5rem | Controls action spacing from the description. |
| --toast-action-padding-x | 0.5rem | Controls action horizontal padding. |
| --toast-action-padding-y | 0.25rem | Controls action vertical padding. |
| --toast-action-radius | var(--radius-sm) | Controls action button border radius. |
| --toast-anchored-arrow-height | 0.625rem | Controls anchored toast arrow height. |
| --toast-anchored-arrow-offset-x | -13px | Controls horizontal anchored arrow offset. |
| --toast-anchored-arrow-offset-y | -8px | Controls vertical anchored arrow offset. |
| --toast-anchored-arrow-width | 1.25rem | Controls anchored toast arrow width. |
| --toast-anchored-font-size | var(--text-sm) | Controls anchored toast font size. |
| --toast-anchored-line-height | var(--line-height-text-sm) | Controls anchored toast line height. |
| --toast-anchored-max-width | 20rem | Controls anchored toast max width. |
| --toast-anchored-padding-x | 0.5rem | Controls anchored toast horizontal padding. |
| --toast-anchored-padding-y | 0.25rem | Controls anchored toast vertical padding. |
| --toast-anchored-scale | 0.9 | Controls anchored toast entering/leaving scale. |
| --toast-anchored-transition | transform 150ms, opacity 150ms | Controls anchored toast transition. |
| --toast-bg | var(--color-popover) | Controls toast background color. |
| --toast-border-color | var(--color-border) | Controls toast border color. |
| --toast-border-width | var(--border-width-sm) | Controls toast border width. |
| --toast-close-bg | transparent | Controls close button background. |
| --toast-close-bg-hover | var(--color-accent) | Controls close hover background. |
| --toast-close-color | var(--color-muted-foreground) | Controls close button color. |
| --toast-close-color-hover | var(--color-foreground) | Controls close hover color. |
| --toast-close-focus-ring-offset | 0 | Controls close button focus ring offset. |
| --toast-close-icon-size | 1rem | Controls default close icon size. |
| --toast-close-offset-right | 0.5rem | Controls close button right offset. |
| --toast-close-offset-top | 0.5rem | Controls close button top offset. |
| --toast-close-padding | 0 | Controls close button inner padding. |
| --toast-close-radius | var(--radius-sm) | Controls close button border radius. |
| --toast-close-size | 1.25rem | Controls close button size. |
| --toast-color | var(--color-popover-foreground) | Controls toast text color. |
| --toast-content-gap | 0.25rem | Controls spacing inside toast content. |
| --toast-description-color | var(--color-muted-foreground) | Controls description color. |
| --toast-description-font-size | var(--text-sm) | Controls description font size. |
| --toast-description-line-height | var(--line-height-text-sm) | Controls description line height. |
| --toast-focus-ring-color | var(--color-ring) | Controls action and close focus rings. |
| --toast-focus-ring-width | var(--toast-border-width, var(--border-width-sm)) | Controls action and close focus ring width. |
| --toast-padding | 1rem | Controls root toast padding. |
| --toast-radius | var(--radius-lg) | Controls toast border radius. |
| --toast-shadow | var(--shadow-lg) | Controls toast shadow. |
| --toast-stack-gap | 0.75rem | Controls expanded stack spacing. |
| --toast-stack-peek | 0.75rem | Controls collapsed stack offset. |
| --toast-title-font-size | var(--text-sm) | Controls title font size. |
| --toast-title-font-weight | var(--weight-semibold) | Controls title font weight. |
| --toast-title-line-height | var(--line-height-text-sm) | Controls title line height. |
| --toast-transition | 0.5s cubic-bezier(0.22, 1, 0.36, 1) | Controls toast movement transition. |
| --toast-viewport-inset | 1rem | Controls viewport distance from the window edge. |
| --toast-viewport-width | 20rem | Controls the fixed toast viewport width. |
| --toast-z-index | var(--z-toast) | Controls toast portal and stack z-index. |
Interactive variables scoped for docs preview without changing size scale tokens.
| Property | Value | Default | Description |
|---|---|---|---|
| --toast-action-bg | var(--color-background) | Controls action button background. | |
| --toast-action-border-color | var(--color-border) | Controls action border color. | |
| --toast-bg | var(--color-popover) | Controls toast background color. | |
| --toast-border-color | var(--color-border) | Controls toast border color. | |
| --toast-color | var(--color-popover-foreground) | Controls toast text color. | |
| --toast-description-color | var(--color-muted-foreground) | Controls description color. | |
| --toast-focus-ring-color | var(--color-ring) | Controls action and close focus rings. | |
| --toast-radius | var(--radius-lg) | Controls toast border radius. | |
| --toast-shadow | var(--shadow-lg) | Controls toast shadow. | |
| --toast-title-font-size | var(--text-sm) | Controls title font size. |
Anatomy
ToastProvider owns the toast managers. ToastRegion renders stacked notifications and
ToastAnchoredRegion renders contextual notifications tied to an anchor element. Both regions
create their Portal, Viewport, and anchored Positioner service slots automatically, so the
public composition stays focused on visible toast content.
ToastProvider
├─ app content
├─ ToastRegion
│ └─ ToastRoot
│ └─ ToastContent
│ ├─ ToastTitle
│ ├─ ToastDescription
│ ├─ ToastAction
│ └─ ToastClose
└─ ToastAnchoredRegion
└─ anchored toast<ToastProvider>
<AppShell />
<ToastRegion placement="bottom-right" />
<ToastAnchoredRegion />
</ToastProvider>| Part | Role |
|---|---|
ToastProvider | Provides the stacked and anchored toast managers to the subtree. |
ToastRegion | Renders the shared portal and viewport for stacked toasts. Use placement and stackBehavior here. |
ToastRoot | Visible notification surface. Use it inside renderToast when a custom toast layout is needed. |
ToastContent | Content wrapper for title, description, actions, icons, and custom layout. |
ToastTitle | Renders the toast title from the toast object. |
ToastDescription | Renders the toast description from the toast object. |
ToastAction | Optional action button rendered from actionProps in the default composition. |
ToastClose | Dismiss button with the default close icon, or custom children. |
ToastAnchoredRegion | Renders anchored feedback near the element passed to useAnchoredToastManager().show({ anchor }). |
The service slots are still customizable when needed: pass container to choose the portal target
and classNames.portal, classNames.viewport, or classNames.positioner to style infrastructure.
For ordinary visual changes, prefer className on ToastRegion or a custom renderToast
composition.
Composition
Mount one ToastProvider near the application root, place ToastRegion once per stacked viewport,
and call useToastManager() from descendants to enqueue notifications. ToastRegion owns
placement, stack behavior, and the default toast markup, so applications do not need to compose
Portal or Viewport manually.
Use renderToast when the default markup is not enough. The callback receives the Base UI toast
object and should return a complete visible composition with ToastRoot and the parts your layout
needs. Anchored feedback uses the same provider, but goes through useAnchoredToastManager() and
ToastAnchoredRegion so contextual toasts do not mix with the stacked notification queue.
Examples
Action
Use actionProps for a compact action button inside the default toast composition.
import { ToastProvider, ToastRegion, useToastManager, Button } from "moduix";export function App() { return ( <ToastProvider> <UploadButton /> <ToastRegion /> </ToastProvider> );}function UploadButton() { const toastManager = useToastManager(); return ( <Button onClick={() => toastManager.add({ title: "File uploaded", description: "The file is ready to share.", actionProps: { children: "Undo", onClick: () => toastManager.add({ description: "Upload reverted." }), }, }) } > Create action toast </Button> );}Placement
Pass placement to ToastRegion to choose the viewport corner or center edge.
import { ToastPlacement, ToastProvider, ToastRegion, useToastManager, Button,} from "moduix";import { useState } from "react";export function App() { const [placement, setPlacement] = useState("bottom-right" as ToastPlacement); return ( <ToastProvider> <AppShell placement={placement} onPlacementChange={setPlacement} /> <ToastRegion placement={placement} /> </ToastProvider> );}function AppShell({ placement, onPlacementChange,}: { placement: ToastPlacement; onPlacementChange: (placement: ToastPlacement) => void;}) { const toastManager = useToastManager(); return ( <div> {placements.map((item) => ( <button key={item} type="button" aria-pressed={item === placement} onClick={() => onPlacementChange(item)} > {item} </button> ))} <Button onClick={() => toastManager.add({ title: "Placement", description: `Current placement: ${placement}`, }) } > Show toast </Button> </div> );}const placements: ToastPlacement[] = [ "top-left", "top-center", "top-right", "bottom-left", "bottom-center", "bottom-right",];Always Expanded
Set stackBehavior="expanded" when the stack should stay readable without requiring hover or focus.
import { ToastProvider, ToastRegion, useToastManager, Button } from "moduix";export function App() { return ( <ToastProvider> <AppShell /> <ToastRegion placement="bottom-right" stackBehavior="expanded" /> </ToastProvider> );}function AppShell() { const toastManager = useToastManager(); return ( <Button onClick={() => toastManager.add({ title: "Background task", description: "Create several notifications to compare the expanded stack.", }) } > Create toast </Button> );}Global Manager
Create a manager outside React when app services need to enqueue notifications through the same renderer.
import { createToastManager, ToastProvider, ToastRegion, Button } from "moduix";const toastManager = createToastManager();export function App() { return ( <ToastProvider toastManager={toastManager}> <AppShell /> <ToastRegion /> </ToastProvider> );}function notifyFromService() { toastManager.add({ title: "Global toast", description: "Created with createToastManager().", });}function AppShell() { return <Button onClick={notifyFromService}>Create global toast</Button>;}Custom Styles
Use renderToast when the application keeps the shared provider and region pattern but needs custom
layout, custom icons, or slot-level className styling for each toast.
import { Button, CloseLineIcon, InfoIcon, ToastProvider, ToastRegion, ToastRoot, ToastContent, ToastTitle, ToastDescription, ToastClose, useToastManager,} from "moduix";import styles from "./custom-toast.module.css";export function App() { return ( <ToastProvider> <CreateToastButton /> <ToastRegion renderToast={(toast) => ( <ToastRoot toast={toast} className={styles.toast}> <ToastContent className={styles.content}> <InfoIcon className={styles.icon} /> <ToastTitle /> <ToastDescription /> <ToastClose aria-label="Close toast"> <CloseLineIcon className={styles.closeIcon} /> </ToastClose> </ToastContent> </ToastRoot> )} /> </ToastProvider> );}function CreateToastButton() { const toastManager = useToastManager(); return ( <Button onClick={() => toastManager.add({ title: "Custom composition", description: "Every important part accepts className and custom children.", }) } > Create custom toast </Button> );}.toast { --toast-bg: var(--color-primary); --toast-color: var(--color-primary-foreground); --toast-border-color: var(--color-primary); --toast-description-color: color-mix( in srgb, var(--color-primary-foreground) 72%, transparent ); --toast-close-color: var(--color-primary-foreground); --toast-close-color-hover: var(--color-primary-foreground); --toast-close-bg-hover: color-mix( in srgb, var(--color-primary-foreground) 14%, transparent );}.content { grid-template-columns: auto minmax(0, 1fr); column-gap: var(--spacing-3); padding-right: 1.75rem;}.icon { grid-row: span 2; inline-size: 1.125rem; block-size: 1.125rem; color: currentColor;}.closeIcon { inline-size: var(--toast-close-icon-size, 1rem); block-size: var(--toast-close-icon-size, 1rem); flex: none;}Anchored Toast
Use useAnchoredToastManager() and ToastAnchoredRegion for transient feedback tied to a specific
button or control. Anchored and stacked toasts can share the same ToastProvider; each region
renders only the toast type it owns.
import { Button, ToastAnchoredRegion, ToastProvider, useAnchoredToastManager,} from "moduix";import { useRef } from "react";export function App() { return ( <ToastProvider> <CopyButton /> <ToastAnchoredRegion /> </ToastProvider> );}function CopyButton() { const buttonRef = useRef(null as HTMLButtonElement | null); const anchoredToast = useAnchoredToastManager(); function showCopiedToast() { if (!buttonRef.current) { return; } anchoredToast.show({ anchor: buttonRef.current, description: "Copied", timeout: 1800, }); } return ( <Button ref={buttonRef} onClick={showCopiedToast}> Copy </Button> );}Stacked and Anchored Toasts
Render both regions under one provider when an app needs page-level notifications and contextual feedback at the same time.
import { Button, ToastAnchoredRegion, ToastProvider, ToastRegion, useAnchoredToastManager, useToastManager,} from "moduix";import { useRef } from "react";export function App() { return ( <ToastProvider> <SaveButton /> <CopyButton /> <ToastRegion /> <ToastAnchoredRegion /> </ToastProvider> );}function SaveButton() { const toastManager = useToastManager(); return ( <Button onClick={() => toastManager.add({ title: "Saved", description: "Changes were saved successfully.", }) } > Save changes </Button> );}function CopyButton() { const buttonRef = useRef(null as HTMLButtonElement | null); const anchoredToast = useAnchoredToastManager(); function showCopiedToast() { if (!buttonRef.current) { return; } anchoredToast.show({ anchor: buttonRef.current, description: "Copied", timeout: 1800, }); } return ( <Button ref={buttonRef} variant="outline" onClick={showCopiedToast}> Copy </Button> );}