> ## Documentation Index
> Fetch the complete documentation index at: https://api.fanvue.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Banner

> A full-width promotional or informational banner in six variants, laid out vertically, horizontally or compactly, with optional actions and a dismiss control.

```tsx theme={null}
import { Banner } from "@fanvue/ui";
import type { BannerLayout, BannerProps, BannerVariant } from "@fanvue/ui";
```

## Examples

## Whats New Compact

<Frame>
  <iframe src={"https://main--697a1b6dd4dad73ee9c0e5f5.chromatic.com/iframe.html?id=components-banner--whats-new-compact&viewMode=story&shortcuts=false&singleStory=true&globals=theme:light"} width="100%" height="220" style={{border: "none", borderRadius: "8px"}} loading="lazy" title="Banner — Whats New Compact" />
</Frame>

```tsx theme={null}
import { ArrowRightIcon, Banner, Button } from "@fanvue/ui";

function BannerTertiaryTextAction({ label }: { label: string }) {
  return (
    <Button
      type="button"
      variant="tertiary"
      size="32"
      className="h-auto min-h-0 px-0 py-1 shadow-none hover:bg-transparent active:bg-transparent"
      rightIcon={<ArrowRightIcon className="size-3" aria-hidden />}
    >
      {label}
    </Button>
  );
}

<Banner
  variant="whatsNew"
  layout="compact"
  media={<div className="typography-description-12px-regular flex size-full items-center justify-center bg-surface-tertiary text-content-secondary">
    Art
  </div>}
  title="Perfectly proportioned"
  description="Aspect ratio selection is here!"
  textAction={<BannerTertiaryTextAction label="See how it works" />}
/>
```

## Subtle Informational

<Frame>
  <iframe src={"https://main--697a1b6dd4dad73ee9c0e5f5.chromatic.com/iframe.html?id=components-banner--subtle-informational&viewMode=story&shortcuts=false&singleStory=true&globals=theme:light"} width="100%" height="220" style={{border: "none", borderRadius: "8px"}} loading="lazy" title="Banner — Subtle Informational" />
</Frame>

```tsx theme={null}
import { ReactNode } from "react";
import { ArrowRightIcon, Badge, Banner, Button, WarningTriangleIcon } from "@fanvue/ui";

const sampleImg = (
  <img
    alt=""
    className="size-full object-cover"
    src="https://placehold.co/96x96/e5e5e5/404040/png?text=•"
  />
);

function NewBadge() {
  return (
    <Badge variant="success" leftDot>
      new
    </Badge>
  );
}

function StatusChip({ children }: { children: ReactNode }) {
  return (
    <Badge
      variant="default"
      leftDot={false}
      leftIcon={<WarningTriangleIcon className="size-2.5" />}
    >
      {children}
    </Badge>
  );
}

<Banner
  variant="Subtle"
  media={sampleImg}
  leadBadge={<NewBadge />}
  title="Find out how OAuth works"
  description="Learn more about how to make an app that works."
  secondaryLine="For the next 7 days when you earn a milestone…"
  stackedAction={<Button variant="primary" size="32" rightIcon={<ArrowRightIcon className="size-3.5" />}>
    Account Health
  </Button>}
  statusRow={<>
    <StatusChip>2 warning</StatusChip>
    <StatusChip>2 media removed</StatusChip>
    <StatusChip>1 media in review</StatusChip>
  </>}
  primaryAction={<Button variant="secondary">Learn more</Button>}
/>
```

## Default Vertical

<Frame>
  <iframe src={"https://main--697a1b6dd4dad73ee9c0e5f5.chromatic.com/iframe.html?id=components-banner--default-vertical&viewMode=story&shortcuts=false&singleStory=true&globals=theme:light"} width="100%" height="220" style={{border: "none", borderRadius: "8px"}} loading="lazy" title="Banner — Default Vertical" />
</Frame>

```tsx theme={null}
import { Banner, Button } from "@fanvue/ui";

const sampleImg = (
  <img
    alt=""
    className="size-full object-cover"
    src="https://placehold.co/96x96/e5e5e5/404040/png?text=•"
  />
);

<Banner
  variant="Default"
  layout="vertical"
  media={sampleImg}
  eyebrow="HOW TO"
  title="Use Paid Media Links"
  description="For the next 7 days when you earn a milestone…"
  primaryAction={<Button variant="brand">Learn more</Button>}
/>
```

## Default Horizontal

<Frame>
  <iframe src={"https://main--697a1b6dd4dad73ee9c0e5f5.chromatic.com/iframe.html?id=components-banner--default-horizontal&viewMode=story&shortcuts=false&singleStory=true&globals=theme:light"} width="100%" height="220" style={{border: "none", borderRadius: "8px"}} loading="lazy" title="Banner — Default Horizontal" />
</Frame>

```tsx theme={null}
import { Banner, Button } from "@fanvue/ui";

const sampleImg = (
  <img
    alt=""
    className="size-full object-cover"
    src="https://placehold.co/96x96/e5e5e5/404040/png?text=•"
  />
);

<Banner
  variant="Default"
  layout="horizontal"
  media={sampleImg}
  eyebrow="HOW TO"
  title="Use Paid Media Links"
  description="For the next 7 days when you earn a milestone…"
  primaryAction={<Button variant="brand">Learn more</Button>}
/>
```

## Default Dismissible

<Frame>
  <iframe src={"https://main--697a1b6dd4dad73ee9c0e5f5.chromatic.com/iframe.html?id=components-banner--default-dismissible&viewMode=story&shortcuts=false&singleStory=true&globals=theme:light"} width="100%" height="220" style={{border: "none", borderRadius: "8px"}} loading="lazy" title="Banner — Default Dismissible" />
</Frame>

```tsx theme={null}
import { useState } from "react";
import { Banner, Button } from "@fanvue/ui";

const sampleImg = (
  <img
    alt=""
    className="size-full object-cover"
    src="https://placehold.co/96x96/e5e5e5/404040/png?text=•"
  />
);

function Example() {
  const [open, setOpen] = useState(true);
  return open ? (
    <Banner
      variant="Default"
      layout="vertical"
      media={sampleImg}
      eyebrow="HOW TO"
      title="Use Paid Media Links"
      description="For the next 7 days when you earn a milestone…"
      primaryAction={<Button variant="brand">Learn more</Button>}
      onDismiss={() => setOpen(false)}
    />
  ) : (
    <Button type="button" variant="text" size="32" onClick={() => setOpen(true)}>
      Reset banner
    </Button>
  );
}
```

## Props

## Banner

<ParamField path="variant" type="&#x22;Default&#x22; | &#x22;Subtle&#x22; | &#x22;whatsNew&#x22; | &#x22;appStore1&#x22; | &#x22;appStore2&#x22; | &#x22;appStore3&#x22;" required>
  Figma `Type` — selects structure, surfaces, and app store gradient.
</ParamField>

<ParamField path="description" type="ReactNode">
  Primary body copy.
</ParamField>

<ParamField path="dismissLabel" type="string" default="Dismiss banner">
  Accessible label for dismiss.
</ParamField>

<ParamField path="eyebrow" type="ReactNode">
  Small uppercase label (e.g. HOW TO).
</ParamField>

<ParamField path="layout" type="&#x22;horizontal&#x22; | &#x22;vertical&#x22; | &#x22;compact&#x22;" default={"\"vertical\"` for `Default`, `\"horizontal\"` for `whatsNew"}>
  Figma `Orientation`. Ignored when `variant` is `Subtle` (horizontal) or an app store type (vertical).
</ParamField>

<ParamField path="leadBadge" type="ReactNode">
  Top badge row (e.g. NEW pill) — mainly for `Subtle`.
</ParamField>

<ParamField path="media" type="ReactNode">
  Leading visual (image, illustration, or composite).
</ParamField>

<ParamField path="onDismiss" type="(() => void)">
  When set, shows a dismiss control (`Default` only).
</ParamField>

<ParamField path="primaryAction" type="ReactNode">
  Primary button (e.g. Learn more).
</ParamField>

<ParamField path="secondaryLine" type="ReactNode">
  Extra line under description (`Subtle`).
</ParamField>

<ParamField path="stackedAction" type="ReactNode">
  Left-stacked pill action (`Subtle`).
</ParamField>

<ParamField path="statusRow" type="ReactNode">
  Row under stacked action (`Subtle`).
</ParamField>

<ParamField path="textAction" type="ReactNode">
  Text-style CTA (`whatsNew` / app store).
</ParamField>

<ParamField path="title" type="ReactNode">
  Main heading.
</ParamField>

## Exported types

Also exported from `@fanvue/ui`: `BannerLayout`, `BannerProps`, `BannerVariant`.

***

**Setup:** [Installation](/docs/ui/installation) · [Theming](/docs/ui/theming)
