API
<Chart> — @zuilib/charts
Renders a ChartSpec plus rows. Default export.
| Prop | Type | Default | Description |
|---|---|---|---|
specrequired | ChartSpec | — | The serializable chart description, discriminated on type. |
rowsrequired | ChartRow[] | — | The rows behind the chart. |
formats | Record<string, FormatterFn | FormatterFactory> | — | Custom format tokens the spec may name; functions stay out of the spec. |
locale | string | user locale | BCP 47 tag for formatted numbers and dates. |
width / height | number | — | Fixed pixel size (tests, SSR). Both set, no ResizeObserver runs; otherwise the chart fills its parent. |
aspect | number | 16 / 9 | Responsive ratio when height is left out. |
loading | boolean | false | Renders a skeleton instead of the chart. |
error | ReactNode | — | Renders a danger-tone alert instead of the chart. |
emptyState | ReactNode | the noData label | Renders when rows is empty. |
ariaLabel | string | spec.title | Accessible name of the figure. |
hiddenSeries | string[] | — | Series fields hidden by the legend (controlled; kept internally when left out). |
defaultHiddenSeries | string[] | — | Initial hidden set when uncontrolled. |
onHiddenSeriesChange | (fields: string[]) => void | — | The next hidden set on a legend interaction. |
onMarkClick | (event: ChartMarkEvent) => void | — | Every mark click, with or without a CrossFilterProvider. |
labels | Partial<ChartLabels> | — | String overrides for another language. |
animate | boolean | true | Mark entrance animation; off automatically under prefers-reduced-motion. |
className | string | — | Merged last onto the container. |
ChartMarkEvent: {field, value, seriesField?, row, additive} — the
category field and value of the clicked mark, the full row behind it, and
whether the click was additive (shift).
ChartFrame — @zuilib/charts/chart-frame
The themed shell for hand-written Recharts composition: series-color CSS
variables, loading/error/empty states, responsive sizing, and the context
the tooltip and legend contents read.
The frame is a CSS size container (@container, min-w-0): it sizes to
the column it is placed in and never holds a flex or grid parent open at a
previous width. Without height the plot follows aspect with a 200px
floor.
| Prop | Type | Description |
|---|---|---|
configrequired | ChartConfig | Series field → {label, color?, theme?, format?}. Declaration order assigns the default palette slots; color is any CSS value; theme is {light, dark} emitted scoped to this chart. |
childrenrequired | ReactNode | One Recharts chart root (e.g. <BarChart>). |
width / height / aspect | number | As on <Chart>. |
loading / error / empty / emptyState | … | As on <Chart>; empty marks the data empty explicitly. |
ariaLabel | string | Accessible name of the figure. |
labels / formats / locale | … | As on <Chart>. |
hiddenSeries / onHiddenSeriesChange | … | Controlled legend visibility. |
categoryField | string | Category charts: the field legend entries cross-filter on (instead of toggling series). |
categories | {value, color}[] | Category charts: the legend entries in palette order. |
Children reference their series color as fill="var(--color-<field>)" /
stroke="var(--color-<field>)" — the frame defines those variables from
config. seriesColorVar(field) from @zuilib/charts/chart-defaults
builds the string. The example below imports Recharts directly, so declare
recharts as a direct dependency of the application for this advanced
composition path. The standard <Chart> API needs only @zuilib/charts.
import ChartFrame from '@zuilib/charts/chart-frame'
import {ChartTooltipPanel} from '@zuilib/charts/chart-tooltip'
import {ChartLegendList} from '@zuilib/charts/chart-legend'
import {cartesianGridDefaults, seriesColorVar, xAxisDefaults, yAxisDefaults} from '@zuilib/charts/chart-defaults'
import {Bar, BarChart, CartesianGrid, Legend, Tooltip, XAxis, YAxis} from 'recharts'
<ChartFrame config={{revenue: {label: 'Revenue'}}} ariaLabel="Revenue by month">
<BarChart data={rows}>
<CartesianGrid {...cartesianGridDefaults} />
<XAxis dataKey="month" {...xAxisDefaults} />
<YAxis {...yAxisDefaults} />
<Tooltip content={<ChartTooltipPanel />} />
<Legend content={<ChartLegendList />} />
<Bar dataKey="revenue" fill={seriesColorVar('revenue')} radius={[4, 4, 0, 0]} />
</BarChart>
</ChartFrame>
Tooltip and legend — /chart-tooltip, /chart-legend
ChartTooltipPanel and ChartLegendList are themed content components
for Recharts' own Tooltip and Legend elements
(content={<ChartTooltipPanel />}). The legend renders real buttons:
click isolates a series (click again restores all), shift-click toggles
one; on category charts the buttons cross-filter.
| Prop | Type | Default | Description |
|---|---|---|---|
labelFormat | FormatToken | 'none' | ChartTooltipPanel: format of the label row (the x value). |
valueFormat | FormatToken | 'number' | ChartTooltipPanel: format for rows whose series declares none. |
showLabel | boolean | true | ChartTooltipPanel: renders the label row. |
className | string | — | Both components: extra classes on the panel / list. |
CrossFilterProvider — @zuilib/charts/cross-filter
| Prop | Type | Default | Description |
|---|---|---|---|
state | CrossFilterState | — | Controlled state; left out, the provider keeps its own. |
defaultState | CrossFilterState | no filters, no highlight | Initial state when uncontrolled. |
onStateChange | (state: CrossFilterState) => void | — | The whole next state on every interaction. |
useCrossFilter() returns {state, filtered, toggleValue, clearField, clearAll, setHighlight, valuesFor}; useOptionalCrossFilter() returns
null outside a provider. See cross-filtering for
the interop converters (toColumnFilters, fromColumnFilters,
toHighlight, applyFilters).
Formatters — @zuilib/charts/format
createFormatters(locale?, custom?) builds the resolver <Chart> uses;
formatters.resolve(token, fallback?) returns a (value) => string. Pure
module, safe in a server component. Built-ins: none, number, compact,
percent, currency:CODE, date:short|medium|long,
datetime:short|medium. An unknown token warns in development and falls
back to String.
Slots
| Slot | Notes |
|---|---|
[data-slot="chart"] | The figure wrapper; carries the series color variables. |
[data-slot="chart-skeleton"] | The loading block. |
[data-slot="chart-error"] | The error alert. |
[data-slot="chart-empty"] | The empty state. |
[data-slot="chart-tooltip"] | The tooltip panel (rows: chart-tooltip-row, chip: chart-tooltip-chip, label: chart-tooltip-label). |
[data-slot="chart-legend"] | The legend list (items: chart-legend-item, buttons: chart-legend-button, chips: chart-legend-chip). |