/// Charts
ChartContainer
The bordered, theme-aware frame that hosts a chart and exposes the --pds-chart-1..5 ramp.
import { ChartContainer } from "@protocore/pds";Basics
Wrap any chart in a ChartContainer to get the family frame: a bordered surface, a mono-UPPERCASE label header, and a fixed-height body. Match height on the container and the chart so the body doesn't clip or leave a gap.
Legend and actions
The actions slot pins controls (a menu, a range toggle) to the right of the header; the legend slot sits below it — typically a ChartLegend. Both are plain ReactNodes, so compose them from any pds control.
Pinning the ramp theme
theme="dark" or theme="light" writes the --pds-chart-* custom properties inline, pinning the ramp regardless of the page theme — use it when a chart always lives on a dark panel. theme="auto" (the default) inherits the page's theme.
The chart color doctrine — monochrome + signal
The categorical ramp is five ranked slots, not five equal colors:
- `--pds-chart-1` — ink. The near-fg tone (
#fafafadark /#0a0a0alight). The lead series. - `--pds-chart-2`, `--pds-chart-3` — progressively muted greys. Secondary and structural series.
- `--pds-chart-4` — signal green (
#3fcf8e/#0e9e6e). - `--pds-chart-5` — signal amber (
#d29922/#9a6c00).
The rule: rank your series and let the ink slot lead; keep supporting series greyscale; spend the two signal hues only where color carries meaning — the live metric, the threshold breach, the healthy-vs-degraded split. A chart where every series is a different bright color says nothing about which one matters. This is the charts-family expression of the system-wide differentiation contract, where --pds-accent and the status hues are reserved signals, never decoration.
The ramp flips per theme so contrast holds on either background, and the values are hardcoded identically in tokens/index.ts (for recharts, via JS) and ChartContainer.css (for CSS) so the two never drift. ChartContainer is what exposes them: the recharts wrappers resolve each series to var(--pds-chart-N) by position, so they inherit whatever the nearest container pins.
When to use it
Use ChartContainer as the shell for every LineChart, AreaChart, and BarChart on a dashboard — it standardizes the header, legend placement, and (critically) the ramp so charts read as one family. It is server-safe and ships in the main @protocore/pds entry.
You don't need it for a bare Sparkline (which is frameless by design), and you can render a recharts wrapper without it — but then you must supply the --pds-chart-* ramp yourself. Prefer the container.
Usage
Do
- Keep `height` on the container and the chart in sync.
- Write `label` as a short mono-UPPERCASE metric with its unit (e.g. "RPC throughput / req·s⁻¹").
- Rank series and let --pds-chart-1 (ink) lead; keep supporting series greyscale.
- Pin `theme` only when a chart lives on a fixed-theme surface; otherwise leave it auto.
Don't
- Don't give five equally-important series five bright colors — the ramp is a rank, not a palette.
- Don't spend the signal hues (chart-4/5) on decorative series; reserve them for meaning.
- Don't override `--pds-chart-*` with raw hex — pin a `theme` or adjust the tokens.
- Don't wrap a Sparkline in it; sparklines are intentionally frameless.
Accessibility
- ChartContainer is a presentational frame; the accessible meaning comes from the chart inside it and its `label`.
- The ramp keeps a monochrome luminance spread, so series stay distinguishable in grayscale and for color-vision deficiencies — pair with a legend rather than relying on hue.
- The `actions` slot must contain real controls (e.g. an IconButton with an `aria-label`); it is not announced on its own.
ChartContainer props
| Prop | Type | Default | Description |
|---|---|---|---|
actions | ReactNode | — | Actions slot pinned to the right of the header row (e.g. a menu button). |
children | ReactNode | — | Chart body — typically one of the recharts wrappers. |
className | string | — | |
height | number | 240 | Fixed body height in px. Defaults to `240`. |
label | ReactNode | — | Mono UPPERCASE label rendered at the left of the header row. |
legend | ReactNode | — | Legend slot rendered below the label row (e.g. a `ChartLegend`). |
style | CSSProperties | — | |
theme | enum | auto | Pin the `--pds-chart-*` ramp to a theme, or defer to CSS defaults (`auto`). |