FeedbackReact
Generates toast notifications.
Rendered by React 19.3.1
Installation
npm i @hamur/reactNot on npm yet. The package goes out under the chosen name.
Anatomy
Import the component and assemble its parts:
<Toast.Provider>
<Toast.Portal>
<Toast.Viewport />
</Toast.Portal>
</Toast.Provider>
<Toast.Root>
<Toast.Content>
<Toast.Title />
<Toast.Description />
<Toast.Close />
</Toast.Content>
</Toast.Root>
// Not in this example: Toast.Action, Toast.Arrow, Toast.PositionerExamples
Anchored
Positioner and Arrow place a toast next to the button that made it, in its own Provider.
Position
The Viewport and Root styles move the stack to the top center.
Undo
An Action button inside the toast undoes what was done.
Promise
One toast moves from loading to success or error, styled by data-type.
Custom
A toast carries custom data that its rendering reads.
Deduplicate
Adding the same toast again updates it in place and replays a pulse.
Varying Heights
--toast-frontmost-height clamps the stack to the front toast, and data-behind hides the content behind it.
API reference
22 props across 11 parts, in React syntax. className, style, render are listed once, under Shared props.
ActionToast.Action
Performs an action when clicked. Renders a <button>.
| Prop | Type | Default |
|---|---|---|
nativeButtonWhether the component renders a native <button> element when replacing it | boolean | true |
| Data attribute | Description |
|---|---|
data-type | The type of the toast. |
ArrowToast.Arrow
Displays an element positioned against the toast anchor. Renders a <div>.
| Data attribute | Description |
|---|---|
data-side | Indicates which side the toast is positioned relative to the anchor. |
data-align | Indicates how the toast is aligned relative to specified side. |
data-uncentered | Present when the toast arrow is uncentered. |
CloseToast.Close
Closes the toast when clicked. Renders a <button>.
| Prop | Type | Default |
|---|---|---|
nativeButtonWhether the component renders a native <button> element when replacing it | boolean | true |
| Data attribute | Description |
|---|---|
data-type | The type of the toast. |
ContentToast.Content
A container for the contents of a toast. Renders a <div>.
| Data attribute | Description |
|---|---|
data-expanded | Present when the toast viewport is expanded. |
data-behind | Present when the toast is behind the frontmost toast in the stack. |
DescriptionToast.Description
A description that describes the toast. Can be used as the default message for the toast when no title is provided. Renders a <p>.
| Data attribute | Description |
|---|---|
data-type | The type of the toast. |
PortalToast.Portal
A portal element that moves the viewport to a different part of the DOM. By default, the portal element is appended to <body>. Renders a <div>.
| Prop | Type | Default |
|---|---|---|
containerA parent element to render the portal element into. | HTMLElement | ShadowRoot | React.RefObject<HTMLElement | ShadowRoot | null> | null | — |
PositionerToast.Positioner
Positions the toast against the anchor. Renders a <div>.
| Prop | Type | Default |
|---|---|---|
disableAnchorTrackingWhether to disable the popup from tracking any layout shift of its positioning anchor. | boolean | false |
toastrequiredThe toast object associated with the positioner. | ToastObject<any> | — |
alignHow to align the popup relative to the specified side. | Align | 'center' |
alignOffsetAdditional offset along the alignment axis in pixels. | number | OffsetFunction | 0 |
sideWhich side of the anchor element to align the toast against. | Side | 'top' |
sideOffsetDistance between the anchor and the popup in pixels. | number | OffsetFunction | 0 |
arrowPaddingMinimum distance to maintain between the arrow and the edges of the popup. | number | 5 |
anchorAn element to position the toast against. | Element | null | — |
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. | Padding | 5 |
stickyWhether to maintain the popup in the viewport after | boolean | false |
positionMethodDetermines which CSS position property to use. | "absolute" | "fixed" | 'absolute' |
| Data attribute | Description |
|---|---|
data-anchor-hidden | Present when the anchor is hidden. |
data-side | Indicates which side the toast is positioned relative to the trigger. |
data-align | Indicates how the toast is aligned relative to specified side. |
| CSS variable | Description |
|---|---|
--available-width | The available width between the anchor and the edge of the viewport. |
--available-height | The available height between the anchor and the edge of the viewport. |
--anchor-width | The anchor's width. |
--anchor-height | The anchor's height. |
--transform-origin | The coordinates that this element is anchored to. Used for animations and transitions. |
ProviderToast.Provider
Provides a context for creating and managing toasts.
| Prop | Type | Default |
|---|---|---|
limitThe maximum number of toasts that can be displayed at once. | number | 3 |
toastManagerA global manager for toasts to use outside of a React component. | ToastManager<any> | — |
timeoutThe default amount of time (in ms) before a toast is auto dismissed. | number | 5000 |
children | React.ReactNode | — |
RootToast.Root
Groups all parts of an individual toast. Renders a <div>.
| Prop | Type | Default |
|---|---|---|
swipeDirectionDirection(s) in which the toast can be swiped to dismiss. | "left" | "right" | "up" | "down" | ("left" | "right" | "up" | "down")[] | ['down', 'right'] |
toastrequiredThe toast to render. | ToastRootToastObject<any> | — |
| Data attribute | Description |
|---|---|
data-expanded | Present when the toast is expanded in the viewport. |
data-limited | Present when the toast was limited because the toast limit was exceeded. |
data-type | The type of the toast. |
data-swiping | Present when the toast is being swiped. |
data-swipe-direction | The direction the toast was swiped. |
data-starting-style | Present when the toast begins animating in. |
data-ending-style | Present when the toast is animating out. |
| CSS variable | Description |
|---|---|
--toast-index | Indicates the index of the toast in the list. |
--toast-offset-y | Indicates the vertical pixels offset of the toast in the list when expanded. |
--toast-height | Indicates the measured natural height of the toast in pixels. |
--toast-swipe-movement-x | Indicates the horizontal swipe movement of the toast. |
--toast-swipe-movement-y | Indicates the vertical swipe movement of the toast. |
TitleToast.Title
A title that labels the toast. Renders a <h2>.
| Data attribute | Description |
|---|---|
data-type | The type of the toast. |
ViewportToast.Viewport
A container viewport for toasts. Renders a <div>.
| Data attribute | Description |
|---|---|
data-expanded | Indicates toasts are expanded in the viewport. |
| CSS variable | Description |
|---|---|
--toast-frontmost-height | Indicates the height of the frontmost toast. |
Shared props
Every part that renders an element takes these.
| Prop | Type |
|---|---|
classNameCSS class applied to the element, or a function that
returns a class based on the component's state. | string | ((state: State) => string | undefined) |
styleStyle applied to the element, or a function that
returns a style object based on the component's state. | React.CSSProperties | ((state: State) => React.CSSProperties | undefined) |
renderAllows you to replace the component's HTML element
with a different tag, or compose it with another component. | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, State> |
Keyboard and accessibility
Keyboard
| Keys | Does | Part |
|---|---|---|
| F6 | Moves focus to the viewport | Viewport |
| Tab | From the focused viewport, moves to the first toast | Viewport |
| ShiftTab | From the first toast, returns focus to where it was before | Viewport |
| F6 | From inside the viewport, returns focus to where it was before | Viewport |
| Escape | Closes the focused toast | Root |
Accessibility
| Part | Sets | So that |
|---|---|---|
| Viewport | role="region", aria-label="Notifications" | screen reader users can find the toasts as a landmark |
| Viewport | aria-live="polite", aria-relevant="additions text", aria-atomic="false" | a new toast is read when the reader is idle, without rereading the others |
| Viewport | a visually hidden role="alert" copy of each high-priority toast while focus is outside | urgent toasts are announced at once |
| Root | role="dialog" (role="alertdialog" for a high-priority toast), aria-modal="false" | a focused toast is read as a small dialog that does not block the page |
| Root | aria-labelledby to Title, aria-describedby to Description | the toast is announced with its heading and message |
| Close | aria-hidden while the stack is collapsed and not focused | hidden close buttons are not read |
| Arrow | aria-hidden="true" | the decorative arrow is not read |
Focus order
- Toasts never take focus on their own; the page keeps it.
F6moves focus to Viewport, andTabmoves on to the first toast and through its buttons.Shift+Tabfrom the first toast, orF6again, returns focus to where it was.