Raft 设计系统

组件 · 反馈

Toast

A dark floating notice that confirms the result of something the person just did, disappears after a few seconds, and can offer View or Undo.

稳定也叫 Snackbar
import { Toast } from "@botiverse/raft-ui";
本页尚未翻译
译文完成之前,这里显示英文原文。 阅读英文版

A toast is the receipt for something the person just did: a message sent, a setting saved, an agent finishing the job they just gave it. It floats above the page on the dark HUD, says one sentence, and goes away after a few seconds. It can carry one text action, such as View or Undo.

toast/compositions/toast

When to use

SituationUse
Something the person just did has a resultToast
An action that can be reversed in placeDo it; when a toast offers Undo is in Feedback
The state of the whole serverNotificationCenter
Something that happened elsewhereActivityInbox
Something to confirm or decideDialog
Something to read before actingBanner

Never put anything in a toast that would confuse people if they missed it (Choosing a component).

Anatomy

  • ToastProvider: holds the toast manager and, by default, renders the viewport. Mount it once near the root.
  • toast: the command API (toast.success, toast.error, …) for the default manager.
  • ToastViewport: where toasts appear on screen. ToastPositioner and ToastArrow anchor a toast to an element instead.
  • ToastRoot and ToastContent: one toast and its layout.
  • ToastIcon: optional. Who did it (an avatar), or a status pixel when there is no "who".
  • ToastBody, holding ToastTitle (required) and an optional ToastDescription, both in text-callout (Typography): 14/20 on a phone, 14/22 on a desktop, like a banner. ToastIcon is one line of that text tall, so the icon stays on the title's line: a status light in it is 9px and an icon 16px, centered in a 20px column 12px before the title, as is an avatar (A mark that leads text).
  • ToastActions: optional, holding one ToastAction and ToastClose.
  • ToastProgress: an optional line that shows the time left before it closes.

Leave out a part you don't need instead of rendering it empty.

Variants

The intent sets the pixel in ToastIcon. When the toast is about someone, show their avatar there instead.

IntentUse for
A person or agent did itTheir avatar in ToastIcon: "Bugen finished reviewing #25."
successSomething finished or saved
warning, errorSomething went wrong. error is announced at a higher priority
infoA neutral result, such as "3 links copied."
A message sent as a taskThe Todo pixel in ToastIcon

With the toast command API, pass the avatar as leading. It takes the pixel's place in ToastIcon, hidden from assistive technology.

toast/compositions/person

Behavior

  • A toast closes on its own after the provider's timeout; hovering or focusing it pauses the timer.
  • People can swipe a toast away, or close it with ToastClose.
  • Stacked toasts appear at the bottom center by default. An anchored toast opens next to the control that caused it.

Content

  • Write one sentence: who, what they did, and the result. Put anything more in ToastDescription, in foreground-on-hud-muted.
  • Label the action View or Undo, or another verb in Title Case.
  • Set IDs, counts and times in Space Mono (Typography).

Accessibility

Toast wraps Base UI's Toast, which announces each toast in a live region and keeps it open while it has focus.

  • Make ToastTitle carry the whole meaning. The pixel in ToastIcon is hidden from assistive technology, and so is ToastProgress.
  • Hide an avatar in ToastIcon with aria-hidden; the name is already in the text. The command API's leading does this for you.
  • Pass loadingLabel to a ToastAction that shows a loading state, so its spinner says what it waits for.

Rules

  • Show at most one toast at a time.
  • Use layer-hud for every toast, with foreground-on-hud text. Don't tint a toast with an intent color, and never use yellow: notices are neutral (Color).
  • Make the action a bold text action that underlines on hover (ToastAction), never a button. Never put a colored button in a toast.
  • Give a toast at most one action besides closing it.

API

ToastAction

Prop类型默认值
loadingbooleanfalse
loadingLabelstring"Loading"
nativeButtonWhether the component renders a native `<button>` element when replacing it via the `render` prop. Set to `false` if the rendered element is not a button (for example, `<div>`).booleantrue
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component.ReactElement | ((props, state) => ReactElement)

Also takes the attributes of its element.

ToastActions

接受其元素的全部属性。

ToastArrow

Prop类型默认值
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component.ReactElement | ((props, state) => ReactElement)

Also takes the attributes of its element.

ToastBody

接受其元素的全部属性。

ToastClose

Prop类型默认值
nativeButtonWhether the component renders a native `<button>` element when replacing it via the `render` prop. Set to `false` if the rendered element is not a button (for example, `<div>`).booleantrue
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component.ReactElement | ((props, state) => ReactElement)

Also takes the attributes of its element.

ToastContent, ToastDescription

The content layout (self-start, title-only sizing, body centering) needs to know which parts actually rendered. That used to be an ancestor `:has()` styling descendants — a whole-page recalculation trap in Chromium (#386). It measures the rendered DOM after layout instead, so wrapped parts and parts that render nothing behave exactly like the old selectors did.
Prop类型默认值
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component.ReactElement | ((props, state) => ReactElement)

Also takes the attributes of its element.

ToastIcon

接受其元素的全部属性。

ToastPortal

Prop类型默认值
containerA parent element to render the portal element into.HTMLElement | ShadowRoot | RefObject<HTMLElement | ShadowRoot | null>
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component.ReactElement | ((props, state) => ReactElement)

Also takes the attributes of its element.

ToastPositioner

Prop类型默认值
alignHow to align the popup relative to the specified side.Align'center'
alignOffsetAdditional offset along the alignment axis in pixels. Also accepts a function that returns the offset to read the dimensions of the anchor and positioner elements, along with its side and alignment.number | OffsetFunction0
anchorAn element to position the toast against.Element
arrowPaddingMinimum distance to maintain between the arrow and the edges of the popup.number5
collisionAvoidanceDetermines how to handle collisions when positioning the popup.CollisionAvoidance
collisionBoundaryAn element or a rectangle that delimits the area that the popup is confined to.Boundary'clipping-ancestors'
collisionPaddingAdditional space to maintain from the edge of the collision boundary.Padding5
disableAnchorTrackingWhether to disable the popup from tracking any layout shift of its positioning anchor.booleanfalse
positionMethodDetermines which CSS `position` property to use."fixed" | "absolute"'absolute'
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component.ReactElement | ((props, state) => ReactElement)
sideWhich side of the anchor element to align the toast against. May automatically change to avoid collisions.Side'top'
sideOffsetDistance between the anchor and the popup in pixels. Also accepts a function that returns the distance to read the dimensions of the anchor and positioner elements, along with its side and alignment.number | OffsetFunction0
stickyWhether to maintain the popup in the viewport after the anchor element was scrolled out of view.booleanfalse
toast (required)The toast object associated with the positioner.ToastObject<any>

Also takes the attributes of its element.

ToastProgress

Prop类型默认值
durationnumberDEFAULT_TOAST_TIMEOUT_MS

Also takes the attributes of its element.

ToastProvider

Prop类型默认值
portalContainerHTMLElement | ShadowRoot | RefObject<HTMLElement | ShadowRoot | null>
renderViewportbooleantrue
viewportClassNamestring
viewportPlacement"none" | "bottom-right" | "top-right" | "bottom-center" | "top-center""bottom-center"
viewportStrategy"fixed" | "absolute""fixed"
childrenReactNode
limitThe maximum number of toasts that can be displayed at once. When the limit is exceeded, the oldest toasts are marked as `limited` (via the `data-limited` attribute) rather than removed, so they can be hidden or animated out.number3
timeoutThe default amount of time (in ms) before a toast is auto dismissed. A value of `0` will prevent the toast from being dismissed automatically.numberDEFAULT_TOAST_TIMEOUT_MS
toastManagerA global manager for toasts to use outside of a React component.ToastManager<any>defaultToastManager

ToastRoot

Prop类型默认值
layout"inline" | "stacked""stacked"
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component.ReactElement | ((props, state) => ReactElement)
swipeDirectionDirection(s) in which the toast can be swiped to dismiss."up" | "down" | "left" | "right" | ("up" | "down" | "left" | "right")[]['down', 'right']
toast (required)The toast to render.ToastRootToastObject<any>

Also takes the attributes of its element.

ToastTitle

Prop类型默认值
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component.ReactElement | ((props, state) => ReactElement)

Also takes the attributes of its element.

ToastViewport

Prop类型默认值
placement"none" | "bottom-right" | "top-right" | "bottom-center" | "top-center""bottom-center"
strategy"fixed" | "absolute""fixed"
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component.ReactElement | ((props, state) => ReactElement)

Also takes the attributes of its element.

改动

  • 0.9.6 · Addedtoast.add/info/success/warning/error(title, { leading }) puts a node, such as a person's avatar, in ToastIcon in place of the status pixel. It is aria-hidden and still shows with icon: false. Calls without leading render exactly as before.
  • 0.5.35 · ChangedToastContent measures its rendered content and writes data-has-icon, data-has-description and data-has-actions on itself; the content layout keys off these attributes instead of descendant selectors.