Skip to content

Breakdown List

Show how a total splits: each part's color, name, value and share, keyed to a split bar.

import { BreakdownItem, BreakdownList } 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 breakdown list as the key to a split bar: revenue by category, cash by account, seats by status. Each row is a color marker, a name, a value and its share of the total. For a few parts inside a stat tile use StatBreakdown; for one row's share of a whole, a Share Bar on its own.

import { useState } from 'react'
import { BreakdownList, ShareBar } from '@youj/react'

const [active, setActive] = useState<number | null>(null)

<ShareBar parts={channels.map((c) => ({ value: c.value }))} active={active} />
<BreakdownList items={channels} format={{ style: 'currency', currency: 'EUR' }} active={active} onActiveChange={setActive} />

Both take the chart colors in order, so give them the same items and the rows match the segments without naming a tone; a tone on an item (the accent, a status, a chart color or neutral) colors both when you pass it to both. Shares are out of the items' sum, or your total. variant="tiles" leads each row with its value in a small panel, for counts; showShare={false} drops the percentages.

Reference

Propsitems, total, format… (12)

Props

BreakdownList props
PropType
itemsRequiredreadonly BreakdownItem[]–
totalnumber

What each share is out of. Default: the items' sum.

–
formatIntl.NumberFormatOptions

Intl.NumberFormat options for the values.

–
localestring

Default: the YoujProvider locale.

–
variantBreakdownListVariant
'rows''tiles'

rows (default) on hairlines, value at the end; tiles lead with the value, for counts.

default 'rows'

'rows'
marker'swatch' | 'bar'

The marker's shape: a square swatch (default) or a bar the row's height.

default 'swatch'

'swatch'
columns1 | 2

Rows side by side while each column can be 14rem wide.

default 1

1
showShareboolean

Show each part's share of the total.

default true

true
activenumber | null

The pointed-at part, controlled.

–
onActiveChange(index: number | null) => void

Called with the row hovered or focused, and null when the pointer and focus leave.

–
Other props pass through: extends ComponentProps<'ul'>.
StylingParts and data attributes

Styling

Parts: breakdown-list (with data-variant: rows or tiles), breakdown-list-item (with data-index, and data-state active or inactive while a row is pointed at), breakdown-list-marker, breakdown-list-label, breakdown-list-detail, breakdown-list-value and breakdown-list-share.

MotionPointing · reduced motion

Motion

Motion tokens
MomentTokens
Point at a rowthe row takes the hover panel; the paired bar’s other parts quiet
duration.fastease.standard

140ms · cubic-bezier(0.2, 0, 0, 1)

140mscubic-bezier(0.2, 0, 0, 1)

Reduced motion

The same: a color change, nothing moves.

Reduced motion

Nothing moves: pointing only changes colors.

AccessibilityList, keyboard

Accessibility

  • It is a list; each row reads its name, detail, value and share in order. Name the list with aria-label when nothing visible names it.
  • The rows are one tab stop. The arrow keys, Home and End move between them, and focus makes a row the active one, so a keyboard lights the bar's segments as a pointer does. Focus leaving the list clears it.
  • The markers are decorative (aria-hidden); the name says which part is which.