Aurora AppKit / Supernova Handover / Banner

Component handover · For all platforms

Banner

A surface card that surfaces a product or feature message — optional leading icon, tagline / heading / subheading, an inline content slot, and an optional call-to-action button.

Open in Figma
Version
v1.3
Released
17 Jun 2026
Scope
All platforms
Breakpoints
xs · md · lg
Implementation
iOS · Android · macOS · Windows · Web
ℹ️ This release (v1.3). Added the variant property with values promotion and action. All existing banners become variant = promotion (text only, no button); the new action variant shows a CTA button. Driver: Supernova next-best-action banners.

Summary

Banner is a surface-card component used to surface a product or feature message. It can include a leading icon (slotStart), a tagline / heading / subheading text stack, an inline content slot (slotContent), an optional dismiss control (closable), and an optional CTA Button. As of v1.3 the variant property drives whether the CTA shows: promotion (text only) vs action (with button). The breakpoint property drives layout — stacking the button below the text (xs) or placing it inline to the right (md / lg).

Anatomy

  • 1
    Banner — root container. Background bg-secondary, radius border-radius-lg (20), drop shadow shadow-bevel.
  • 2
    slotStart — leading icon area (32×32). Depends on Slot (size sm). On by default.
  • 3
    tagline — caption text above the heading. Depends on Text.
  • 4
    IconButton — dismiss control (top-right). IconButton size sm, variant neutralSubtle, appearance transparent. Shown when closable = true.
  • 5
    heading — primary heading text. Depends on Text.
  • 6
    subHeading — secondary text. Depends on Text.
  • 7
    slotContent — content slot below the subheading (progress bars, metadata, chips). Slot size sm. On by default.
  • 8
    Button — CTA. Button variant accent, appearance fill, size lg. Shown for variant = action.
  • 9
    slotEnd — trailing slot (instance-swap). Off by default.
📐Layout tree. Root → vertical Stack with slotStart + a text Stack (tagline, heading, subHeading, slotContent). On md/lg the Button sits inline in the horizontal row; on xs it is a sibling stacked below. slotEnd is the last child.

Properties / API

PropertyType / valuesDefaultDescription
breakpointxs · md · lgxsLayout driver. xs stacks the CTA below the text; md places it inline right; lg uses wider gutters.
variantpromotion · actionpromotionpromotion hides the button; action shows it. New in v1.3.
sizemd · smmdmd: 16px heading, 48px button (xs) / 36px (md). sm scales down proportionally.
statedefault · activedefaultactive applies a highlighted background — for selection / in-progress banners. Not a hover state.
closablebooleanfalseRenders a dismiss IconButton at the top-right of the header row.
slotStartbooleantrueToggles the 32×32 leading icon slot. Set false when no icon is needed.
slotContentbooleantrueToggles the content slot below the subheading.
slotEndbooleanfalseTrailing slot. On xs below the button; on md after it in the same row.
slotStartSwapslot (instance-swap)Icon, avatar or brand mark (32×32 recommended).
slotContentSwapslot (instance-swap)Progress bars, metadata rows, chips below the subheading.
slotEndSwapslot (instance-swap)Hidden by default; shown when slotEnd = true.
tagline / heading / subHeadingtextText content layers.

Variants

  • promotion (default) — text + content, no CTA button. Informational / marketing messages without a direct action.
  • action — shows the CTA button. Use only when a clear call-to-action is required; overuse reduces effectiveness.

States

  • default — standard banner on bg-secondary.
  • active — highlighted / tinted background, driven by application logic for selection or in-progress banners.
⚠️Not a hover state. state=active reflects app state — don’t use it as a :hover/:pressed replacement. Hover/pressed/focus/disabled belong to the embedded Button & IconButton.

Sizes

  • md (default) — 16px heading; button 48px tall (xs) / 36px tall (md).
  • sm — proportionally smaller, compact layout.

Breakpoints

The breakpoint prop is the primary layout driver (a discrete prop, not a CSS media query — the consumer sets it to match its container/viewport).

BreakpointButton widthButton heightButton fontCTA placement
xsFull width (100%)48px16px MediumSibling of text block, stacked below
mdHug / inline36px14px MediumInside the horizontal row, right
lgHug / inline36px14px MediumInline (as md) with wider gutters
📝Same Button component in all cases — only position and sizing differ. No xl breakpoint is documented; button sizing is not shared between breakpoints, so reference the per-breakpoint tokens.

Design tokens

Colour

TokenValueUsage
bg-secondary#FFFFFFBanner background (bind — never hard-code)
bg-accent#3E5FFFCTA button fill
border-accent#3E5FFFAccent border
text-primary#2A2A2DHeading
text-secondary#696A6DTagline / subheading
text-primary-on-color#FFFFFFButton label

Radius · spacing · type · elevation

  • Radius: border-radius-lg = 20 (banner) · border-radius-full = 9999 (button pill).
  • Spacing (px): 2 · 8 · 12 · 16 · 28. xs internal stack uses 16px gap + 16px padding.
  • Type (Inter): subHeading = Medium 16/22 · caption = Regular 12/18.
  • Elevation: shadow-bevel = drop #0000000a 0/2/8 + inner #ffffff00 0/0.5.

Accessibility

⚠️No dedicated accessibility section exists on the Figma page — the items below are derived from anatomy and flagged for design follow-up.
  • The dismiss affordance is a real IconButton — expose an accessible “Close / dismiss” label.
  • The CTA is a real Button sub-component and inherits its own accessibility (focus, role, label).
  • state=active conveys meaning beyond colour — ensure it is announced/structured for assistive tech where it carries information.
  • Follow-up: explicit role, keyboard order, contrast ratios, hit-area, screen-reader behaviour.

Usage

✓ Do

  • Use variant=action only when a CTA is genuinely required.
  • Set slotStart=false when there is no leading icon.
  • Bind the background to bg-secondary.
  • Use design tokens for button sizing & padding per breakpoint.

✕ Don't

  • Don’t hard-code #FFFFFF — it breaks dark mode.
  • Don’t hard-code pixel values; button sizing differs per breakpoint.
  • Don’t use state=active as a hover replacement.
  • Don’t enable slotEnd on xs unless the extra height is intended.

Implementation status

Existing native implementations found in the playground repos (parity with v1.3 to be verified per platform):

Android ✓ iOS ✓ macOS ✓ Windows ✓ Web reference ✓
📝Cross-platform naming differs: CTA is ctaTitle/onCtaTap (iOS), buttonState/onBannerClick (Android); size enum is SM/MD (Android) and sm/md (macOS). The v1.3 variant = promotion/action property must be added on every platform.

Changelog

  • v1.317.6.2026
    • Added property variant = promotion / action.
    • Existing banners become promotion; new action exposes the CTA.
    • Driver: Supernova next-best-action banners.
  • v1.214.1.2026
    • Added size sm.
    • Renamed slots to slotStart & slotContent.
    • Driver: Leap Dashboard DIP banner.
  • v1.119.12.2025
    • Adjusted “closable” IconButton to use the correct sm variant.
  • v1.016.10.2025
    • Initial release.
📝Granular fixes: 8.6.2026 — fixed close IconButton hover colour · 27.11.2025 — fixed xs close button flipped 180° · 15.10.2025 — background changed from bg-glass + blur-md to bg-secondary · 1.10.2025 — close button 16→24×24, sm gap to icons.

Ticket scaffold

Title: Banner v1.3 — add variant property (promotion / action) [PLATFORM]

Acceptance criteria

  • Adds a variant property with values promotion (default) and action.
  • Existing banner usages default to promotion (no behaviour change → backwards compatible).
  • action renders the CTA Button (accent / fill / lg) using per-breakpoint sizing.
  • Breakpoint layout verified: xs full-width button stacked below; md/lg inline.
  • Background bound to bg-secondary; light + dark mode verified.
  • Dismiss IconButton (when closable) has an accessible label.
  • Visual diff against the Figma Specification and Developer Handover frames.

Jira ticket template

Jira wiki-markup. Copy into a new issue, replace every [PLACEHOLDER], and duplicate one per platform.

Jira · duplicate per platform
h2. [PLATFORM] · Banner v1.3 — add variant property (promotion / action)

*Project / Epic*  : [EPIC-KEY]  Aurora AppKit · Supernova
*Issue type*      : Story
*Components*      : Banner · [PLATFORM]
*Labels*          : aurora-appkit, supernova, design-system, banner
*Priority*        : [Medium]
*Story points*    : [estimate]
*Fix version*     : Banner v1.3
*Sprint*          : [sprint]
*Assignee*        : [assignee]

h3. Background
The Supernova "next best action" work introduces a call-to-action Banner. v1.3 adds a {{variant}} property so the same component renders as a passive promotion or an actionable banner. Existing banners become {{variant = promotion}} (no behaviour change); the new {{variant = action}} exposes the CTA button.

h3. Objective
Implement Banner v1.3 on [PLATFORM]: add the {{variant}} property and the action layout, mapped to [PLATFORM] conventions, with no regression to existing promotion banners.

h3. Design source
* Figma — "Aurora AppKit · Components" -> Banner page (Specification, Developer Handover, Changelog frames)
* Handover spec — supernova-handover/banner.html
* [paste the platform-specific Figma frame link]

h3. Spec (platform-agnostic — map to [PLATFORM] idioms)
* New property {{variant}} : {{promotion}} (default) | {{action}}. promotion hides the CTA; action shows it.
* Unchanged props : {{breakpoint}} (xs | md | lg) · {{size}} (md | sm) · {{state}} (default | active) · {{closable}} · {{slotStart}} · {{slotContent}} · {{slotEnd}} (+ swaps) · {{tagline}} / {{heading}} / {{subHeading}}.
* CTA (action only) : Button variant accent · appearance fill · size lg.
* CTA per breakpoint : xs = full-width, 48 tall, stacked below text; md / lg = hug/inline, 36 tall, right of text (lg = wider gutters).
* Tokens (bind, never hard-code) : {{bg-secondary}} · {{bg-accent}} · {{text-primary}} / {{text-secondary}} · {{text-primary-on-color}} · {{border-radius-lg}} 20 · {{border-radius-full}} · {{shadow-bevel}}.
* Accessibility : CTA is a real Button (inherits focus/role/label); closable dismiss needs an accessible "Close" label.

h3. Scope
In scope : {{variant}} + action layout at xs / md / lg; default existing usages to {{promotion}}.
Out of scope : other platforms (separate tickets); Button / IconButton internals.

h3. Dependencies
* Button + IconButton available on [PLATFORM]
* Tokens for the per-breakpoint button sizing

h3. Acceptance criteria
# Given an existing banner upgraded to v1.3 with no variant set, Then it renders as {{promotion}} with no visual/behaviour change.
# Given {{variant = action}}, Then the accent/fill/lg CTA shows and fires its action.
# Given {{breakpoint = xs}}, Then the CTA is full-width below the text; given md/lg, inline to the right.
# Background is bound to {{bg-secondary}}; verified light and dark.
# When {{closable = true}}, the dismiss control exposes an accessible "Close" label.
# All sizing/spacing use tokens; button sizing is per-breakpoint (not shared).

h3. Definition of Done
* Matches the Figma Specification + Developer Handover (visual diff) at xs / md / lg, light and dark
* No hard-coded colours/sizes — Aurora tokens only
* Unit / snapshot tests updated; existing banner tests pass
* Reviewed and merged; component version bumped to v1.3; changelog updated

h3. QA / test notes
* Regression: existing promotion banners unchanged
* Toggle variant / breakpoint / closable / slots; empty slots collapse with no residual gap
* Dark mode and dynamic text sizes
Source: Figma “Aurora AppKit – Components” · Banner page · Specification, Developer Handover & Changelog frames. Styled with the Aurora vibe package. Compiled 30.6.2026.