Dots

Alert Banner

An account or feature state shown above the content it affects, with what to do and an optional deadline.

The AlertBanner shows a state of the account or a feature that lasts until the user acts on it: details to confirm, an account under review, a frozen card, a closing account. It has an icon, a title naming the state, one line on what to do and an optional deadline, and the whole banner can open the screen that resolves it. Use Alert for a message about the content on the current screen, and ActionToast for the result of an action that goes away on its own.

Installation

pnpm dlx shadcn@latest add @dots/alert-banner

Usage

import {
  AlertBanner,
  AlertBannerContent,
  AlertBannerDescription,
  AlertBannerIcon,
  AlertBannerMeta,
  AlertBannerTitle,
} from "@/components/ui/alert-banner"
<AlertBanner href="/account/details">
  <AlertBannerIcon>
    <UserCheckIcon />
  </AlertBannerIcon>
  <AlertBannerContent>
    <AlertBannerTitle>Confirm your details</AlertBannerTitle>
    <AlertBannerDescription>Takes a minute.</AlertBannerDescription>
    <AlertBannerMeta>Due Nov 30 · 20 days left</AlertBannerMeta>
  </AlertBannerContent>
</AlertBanner>

Composition

Use the following composition to build an alert banner:

AlertBanner
├── AlertBannerIcon
├── AlertBannerContent
│   ├── AlertBannerTitle
│   ├── AlertBannerDescription
│   └── AlertBannerMeta
└── AlertBannerAction

Features

  • Three statuses: default, warning and destructive, colouring only the icon, never the text
  • A screen reader prefix, "Warning" or "Urgent", so the status is not carried by colour alone
  • Static, link (href) or button (onPress) in one component; a pressable banner gets a chevron
  • One next step as a kit Button pill, which turns into a plain label inside a pressable banner
  • Two sizes: a card with a 44px icon tile, and a 44px strip for inner screens

Status

Use status="warning" for a risk of losing access to money and status="destructive" for a problem that blocks it. Keep default for everything else.

Pressable

Pass href to make the whole banner one link, or onPress to make it one button, for example to open a sheet. A chevron is added at the end, unless there is an AlertBannerAction, which then renders as a label.

Press the banner

"use client"

import * as React from "react"

Action

On a static banner, AlertBannerAction is a real button. Use it for a state the user can change in place, such as freezing a card.

Card is frozenPayments are declined until you unfreeze it.
"use client"

import * as React from "react"

Compact

Use size="compact" for a 44px strip on inner screens, such as above a card's settings. AlertBannerMeta is hidden on the strip, so put the deadline in the description.

Accessibility

A pressable banner renders a React Aria Link (with href) or Button (with onPress), so the whole banner is one control with press, focus and keyboard handling. A static banner renders a <div>, and its AlertBannerAction is the kit Button.

Status is spoken

Before the content, the banner reads "Warning:" or "Urgent:" for those statuses. Pass statusLabel to change the word, or statusLabel="" to drop it.

<AlertBanner status="warning" statusLabel="Action needed" href="/closing">
  {/* ... */}
</AlertBanner>

Live region

The banner sets no live-region role. When it appears in response to an action, wrap it in <div role="status">, or role="alert" for a blocking problem. Never put a live role on a pressable banner itself; it would replace the link or button role.

One control at a time

Inside a pressable banner, AlertBannerAction is inert text so that presses and focus belong to the banner. Do not nest other buttons or links in a pressable banner.

Icons

AlertBannerIcon is decorative. Make sure the title names the state on its own.

API Reference

AlertBanner

The banner. Renders a <div>, or a React Aria Link with href, or a React Aria Button with onPress, and accepts the props of the element it renders.

PropTypeDefaultDescription
status"default" | "warning" | "destructive""default"The severity. Only the icon and the compact strip's fill take the colour.
size"default" | "compact""default"A card with an icon tile, or a 44px strip.
statusLabelstring-Read before the content. Defaults to "Warning" and "Urgent"; "" drops it.
hrefstring-Makes the whole banner one link.
onPress(e: PressEvent) => void-Makes the whole banner one button. Not allowed with href.
classNamestring-Additional classes to apply.

AlertBannerIcon

The icon, in a 44px tile on the default size and bare on the compact strip. A round image fills the tile. Hidden from assistive technology.

PropTypeDefaultDescription
classNamestring-Additional classes to apply.

AlertBannerContent

Wraps the title, description and meta.

PropTypeDefaultDescription
classNamestring-Additional classes to apply.

AlertBannerTitle

Names the state, such as "Passport expires in 22 days".

PropTypeDefaultDescription
classNamestring-Additional classes to apply.

AlertBannerDescription

What it means or what to do, in one phrase.

PropTypeDefaultDescription
classNamestring-Additional classes to apply.

AlertBannerMeta

The deadline or date. Hidden on the compact strip.

PropTypeDefaultDescription
classNamestring-Additional classes to apply.

AlertBannerAction

The one next step. Renders a Button on a static banner and accepts its props except size; inside a pressable banner it renders the same pill as text.

PropTypeDefaultDescription
variantButton["variant"]"secondary" for default, "default" otherwiseThe button variant.
onPress(e: PressEvent) => void-Called on press. Ignored inside a pressable banner.