# Funnel Chart

> Steps that narrow, like joining or trials, as numbered rows with a pill bar, each step's share of the first, and how many stopped before it.

- Name: `funnel-chart`
- Status: beta
- Categories: charts
- File: the install writes `funnel-chart.tsx` to your `ui` alias, `@/components/ui` by default.
- Other registry items: `@arbokui/breakdown-list`, `@arbokui/chart`. The install adds them.
- Gallery: https://arbokui.com/components/funnel-chart
- Registry item: https://arbokui.com/r/funnel-chart.json

## Install

1. Add the registry to `components.json`. Do this first, once:

   ```bash
   npx shadcn@latest registry add "@arbokui=https://arbokui.com/r/{name}.json"
   ```

   The command writes this entry. You can also add it by hand:

   ```json
   {
     "registries": {
       "@arbokui": "https://arbokui.com/r/{name}.json"
     }
   }
   ```

   Without this step, the shadcn CLI looks up `@arbokui` in a public list that Arbokui does not control.

2. Add the theme once per app. It replaces your color tokens with ones checked for contrast:

   ```bash
   npx shadcn@latest add @arbokui/theme
   ```

3. Add the component:

   ```bash
   npx shadcn@latest add @arbokui/funnel-chart
   ```

## Use it for

- Steps people pass through in order, where some stop at each step: sign-up forms, trials, a checkout.
- Pass stages, first to last, each with a label and a value, and a title or aria-label.
- Each bar is its share of the first step. Each step after the first says how many stopped before it.
- Give a stage meta to replace the automatic 'stopped' line.
- Pass value: null for a step with no figure yet. It shows a dash, not a zero.

## Avoid it for

- Parts of a whole or a ranking. Use BreakdownList. Its rows take the same shape.
- Steps that do not narrow, like a timeline. Use a list or a table.
- A trend over time. Use LineChart or AreaChart.

## Props

- `stages`: `{ id?: string; label: string; value: number | null; meta?: ReactNode }[]`. Required. The steps, first to last. The same shape as a BreakdownList row, so one set of rows fits either.
- `title`: `ReactNode`. A visible title. It names the funnel. TypeScript requires title, aria-label, or aria-labelledby.
- `aria-label`: `string`. Names the funnel when it has no visible title.
- `valueFormat`: `Intl.NumberFormatOptions | ((value: number) => string)`. How each step's value prints, like v => \`${v} people\`. Options work from a server component. A function works from a client component only.
- `locale`: `string`. Default `"en-US"`. The locale for numbers.
- `loading`: `boolean`. Default `false`. Shows placeholder rows, as many as stages, or three.
- `emptyText`: `ReactNode`. Default `"No data yet"`. Shown when stages is empty.
- `className`: `string`. Extra classes for the card. Later classes win.

## Accessibility

- Renders a \<figure> named by its title, or by aria-label. TypeScript requires one. The steps are an ordered list.
- Each step reads as its label, its value, and its share of the first step, then its meta, like 'Paid: 51, 80% of the first step, 13 stopped before this step'.
- A step with no value reads 'no figure', and shows a dash with no bar.
- The bars are hidden from screen readers. The track is quiet, so the numbers in text carry the meaning.
- Bars use --chart-1, which the theme holds to 3:1 on the page.
- Bars grow in once the funnel is on screen, over three times --motion-duration-base. Reduced motion and motion off draw them at once.

## Examples

### Each step, with its share of the first

```tsx
<FunnelChart
  title="New sign-ups this quarter"
  stages={[
    { label: "Started a form", value: 64 },
    { label: "Paid", value: 51 },
    { label: "First login", value: 46 },
  ]}
/>
```

### With its own lines

```tsx
<FunnelChart
  aria-label="Free trials"
  stages={[
    { label: "Started a trial", value: 40 },
    { label: "Came back a second day", value: 31, meta: "A holiday slowed 6 down" },
    { label: "Signed up", value: null, meta: "Counted on Friday" },
  ]}
/>
```
