Getting Started
Components
- Accordion
- Alert
- Alert Dialog
- Avatar
- Badge
- Button
- Calendar
- Card
- Carousel
- Chart
- Checkbox
- Circular Progress
- Collapsible
- Compare Slider
- Dialog
- Dropdown Menu
- Gauge
- Input
- Label
- Marquee
- Navigation Menu
- Number Field
- Pagination
- Popover
- Progress
- Radio Group
- Scroll Area
- Select
- Separator
- Sheet
- Sidebar
- Skeleton
- Slider
- Switch
- Table
- Tabs
- Textarea
- Toggle
- Tooltip
Demos
A bar chart with a tooltip.
"use client"
import { Bar, BarChart, CartesianGrid, XAxis } from "recharts"
import {
type ChartConfig,
ChartContainer,
ChartTooltip,
ChartTooltipContent,
} from "@workspace/ui/components/chart"
const data = [
{ month: "May", steps: 7400 },
{ month: "Jun", steps: 8100 },
{ month: "Jul", steps: 9200 },
{ month: "Aug", steps: 8700 },
{ month: "Sep", steps: 10300 },
{ month: "Oct", steps: 11000 },
]
const chartConfig = {
steps: {
label: "Daily steps",
color: "var(--chart-5)",
},
} satisfies ChartConfig
export function ChartDemo() {
return (
<ChartContainer config={chartConfig} className="h-56 w-full max-w-md">
<BarChart accessibilityLayer data={data}>
<CartesianGrid vertical={false} />
<XAxis dataKey="month" tickLine={false} axisLine={false} tickMargin={8} />
<ChartTooltip cursor={false} content={<ChartTooltipContent />} />
<Bar dataKey="steps" fill="var(--color-steps)" radius={4} />
</BarChart>
</ChartContainer>
)
}
Usage
Use a chart to show how a value changes over time or compares across groups. The chart components do not draw anything themselves. They add theme colours, a tooltip, and a legend to Recharts, which you use for the chart.
Install recharts in the app that renders the chart.
Import the wrappers from @workspace/ui/components/chart.
Anatomy
- ChartContainer — Sizes the chart, applies theme styles, and holds the config. Takes one Recharts chart as its child.
- ChartTooltip and ChartTooltipContent — The Recharts tooltip and a themed body for it.
- ChartLegend and ChartLegendContent — The Recharts legend and a themed body for it.
- ChartStyle — Writes the colour variables.
ChartContaineralready renders it.
Config
config maps each data key to a label and a colour. Each colour becomes a CSS variable named after the key, so steps is var(--color-steps). Use these variables for fill and stroke.
Use theme instead of color to set a different colour for light and dark mode.
Notes
- Give
ChartContainera height. It isaspect-videoby default. --chart-5matches the primary colour.--chart-1and--chart-2are almost white in light mode, so do not use them for marks.- Add
accessibilityLayerto the Recharts chart so the reader can move through the data with the arrow keys. - Put units in the label, such as
LDL-C (mg/dL). The tooltip shows labels fromconfig.
Examples
Line
A trend for one biomarker. The tooltip uses the line indicator.
"use client"
import { CartesianGrid, Line, LineChart, XAxis, YAxis } from "recharts"
import {
type ChartConfig,
ChartContainer,
ChartTooltip,
ChartTooltipContent,
} from "@workspace/ui/components/chart"
const data = [
{ date: "Jan", ldl: 142 },
{ date: "Mar", ldl: 131 },
{ date: "May", ldl: 118 },
{ date: "Jul", ldl: 109 },
{ date: "Sep", ldl: 101 },
{ date: "Oct", ldl: 96 },
]
const chartConfig = {
ldl: {
label: "LDL-C (mg/dL)",
color: "var(--chart-5)",
},
} satisfies ChartConfig
export function ChartLine() {
return (
<ChartContainer config={chartConfig} className="h-56 w-full max-w-md">
<LineChart accessibilityLayer data={data} margin={{ left: 0, right: 12 }}>
<CartesianGrid vertical={false} />
<XAxis dataKey="date" tickLine={false} axisLine={false} tickMargin={8} />
<YAxis
width={32}
tickLine={false}
axisLine={false}
domain={[80, 150]}
/>
<ChartTooltip
cursor={false}
content={<ChartTooltipContent indicator="line" />}
/>
<Line
dataKey="ldl"
type="monotone"
stroke="var(--color-ldl)"
strokeWidth={2}
dot={false}
/>
</LineChart>
</ChartContainer>
)
}
Legend
A stacked area chart with two series and a legend.
"use client"
import { Area, AreaChart, CartesianGrid, XAxis } from "recharts"
import {
type ChartConfig,
ChartContainer,
ChartLegend,
ChartLegendContent,
ChartTooltip,
ChartTooltipContent,
} from "@workspace/ui/components/chart"
const data = [
{ month: "May", deep: 1.2, rem: 1.6 },
{ month: "Jun", deep: 1.3, rem: 1.7 },
{ month: "Jul", deep: 1.1, rem: 1.5 },
{ month: "Aug", deep: 1.4, rem: 1.8 },
{ month: "Sep", deep: 1.5, rem: 1.9 },
{ month: "Oct", deep: 1.6, rem: 2.0 },
]
const chartConfig = {
deep: {
label: "Deep sleep (h)",
color: "var(--chart-5)",
},
rem: {
label: "REM sleep (h)",
color: "var(--chart-4)",
},
} satisfies ChartConfig
export function ChartLegendDemo() {
return (
<ChartContainer config={chartConfig} className="h-60 w-full max-w-md">
<AreaChart accessibilityLayer data={data}>
<CartesianGrid vertical={false} />
<XAxis dataKey="month" tickLine={false} axisLine={false} tickMargin={8} />
<ChartTooltip content={<ChartTooltipContent indicator="dot" />} />
<ChartLegend content={<ChartLegendContent />} />
<Area
dataKey="rem"
type="natural"
stackId="sleep"
fill="var(--color-rem)"
fillOpacity={0.4}
stroke="var(--color-rem)"
/>
<Area
dataKey="deep"
type="natural"
stackId="sleep"
fill="var(--color-deep)"
fillOpacity={0.4}
stroke="var(--color-deep)"
/>
</AreaChart>
</ChartContainer>
)
}
Props
ChartContainer
| Prop | Type | Default | Description |
|---|---|---|---|
config | ChartConfig | — | Labels and colours for each data key. Required. |
id | string | generated | Scopes the colour variables. |
initialDimension | { width, height } | 320 × 200 | Size used before the container is measured. |
className | string | — | Classes merged onto the wrapper. Set the height here. |
ChartTooltipContent
| Prop | Type | Default | Description |
|---|---|---|---|
indicator | "dot", "line", or "dashed" | dot | Shape of the colour mark beside each value. |
hideLabel | boolean | false | Hides the heading. |
hideIndicator | boolean | false | Hides the colour marks. |
nameKey | string | — | Data field to use for each row's name. |
labelKey | string | — | Data field to use for the heading. |
labelFormatter | (label, payload) => ReactNode | — | Formats the heading. |
formatter | (value, name, item, index, payload) => ReactNode | — | Replaces each row. |
ChartLegendContent
| Prop | Type | Default | Description |
|---|---|---|---|
hideIcon | boolean | false | Shows a colour square even when the config has an icon. |
nameKey | string | — | Data field to use for each item's label. |
verticalAlign | "top" or "bottom" | bottom | Which side the spacing goes on. |
ChartConfig
| Field | Type | Description |
|---|---|---|
label | ReactNode | Shown in the tooltip and legend. |
color | string | Any CSS colour. |
theme | { light, dark } | Colours per theme. Use instead of color. |
icon | ComponentType | Shown instead of the colour mark. |