DocumentationComponentsTheme CreatorGitHub
Theme CreatorGitHubIntroduction
InstallationUsageTheming
ComponentsAccordionAction SheetAlertAlertDialogArea ChartAspectRatioAvatarBadgeBannerBar ChartBottom NavBreadcrumbButtonButtonGroupCalendarCardCarouselChartChatBubbleChatBubbleNewCheckboxChipCoachMarkCodeBlockCollapsibleColor PickerComboboxCommandContainerContextMenuDate PickerDividerDrawerDropdown MenuEmptyStateFABFieldFieldsetFile UploadFlexFormGridHoverCardIconButtonLabelLine ChartLinkMenubarMeterModalNavigation MenuNumberFieldOTP InputPaginationPickerPie ChartPopoverProgressPromptInputRadar ChartRadial ChartRadioRatingScroll AreaSearchSegmentedControlSelectShortcutSidebarSkeletonSliderCircularSliderMediaTrimmerSpacerSpinnerSplit ButtonStackStatusStepperSurfaceSwitchTableTabsTextareaTime PickerToastToggleButtonToggleGroupTokenizerToolbarTooltipTop Header DesktopTop Header Mobile
Contributing
Components

Area Chart

Token-driven area chart built on Recharts v3 with gradient fills, stacking, single and multi-series support, and full light/dark theming via chart tokens.

Playground

Installation

pnpm add @tessinaui/ui recharts

Usage

import { AreaChart } from "@tessinaui/ui";
import type { ChartConfig } from "@tessinaui/ui";

const config: ChartConfig = {
  desktop: { label: "Desktop", color: "var(--chart-1)" },
  mobile: { label: "Mobile", color: "var(--chart-2)" },
};

const data = [
  { month: "Jan", desktop: 186, mobile: 80 },
  { month: "Feb", desktop: 305, mobile: 200 },
  { month: "Mar", desktop: 237, mobile: 120 },
];

<AreaChart data={data} config={config} categoryKey="month" />

Series colours come from the --chart-1 … --chart-6 tokens, referenced as var(--chart-N) in each config entry. They are brand-led, contrast-checked in both modes, and recolour automatically when the theme flips — no JS re-render.

Examples

Default

A single series with the softest natural curve and a brand-tone gradient fill.

Multiple Series

Two series in brand tones with a legend; the areas overlap rather than stack.

Stacked

Two series stacked into a cumulative area, with each solid contour separating the bands.

Expanded

Three series normalised to 0–100% proportional bands with expand.

Curve

linear joins points with straight segments; step holds each value until the next.

Axes

Both axes labelled, values formatted, and the chart given an accessible name and summary.

Reference lines and bands

Recharts children compose straight through: a shaded band for the weekend, a dashed goal line with its own label.

Range band

A [low, high] pair plots a band between two bounds — a normal range, a forecast envelope — with the actual reading drawn over it.

Missing data

A null leaves a gap. connectNulls bridges it with a straight segment interpolated between the surrounding readings — a value nobody measured, drawn in the same stroke as the data. Only correct when a gap genuinely means "unchanged".

Negative values

Values crossing zero, with a reference line marking the baseline.

Sparklines

Every piece of chrome turned off, so the chart reads as a trend line inside a stat card.

Interactive

A time-range control filtering the data, with a running total above the plot.

States

The loading skeleton and the empty state shown side by side.

Theming

Every colour resolves to a Tessina token — nothing is hardcoded:

ElementToken
Series fill / stroke--chart-1 … --chart-6 (via config[key].color)
Grid + axis linesborder
Axis tick labelsmuted-foreground
Tooltip surfacepopover / popover-foreground / border

To re-skin a series, change the token reference in config (e.g. color: "var(--chart-3)") or override the --chart-N token in your theme.

Accessibility

  • Name the insight, not the axes. label renders the chart as a named role="figure"; description adds a visually hidden summary. A static read has to carry the message — interaction is additive, never required.
  • Keyboard. Recharts' accessibilityLayer is on by default: the chart surface is a tab stop, ←/→ step through data points, Enter pins the tooltip and Esc dismisses it. There is no wrapping and no Home/End. The focus ring is drawn by ChartContainer — Recharts ships none. See the Chart page for the full keyboard table and the VoiceOver QuickNav caveat.
  • Gaps are never interpolated. connectNulls is off by default: a missing value stays a gap rather than being bridged. Turn it on only when a gap genuinely means "unchanged".
  • Colour is never the only differentiator. Pair multi-series with dashedSeries, dots or direct labels, and keep to about five series — past that a stacked area stops being readable and a data table serves better.

Core props

PropTypeDefaultDescription
dataAreaChartDatum[]—Row-per-category data. A value may be a [low, high] pair for a banded area.
configChartConfig—Series metadata (label, color, icon).
categoryKeystring—Datum key for the x-axis.
seriesstring[]all config keysWhich series to plot.
curve"monotone" | "natural" | "linear" | "step""monotone"Interpolation.
stackedbooleanfalseStack series cumulatively.
expandbooleanfalseNormalise the stack to 0–100% bands. Implies stacked.
fill"gradient" | "solid""gradient"Fade toward the baseline, or a flat wash.
fillOpacitynumber0.25Top stop opacity of the fill.
connectNullsbooleanfalseBridge null gaps with an interpolated segment.
size"sm" | "md" | "lg""md"Aspect ratio.
showGrid / showXAxis / showLegend / showTooltipbooleantrueToggle chart chrome.
showYAxis / showDotsbooleanfalseOff by default.
xAxisLabel / yAxisLabelstring—Axis titles.
xTickFormatter / yTickFormatter(value, index) => string—Format tick text.
startEndOnlybooleanfalseRender only the first and last category ticks.
dashedSeriesstring[][]Series keys rendered with a dashed stroke.
labelstring—Accessible name; renders the chart as a role="figure".
descriptionstring—Visually hidden summary for assistive tech.
childrenReactNode—Extra Recharts children — ReferenceLine, ReferenceArea, Brush.
dir"ltr" | "rtl""ltr"Reading direction.
loadingbooleanfalseRender the skeleton.
errorReactNode—Render an error message instead of the chart.
emptyStateReactNode"No data to display"Shown when data is empty.
initialDimension / debounce—{320,200}Pre-measurement size and resize debounce, forwarded to Recharts.
AlertDialogAspectRatio

On this page

PlaygroundInstallationUsageExamplesDefaultMultiple SeriesStackedExpandedCurveAxesReference lines and bandsRange bandMissing dataNegative valuesSparklinesInteractiveStatesThemingAccessibilityCore props