Theme studio

Design a theme, preview it live, then export it. Saved in this browser.

Quick picks #10b981
Generated scale
50100200300400500600700800900
Some text is below AA

FunnelChart

  • Stable
  • WCAG 2.2 evidence
  • RTL

A funnel chart: how many reach each stage of a process and what share is lost between stages. Data driven: stages in, SVG out; the same props render the static SVG on the server. A plot of 420 px or more has three columns as in Figma (names and counts, trapezoid bars on a centred axis, conversion pills); a narrower one stacks a label line above each full-width bar so it reflows at 320 px. Accessibility: the figure is named by title and described by summary; the data table has every stage with its count, conversion, drop-off and share of the first stage as text, so the drop-off is not only a narrowing bar (WCAG 1.1.1, 1.3.1, 1.4.1). Every stage shows its name and count as text; the colour only orders the stages. The plot is ONE tab stop: Up and Down move between stages, Home and End jump to the ends, Page Up and Page Down skip a tenth; each stage is announced with its count, conversion and drop-off. The tooltip shows on hover and focus, stays while hovered and closes with Escape (1.4.13, 2.1.1). The draw-in is behind motion-safe:; the plot stays left-to-right in right-to-left pages while the card mirrors, and digits follow the locale. Consumer duties: a title that asks the question, a summary with the main message, the unit of the counts, saying which scale the widths use. The stage fills heatmap-2 and heatmap-3 are lighter than the 3:1 that a graphic needs on the card; they repeat what the names and counts say, which is why this is acceptable.

import { FunnelChart } from "@nexera-ui/react";
Loading example…
13
examples
20
props
4
live controls
1
platform
9
WCAG criteria
1
block uses it

Try every prop. Copy the code.

Change the props and the code updates. Check light and dark, LTR and RTL, and phone width.

Loading…
scale
pill
title
description
Generated code
import { FunnelChart } from "@nexera-ui/react";

<FunnelChart />

Examples 12

The same examples as Storybook, rendered live. Open Code to copy one.

Drop off

pill="drop-off" shows the share lost at each step instead of the share kept. Both are always in the tooltip and the table.

Loading example…

Linear scale

scale="linear" draws the widths to scale: the late stages become slivers, at least 4 px wide.

Loading example…

Without pills

pill="none" leaves out the conversion column; the counts stay on the stage names.

Loading example…

Missing values

A stage without a count draws no bar and reads "No data"; the next stage converts from the last one that has a count.

Loading example…

Loading

Loading example…

Empty

Loading example…

Error state

Loading example…

Single point

One stage: a single full-width bar in the brand colour, no pills.

Loading example…

Many points

Twelve stages: the plot grows with the stages (53 px each), the heat ramp repeats its steps and the keys reach every stage.

Loading example…

Long labels

Long stage names are shortened beside the bars (the tooltip, the point label and the table keep them in full); the title and header wrap.

Loading example…

Narrow

In a narrow container (under 420 px) the labels move above full-width bars, so the funnel reflows without cutting anything off.

Loading example…

Right to left

Right-to-left page: the card, header and table mirror, the plot keeps its left-to-right layout, digits and signs follow the locale.

Loading example…

Props 20

Press "Try it" on a card to load that prop into the playground.

20 props shown

stages*Nexera
readonly FunnelStageInput[]

The stages from the widest to the narrowest, top to bottom: how many reached each (applied, screened, interviewed, offered, hired). A stage with value: null is a gap: no bar, "No data".

Default –
scaleNexera
"sqrt" | "linear"

How a count becomes a width. sqrt widens late stages that a linear scale would draw as slivers; linear is to scale. Say which one you use in the description.

Default sqrt
pillNexera
"conversion" | "drop-off" | "none"

What the pill beside each stage shows: the conversion from the stage before, the drop-off, or none. The tooltip, the point label and the table always state conversion and drop-off in text.

Default conversion
valueLabelNexera
string

Name of what is counted ("People"): the tooltip row, the point label and the table column. Translate it.

Default Count
heightNexera
number

Height of the plot in px. Leave it out to size the plot to the number of stages: 280 px for five stages in the wide layout, a label line above every bar in the narrow one.

Default –
labelsNexera
Partial<FunnelLabels>

Texts the chart invents: headers, and the names of conversion and drop-off. Translate them.

Default –
title*Nexera
string

Chart title: the question the chart answers ("Headcount"). Required: it names the figure, the plot and the data table (WCAG 1.1.1).

Default –
descriptionNexera
ReactNode

Secondary line under the title.

Default –
summary*Nexera
string

One or two sentences with what the chart shows and its main message ("Headcount grew from 96 to 128 over twelve months"). Required: it describes the figure for assistive technology (WCAG 1.1.1); the data table has the details.

Default –
rangeNexera
ChartRangeProps

Range switch in the header: 3M, 6M, 12M. Pass the data of the chosen range back in.

Default –
actionsNexera
ReactNode

Extra controls in the header, after the range switch.

Default –
kpiNexera
ChartKpiProps

KPI row above the plot: the headline number with an optional label or change badge.

Default –
stateNexera
ChartPlotState

The state that replaces the plot: loading (skeleton), empty or error. A chart without a value to plot shows the empty state by itself; pass { status: "empty", title, description, action } to give it your wording.

Default –
tableNexera
ChartTableOptions

The data table that is the text alternative: caption, first-column header and whether it is visible or only for assistive technology.

Default –
localeNexera
string

Locale of digits and separators.

Default the `NexeraProvider` locale
valueFormatNexera
NumberFormatOptions

Intl.NumberFormat options for values ({ style: "currency", currency: "PKR" }, { style: "percent" }). Serialisable, so it works from a Server Component; formatValue needs a Client Component.

Default –
formatValueNexera
(value: number) => string

Formats a value for tooltips, point labels and the table (full precision). Wins over valueFormat.

Default –
formatAxisValueNexera
(value: number) => string

Formats an axis tick (short: "29M").

Default the compact notation of `valueFormat`
plotLabelNexera
string

Accessible name of the plot group. Translate it.

Default the chart `title`
noDataLabelNexera
string

Text for a missing value in the tooltip and the table. Translate it.

Default No data

* Required. React Aria props shown are the ones most apps use; the component accepts the rest of its React Aria props too.

Accessible by default.

Built on React Aria, and covered by the WCAG 2.2 evidence generated on every build.

WCAG 2.2 evidence

8 direct · 1 supporting
  • 1.1.1Non-text ContentLevel A · tested directly
  • 1.3.1Info and RelationshipsLevel A · tested directly
  • 1.4.1Use of ColorLevel A · tested directly
  • 1.4.10ReflowLevel AA · tested directly
  • 1.4.13Content on Hover or FocusLevel AA · tested directly
  • 2.1.1KeyboardLevel A · tested directly
  • 2.3.3Animation from InteractionsLevel AAA · supporting test
  • 4.1.2Name, Role, ValueLevel A · tested directly
  • 4.1.3Status MessagesLevel AA · tested directly

Fits any width.

Nexera components respond to the space they are given. Drag the corner of the frame, or pick a width.

0 px · drag the corner

Styling hooks

Pass className to add Tailwind classes (merged last). State is exposed as data attributes, so you can style it with variants like data-pressed:.

Usage
<FunnelChart className="shadow-sm" />

Used in blocks

Related components