Notification
Chassis React Notification component gives contextual feedback for common user operations across the six semantic contexts.
Overview
Things to know when using Notification:
- It works standalone — render
<Notification>directly. It is shown and dismisses itself; passvisiblewithonVisibleChangeto control it, same as any other component. - Or push it into a stack — call
addNotification()from anywhere to queue one, and render a<NotificationStack>wherever it should appear. See Stacking. role="status"(the default) suits routine confirmations and informational updates. Reserverole="alert"for errors and messages requiring immediate attention. See Accessibility.- The
icon/title/text/actionsprops are shorthand for the manualNotificationIcon/NotificationTitle/NotificationTextcomposition — reach for manual composition only when a notification needs more than one block of body content. See Shorthand props. - To dismiss a notification from hand-composed markup — a labeled button in
actions, instead of (or alongside) thedismissibleclose icon — calluseNotification()and wire itscloseto any element'sonClick. See Dismissing.
Examples
Use <Notification> to give users feedback about common operations in a way that is visible and easily dismissed.
import { Notification } from '@chassis-ui/react'
export const Example = () => {
return <Notification>A simple notification — check it out!</Notification>
}Shorthand props
For the common case — an icon, a heading, one block of message text — icon/title/text render the same markup as composing NotificationIcon/NotificationTitle/NotificationText by hand, without the wiring. icon accepts an icon name string (rendered via NotificationIcon) or any other node for a fully custom icon; title renders through NotificationTitle (pass titleComponent to change its tag, default h4); text renders through a single NotificationText. When both title and text are set, the notification's aria-labelledby/aria-describedby are wired to them automatically.
Well done!
import { Notification } from '@chassis-ui/react'
export const Example = () => {
return (
<Notification
color="success"
icon="check-solid"
title="Well done!"
text="Aww yeah, you successfully read this important notification message."
dismissible
/>
)
}text wraps everything in one NotificationText — for multi-block content (more than one paragraph, or content mixing paragraphs with other elements), compose children manually instead, as shown in the sections below. actions is unstyled passthrough markup rendered after text/children, e.g. a row of buttons — see Actions.
The rest of this page documents the manual composition these props are shorthand for.
Colors
Use one of the required contextual color props (e.g., primary) for styling. For inline dismissal, use the dismissible prop.
import { Notification } from '@chassis-ui/react'
export const Example = () => {
return (
<>
<Notification color="primary">A simple primary notification—check it out!</Notification>
<Notification color="secondary">A simple secondary notification—check it out!</Notification>
<Notification color="success">A simple success notification—check it out!</Notification>
<Notification color="danger">A simple danger notification—check it out!</Notification>
<Notification color="warning">A simple warning notification—check it out!</Notification>
<Notification color="info">A simple info notification—check it out!</Notification>
</>
)
}Color alone doesn't convey meaning to assistive technology. Ensure information denoted by color is
either obvious from the visible text, or included through alternative means, such as additional
text hidden with the .visually-hidden class.
Solid style
Add the solid prop alongside a color for a filled, higher-emphasis treatment that swaps the soft background for the context's full color. Use it when the notification needs to stand out against a busy surrounding layout.
import { Notification } from '@chassis-ui/react'
export const Example = () => {
return (
<>
<Notification solid color="primary">
A simple primary notification—check it out!
</Notification>
<Notification solid color="secondary">
A simple secondary notification—check it out!
</Notification>
<Notification solid color="success">
A simple success notification—check it out!
</Notification>
<Notification solid color="danger">
A simple danger notification—check it out!
</Notification>
<Notification solid color="warning">
A simple warning notification—check it out!
</Notification>
<Notification solid color="info">
A simple info notification—check it out!
</Notification>
</>
)
}Notification icon
Render <NotificationIcon> as a child to add a leading icon sized and colored from the component's design tokens. Its presence switches the notification to a two-column grid — the icon in the first column, the message in the second — vertically centered by default. For multi-line messages, add className="align-self-start" to the icon so it aligns with the first line of text instead. NotificationIcon accepts the same props as Icon (name, size, font, title, sprite) and is hidden from assistive technology by default, since it duplicates the message visually — see Accessibility.
import { Notification, NotificationIcon, NotificationText } from '@chassis-ui/react'
export const Example = () => {
return (
<>
<Notification color="info">
<NotificationIcon name="info-circle-solid" />
<NotificationText>
An example notification with an icon and <a href="#">a link</a>.
</NotificationText>
</Notification>
<Notification color="info" solid>
<NotificationIcon name="info-circle-solid" />
<NotificationText>
An example notification with an icon and <a href="#">a link</a>.
</NotificationText>
</Notification>
</>
)
}Notification title
Wrap longer messages in <NotificationTitle> and one or more paragraphs to give them structure. NotificationTitle renders an <h4> by default — pass component to render a different element. The notification lays out its children on a grid; spacing between them comes from --notification-text-gap, not margin.
A notification with a title
import {
Notification,
NotificationIcon,
NotificationTitle,
NotificationText
} from '@chassis-ui/react'
export const Example = () => {
return (
<Notification color="success" dismissible>
<NotificationIcon name="check-solid" className="align-self-start" />
<NotificationTitle>A notification with a title</NotificationTitle>
<NotificationText>
Body text has no margin — spacing between the title and text comes from the grid gap.
</NotificationText>
</Notification>
)
}Notification text
NotificationText wraps the message in a <div> by default — pass component to render a different element. Unlike <p>, a <div> carries no default browser margin, so it needs no extra CSS to line up with the grid gap that already spaces a notification's children.
A notification with a title
import { Notification, NotificationTitle, NotificationText } from '@chassis-ui/react'
export const Example = () => {
return (
<Notification color="success" dismissible>
<NotificationTitle>A notification with a title</NotificationTitle>
<NotificationText>
Wrapping the message in a div sidesteps the browser's default paragraph margin, so no extra
CSS is needed to keep spacing consistent with the grid gap.
</NotificationText>
</Notification>
)
}Actions
When a notification carries action buttons, use flex utilities to compose them with the message and adapt across breakpoints. The example below stacks the message above the actions on narrow viewports and lays them side-by-side from xl upward.
A notification with inline actions — stacked on narrow viewports, side-by-side from xl up.
import { Notification, NotificationIcon, Button } from '@chassis-ui/react'
export const Example = () => {
return (
<Notification color="danger" role="alert" dismissible>
<NotificationIcon
name="exclamation-triangle-solid"
className="align-self-start xl:align-self-center"
/>
<div className="d-flex flex-column xl:flex-row gap-md">
<p className="m-0">
A notification with inline actions — stacked on narrow viewports, side-by-side from xl up.
</p>
<div className="hstack gap-sm align-items-center justify-content-end">
<Button color="danger" size="sm">
Take Action
</Button>
</div>
</div>
</Notification>
)
}Dismissing
Add the dismissible prop to render a close button and let users dismiss the notification. onClose fires once the fade-out transition finishes. The close button's accessible name defaults to 'Close' — override it with closeLabel for non-English UIs.
import { Notification } from '@chassis-ui/react'
export const Example = () => {
return (
<Notification
color="warning"
dismissible
onClose={() => {
alert('Dismissed!')
}}
>
<strong>Go right ahead</strong> and click that dismiss button over there on the right.
</Notification>
)
}Not every notification should be dismissed via the icon-only close button — sometimes a labeled action ("Dismiss", "Got it") in the actions row is the better fit, without dismissible's close icon at all. Call useNotification() from a child of Notification and wire its close to any element's onClick; there's no separate close subcomponent to reach for, the same normal Button works.
A notification dismissed by a normal button, not the close icon.
import { Button, Notification, useNotification } from '@chassis-ui/react'
const Actions = () => {
const { close } = useNotification()
return (
<div className="hstack gap-sm align-items-center justify-content-end">
<Button color="primary" size="sm">
Take Action
</Button>
<Button variant="outline" size="sm" onClick={close}>
Dismiss
</Button>
</div>
)
}
export const Example = () => {
return (
<Notification color="primary">
<p className="m-0">A notification dismissed by a normal button, not the close icon.</p>
<Actions />
</Notification>
)
}Auto-dismiss
Set autohide to dismiss the notification on its own after delay (defaults to 5000ms). Unlike Toast, Notification does not auto-hide by default — it's documented as a persistent banner, so opt in explicitly. The timer pauses while the pointer or keyboard focus is on the notification, and resumes when it leaves.
import { Notification } from '@chassis-ui/react'
export const Example = () => {
return (
<Notification color="info" icon="info-circle-solid" autohide>
This notification dismisses itself after 5 seconds — hover or focus it to pause the timer.
</Notification>
)
}Stacking
For notifications created at runtime — in response to a save, an upload, an error — call addNotification() from anywhere: an event handler, an async callback. It returns a key that can be passed to closeNotification() to dismiss it programmatically. NotificationStack subscribes to the same shared queue and renders whatever's currently in it; nothing else needs to know about it — pass dismissible in the options and its close button removes it from the queue on click, same as any other notification.
import { Button, NotificationStack, NotificationTitle, addNotification } from '@chassis-ui/react'
export const Example = () => {
const handleSave = () => {
addNotification(
<>
<NotificationTitle>Saved!</NotificationTitle>
Your changes have been saved successfully.
</>,
{ color: 'success', dismissible: true }
)
}
return (
<>
<Button color="primary" onClick={handleSave}>
Save changes
</Button>
<NotificationStack aria-label="Notifications" className="mt-md" />
</>
)
}NotificationStack doubles as a plain grouping wrapper, too — pass <Notification> elements to it directly as children and it just adds spacing between them, no queue required. Combine both: static children render first, followed by anything queued.
By default, the most recently queued notification renders first — the typical toast pattern. Pass reverse for a chronological transcript instead, oldest first.
Accessibility
Notification renders with role="status" by default — an implicitly polite live region suited to confirmation, progress, and informational messages ("Saved", "Upload complete"). For messages that need immediate attention — validation errors, failed operations, lost connection — pass role="alert" instead, which interrupts the screen reader rather than waiting for a pause. Pick the role from the message's urgency, not its color: a danger notification reporting passive state can stay status, and an info notification demanding an immediate response should be alert.
<NotificationIcon> is hidden from assistive technology (aria-hidden) by default, since it duplicates the adjacent text visually and shouldn't be announced separately. Pass a title if the icon ever needs to convey information the text doesn't.
Place the close button as the last child even when it's visually pinned to the top-right corner — dismissible already does this automatically, appending its CloseButton after children. Because status and alert are both implicitly aria-atomic, the whole notification is announced as one unit, so close-last means the message is read before the dismiss control, and it's also the last stop in tab order.
Dismissing a notification unmounts it, which can leave keyboard focus orphaned. Move focus in onClose — to the control that triggered the notification, the next one in a stack, or the main content landmark.
API
Notification
| Prop | Type | Default |
|---|---|---|
actions? | ReactNode | — |
Optional trailing content — e.g. a row of Buttons — rendered after text/children. | ||
autohide? | boolean | false |
Automatically dismiss the notification after delay. The timer pauses while the pointer
or focus is on the notification, and only starts once the notification is visible.
Defaults to false — unlike Toast, notifications are persistent banners by default. | ||
className? | string | — |
| A string of all className you want applied to the component. | ||
closeLabel? | string | Close |
Overrides the dismiss button's accessible name (defaults to 'Close'). Set this for
non-English UIs. | ||
color? | ContextColor | primary |
| Sets the color of the component to one of Chassis context colors. | ||
defaultVisible? | boolean | true |
Whether the notification is shown when it first renders. Such a notification is
uncontrolled: its close button and the autohide timer hide it. Use visible to show and
hide it from outside. | ||
delay? | number | 5000 |
Delay in ms before an autohide notification dismisses itself. | ||
dismissible? | boolean | — |
| Optionally add a close button to the notification and allow it to self dismiss. | ||
icon? | ReactNode | — |
Leading icon. A string is an icon name, rendered like <NotificationIcon name={icon} /> (or
by IconProvider's component); pass any other
node for a fully custom icon. Automatically top-aligns with title when both are set —
a custom icon node is responsible for its own alignment. | ||
onClose? | (() => void) | — |
| Callback fired once the notification has hidden: after its exit transition. | ||
onShow? | (() => void) | — |
| Callback fired when the notification starts to show. | ||
onVisibleChange? | ((visible: boolean) => void) | — |
Callback fired with false when the notification asks to hide: its close button, close
from useNotification, or the autohide timer. With visible set, the notification hides
only when visible becomes false. | ||
role? | "status" | "alert" | status |
ARIA live-region role. Use status (the default) for confirmation, progress, and
informational messages, which announce politely. Use alert for messages that need
immediate attention — validation errors, failed operations — which interrupt speech. | ||
solid? | boolean | — |
| Applies the solid context style to the notification. | ||
text? | ReactNode | — |
Message body, rendered via a single <NotificationText>. For multi-block content, compose
children manually instead — text wraps everything in one element. | ||
title? | ReactNode | — |
Heading, rendered via <NotificationTitle>. | ||
titleComponent? | ElementType | h4 |
Element or component used for the title heading. Passed through to NotificationTitle's
own component prop. Defaults to 'h4'. | ||
visible? | boolean | — |
Whether the notification is shown. Setting it makes the notification controlled: it hides
only when this becomes false, so pair it with onVisibleChange. Left unset, the
notification is shown and hides itself (see defaultVisible). | ||
NotificationTitle
| Prop | Type | Default |
|---|---|---|
asChild? | boolean | — |
Render the single child element in place of this component's own element, with this
component's classes, props and ref merged onto it: <Button asChild><Link href="/login">Log
in</Link></Button>. The alternative to component for React Server Components — an element
can be passed from the server to this package's client components, a component reference
(component={Link}) can't. | ||
className? | string | — |
| A string of all className you want applied to the base component. | ||
component? | ElementType | — |
| Component used for the root node. Either a string to use a HTML element or a component. | ||
ref? | any | — |
NotificationIcon
| Prop | Type | Default |
|---|---|---|
className? | string | — |
| A string of all className you want applied to the component. A string of all className you want applied to the base component. | ||
font? | boolean | — |
name | string | — |
Icon name, e.g. folder-tree. Matches an id in the SVG sprite, or a cx-{name} font glyph
class in font mode (see IconProvider's fontPrefix). | ||
size? | string | number | — |
Icon size: a number of pixels, or any CSS length ('1.25rem', '1em'). Sets chassis-css's
--cx-icon-size on the icon, so it applies in font mode too. Leave unset to keep the size
chassis-css gives icons in context (inside a button, an input, a navbar toggler, ...). | ||
sprite? | string | — |
URL of the SVG sprite file. Defaults to IconProvider's sprite, or to none — a sprite
embedded in the page, referenced as #name. Ignored in font mode. | ||
title? | string | — |
| Accessible name. When set, the icon is exposed to assistive tech instead of hidden. | ||
NotificationText
| Prop | Type | Default |
|---|---|---|
asChild? | boolean | — |
Render the single child element in place of this component's own element, with this
component's classes, props and ref merged onto it: <Button asChild><Link href="/login">Log
in</Link></Button>. The alternative to component for React Server Components — an element
can be passed from the server to this package's client components, a component reference
(component={Link}) can't. | ||
className? | string | — |
| A string of all className you want applied to the component. | ||
component? | ElementType | — |
| Component used for the root node. Either a string to use a HTML element or a component. | ||
ref? | any | — |
NotificationStack
| Prop | Type | Default |
|---|---|---|
className? | string | — |
| A string of all className you want applied to the base component. | ||
reverse? | boolean | — |
Queued notifications show newest-first by default — the typical toast pattern. Set
reverse for a chronological transcript instead, oldest-first. | ||