Contribution List
Explain how a figure got from where it started to where it lands, one signed step per row.
import { ContributionEnd, ContributionList, ContributionStep } from '@youj/react'
Installation & usage
npm i @youj/reactFor an app already set up with npx @youj/cli init, which installs the peers (@youj/core, @youj/motion, motion and Base UI) and wires the provider. New app? Start at Installation.
Use a contribution list to explain a figure: a forecast against a typical week, this month's bill against last month's, a score against its target. It is a waterfall chart told as a list: the baseline, each step with its sign, and the total, highlighted. For one value against another use a Diff Bar; for how a total splits into parts, a Breakdown List.
import { MegaphoneIcon, TagIcon } from '@youj/icons'
import { ContributionList, runningTotals } from '@youj/react'
<ContributionList
baseline={{ label: 'A normal week', value: 1840 }}
items={[
{ icon: <MegaphoneIcon />, label: 'Launch post', detail: 'Goes out Tuesday', value: 310 },
{ icon: <TagIcon />, label: 'Price change', detail: 'Starter goes to €12', value: -120 },
]}
total={{ label: 'Expected next week' }}
/>
runningTotals(1840, [{ value: 310 }, { value: -120 }]) // [1840, 2150, 2030]The total's value is never passed: it is the baseline plus every step, so the list always adds up. runningTotals gives the same numbers for a headline elsewhere on the page. format and locale set how every figure reads; the steps always carry their sign.
Beside each value a thin mark shares one scale, from the lowest running total to the highest: the baseline and the total are ticks at their place, and each step is a bar from where the figure was to where it went. Rises take the good ink and falls the bad one; invert swaps them where a fall is good news, as with costs. marks={false} drops them, and they hide on their own below 28rem.
Description
Why next week's signups differ from a normal week: each driver, the line of why, and how many it adds or takes away.
A cost bridge from one month's bill to the next, where invert lights the savings in the good ink.
Code
contribution-list-demo.tsx, the Demo story. The component itself comes from the package.
Reference
Propsbaseline, items, total… (7)
Props
| Prop | Type | |
|---|---|---|
baselineRequired | ContributionEnd & { value: number }Where the figure starts: its label and value. | – |
itemsRequired | readonly ContributionStep[]The steps, in the order they're applied. | – |
totalRequired | ContributionEndThe landing row's label. Its value is the baseline plus every step. | – |
format | Intl.NumberFormatOptionsIntl.NumberFormat options for every figure; steps always show their sign. | – |
locale | stringDefault: the YoujProvider locale. | – |
invert | booleanA fall is good news (costs, latency): falls take the good ink, rises the bad. default false | false |
marks | booleanThe waterfall marks beside the values. default true | true |
Other props pass through: extends ComponentProps<'ol'>. | ||
StylingParts and data attributes
Styling
Parts: contribution-list, contribution-list-baseline, contribution-list-item (with data-direction: up, down or flat), contribution-list-icon, contribution-list-label, contribution-list-detail, contribution-list-mark, contribution-list-step, contribution-list-value and contribution-list-total.
MotionFirst view · reduced motion
Motion
| Moment | Tokens | ||
|---|---|---|---|
| First vieweach step’s bar grows from where the figure was, one after another down the list, once a third of the list is in view | duration.slowease.emphasized340ms · cubic-bezier(0.6, 0, 0.1, 1) | 340mscubic-bezier(0.6, 0, 0.1, 1) |
Reduced motion
Drawn at once.
Reduced motion
The bars are drawn at their size from the start.
AccessibilityOrdered list
Accessibility
- It is an ordered list read top to bottom: the baseline, each step with its signed value, then the total. Name it with
aria-labelwhen no heading does. - The icons and the marks are decorative (
aria-hidden); the label, detail and signed value carry the meaning. - The bars grow from the inline start's side of the scale, so the marks mirror in RTL.