Skip to main content

API

<Chart>@zuilib/charts

Renders a ChartSpec plus rows. Default export.

PropTypeDefaultDescription
specrequiredChartSpecThe serializable chart description, discriminated on type.
rowsrequiredChartRow[]The rows behind the chart.
formatsRecord<string, FormatterFn | FormatterFactory>Custom format tokens the spec may name; functions stay out of the spec.
localestringuser localeBCP 47 tag for formatted numbers and dates.
width / heightnumberFixed pixel size (tests, SSR). Both set, no ResizeObserver runs; otherwise the chart fills its parent.
aspectnumber16 / 9Responsive ratio when height is left out.
loadingbooleanfalseRenders a skeleton instead of the chart.
errorReactNodeRenders a danger-tone alert instead of the chart.
emptyStateReactNodethe noData labelRenders when rows is empty.
ariaLabelstringspec.titleAccessible name of the figure.
hiddenSeriesstring[]Series fields hidden by the legend (controlled; kept internally when left out).
defaultHiddenSeriesstring[]Initial hidden set when uncontrolled.
onHiddenSeriesChange(fields: string[]) => voidThe next hidden set on a legend interaction.
onMarkClick(event: ChartMarkEvent) => voidEvery mark click, with or without a CrossFilterProvider.
labelsPartial<ChartLabels>String overrides for another language.
animatebooleantrueMark entrance animation; off automatically under prefers-reduced-motion.
classNamestringMerged 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.

PropTypeDescription
configrequiredChartConfigSeries 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.
childrenrequiredReactNodeOne Recharts chart root (e.g. <BarChart>).
width / height / aspectnumberAs on <Chart>.
loading / error / empty / emptyStateAs on <Chart>; empty marks the data empty explicitly.
ariaLabelstringAccessible name of the figure.
labels / formats / localeAs on <Chart>.
hiddenSeries / onHiddenSeriesChangeControlled legend visibility.
categoryFieldstringCategory 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.

PropTypeDefaultDescription
labelFormatFormatToken'none'ChartTooltipPanel: format of the label row (the x value).
valueFormatFormatToken'number'ChartTooltipPanel: format for rows whose series declares none.
showLabelbooleantrueChartTooltipPanel: renders the label row.
classNamestringBoth components: extra classes on the panel / list.

CrossFilterProvider@zuilib/charts/cross-filter

PropTypeDefaultDescription
stateCrossFilterStateControlled state; left out, the provider keeps its own.
defaultStateCrossFilterStateno filters, no highlightInitial state when uncontrolled.
onStateChange(state: CrossFilterState) => voidThe 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

SlotNotes
[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).