Skip to content
Feedback

Banner

One message about the whole app or page, edge to edge.

import { Banner } from "@flinbu/seed";

Subtle

The default: the page's own surface, only the icon is in color.

Info: Seed 0.2 adds 24 components.

Warning: Figma sync paused. Your token changes are saved here.

You’re viewing v2.3. Changes go into a new draft.

Error: We couldn’t reach GitHub, so nothing was published.

import { Banner, Button, Stack } from "@flinbu/seed";

const [open, setOpen] = React.useState(true);

<Stack gap="sm" className="w-full">
  {open ? <Banner action={<Button size="sm" variant="secondary">See what’s new</Button>} onDismiss={() => setOpen(false)}>Seed 0.2 adds 24 components.</Banner> : null}
  <Banner variant="warning" title="Figma sync paused." action={<Button size="sm" variant="secondary">Reconnect</Button>}>Your token changes are saved here.</Banner>
  <Banner variant="neutral">You’re viewing v2.3. Changes go into a new draft.</Banner>
  <Banner variant="error">We couldn’t reach GitHub, so nothing was published.</Banner>
</Stack>

Loud

The bottom hairline takes the tone. Keep it for a failed sync, no credits left or a blocking error.

Info: Seed 2.0 is coming. Token names change on March 3. Read the guide

Success: Back online. Sync with Figma resumed.

Warning: You’re out of credits. Pluto pauses until the 1st.

Error: Sync failed. Nothing reached Figma since 9:40.

import { Banner, Button, Link, Stack } from "@flinbu/seed";

<Stack gap="sm" className="w-full">
  <Banner emphasis="loud" title="Seed 2.0 is coming.">Token names change on March 3. <Link href="#">Read the guide</Link></Banner>
  <Banner emphasis="loud" variant="success" title="Back online.">Sync with Figma resumed.</Banner>
  <Banner emphasis="loud" variant="warning" title="You’re out of credits." action={<Button size="sm" variant="secondary">Add credits</Button>}>Pluto pauses until the 1st.</Banner>
  <Banner emphasis="loud" variant="error" title="Sync failed." action={<Button size="sm" variant="secondary">Try again</Button>}>Nothing reached Figma since 9:40.</Banner>
</Stack>

Light and Dark

Both modes and all four tones in each theme.

Light

Info: Subtle info: only the icon is in color.

Success: Subtle success: only the icon is in color.

Warning: Subtle warning: only the icon is in color.

Error: Subtle error: only the icon is in color.

Info: Loud info: the hairline takes the tone.

Success: Loud success: the hairline takes the tone.

Warning: Loud warning: the hairline takes the tone.

Error: Loud error: the hairline takes the tone.

Dark

Info: Subtle info: only the icon is in color.

Success: Subtle success: only the icon is in color.

Warning: Subtle warning: only the icon is in color.

Error: Subtle error: only the icon is in color.

Info: Loud info: the hairline takes the tone.

Success: Loud success: the hairline takes the tone.

Warning: Loud warning: the hairline takes the tone.

Error: Loud error: the hairline takes the tone.

import { Banner } from "@flinbu/seed";

<div className="grid w-full gap-base md:grid-cols-2">
  {(["light", "dark"] as const).map((theme) => (
    <div key={theme} data-theme={theme} className="flex flex-col gap-sm overflow-hidden rounded-xl border border-secondary bg-primary pb-base">
      <span className="px-base pt-base mono-label-medium text-tertiary">{theme === "light" ? "Light" : "Dark"}</span>
      {(["info", "success", "warning", "error"] as const).map((v) => <Banner key={v} variant={v}>Subtle {v}: only the icon is in color.</Banner>)}
      {(["info", "success", "warning", "error"] as const).map((v) => <Banner key={v} variant={v} emphasis="loud">Loud {v}: the hairline takes the tone.</Banner>)}
    </div>
  ))}
</div>

Use it for

  • A paused sync, a read-only version, a trial ending.

Use something else for

  • A message about one section: use Alert.
  • Something that just happened: use a toast.

Props

PropTypeDefaultDescription
variant'info''neutral''success''warning''error''offer''inverse''info'Meaning.
emphasis'subtle''loud''subtle'loud gives the bottom hairline the tone's color. inverse ignores it.
titleReactNode–Bold lead-in with a period.
actionReactNode–One small Button.
onDismiss() => void–Shows a close button.
stickyboolean–Stays on top while scrolling.
liveboolean–Set when the banner appears after the page loads, so it's announced.
toneLabelstringfalse–The hidden word read first. Default Info, Success, Warning or Error.

Accessibility

  • A banner rendered with the page has no live role. Set live when it appears later: role status, or role alert for errors only.
  • A visually hidden Info:, Success:, Warning: or Error: is read first, so the tone never depends on color. Translate it with toneLabel.
  • The loud hairline is decorative; the icon and the words carry the meaning.