Brik Design System
Components

Banner group

Vertical stack of Banner elements with locked spacing, for a surface carrying more than one notice.

BannerGroup is the vertical-axis sibling of BadgeGroup and TagGroup. It replaces the per-banner marginBottom and the ad-hoc Stack wrapper consumers reach for when a page needs more than one Banner.

The order, placement, and don't-stack rules live in the banner-groups build standard — this page is the API.

Use it for

  • A page whose top region carries two or more banners (an account-level alert plus a page-level nudge)
  • A small, bounded set of same-tone banners where each item needs its own action
  • Any surface where the banner set is assembled from data and the count varies

Import

import { BannerGroup, Banner } from '@brikdesigns/bds';

Variants

Default

Children render in source order — sort before you map. negative → warning → info → positive → announcement.

Gap sizes

Three locked gaps — md (default) so the banners read as one notice block, sm for two facets of one incident, lg only when the banners are genuinely unrelated.

Pattern: the top of a page

The canonical use — the first child of PageContent, above the first section. The group spaces its own children; the space below it comes from PageContent's gap, so nothing here carries a margin.

import { Banner, BannerGroup, Button, Page, PageContent, PageHeader } from '@brikdesigns/bds';

<Page padding="none">
  <PageHeader title="Good morning, Nick" subtitle="Portal activity and quick stats." />

  <PageContent>
    <BannerGroup>
      {alerts.map((a) => (
        <Banner key={a.id} tone="warning" title={a.title} description={a.description} />
      ))}
      <Banner
        title="Want to set up a new client?"
        description="Click to begin the setup workflow for new clients."
        action={<Button variant="on-color" size="md" href="/admin/companies/new">Get Started</Button>}
      />
    </BannerGroup>

    {/* sections… */}
  </PageContent>
</Page>

When not to use

Don't wrap a statically single Banner. If the surface has one banner and always will, the group adds a DOM node and no arrangement — render <Banner> directly and let the parent layout's gap space it. The same rule BadgeGroup and TagGroup carry.

A data-driven set keeps its group even when today's data yields one banner: the count varies per render, and toggling between a group and a bare banner puts the arrangement rule back in the page.

  • Don't stack more than three. Three role="alert" banners announce serially with no way to skip. Cap the rendered set and roll the remainder into one summarizing banner. See when not to stack banners.
  • Don't render a per-item status list as banners. Items sharing an attribute set are a table with a status column or a list with a trailing Badge.
  • Don't put an announcement in a group carrying a negative. Suppress the marketing banner while anything is broken.
  • Don't use non-Banner children. The group locks the vertical rhythm for Banner's footprint; arbitrary nodes misalign.
  • Don't add margins to the children. The group's gap is the only spacing mechanism between banners, and the parent layout owns the space below.

Accessibility

  • Renders a plain <div> — no role, no aria-label. Each Banner keeps its own semantics (role="alert" for negative / warning / info, role="status" for positive, role="banner" for announcement).
  • Source order is announced order. The severity ordering rule is the screen-reader experience, not a sighted-only convention.
  • The three-banner cap exists because assertive roles compound — see the standard's accessibility section.

API

PropTypeDefault
gap'sm' | 'md' | 'lg''md'
childrenReactNode

On this page

💬