Skip to main contentSkip to docs navigation

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; pass visible with onVisibleChange to 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. Reserve role="alert" for errors and messages requiring immediate attention. See Accessibility.
  • The icon/title/text/actions props are shorthand for the manual NotificationIcon/NotificationTitle/NotificationText composition — 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) the dismissible close icon — call useNotification() and wire its close to any element's onClick. See Dismissing.

Examples

Use <Notification> to give users feedback about common operations in a way that is visible and easily dismissed.

A simple notification — check it out!
JSX
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!

Aww yeah, you successfully read this important notification message.
JSX
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.

A simple primary notification—check it out!
A simple secondary notification—check it out!
A simple success notification—check it out!
A simple danger notification—check it out!
A simple warning notification—check it out!
A simple info notification—check it out!
JSX
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.

A simple primary notification—check it out!
A simple secondary notification—check it out!
A simple success notification—check it out!
A simple danger notification—check it out!
A simple warning notification—check it out!
A simple info notification—check it out!
JSX
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.

An example notification with an icon and a link.
An example notification with an icon and a link.
JSX
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

Body text has no margin — spacing between the title and text comes from the grid gap.
JSX
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

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.
JSX
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.

JSX
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.

Go right ahead and click that dismiss button over there on the right.
JSX
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.

JSX
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.

This notification dismisses itself after 5 seconds — hover or focus it to pause the timer.
JSX
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.

JSX
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

PropTypeDefault
actions?ReactNode—
Optional trailing content — e.g. a row of Buttons — rendered after text/children.
autohide?booleanfalse
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?stringClose
Overrides the dismiss button's accessible name (defaults to 'Close'). Set this for non-English UIs.
color?ContextColorprimary
Sets the color of the component to one of Chassis context colors.
defaultVisible?booleantrue
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?number5000
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?ElementTypeh4
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

PropTypeDefault
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

PropTypeDefault
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—
namestring—
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

PropTypeDefault
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

PropTypeDefault
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.