Skip to content

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/react

For 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.

Reference

Propsbaseline, items, total… (7)

Props

ContributionList props
PropType
baselineRequiredContributionEnd & { value: number }

Where the figure starts: its label and value.

–
itemsRequiredreadonly ContributionStep[]

The steps, in the order they're applied.

–
totalRequiredContributionEnd

The landing row's label. Its value is the baseline plus every step.

–
formatIntl.NumberFormatOptions

Intl.NumberFormat options for every figure; steps always show their sign.

–
localestring

Default: the YoujProvider locale.

–
invertboolean

A fall is good news (costs, latency): falls take the good ink, rises the bad.

default false

false
marksboolean

The 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

Motion tokens
MomentTokens
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.emphasized

340ms · 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-label when 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.