moduix

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.

Base UI API

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.

PropertyDefaultDescription
--toast-action-bgvar(--color-background)Controls action button background.
--toast-action-bg-hovervar(--color-accent)Controls action hover background.
--toast-action-border-colorvar(--color-border)Controls action border color.
--toast-action-border-widthvar(--toast-border-width, var(--border-width-sm))Controls action button border width.
--toast-action-colorvar(--color-foreground)Controls action text color.
--toast-action-font-sizevar(--text-xs)Controls action font size.
--toast-action-font-weightvar(--weight-medium)Controls action font weight.
--toast-action-line-heightvar(--line-height-text-xs)Controls action line height.
--toast-action-margin-top0.5remControls action spacing from the description.
--toast-action-padding-x0.5remControls action horizontal padding.
--toast-action-padding-y0.25remControls action vertical padding.
--toast-action-radiusvar(--radius-sm)Controls action button border radius.
--toast-anchored-arrow-height0.625remControls anchored toast arrow height.
--toast-anchored-arrow-offset-x-13pxControls horizontal anchored arrow offset.
--toast-anchored-arrow-offset-y-8pxControls vertical anchored arrow offset.
--toast-anchored-arrow-width1.25remControls anchored toast arrow width.
--toast-anchored-font-sizevar(--text-sm)Controls anchored toast font size.
--toast-anchored-line-heightvar(--line-height-text-sm)Controls anchored toast line height.
--toast-anchored-max-width20remControls anchored toast max width.
--toast-anchored-padding-x0.5remControls anchored toast horizontal padding.
--toast-anchored-padding-y0.25remControls anchored toast vertical padding.
--toast-anchored-scale0.9Controls anchored toast entering/leaving scale.
--toast-anchored-transitiontransform 150ms, opacity 150msControls anchored toast transition.
--toast-bgvar(--color-popover)Controls toast background color.
--toast-border-colorvar(--color-border)Controls toast border color.
--toast-border-widthvar(--border-width-sm)Controls toast border width.
--toast-close-bgtransparentControls close button background.
--toast-close-bg-hovervar(--color-accent)Controls close hover background.
--toast-close-colorvar(--color-muted-foreground)Controls close button color.
--toast-close-color-hovervar(--color-foreground)Controls close hover color.
--toast-close-focus-ring-offset0Controls close button focus ring offset.
--toast-close-icon-size1remControls default close icon size.
--toast-close-offset-right0.5remControls close button right offset.
--toast-close-offset-top0.5remControls close button top offset.
--toast-close-padding0Controls close button inner padding.
--toast-close-radiusvar(--radius-sm)Controls close button border radius.
--toast-close-size1.25remControls close button size.
--toast-colorvar(--color-popover-foreground)Controls toast text color.
--toast-content-gap0.25remControls spacing inside toast content.
--toast-description-colorvar(--color-muted-foreground)Controls description color.
--toast-description-font-sizevar(--text-sm)Controls description font size.
--toast-description-line-heightvar(--line-height-text-sm)Controls description line height.
--toast-focus-ring-colorvar(--color-ring)Controls action and close focus rings.
--toast-focus-ring-widthvar(--toast-border-width, var(--border-width-sm))Controls action and close focus ring width.
--toast-padding1remControls root toast padding.
--toast-radiusvar(--radius-lg)Controls toast border radius.
--toast-shadowvar(--shadow-lg)Controls toast shadow.
--toast-stack-gap0.75remControls expanded stack spacing.
--toast-stack-peek0.75remControls collapsed stack offset.
--toast-title-font-sizevar(--text-sm)Controls title font size.
--toast-title-font-weightvar(--weight-semibold)Controls title font weight.
--toast-title-line-heightvar(--line-height-text-sm)Controls title line height.
--toast-transition0.5s cubic-bezier(0.22, 1, 0.36, 1)Controls toast movement transition.
--toast-viewport-inset1remControls viewport distance from the window edge.
--toast-viewport-width20remControls the fixed toast viewport width.
--toast-z-indexvar(--z-toast)Controls toast portal and stack z-index.

Interactive variables scoped for docs preview without changing size scale tokens.

PropertyValueDefaultDescription
--toast-action-bgvar(--color-background)Controls action button background.
--toast-action-border-colorvar(--color-border)Controls action border color.
--toast-bgvar(--color-popover)Controls toast background color.
--toast-border-colorvar(--color-border)Controls toast border color.
--toast-colorvar(--color-popover-foreground)Controls toast text color.
--toast-description-colorvar(--color-muted-foreground)Controls description color.
--toast-focus-ring-colorvar(--color-ring)Controls action and close focus rings.
--toast-radiusvar(--radius-lg)Controls toast border radius.
--toast-shadowvar(--shadow-lg)Controls toast shadow.
--toast-title-font-sizevar(--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>
PartRole
ToastProviderProvides the stacked and anchored toast managers to the subtree.
ToastRegionRenders the shared portal and viewport for stacked toasts. Use placement and stackBehavior here.
ToastRootVisible notification surface. Use it inside renderToast when a custom toast layout is needed.
ToastContentContent wrapper for title, description, actions, icons, and custom layout.
ToastTitleRenders the toast title from the toast object.
ToastDescriptionRenders the toast description from the toast object.
ToastActionOptional action button rendered from actionProps in the default composition.
ToastCloseDismiss button with the default close icon, or custom children.
ToastAnchoredRegionRenders 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>  );}

On this page