Share Bar
Show a share of a total in a table cell or list row.
import { ShareBar, ShareBarPart } 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 share bar to show how much of a whole one row takes: a plan's share of revenue, a suite's pass rate, a volume against its size. It's a mark, not a chart: no axis and no tooltip, so put the number beside it. For the shape of values over time use a Sparkline; for how a whole divides into parts at once, a Treemap.
import { ShareBar } from '@youj/react'
<ShareBar value={0.412} segments={24} tone="accent" />
<ShareBar value={268} max={480} tone="neutral" label="Build minutes used" />value is a share from 0 to 1, or a value out of max. Without segments it's one solid bar; with it, it's a run of that many cells, and the value rounds to whole cells: any share above zero lights at least one, and only a full share lights them all. tone takes the accent, a chart color (chart-1 to chart-5), a status (success, warning, danger) or neutral. Give it a width from its container; the height is 6px solid and 12px in cells, and a class changes it.
With parts the fill is a whole split into its parts, each in its tone (the chart colors in order by default), from the inline start; max defaults to their sum, so they fill the bar. In cells, each part gets whole cells and any part above zero keeps one. mark="tick" draws the segments as hairlines on a taller bar instead of cells. active lights one part and quiets the rest: pair the bar with a Breakdown List and pass its onActiveChange here, so pointing at a row lights its segment.
<ShareBar parts={[{ value: 61_420 }, { value: 38_960 }, { value: 21_310 }]} active={active} />In a table where every row is a share of the same whole, pass the largest share as max so the top row fills its bar and the rest compare to it.
Description
A plan list where each row has a revenue figure, a segmented share bar and a percentage.
Two named bars, solid and segmented, at the same value, with a button that picks a new one.
With label the bar is a meter: screen readers hear its name and the share as a percentage in the provider's locale (or your valueText). Without it the bar is decorative and hidden from assistive technology, which is right when the number sits beside it, as it does in a table cell. That's the default because it's the common case: a meter and a visible number would say the same thing twice.
Test suites by result as a run of ticks, over a legend of counts that points at its part.
mark="tick" draws each of the segments as a hairline on a taller bar, colored by the part it falls in. Hovering a legend entry passes its index to active, which quiets the other parts.
Code
share-bar-demo.tsx, the Demo story. The component itself comes from the package.
Reference
Propsvalue, max, parts… (9)
Props
| Prop | Type | |
|---|---|---|
value | numberThe share, 0–1. With | – |
max | numberWhat | – |
parts | readonly ShareBarPart[]Split the fill into parts, each in its tone, from the inline start. | – |
active | number | nullWith | – |
segments | numberDraw this many cells instead of one solid bar. | – |
mark | 'cell' | 'tick'With default 'cell' | 'cell' |
tone | ShareBarTone'accent''neutral''success''warning''danger''chart-1''chart-2''chart-3''chart-4''chart-5'The fill's color: the accent, a chart color, a status or neutral. default 'accent' | 'accent' |
label | stringAccessible name. With it the bar is a | – |
valueText | stringThe value as spoken. Default: the share as a percentage, in the provider's locale. | – |
Other props pass through: extends ComponentProps<'div'>. | ||
MotionFill, new value · reduced motion
Motion
| Moment | Tokens | ||
|---|---|---|---|
| Fillthe edge travels from empty when half the bar scrolls into view, once; a clip, so cells and rounded ends never stretch | spring.smooth0.36s, bounce 0 | 0.36s, bounce 0 | |
| New valueretargets from where the edge is, so a burst of updates glides instead of restarting | spring.smooth0.36s, bounce 0 | 0.36s, bounce 0 |
Reduced motion
Drawn at its value; a new value jumps.
Reduced motion
The bar is drawn at its value, and changes land at once.
AccessibilityARIA
Accessibility
- With
label,role="meter"witharia-valuenow,aria-valuemin,aria-valuemaxand a percentage asaria-valuetext. - Without
label(oraria-label,aria-labelledby) it'saria-hidden: say the value in the text beside it. - With
partsand alabel, the meter speaks each part's share when every part has alabel: "Online 75%, Away 25%". - The fill grows from the inline start, so it runs right to left in RTL.