Banner
Promotional / informational surface for marketing, onboarding, upsell, and announcements. Three layouts (inline, centered, landscape with edge-to-edge image), four variants, six intents, prefix/suffix slots, primary + secondary actions, inline arrow link, optional footer row, dismissible, LTR/RTL.
Playground
Installation
pnpm add @tessinaui/uiUsage
import { Banner } from "@tessinaui/ui";{/* Inline — text + trailing icon tile (Chime+ pattern) */}
<Banner
intent="success"
variant="soft"
rounded="xl"
dismissible
inlineLink={{ label: "Unlock Chime+" }}
title="Accelerate your savings with a 3.50% savings APY with Chime+"
image={<ChimeLogo />}
/>
{/* Inline — text + inline button (7-Eleven pattern) */}
<Banner
intent="info"
variant="soft"
title="Earn rewards with your 7REWARDS loyalty account"
action={{ label: "See details", variant: "secondary", intent: "none" }}
image={<SevenElevenLogo />}
/>
{/* Centered — POF-style stacked promo */}
<Banner
layout="centered"
variant="soft"
icon={<Volleyball />}
title="Keep the ball rolling"
description="You probably know at least 1 person that has found someone on POF!"
action={{ label: "Meet new people", rounded: "full" }}
/>
{/* Solid centered — premium upsell */}
<Banner
layout="centered"
intent="primary"
variant="solid"
title="Premium"
description="Up to 2× the matches and more"
action={{ label: "Upgrade now", variant: "secondary", intent: "none" }}
/>
{/* Landscape with footer (Verify-yourself pattern) */}
<Banner
layout="landscape"
variant="soft"
title="Verify yourself"
description="Real connections are just a selfie away"
inlineLink={{ label: "Selfie-verified" }}
image={<HeroPhoto />}
footer={
<>
<span>+20,000 verified singles</span>
<button>Get verified</button>
</>
}
/>Showcase
Banner vs Alert
| Banner | Alert | |
|---|---|---|
| Purpose | Promotional / informational — marketing, upsell, onboarding | Feedback / status — error, warning, success, info |
| User context | Opt-in — user wasn't asking for it, but it's relevant | Reactive — surface in response to a user action or system event |
| Examples | "Unlock Chime+", "Premium upsell", "7-Eleven loyalty" | "Failed to save", "Payment received", "Update available" |
| Layouts | Inline / centered / landscape — designed for richer content | Inline only — designed for a tight message + optional CTA |
| Image / photo | First-class — leading icon tile, trailing logo, full-bleed photo | Decorative icon only |
If the surface is selling, onboarding, or otherwise promotional — use Banner. If it's reporting what just happened — use Alert.
Layouts
| Layout | When to use |
|---|---|
inline (default) | Text + small icon / logo on the side. Most marketing slots. |
centered | Stacked icon, title, description, CTA. Hero promos, opt-in cards. |
landscape | Image fills one full edge of the banner. Use when the visual carries the message. |
API Reference
Props
| Prop | Type | Default | Description |
|---|---|---|---|
title | ReactNode | — | Headline |
description | ReactNode | — | Subhead / body copy |
layout | "inline" | "centered" | "landscape" | "inline" | Visual layout |
imagePosition | "leading" | "trailing" | "trailing" | Side the image / icon sits on (inline + landscape) |
align | "start" | "center" | "center" | Text alignment in centered layout |
icon | ReactNode | — | Small leading icon — renders as a tinted square tile |
image | ReactNode | — | Larger graphic / photo — fills its edge in landscape |
action | BannerAction | ReactNode | — | Primary CTA |
secondaryAction | BannerAction | ReactNode | — | Quieter secondary CTA next to primary |
inlineLink | BannerInlineLink | — | Inline arrow-style link below the description |
footer | ReactNode | — | Free-form bottom row (stat + CTA, terms, etc.) |
dismissible | boolean | false | Show × button in the top-end corner |
onDismiss | () => void | — | Called when the dismiss button is clicked |
dismissLabel | string | "Dismiss" | aria-label for the × button |
intent | "none" | "primary" | "error" | "warning" | "success" | "info" | "none" | Color intent — affects bg/border + default action intent |
variant | "solid" | "soft" | "outline" | "ghost" | "soft" | Visual weight |
size | "sm" | "md" | "lg" | "md" | Size token — scales padding and font sizes |
rounded | "none" | "sm" | "md" | "lg" | "xl" | "full" | "lg" | Container border radius |
shadow | boolean | false | Drop shadow |
dir | "ltr" | "rtl" | inherited | Text direction |
role | AriaRole | "region" | ARIA role — set to "alert" for live announcements |
BannerAction
When you pass an object, the banner renders a <Button> for you. When you pass a ReactNode, that node is rendered as-is — useful for SplitButton, IconButton, custom links, etc.
| Field | Type | Description |
|---|---|---|
label | ReactNode | Button text |
onClick | (event) => void | Click handler |
href | string | When set, the button renders as <a href> via Button's render prop |
variant | "primary" | "secondary" | "ghost" | "outline" | Button variant |
intent | "none" | "error" | "warning" | "success" | "info" | Button intent |
size | "xs" | "sm" | "md" | "lg" | "xl" | Button size |
rounded | "none" | "sm" | "md" | "lg" | "full" | Button corner radius |
loading | boolean | Show spinner |
disabled | boolean | Disabled state |
leadingIcon / trailingIcon | ReactNode | Icons inside the button |
BannerInlineLink
Quieter than a button — a small underlined arrow link, typically placed below the description.
| Field | Type | Description |
|---|---|---|
label | ReactNode | Link text |
href | string | Link target — when set, renders as <a> |
onClick | (event) => void | Click handler |
trailingIcon | ReactNode | Override the default → arrow |
Notes
- Action defaults: when you pass a
BannerActionobject, itsvariant,intent,size, androundeddefault to sensible values for the banner's intent + variant — so the common case (<Banner intent="primary" action={{ label: "Action" }} />) needs no extra tuning. solidactions: when the banner isvariant="solid", the default action variant flips tosecondary(white pill on color) to read against the saturated background — see the Premium upsell example.- Image vs icon:
iconbecomes a tinted square tile sized to the banner.imageis rendered as-is — pass any element. Inlandscape,imagefills the full-edge column. - Footer row: rendered with a soft divider on non-solid variants and a translucent overlay on solid. Pass any layout you want — typically a stat on one side and a CTA on the other.
- Distinct from Alert: Banner is for opt-in promotional content; Alert is for reactive feedback. Same primitives, different role.
- Accessibility: defaults to
role="region". Passrole="alert"for live promotional announcements you want screen readers to interrupt for.
Alert
Contextual feedback messages for user actions or system events. Four visual variants (solid, soft, outline, ghost), five intents, three sizes, six rounded options, optional close button, actions, and RTL support.
Toast
Transient floating notifications for short feedback messages, with optional actions and auto-dismiss.