Skip to content

Toast

An individual toast notification.

Saved successfully
<Toast {...args} onDismiss={() => {}} />
<Toast {...args} onDismiss={() => {}} />
Saved successfully
<Toast {...args} onDismiss={() => {}} />
<Toast {...args} onDismiss={() => {}} />
function HookStory(): React.JSX.Element {
const toast = useToast();
return (
<HStack gap={2}>
<Button
label="Info"
onClick={() => toast({body: 'Saved successfully'})}
/>
<Button
label="Success"
onClick={() => toast({body: 'Changes published', type: 'success'})}
/>
<Button
label="Warning"
onClick={() => toast({body: 'Storage almost full', type: 'warning'})}
/>
<Button
label="Error"
onClick={() => toast({body: 'Unable to save', type: 'error'})}
variant="destructive"
/>
</HStack>
);
}
<ToastViewport>
<HookStory />
</ToastViewport>
function AutoDismissStory(): React.JSX.Element {
const toast = useToast();
return (
<Button
label="Show auto-dismiss toast"
onClick={() =>
toast({
body: 'This will disappear in 3 seconds',
autoHideDuration: 3000,
})
}
/>
);
}
<ToastViewport>
<AutoDismissStory />
</ToastViewport>
function WithEndContentStory(): React.JSX.Element {
const toast = useToast();
return (
<Button
label="Show with action"
onClick={() =>
toast({
body: 'Item deleted',
endContent: <Button label="Undo" size="sm" variant="onSolid" />,
})
}
/>
);
}
<ToastViewport>
<WithEndContentStory />
</ToastViewport>

Toasts render inside the topmost open modal, so they stay above it and their actions stay clickable. Toasts shown earlier move with them without restarting their timers.

Toasts render inside the topmost open modal, so they stay above it and their actions stay clickable. Toasts shown earlier move with them without restarting their timers.

function OverDialogStory(): React.JSX.Element {
const toast = useToast();
const showActionToast = useActionToast();
const [isOpen, setIsOpen] = useState(false);
return (
<>
<HStack gap={2}>
<Button
label="Show toast with action"
onClick={() => showActionToast('Shown before the dialog')}
/>
<Button
label="Show 8s toast"
onClick={() =>
toast({body: 'Hides 8s after it was shown', autoHideDuration: 8000})
}
/>
<Button label="Open dialog" onClick={() => setIsOpen(true)} />
</HStack>
<ToastDemoDialog depth={1} isOpen={isOpen} onOpenChange={setIsOpen} />
</>
);
}
function ToastDemoDialog({
depth,
isOpen,
onOpenChange,
}: {
depth: number;
isOpen: boolean;
onOpenChange: (isOpen: boolean) => void;
}): React.JSX.Element {
const toast = useToast();
const showActionToast = useActionToast();
const [isNestedOpen, setIsNestedOpen] = useState(false);
const name = depth === 1 ? 'dialog' : 'nested dialog';
return (
<Dialog
isOpen={isOpen}
label={depth === 1 ? 'Edit item' : 'Confirm'}
onOpenChange={onOpenChange}
width={depth === 1 ? 560 : 440}>
<Layout
content={
<LayoutContent>
<Text as="p" color="secondary">
Toasts render inside the topmost open modal, so they stay above it
and their actions stay clickable. Toasts shown earlier move with
them without restarting their timers.
</Text>
<HStack gap={2} wrap="wrap">
<Button
label="Show toast"
onClick={() => toast({body: `Shown from the ${name}`})}
/>
<Button
label="Show toast with action"
onClick={() => showActionToast(`Deleted from the ${name}`)}
/>
{depth === 1 ? (
<Button
label="Open nested dialog"
onClick={() => setIsNestedOpen(true)}
/>
) : null}
</HStack>
{depth === 1 ? (
<ToastDemoDialog
depth={2}
isOpen={isNestedOpen}
onOpenChange={setIsNestedOpen}
/>
) : null}
</LayoutContent>
}
footer={
<LayoutFooter
primaryButton={
<Button label="Close" onClick={() => onOpenChange(false)} />
}
/>
}
/>
</Dialog>
);
}
<ToastViewport>
<OverDialogStory />
</ToastViewport>
A new version is available
Your export is ready
<div style={{display: 'flex', flexDirection: 'column', gap: '1rem'}}>
<Toast
autoHideDuration={5000}
body="A new version is available"
endContent={<Button label="Update now" size="sm" variant="primary" />}
isAutoHide={false}
onDismiss={() => {}}
type="info"
/>
<Toast
autoHideDuration={5000}
body="Your export is ready"
endContent={<Button label="Download" size="sm" variant="primary" />}
isAutoHide={false}
onDismiss={() => {}}
type="success"
/>
<Toast
autoHideDuration={5000}
body="Storage almost full"
endContent={<Button label="Upgrade plan" size="sm" variant="primary" />}
isAutoHide={false}
onDismiss={() => {}}
type="warning"
/>
<Toast
autoHideDuration={5000}
body="Unable to save"
endContent={<Button label="Retry" size="sm" variant="primary" />}
isAutoHide={false}
onDismiss={() => {}}
type="error"
/>
</div>
function PositionsStory(): React.JSX.Element {
const [position, setPosition] = useState<ToastPosition>('bottomEnd');
return (
<ToastViewport position={position}>
<PositionButtons onChangePosition={setPosition} position={position} />
</ToastViewport>
);
}
function PositionButtons({
position,
onChangePosition,
}: {
onChangePosition: (p: ToastPosition) => void;
position: ToastPosition;
}): React.JSX.Element {
const toast = useToast();
const positions: ToastPosition[] = [
'topStart',
'topEnd',
'bottomStart',
'bottomEnd',
];
return (
<HStack gap={2}>
{positions.map(p => (
<Button
key={p}
label={p}
onClick={() => {
onChangePosition(p);
requestAnimationFrame(() => toast({body: `Position: ${p}`}));
}}
variant={p === position ? 'primary' : 'secondary'}
/>
))}
</HStack>
);
}
<PositionsStory />

An individual toast notification.

PropTypeDefaultDescription
autoHideDuration*number—Auto-dismiss duration in milliseconds.
body*ReactNode—Toast message content.
classNamestring—Additional CSS class names applied to the toast.
data-testidstring—Test ID applied to the toast.
endContentReactNode—Content rendered before the dismiss button.
isAutoHide*boolean—Whether the toast auto-dismisses.
isExitingbooleanfalseWhether the toast is exiting.
isPausedbooleanfalseWhether the toast auto-dismiss timer is paused by its container.
onDismiss*(reason: ToastDismissReason) => void—Called when the toast should be dismissed.
refRef<HTMLDivElement>—Ref forwarded to the toast element.
styleCSSProperties—Inline styles applied to the toast.
type*"error" | "info" | "success" | "warning"—Toast tone.

Toast provider and viewport. Mount once near the app root to enable toast notifications. Components below this provider can call `useToast()` to show toasts.

PropTypeDefaultDescription
childrenReactNode—App content that should receive the toast context.
classNamestring—Additional CSS class names applied to the viewport.
data-testidstring—Test ID applied to the viewport.
insetReadonly<ToastViewportInset>—Custom viewport inset.
isTopLayerbooleantrueWhether to promote the viewport to the CSS top layer using popover. While a modal dialog is open, a top-layer viewport moves inside it so its toasts stay visible and operable above the modal.
maxVisiblenumber5Maximum visible toast count.
position"bottomEnd" | "bottomStart" | "topEnd" | "topStart"'bottomEnd'Toast stack position.
refRef<HTMLDivElement>—Ref forwarded to the viewport element.
styleCSSProperties—Inline styles applied to the viewport.