Skip to content

Banner

A full-width, solid-intent announcement bar with an optional dismiss button and top or bottom pinning. Made for page-level messages: maintenance notices, promos, and outage warnings.

Import

import { Banner } from "@hyzer-labs/ui"

Demo

Banner vs Alert

Use Banner for a solid, full-width announcement at page level: maintenance notices, promos, outage bars. You can pin it to an edge. When the message is inline and sits next to the thing it describes, use Alert instead.

The intent vocabulary, using a solid fill instead of the tint Alert uses.

Course note: hole 7 tee pads were resurfaced this week.
League night: tags round starts at 5:30pm on Thursday.
Doubles signup: random-draw doubles opens 30 minutes early.
Course closed: lightning in the area. Clear the course now.
High winds: gusts over 30mph expected after 2pm.
Round saved: your scorecard was synced to the league.
Cart friendly: the back nine is paved end to end.
<Banner>Course note: hole 7 tee pads were resurfaced this week.</Banner>
<Banner intent="primary">League night: tags round starts at 5:30pm on Thursday.</Banner>
<Banner intent="secondary">Doubles signup: random-draw doubles opens 30 minutes early.</Banner>
<Banner intent="danger">Course closed: lightning in the area. Clear the course now.</Banner>
<Banner intent="warning">High winds: gusts over 30mph expected after 2pm.</Banner>
<Banner intent="success">Round saved: your scorecard was synced to the league.</Banner>
<Banner intent="info">Cart friendly: the back nine is paved end to end.</Banner>

Props

NameTypeDefaultNote
childrenSnippetRequired. The banner body.
intentIntent'neutral'See Foundation → Colors & Intent.
pin'top' | 'bottom'Sticks the bar to that edge, in flow (position: sticky). Static by default.
iconSnippetDecorative; rendered aria-hidden.
actionsSnippetTrailing slot — a Link or Button, e.g. "Learn more".
onDismiss() => voidRenders the dismiss button. Visibility is your state — the Banner never hides itself.
dismissLabelstring'Dismiss'
asstring'div'Polymorphic root — e.g. section or aside for landmark semantics.
classstringMerged after the hz-banner class.

Theme hooks

What this component promises your CSS. The reference theme styles exactly these — from @layer hz-theme, so your unlayered rules win. See Styling Components for the how.

Root class: .hz-banner

Data attributes

HookValuesStyles
data-intent'neutral' | any registered intentDrives the solid fill via --hz-banner-bg; spans the intent registry.
data-pin'top' | 'bottom'Present only when pinned; sticks the bar to that edge via position: sticky.
data-dismissiblepresent when dismissiblePresent only when onDismiss is set — target it to style the dismissible form.

Custom properties

HookValuesStyles
--hz-banner-bg<color> — default var(--hz-intent-neutral)The solid fill, switched per intent — override to restyle every intent's bar.
--hz-banner-fg<color> — default var(--hz-color-surface)On-fill text colour, the surface role so it flips with the mode and keeps text ≥ 4.5:1 in both.
--hz-banner-padding-block<length> — default 1.5remVertical padding of the bar.
--hz-banner-padding-inline<length> — default 2.5remHorizontal padding of the bar.

Part classes

HookValuesStyles
.hz-banner-iconchild elementThe decorative leading icon.
.hz-banner-contentchild elementThe message body.
.hz-banner-actionschild elementThe trailing actions slot.
.hz-banner-dismisschild elementThe dismiss button.
.hz-banner-titleopt-in classBanner never emits this — put it on your own lead element (strong, a heading) and it goes block-level semibold, stacking over the body copy. The .hz-card-title convention.

Accessibility

A statically rendered Banner is plain content: no role, no live region. For a Banner inserted after load, pass role="status" (polite) or role="alert" (assertive, use sparingly) via the rest props.

The icon slot is decorative (aria-hidden). Links inside are underlined, and color is never the only signal. The dismiss button is a real labeled <button>, and dismissal is your state change.

A pinned Banner can cover a focused element that scrolls under it. Keep pinned banners short, one line where possible. Give in-page anchor targets scroll-margin-block-start/-end equal to the banner height so they clear it. The Banner itself sets no scroll-margin.

There is deliberately no Toast component. A timed self-dismissing overlay is hard to make accessible. Under WCAG 2.2.1 the timing has to be adjustable, extendable, or pausable. A message that vanishes on its own often goes unannounced as well. The library prefers dismissal the reader chooses, so content never disappears out from under them. Banner is the supported pattern for a pinned or site-wide message instead, with opt-in role="status" and dismissal you own.

References: WCAG 2.4.11: Focus Not Obscured (Minimum) · MDN: status role · MDN: alert role