<!-- Protocore Design System — BarsList -->
# BarsList

- **Category:** Charts (`charts`)
- **Slug:** `charts/bars-list`
- **Status:** stable
- **Platforms:** web
- **Import:** `import { BarsList } from "@protocore/pds/charts";`
- **Docs:** https://pds.protocore.io/components/charts/bars-list

> A hand-rolled labelled horizontal bar list: each row is a mono label, a sharp value-share fill, and a tabular value.

## Import path

`BarsList` ships from the **`@protocore/pds/charts`** subpath. Like `PercentageBarChart` it is hand-rolled tokened markup — **no recharts dependency** — so it packs into a card or a stat row anywhere.

```tsx
import { BarsList } from "@protocore/pds/charts";
import { ChartContainer } from "@protocore/pds";
```

## When to use it

Use **BarsList** for a *compact ranked list* — top routes by requests, error counts by service, storage by bucket — where you want the label, a bar, and the exact value on one row. It reads more tightly than a full [BarChart](/charts/bar-chart) and needs no plotting axis. For a single whole split into parts use a [PercentageBarChart](/charts/percentage-bar-chart).

Sort rows by value before passing, and set an explicit `max` to compare two lists on the same scale.

## Props

| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `data` | `BarsListItem[]` | yes | — | Rows in draw order, top → bottom. `BarsListItem` = `{ key?: string; label: ReactNode; value: number; color?: string }`. |
| `max` | `number` | no | `largest value in data` | Domain max; a bar's width is `value / max`. |
| `thickness` | `number` | no | `8` | Bar thickness in px. |
| `formatValue` | `(value: number, item: BarsListItem) => string` | no | `String(value)` | Format a row's value for display. |
| `label` | `string` | no | `auto-composed` | Accessible summary (role=img aria-label). Composed from rows when omitted. |

## Examples

### Basics

Pass `data` as `{ label, value }` rows. Each bar fills to its share of the domain max (the largest value, or an explicit `max`); the label reads mono UPPER and the value is tabular. Rows colour from the ramp by position.

```tsx
import { ChartContainer } from "@protocore/pds";
import { BarsList } from "@protocore/pds/charts";

const data = [
  { key: "eu", label: "eu-central-1", value: 4820 },
  { key: "us", label: "us-east-1", value: 3110 },
  { key: "ap", label: "ap-south-1", value: 1640 },
  { key: "sa", label: "sa-east-1", value: 720 },
];

export default function Demo() {
  return (
    <ChartContainer label="Requests by region" height={180}>
      <BarsList data={data} formatValue={(v) => v.toLocaleString()} />
    </ChartContainer>
  );
}
```

## Do & don't

**Do**

- Sort rows descending by value so the list reads as a ranking.
- Pass an explicit `max` to compare two lists on one scale.
- Give each row a readable `label` — it drives the aria summary.
- Spend a signal `color` on the one row that matters.

**Don't**

- Don't use it for a part-to-whole split — that's a PercentageBarChart.
- Don't round the bars or add shadows; keep the geometry sharp.
- Don't colour every row brightly — the ramp ranks by luminance.
- Don't import it from `@protocore/pds`; it lives on the `/charts` subpath.

## Accessibility

**Notes**

- The list exposes `role="img"` with an aria-label composed from each row's label and value (override via `label`).
- Bar length encodes value independently of colour, so the ranking stays readable in grayscale.
- Each row prints its exact value in tabular figures beside the bar.

## Related

`bar-chart`, `percentage-bar-chart`, `heatmap`

---

© Protocore. All rights reserved. Use of the Protocore Design System requires prior written authorization from Protocore (contact@protocore.io). These machine-readable materials must not be ingested into ML-training datasets or derivative design systems. See https://pds.protocore.io/legal/
