Split barPro
A single 100% bar split into shares: rest on a segment to widen it and read its exact figures, toggle segments from the legend and the rest reflow, with labels inside when they fit and on leader lines when they don't.
- A compact part to whole view that fits in a card row or a dashboard header.
- Comparing shares where people also want exact figures on demand and the option to leave a category out.
- Showing how a mix changes between periods or filters with one continuous reflow.
- Use bar-chart to compare absolute values across many categories.
- Use donut-chart when the total in the middle is the headline, or waffle-chart for a count of units.
- Use a stacked chart over time when the trend of each share matters more than today's split.
Installation
Pro source and install commands unlock with a Pro plan.
import { SplitBar, type SplitSegment } from "@/components/arc/split-bar/split-bar"; const budget: SplitSegment[] = [ { id: "payroll", label: "Payroll", value: 412_000 }, { id: "cloud", label: "Cloud", value: 96_500 }, { id: "marketing", label: "Marketing", value: 74_200 }, { id: "tools", label: "Software", value: 18_900 }, { id: "other", label: "Other", value: 9_300 },]; export function BudgetSplit() { const [hidden, setHidden] = useState<string[]>([]); return ( <SplitBar title="Q4 budget" segments={budget} format={{ style: "currency", currency: "USD", maximumFractionDigits: 0 }} hidden={hidden} onHiddenChange={setHidden} /> );}SplitBar
One 100% bar split into shares, for traffic sources, budgets, storage or votes. Rest on a segment and it widens a little (small ones widen enough to show their own label) while the others give way proportionally and dim, and the readout above names it precisely: share, value and unit. Labels sit inside a segment when they fit, as name and percent or percent alone, and otherwise move to a lane under the bar with soft leader lines, pushed apart so they never overlap. The legend switches segments off and on: a hidden segment collapses in place and the rest reflow to fill the bar on springs, their percentages rolling to the new shares. New data does the same, so switching a period is one continuous reflow.
segmentsreadonly SplitSegment[]–The shares in display order: { id, label, value, color? }. Shares are each value over the total of the visible segments; zero and negative values are left out. Segments are matched by id when the data changes.segments[].colorstring–Any CSS color. Defaults to --series-1 to --series-4, then two neutrals meant for catch-all shares such as Referral or Other.titlestring–Heading above the bar and the accessible name unless label is set.descriptionstring–One line under the title.formatIntl.NumberFormatOptions–Number format for values in the readout, such as currency for a budget. Shares always read as percentages with one decimal.unitstring–Word after values in the readout, such as sessions.totalLabelstring"Total"Label of the readout when nothing is highlighted.hiddenreadonly string[]–Ids of segments that are switched off (controlled).defaultHiddenreadonly string[][]Ids switched off at first (uncontrolled).onHiddenChange(hidden: string[]) => void–Called with the new list when the legend or the keyboard switches a segment.legendbooleantrueShow the legend. Each item toggles its segment and highlights it on hover.localestring"en-US"Formatting locale. Fixed by default so server and client render the same digits.labelstring–Accessible name. Defaults to the title.classNamestring–Class on the root element.styleCSSProperties–Inline styles on the root element.- Tab
- Focuses the bar, then each legend item.
- Arrow RightorArrow Down
- On the bar: highlights the next visible segment, widening it and reading it out.
- Arrow LeftorArrow Up
- On the bar: highlights the previous visible segment.
- HomeorEnd
- On the bar: highlights the first or last visible segment.
- EnterorSpace
- On the bar: switches the highlighted segment off. On a legend item: switches its segment off or back on.
- Escape
- Clears the highlight.
- The bar is a focusable group with the role description split bar, named with every visible share (Organic search 41.6%, Direct 24.8% and so on) and how to read each one.
- Moving through segments with the arrow keys announces the segment's name, share and value in a polite live region; switching a segment off or on is announced too.
- Legend items are toggle buttons with aria-pressed, named with the segment and its share or hidden. An off segment is also shown without color: a hollow swatch, struck through name and the word Off.
- The last visible segment cannot be switched off; the legend item gives a small shake and the reason is announced.
- Inside labels, outside labels, leader lines and rolling digits are hidden from assistive technology; the group name and readout carry the same numbers as text.
- Segments use the shared chart palette, validated for color vision deficiency in both themes, and every segment is named in the legend, so color is never the only key.
- Each segment is a full width layer cut to its share with an animated clip-path, and its edges ride the smooth spring. Reflow never touches layout, and a new target mid flight retargets from where the edges are.
- Hovering or arrowing onto a segment widens it by about 4.5% of the bar, or enough to fit its name and share when it is small, while the others give way proportionally and dim, so the bar always stays at 100%.
- Labels live inside the clipped layer, so they slide with their segment and are cut cleanly at its edge instead of spilling into a neighbour. When a segment grows or shrinks, its name opens or closes on a spring beside the percentage.
- Outside labels glide to their new places and fade in and out; their leader lines are S curves that morph with them. The label lane opens and closes smoothly when the first label moves outside or the last one comes back.
- Percentages, values and the total roll digit by digit like an odometer, in the direction they changed.
- The readout above the bar crossfades between the total and the highlighted segment with a short rise and a little blur.
- With reduced motion segments and labels move at once, digits change in place, readouts swap without travel and the refusal shake is skipped.
- The bar spans its container. Its width is measured with a ResizeObserver and label fitting is recalculated, so the same data shows more labels inside on a wide card and moves more of them outside on a phone.
- The readout wraps under the title on narrow screens; the legend wraps to as many rows as it needs.
- On touch, a tap on a segment highlights it and a tap elsewhere clears it; vertical page scrolling is never captured.
- Label fitting uses canvas text metrics cached per font, so it never reads layout while animating.
- Segment edges, caps and labels are driven by motion values; React renders only when the data, the hidden set or the highlighted segment changes.
- Segments animate clip-path and transform only.
Notes for AI
Give your coding assistant the Markdown reference instead of screenshots.
- Use it for a part to whole split of two to eight categories where people compare shares at a glance: traffic sources, budget lines, storage by file type, survey answers, device mix.
- Order segments by size or by a meaningful sequence, and put catch-all shares such as Other last so they take the neutral colors.
- Set unit or format so the readout gives the exact figure, not only the percentage.
- Keep labels short. Long names only show inside wide segments; everything else moves to the outside lane.
- Pass new segments with the same ids to animate between periods or filters; the bar reflows instead of redrawing.
The full library index for assistants is at /llms.txt.