
Card with a monthly column chart of sessions, the value printed above each rounded bar, and a footer with a trend sentence and icon plus a note. Client component on recharts 3.8.
blocks/charts/bar-chart-01/index.tsx
"use client"
import { TrendUpIcon } from "@phosphor-icons/react"
import { Bar, BarChart, CartesianGrid, LabelList, XAxis } from "recharts"
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card"
import {
ChartContainer,
ChartTooltip,
ChartTooltipContent,
type ChartConfig,
} from "@/components/ui/chart"
// The copy: change text here, not in the markup.
const COPY = {
title: "Sessions",
description: "May to October 2026",
trend: "Up 6.4% on September",
note: "Sessions started on any device.",
} as const
const SESSIONS = [
{ month: "May", sessions: 1860 },
{ month: "June", sessions: 2050 },
{ month: "July", sessions: 2370 },
{ month: "August", sessions: 1730 },
{ month: "September", sessions: 2090 },
{ month: "October", sessions: 2224 },
]
const CHART_CONFIG = {
sessions: { label: "Sessions", color: "var(--chart-2)" },
} satisfies ChartConfig
export default function BarChart01() {
return (
<Card className="mx-auto w-full max-w-md">
<CardHeader>
<CardTitle>
<h2>{COPY.title}</h2>
</CardTitle>
<CardDescription>{COPY.description}</CardDescription>
</CardHeader>
<CardContent>
<ChartContainer config={CHART_CONFIG}>
<BarChart accessibilityLayer data={SESSIONS} margin={{ top: 24 }}>
<CartesianGrid vertical={false} />
{/* Stock ChartContainer's label color misses recharts 3's label layer. */}
<XAxis
tick={{ fill: "var(--muted-foreground)" }}
dataKey="month"
tickLine={false}
axisLine={false}
tickMargin={10}
tickFormatter={(value: string) => value.slice(0, 3)}
/>
<ChartTooltip
cursor={false}
content={<ChartTooltipContent hideLabel />}
/>
<Bar dataKey="sessions" fill="var(--color-sessions)" radius={8}>
{/* The printed value carries the number, so the bar need not. */}
<LabelList
dataKey="sessions"
position="top"
offset={10}
className="fill-foreground"
fontSize={12}
formatter={(value) => Number(value).toLocaleString("en-US")}
/>
</Bar>
</BarChart>
</ChartContainer>
</CardContent>
<CardFooter className="flex-col items-start gap-2 text-sm">
<p className="flex items-center gap-2 font-medium">
{COPY.trend}
<TrendUpIcon aria-hidden="true" className="size-4" />
</p>
<p className="text-muted-foreground">{COPY.note}</p>
</CardFooter>
</Card>
)
}