Tooltip
An interactive tooltip component for charts with crosshair, dots, date picker, and customizable content
Installation
pnpm dlx shadcn@latest add @bklit/chart-tooltipUsage
The ChartTooltip component provides hover interactions for charts. It must be used inside a chart component (LineChart, AreaChart, BarChart).
import { LineChart, Line, Grid, ChartTooltip } from "@bklitui/ui/charts";
<LineChart data={data}>
<Grid horizontal />
<Line dataKey="value" />
<ChartTooltip />
</LineChart>Props
| Prop | Type | Default | Description |
|---|---|---|---|
showDatePill | boolean | true | Show animated date ticker at bottom |
showCrosshair | boolean | true (false in BarChart and jittered ScatterChart) | Show the crosshair indicator line. Bar charts (vertical and horizontal) and ScatterChart with jitter (hover snaps to the nearest point, not a date) hide it by default — pass showCrosshair to opt in |
showDots | boolean | true | Show dots on data points |
indicatorColor | string | (point) => string | — | Crosshair and dot color; pass a function for dynamic colors |
indicatorDasharray | string | — | SVG dash pattern for the crosshair (e.g. "4,4"). Omit for solid |
indicatorFadeEdges | "both" | "top" | "bottom" | "none" | "both" | Vertical crosshair fade; none = solid line |
indicatorFadeLength | number | 10 | Fade zone size (% of crosshair height) when fading |
matchCrosshair | boolean | false | When true, the panel uses the crosshair spring and moves in sync |
damping | number | 20 | Panel follow damping (default). 0 = instant. Ignored when matchCrosshair is true |
springConfig | { stiffness: number; damping: number } | chart config | Full spring override for crosshair, dots, and date pill |
boxSpringConfig | { stiffness: number; damping: number } | chart config | Full spring override for the floating tooltip panel |
exit | boolean | true | Fade the panel out when hover ends. false hides it immediately |
backgroundColor | string | var(--chart-tooltip-background) | Panel background (CSS variable or color value) |
panelStyle | CSSProperties | — | Inline styles for tooltip background and blur |
dotVariant | "dot" | "ring" | "dot" | Dot style on series markers. dot is a solid core with a soft same-color halo |
dotSize | number | 5 | Dot core / ring radius in pixels |
dotHaloScale | number | 2.6 | Halo radius as a multiple of dotSize; 0 hides the halo. Dot variant only |
dotHaloOpacity | number | 0.3 | Halo opacity (0–1). Dot variant only |
dotRadiusFraction | number | — | Ring corner radius as a fraction of side length (0 = square, 0.5 = circle). Ring variant only |
dotScale | number | 1 | Multiplier applied to the dot / ring radius |
dotStrokeWidth | number | 1.5 (ring) / 0 (dot) | Ring stroke width; for the dot variant, a background-colored outline around the core |
dotColor | string | (point, line) => string | — | Override dot/ring color (e.g. when fill is gradient/pattern) |
content | (props) => ReactNode | - | Custom content renderer |
rows | (point) => TooltipRow[] | - | Custom row generator |
children | ReactNode | - | Additional content (e.g., markers) |
className | string | "" | Additional CSS class |
TooltipRow Interface
interface TooltipRow {
color: string; // Dot color
label: string; // Row label
value: string | number; // Display value
}Anatomy
The tooltip has several visual components:
- Crosshair - Vertical line that follows the cursor
- Dots - A solid dot with a soft halo in the series color on each data point at the hovered position
- Tooltip Box - Popover-style panel: a header row with the date / category, a full-width separator, then rows (color dot, muted label, right-aligned value)
- Date Pill - Animated date ticker at the bottom
Each component can be shown/hidden independently.
Examples
Default Tooltip
Full-featured tooltip with crosshair, dots, and date pill.
<LineChart data={data}> <Grid horizontal /> <Line dataKey="users" stroke="var(--chart-line-primary)" /> <Line dataKey="pageviews" stroke="var(--chart-line-secondary)" /> <XAxis /> <ChartTooltip /></LineChart>Solid crosshair
Remove vertical fade with indicatorFadeEdges="none" for a flat crosshair line.
<LineChart data={data}><Grid horizontal /><Line dataKey="users" stroke="var(--chart-line-primary)" /><XAxis /><ChartTooltip showDots={false} showDatePill={false} indicatorFadeEdges="none" indicatorColor="var(--chart-2)"/></LineChart>Crosshair fade
Fade the crosshair from the top, bottom, both ends, or not at all. Use indicatorFadeLength to control how far the fade extends (percentage of chart height).
<LineChart data={data}><Grid horizontal /><Line dataKey="users" stroke="var(--chart-line-primary)" /><XAxis /><ChartTooltip showDots={false} showDatePill={false} indicatorFadeEdges="top" indicatorFadeLength={22} indicatorColor="var(--chart-2)"/></LineChart>Dashed crosshair
Pass an SVG dash pattern to indicatorDasharray.
<LineChart data={data}><Grid horizontal /><Line dataKey="users" stroke="var(--chart-line-primary)" /><XAxis /><ChartTooltip showDots={false} showDatePill={false} indicatorDasharray="6,4" indicatorColor="var(--chart-2)"/></LineChart>Match crosshair
By default the tooltip panel eases independently with damping={20}. Set matchCrosshair to lock the panel to the crosshair spring.
<LineChart data={data}> <Grid horizontal /> <Line dataKey="users" stroke="var(--chart-line-primary)" /> <XAxis /> <ChartTooltip matchCrosshair /></LineChart>Panel damping
The default panel uses damping={20} without any props. Increase damping for heavier lag, or set damping={0} for instant follow.
<LineChart data={data}><Grid horizontal /><Line dataKey="users" stroke="var(--chart-line-primary)" /><XAxis /><ChartTooltip damping={55} indicatorColor="var(--chart-2)"/></LineChart>Crosshair Only
Minimal tooltip with just the crosshair line and tooltip box.
<LineChart data={data}> <Grid horizontal /> <Line dataKey="users" stroke="var(--chart-line-primary)" /> <XAxis /> <ChartTooltip showDots={false} showDatePill={false} /></LineChart>Minimal (Box Only)
Just the tooltip content box, no visual indicators.
<LineChart data={data}><Grid horizontal /><Line dataKey="users" stroke="var(--chart-line-primary)" /><XAxis /><ChartTooltip showCrosshair={false} showDots={false} showDatePill={false}/></LineChart>Custom Row Labels
Use the rows prop to customize row labels and value formatting.
<LineChart data={data}><Grid horizontal /><Line dataKey="users" stroke="var(--chart-line-primary)" /><Line dataKey="pageviews" stroke="var(--chart-line-secondary)" /><XAxis /><ChartTooltip rows={(point) => [ { color: "var(--chart-line-primary)", label: "Active Users", value: point.users.toLocaleString(), }, { color: "var(--chart-line-secondary)", label: "Page Views", value: point.pageviews.toLocaleString(), }, ]}/></LineChart>With Bar Chart
The tooltip adapts to bar charts, showing category names instead of dates. Inside BarChart the crosshair line is hidden by default (only the hover dots and panel show); pass showCrosshair to bring it back.
<BarChart data={data} xDataKey="month"><Grid horizontal /><Bar dataKey="revenue" fill="var(--chart-line-primary)" /><BarXAxis /><ChartTooltip rows={(point) => [ { color: "var(--chart-line-primary)", label: "Revenue", value: `$${point.revenue.toLocaleString()}`, }, ]}/></BarChart>Fully Custom Content
Use the content prop for complete control over the tooltip layout.
<LineChart data={data}><Grid horizontal /><Line dataKey="users" stroke="var(--chart-line-primary)" /><Line dataKey="pageviews" stroke="var(--chart-line-secondary)" /><XAxis /><ChartTooltip content={({ point }) => ( <div className="flex flex-col gap-2 p-3"> <div className="text-sm font-medium"> {point.date.toLocaleDateString("en-US", { weekday: "short", month: "short", day: "numeric", })} </div> <div className="grid grid-cols-2 gap-x-4 gap-y-1 text-sm"> <span className="text-zinc-400">Users</span> <span className="font-mono">{point.users.toLocaleString()}</span> <span className="text-zinc-400">Views</span> <span className="font-mono">{point.pageviews.toLocaleString()}</span> <span className="text-zinc-400">Ratio</span> <span className="font-mono"> {(point.pageviews / point.users).toFixed(2)}x </span> </div> </div> )}/></LineChart>Animation
The tooltip features smooth animations:
- Tooltip panel - By default the panel eases with
damping={20}. SetmatchCrosshairto share the crosshair spring, or tune lag withdamping(0–100) orboxSpringConfig. - Crosshair - Spring physics for snappy following (
springConfig) - Crosshair style - Solid by default; pass
indicatorDasharray="4,4"(or any SVG dash pattern) for a dashed line. - Tooltip Box - Scale/fade in, fade out on leave (
exit), flip detection (boxSpringConfig). Underprefers-reduced-motionthe panel jumps to position and skips the scale; the opacity fade remains - Date Pill - Slot machine-style number animation
- Dots - Follow the crosshair spring; the core and halo spring open on hover
All animations use motion/react for fluid, natural movement.
<ChartTooltip
indicatorDasharray="6,4"
damping={60}
indicatorColor="var(--chart-2)"
/>Theming
The tooltip uses CSS variables for theming:
:root {
--chart-background: oklch(1 0 0);
--chart-crosshair: oklch(0.4 0.1828 274.34);
}
.dark {
--chart-background: oklch(0.145 0 0);
--chart-crosshair: oklch(0.45 0 0);
}The tooltip box matches shadcn popovers: --chart-tooltip-background (default var(--popover)), --chart-tooltip-foreground (default var(--popover-foreground)), --chart-tooltip-muted (default var(--muted-foreground)), the theme border color, rounded-xl and a soft shadow-lg/5. Pass backgroundColor or panelStyle to override, e.g. for a translucent blurred panel.
To match the built-in header in custom content, use TooltipHeader:
<ChartTooltip
content={({ point }) => (
<>
<TooltipHeader>{String(point.label)}</TooltipHeader>
<div className="px-3.5 py-3 text-sm">…</div>
</>
)}
/>