Charts & metrics
Funnel Chart
Conversion funnel with per-stage drop-off and a loss summary
detent-funnel-chart
Port status
- Catalog status
- implemented
- Origin
- upstream
- Phase
- 3
- Wave
- phase-3-data
- Group
- Charts & metrics
6.3 KB gzip for the class module
Variants
Tab into a chart and press ArrowDown to inspect a stage.
Recorded states
closedrecorded state; no setterreduced motionrecorded state; no setter
Usage
Import
import '/components/funnel-chart/define.js';
// or register it yourself
import { DetentFunnelChart } from '/components/funnel-chart/funnel-chart.js';
Attributes
animatedaria-labelshow-summary
Properties
formatValuestages
Slots
No slots are recorded for this component.
Events
No events are recorded for this component.
Example
Runnable example: site/examples/funnel-chart.ts. The snippet below is generated from the catalogued attributes.
<detent-funnel-chart
animated
aria-label="auto-generated"
show-summary
></detent-funnel-chart>
Property-only values
const element = document.querySelector('detent-funnel-chart');
if (element !== null) {
// stages: FunnelStage[]
element.stages = [];
// formatValue: (n: number) => string
element.formatValue = () => {};
}
Source
The pinned upstream source for this row:
src/components/ui/FunnelChart.tsxsha256 aba263364288…
Native files
The native module and its artifacts:
src/components/funnel-chart/funnel-chart.tssrc/components/funnel-chart/styles.csssrc/components/funnel-chart/define.tsdocs/components/funnel-chart.mdsite/examples/funnel-chart.tstests/browser/funnel-chart.spec.tsevidence/components/funnel-chart.md
API
Boolean attributes follow HTML presence semantics: present means true, absent means false, and disabled="false" still means disabled.
Attributes
| Attribute | Property | Type | Default | Notes |
|---|---|---|---|---|
animated | animated | boolean | true | Presence semantics: present means true, absent means false. |
aria-label | ariaLabel | string | auto-generated | Kebab-case attribute; camelCase property. |
show-summary | showSummary | boolean | true | Presence semantics: present means true, absent means false. |
Properties
| Property | Type | Default | Notes |
|---|---|---|---|
formatValue | (n: number) => string | Intl.NumberFormat | Property-only: assign from script; not accepted as an attribute. |
stages | FunnelStage[] | — | Property-only: assign from script; not accepted as an attribute. |
Events
No custom events are recorded for this component.
Slots
No slots are recorded for this component.
CSS customisation
- `className` prop is replaced by documented CSS parts/custom properties; no Tailwind in consumers.
- Framer Motion springs/AnimatePresence ported to CSS transitions, WAAPI or the shared rAF spring helper.
- React state/hooks replaced by element-owned state with pre-upgrade property preservation.
- className is replaced by the documented CSS parts and custom properties; consumers need no Tailwind.
- Framer Motion springs and AnimatePresence are replaced by WAAPI entrance motion over opacity/transform; both are removed under reduced motion.
- React state/hooks are replaced by element-owned state with pre-upgrade property preservation.
- The bar ramp uses the shared --detent-chart-series-N tokens instead of upstream's color-mix(in oklch, #6d7cff, #34d1bf …), so it adapts to light and dark and every bar keeps ≥ 3:1 against the chart surface (PC-9.5, PC-12.6).
- Percentages are guarded: when the first stage is 0 the share is shown as — instead of dividing by 1e-9.
- The pinned source declares no variant prop; the element exposes no variant (confirmed absence, not an omission).
- Drop chips expose a <title> naming both stages; upstream relies on visual placement alone.
What it does
A conversion funnel: proportional rounded bars, curved bridges showing the users lost between each pair of stages, a drop chip between every pair, a summary line with the overall conversion and the biggest single drop-off, and a screen-reader table mirroring every value. Zero charting dependencies.
Upstream behaviour
- Proportional stage bars with rounded ends and a color ramp from first to last stage
- Curved bridges show the users lost between each pair of stages
- Drop-off chips sit between stages and highlight the hovered step
- Summary line reports overall conversion and the biggest single drop-off
- Floating tooltip shows users, percentage of the top stage, and the next loss
- Container-aware sizing keeps labels and values readable on mobile
- Keyboard navigation with ArrowUp, ArrowDown, and Escape
- Screen-reader table mirrors every stage value and percentage
- prefers-reduced-motion disables bridge and bar entrance animations
Differences from upstream
- `className` prop is replaced by documented CSS parts/custom properties; no Tailwind in consumers.
- Framer Motion springs/AnimatePresence ported to CSS transitions, WAAPI or the shared rAF spring helper.
- React state/hooks replaced by element-owned state with pre-upgrade property preservation.
- className is replaced by the documented CSS parts and custom properties; consumers need no Tailwind.
- Framer Motion springs and AnimatePresence are replaced by WAAPI entrance motion over opacity/transform; both are removed under reduced motion.
- React state/hooks are replaced by element-owned state with pre-upgrade property preservation.
- The bar ramp uses the shared --detent-chart-series-N tokens instead of upstream's color-mix(in oklch, #6d7cff, #34d1bf …), so it adapts to light and dark and every bar keeps ≥ 3:1 against the chart surface (PC-9.5, PC-12.6).
- Percentages are guarded: when the first stage is 0 the share is shown as — instead of dividing by 1e-9.
- The pinned source declares no variant prop; the element exposes no variant (confirmed absence, not an omission).
- Drop chips expose a <title> naming both stages; upstream relies on visual placement alone.