Feedback

Banner

A full-width announcement bar typically rendered at the top of a page or layout. Eight colors, optional icon, inline actions, dismiss button, clickable mode, and localStorage-backed dismissal persistence when an id is provided.

Basic Usage

A minimal banner with just a title.

A neutral announcement at the top of the page.
<script lang="ts">
  import { Banner } from 'sv5ui';
</script>

<Banner title="A neutral announcement at the top of the page." />

With Icon

Pass any Iconify icon name to icon.

New features available — check the changelog!
<Banner
  icon="lucide:megaphone"
  title="New features available — check the changelog!"
/>

Colors

8 color tokens map to the theme's background/foreground pairs.

Primary
Secondary
Tertiary
Success
Warning
Error
Info
Surface
<Banner color="primary"   icon="lucide:sparkles"      title="Primary" />
<Banner color="secondary" icon="lucide:sparkles"      title="Secondary" />
<Banner color="tertiary"  icon="lucide:sparkles"      title="Tertiary" />
<Banner color="success"   icon="lucide:check-circle"  title="Success" />
<Banner color="warning"   icon="lucide:alert-triangle" title="Warning" />
<Banner color="error"     icon="lucide:x-circle"      title="Error" />
<Banner color="info"      icon="lucide:info"          title="Info" />
<Banner color="surface"   icon="lucide:bell"          title="Surface" />

With Actions

Pass actions as an array of ButtonProps. Banner applies size="xs" and inherits the bar color — override per item.

A new version is available.
<!-- Each action is spread onto a <Button>. -->
<Banner
  color="primary"
  icon="lucide:rocket"
  title="A new version is available."
  actions={[
    { label: 'Release notes', variant: 'outline' },
    { label: 'Update now', trailingIcon: 'lucide:arrow-right' }
  ]}
/>

Dismissible (session only)

Set close to show a close button. Without an id the dismissal is session-only — the banner returns on the next reload.

A neutral notice you can dismiss for this session.
<!-- Session-only dismissal (no `id`) — close hides the banner
     but it returns on the next reload. -->
<Banner
  color="info"
  icon="lucide:info"
  title="A neutral notice you can dismiss for this session."
  close
/>

Persisted Dismissal

Pass an id alongside close — once dismissed, the banner writes sv5ui-banner-{id} to localStorage and stays hidden across reloads.

Scheduled maintenance this weekend.

To bring the banner back after testing, run in DevTools: localStorage.removeItem('sv5ui-banner-announce-2026-q2')

<!-- Pass an `id` to opt into localStorage persistence.
     Once dismissed, the banner stays hidden across reloads. -->
<Banner
  id="announce-2026-q2"
  color="warning"
  icon="lucide:alert-triangle"
  title="Scheduled maintenance this weekend."
  close
/>

Clickable

Set to to make the whole banner act as a link. It uses an absolute-positioned overlay anchor so any inner buttons (close / actions) stay outside the <a> — valid HTML.

Black Friday — 30% off all plans. Click for details.
Read our latest blog post →
<!-- Whole banner is a link — `to` adds an overlay anchor so
     inner buttons stay outside the <a>, which is valid HTML. -->
<Banner
  color="primary"
  icon="lucide:gift"
  title="Black Friday — 30% off all plans. Click for details."
  to="/pricing"
/>

<!-- External link with target="_blank" -->
<Banner
  color="info"
  icon="lucide:book-open"
  title="Read our latest blog post →"
  to="https://example.com/blog"
  target="_blank"
/>

Custom Snippets

Replace any of leading, titleSlot, actionsSlot, or closeSlot. When you use closeSlot, you own the dismiss logic — bind open.

v1.8 Editor, Stepper & Banner are here. Try the Editor
<script lang="ts">
  import { Banner, Button, Badge } from 'sv5ui';

  let open = $state(true);
</script>

<!-- Replace any of: leading, titleSlot, actionsSlot, closeSlot.
     When you use closeSlot you own the dismiss logic — bind `open`. -->
<Banner color="primary" bind:open close>
  {#snippet leading()}
    <Badge label="v1.8" variant="solid" color="surface" size="xs" />
  {/snippet}

  {#snippet titleSlot()}
    <span class="font-semibold">Editor, Stepper &amp; Banner are here.</span>
  {/snippet}

  {#snippet actionsSlot()}
    <Button label="Try the Editor" variant="outline" size="xs" href="/docs/components/editor" />
  {/snippet}
</Banner>

Forgetting a Dismissal

If you ever need to bring a persisted banner back programmatically (e.g. when the announcement updates), remove the matching localStorage key. The exact key is sv5ui-banner-{sanitized-id} — non-alphanumeric / dash / underscore characters in id are replaced with -.

No interactive demo — call this helper from your own code whenever you want to re-show a previously dismissed banner.

<script lang="ts">
  // Forget the dismissal so the banner reappears on the next mount.
  function resetBannerDismissal(id: string) {
    const key = `sv5ui-banner-${id.replace(/[^a-zA-Z0-9_-]/g, '-')}`;
    localStorage.removeItem(key);
  }
</script>

UI Slots

Use the `ui` prop to override classes on internal elements.

SlotDescription
rootOutermost wrapper — full-width bar, controls background color
containerInner flex container with horizontal padding
leftLeft spacer area (hidden below `lg` breakpoint)
centerCenter area holding icon + title + actions
rightRight spacer area holding the close button
iconLeading icon
titleTitle text
actionsAction buttons container
closeClose button

Snippets

SnippetDescription
leadingCustom leading content — replaces the default `icon` rendering
titleSlotCustom title content — replaces the default `title` text
actionsSlotCustom actions content — replaces the default `actions` array
closeSlotCustom close button. You own the dismiss logic — bind `open` externally

Props

PropTypeDefault
idstring-
titlestring-
iconstring-
color'primary' | 'secondary' | 'tertiary' | 'success' | 'warning' | 'error' | 'info' | 'surface''primary'
tostring-
targetstring-
closeboolean | ButtonPropsfalse
closeIconstring'lucide:x'
actionsButtonProps[]-
openbooleantrue
onClose() => void-
askeyof HTMLElementTagNameMap'div'
refHTMLElement | nullnull
classstring-
uiRecord<Slot, Class>-