JGuang

Banner

Banner · Astryx

Preview
npm install @astryxdesign/core@0.7.1 @astryxdesign/theme-neutral@0.7.1 @stylexjs/stylex@0.19.0

Banner

Banner shows a persistent message at the top of a page or section. Use it for form errors, system updates, maintenance notices, or success confirmations that the user needs to see until they act on it.

Installation

npm install @astryxdesign/core@0.7.1 @astryxdesign/theme-neutral@0.7.1 @stylexjs/stylex@0.19.0

Requires React 19+, base CSS and a Theme provider. See Setup.

Banner shows a persistent message at the top of a page or section. Use it for form errors, system updates, maintenance notices, or success confirmations that the user needs to see until they act on it.

PropTypeDefaultDescription
status *'info' | 'warning' | 'error' | 'success'Status type controlling icon and color.
title *ReactNodeTitle text or ReactNode displayed in the header.
descriptionReactNodeDescription text rendered below the title in the header.
iconReactNodeOverride the default status icon.
isDismissablebooleanfalseWhether the banner can be dismissed by the user.
onDismiss() => voidCalled when the dismiss button is clicked; banner hides itself regardless of whether this is provided.
dismissLabelstringAccessible name and visible tooltip for the dismiss button (pass it already translated). Defaults to "Dismiss <title>" for a string title, so stacked banners are distinguishable; set it when the title is a ReactNode.
endContentReactNodeAction content rendered in the header area, end-aligned. Wraps to its own row below the text when the header is too narrow to hold both.
container'card' | 'section''card'Container type: card has border-radius; section is full-width with no border-radius for page-level use.
elevation'none' | 'low' | 'med' | 'high''none'Resting shadow depth. Use for a floating banner that hovers above content; none is the default inline banner. A card-container banner rounds its shadow to match.
childrenReactNodeContent rendered in the card-background area below the colored header. Sits behind an expand/collapse toggle unless collapsible={false}.
collapsibleboolean | {defaultIsOpen?: boolean; isOpen?: boolean; onOpenChange?: (isOpen: boolean) => void}trueWhether the content area (children) sits behind an expand/collapse toggle in the header. On by default, starting collapsed. false opts out: children are always visible with no toggle. {defaultIsOpen: true} starts open; {isOpen, onOpenChange} is controlled. Takes the same CollapsibleConfig as Collapsible.
xstyleStyleXStylesStyleX styles for layout customization (margins, positioning, sizing). Must be a stylex.create() value, not an inline style object like style={{}}.

Usage guidance

  • Pick a status that matches the message: info for updates, warning for caution, error for problems, success for confirmations.
  • Use the card container inside page content and the section container for full-width messages that span the entire page.
  • Make info and success banners dismissable. Keep error banners visible until the user fixes the issue.
  • Keep titles short and scannable: "Payment failed" not "There was a problem processing your most recent payment."
  • Avoid: Use Banner for short-lived messages that disappear on their own; use Toast instead.
  • Avoid: Stack multiple banners with the same status; combine related messages into one banner.
  • Set collapsible={false} when the user needs the content to act on the message, like the list of fields that failed validation. Keep the default toggle when the detail is long enough to bury the banner's own message.
  • Banner status controls color and icon only; it does not create a live region. Announce async outcomes from the transition handler with useAnnounce. Add an explicit role="status" only when the visible banner is intended as a persistent semantic mirror; reserve role="alert" for genuinely urgent, interruptive content.
  • Avoid: Rely on the status color or icon alone to carry meaning; say which status it is in the title text, because the icon is decorative to a screen reader.

Announce an async outcome from its transition handler

import {useState} from 'react';
import {Banner} from '@astryxdesign/core/Banner';
import {Button} from '@astryxdesign/core/Button';
import {useAnnounce} from '@astryxdesign/core/hooks';

function SaveSettings() {
  const announce = useAnnounce();
  const [result, setResult] = useState<'success' | 'error' | null>(null);

  async function handleSave() {
    try {
      await saveSettings();
      setResult('success');
      announce('Settings saved');
    } catch {
      setResult('error');
      announce('Settings could not be saved');
    }
  }

  return (
    <>
      <Button label="Save settings" onClick={handleSave} />
      {result != null ? (
        <Banner
          status={result}
          title={result === 'success' ? 'Settings saved' : 'Save failed'}
        />
      ) : null}
    </>
  );
}

Theming API

{
  "targets": [
    {
      "className": "astryx-banner-frame",
      "visualProps": [
        "container",
        "elevation"
      ]
    },
    {
      "className": "astryx-banner",
      "visualProps": [
        "container",
        "status"
      ]
    },
    {
      "className": "astryx-banner-icon",
      "visualProps": [
        "status"
      ]
    },
    {
      "className": "astryx-banner-description"
    },
    {
      "className": "astryx-banner-content",
      "visualProps": [
        "container",
        "status"
      ]
    }
  ],
  "vars": [
    {
      "name": "--_banner-radius",
      "description": "Border radius of the card container (header, content area and the elevated root silhouette)",
      "default": "var(--radius-container)",
      "private": true
    }
  ],
  "derived": [
    {
      "property": "borderRadius",
      "vars": [
        "--_banner-radius"
      ]
    }
  ]
}

Anatomy

  • Banner frame: Outer frame that groups the status surface and optional content surface. It carries whole-banner elevation and, for elevated card banners, the radius that shapes that silhouette.
  • Status surface: The primary painted surface. It communicates status and contains the icon, title, description, actions, and controls.
  • Icon: Automatically set based on the status (info, warning, error, success).
  • Title: The main message. Always required.
  • Description: Additional detail below the title.
  • Action button: A button for the user to act on the message, like "Review" or "Retry".
  • Dismiss button: Lets the user close the banner. Enabled by setting isDismissable.
  • Content surface: Secondary surface for extra detail below the status surface, like a list of errors. Sits behind an expand/collapse toggle by default; set collapsible={false} to keep it visible.

Examples

  • Banner — Statuses: All four status banners stacked: info, success, warning, and error. A quick visual reference for choosing the right status.
  • Banner — Collapsible: Combine an action button, dismiss control, and a collapsible detail area in one banner. Children sit behind the toggle by default; collapsible={{defaultIsOpen: true}} starts it open, and collapsible={false} drops the toggle entirely. Use for complex notifications like config changes or deployment summaries.
  • Banner — Dismiss: Let the user close a banner after reading it. Use for maintenance notices, feature tips, or any non-critical message the user can acknowledge.
  • Banner — Floating: A floating banner raised with elevation="med". Banners are inline by default; raise one when it should read as an overlay above content.
  • Banner — Full Width: A full-width banner with no border radius for page-level notifications. Use at the top of a page for site-wide announcements or maintenance alerts.
  • Banner — Statuses: All 4 banner statuses: info, success, warning, and error. Use to show persistent messages like updates, confirmations, cautions, or problems at the top of a page or section.
  • Banner — Action: Add a button to a banner so the user can act on the message. Use for trial expirations, payment failures, or anything that needs a response.