Acronis UIKit
Components

CategoryBar

A single bar split into proportional colored category segments.

Usage

import { CategoryBar } from '@acronis-platform/ui-react';
import type { ChartConfig } from '@acronis-platform/ui-react';

CategoryBar renders a single horizontal bar split into proportional colored segments — a part-to-whole across a handful of categories, in one row. Give it a data array (key + value) and a per-segment config; each segment's width is its value over the total. It's a plain flex composition, not a recharts chart, so there are no axes or grid.

Segment colors come from the palette prop, not from config — see Palettes. Segment keys are the color keys, keyed into config: each entry maps a segment to a label and an optional tone that re-points it within the palette, resolved into the --color-<key> custom properties the segments fill from. Keys must be unique and CSS-safe.

Examples

A three-part split that sums to 100, with the count/% legend:

const config = {
  passed: { label: 'Passed', tone: { status: 'success' } },
  warnings: { label: 'Warnings', tone: { status: 'warning' } },
  failed: { label: 'Failed', tone: { status: 'danger' } },
} satisfies ChartConfig;

<CategoryBar
  config={config}
  palette={{ type: 'status' }}
  data={[
    { key: 'passed', value: 68 },
    { key: 'warnings', value: 22 },
    { key: 'failed', value: 10 },
  ]}
  showLegend
/>;

showLegend renders a color swatch + label per segment plus each segment's value and its share of the total. Set the track height with size (sm / md / lg), and hover a segment for its tooltip (showTooltip, on by default).

<CategoryBar config={config} data={data} size="lg" showTooltip={false} />;

Format the numbers with valueFormatter (it drives both the legend and the tooltip; defaults to toLocaleString()), and replace the tooltip body with tooltipContent — it receives the resolved segment, so you keep the value and share without recomputing them:

<CategoryBar
  config={config}
  data={data}
  showLegend
  valueFormatter={(value) => `${value} checks`}
  tooltipContent={({ label, value, percent, color }) => (
    <div className="flex items-center gap-1.5">
      <span className="size-2.5 rounded-full" style={{ backgroundColor: color }} />
      {label}: {value} ({percent}%)
    </div>
  )}
/>;

color there is the segment's var(--color-<key>) reference rather than a literal, so it resolves whatever stop of the palette the segment took. label is whatever the config carries — a string or any node.

The tooltip is pointer-driven: the segments sit inside a role="img" bar, so they are deliberately not separate focusable controls. The bar's aria-label (auto-generated from the data, or your own) is what assistive tech reads — showLegend is the way to put the same numbers on screen for everyone.

For a visual-regression or test render, defaultOpenIndex opens one segment's tooltip on mount:

<CategoryBar config={config} data={data} defaultOpenIndex={0} />;

Accessibility

The track is one role="img" with an aria-label, so assistive tech gets a single coherent image rather than a row of unlabelled boxes. The default label is a locale-neutral list of "<label> <value>" pairs joined with commas — "Passed 68, Warnings 22, Failed 10". Three things feed it: config[key].label (the segment key stands in when that label is a node instead of a string or number, since an aria-label has to be plain text), valueFormatter (the same one the legend and tooltip use, so a formatter that appends a unit changes the announcement too), and the aria-label prop, which replaces the generated summary outright.

That summary carries the values but not the shares, so the percentages reach a screen-reader user only through the legend. The per-segment tooltip is pointer-driven and cannot be reached by keyboard at all — the segments are non-focusable <div>s inside the image — so it must never be the only place a number appears.

Direction (RTL)

Plain DOM throughout — a flex track and a flex legend, with no physical directional utilities — so the whole widget mirrors under dir="rtl". The segments follow the flex direction, which puts the first entry in data at the inline start (the right edge) and keeps the bar reading in the same order as the text around it. Nothing is flipped by hand; there is no directional artwork.

API Reference

Prop

Type

Edit on GitHub

On this page