Tooltip

The panel every chart shows on hover — composed from its parts, or driven straight from a payload by the adapter the charts use internally.

Q1 2025
Organic22,000
Paid Ads14,500
Referral5,200

Installation

pnpm add @blakeui/pro-react
npm install @blakeui/pro-react
yarn add @blakeui/pro-react
bun add @blakeui/pro-react

Usage

There are two layers here, and which one you want depends on whether you have a payload.

ChartTooltip is the panel, composed from its parts. You author the row, so it can hold anything — a sparkline, a delta chip, a second line of context.

ChartTooltip.Content is the adapter: hand it a payload and it composes the rows for you. Every chart in the library renders this internally, which is why their tooltips all look the same.

import { ChartTooltip } from "@blakeui/pro-react";

<ChartTooltip indicator="line">
  <ChartTooltip.Header>Q1 2025</ChartTooltip.Header>
  <ChartTooltip.Item>
    <ChartTooltip.Indicator color="var(--chart-1)" />
    <ChartTooltip.Label>Organic</ChartTooltip.Label>
    <ChartTooltip.Value>22,000</ChartTooltip.Value>
  </ChartTooltip.Item>
</ChartTooltip>;

Anatomy

A root holding an optional header and one item per series; each item is an indicator, a label, and a value. The root owns the panel chrome — border, radius, surface, shadow — so a chart only has to position it.

<ChartTooltip>
  <ChartTooltip.Header />
  <ChartTooltip.Item>
    <ChartTooltip.Indicator />
    <ChartTooltip.Label />
    <ChartTooltip.Value />
  </ChartTooltip.Item>
</ChartTooltip>

Positioning is the chart's job

The tooltip is a panel, not a popover. It has no trigger, no portal, and no opinion about where it sits — it renders where you put it. Each chart owns its own placement: it tracks the hovered point, positions a wrapper, and renders ChartTooltip.Content inside. That split is deliberate. A chart already knows its plot geometry, its margins, and which point is active; a generic positioner would have to be told all three.

If you are building your own chart, put the panel in an absolutely-positioned wrapper and move that. Give the wrapper the offset and the transition; leave the panel alone.

Indicator shapes

indicator is set once on the root and reaches every Indicator through context, so rows never disagree. dot is an 8px circle; line is a 4×12 bar that reads better against line series.

Dot
Organic22,000
Line
Organic22,000

Colours

Indicators take any CSS colour, but reach for the categorical series tokens — --chart-1 through --chart-5 — so a hand-composed tooltip matches the chart beside it. Panel chrome is already on the neutral tokens and resolves both themes on its own.

From a payload

ChartTooltip.Content takes the payload shape a chart produces and composes the rows. active and payload are what a chart feeds it; it renders nothing when active is false or the payload is empty, so you can leave it mounted.

labelFormatter and valueFormatter both return ReactNode, not a string. That is the extension point the charts use — it is how they inject a rolling odometer for the value and an animated reel for the header without the adapter knowing anything about either.

March 2025
Revenue$48.2k
Costs$21.8k

In a chart

Most of the time you will not render this yourself. Every chart that has a hover tooltip renders the adapter internally and drives it from the hovered point — hover the plot below, or focus it and arrow across. The values roll because the chart passes its own formatter through valueFormatter.

API Reference

ChartTooltip

The panel root. Owns the chrome and provides the slot context its parts read.

PropTypeDefaultDescription
childrenReactNodeThe header and item rows. Required.
activebooleantrueWhen false the panel renders nothing, so it is safe to leave mounted.
indicator"dot" | "line""dot"Indicator shape for every row, applied through context.
classNamestringClass name for the panel.
…div propsComponentPropsWithRef<"div">Everything else is spread onto the panel element.

ChartTooltip.Content

The payload adapter. Composes a header and one row per payload entry.

PropTypeDefaultDescription
payloadPayloadEntry[]The hovered point's series entries. Renders nothing when empty.
activebooleanWhether the tooltip is showing. Renders nothing when false.
labelstring | numberThe header value, usually the hovered x-axis label.
labelFormatter(label: string | number) => ReactNodeFormats the header. Returns a ReactNode, so it can return a component — this is how the charts animate their headers.
valueFormatter(value: string | number) => ReactNodeFormats each value, and likewise returns a ReactNode — the charts return a rolling odometer here.
hideHeaderbooleanfalseDrop the header row even when a label is present.
indicator"dot" | "line""dot"Passed through to the root.
classNamestringClass name for the panel.

Payload entry

What each entry in payload may carry. The colour is resolved from the first of stroke, color, fill, then payload.fill, which is why the same object works whether it came from a line, a bar, or an area.

FieldTypeDefaultDescription
namestringRow label. Falls back to dataKey.
valuenumber | stringRow value, passed through the formatter.
dataKeystring | numberSeries key. Used as the label fallback and part of the row key.
colorstringIndicator colour.
stroke / fillstringAlternate colour sources, checked before color and after it respectively.

ChartTooltip.Header

The title row — typically the hovered x-axis label.

PropTypeDefaultDescription
childrenReactNodeHeader content. Required.
classNamestringClass name for the header.

ChartTooltip.Item

One series row.

PropTypeDefaultDescription
childrenReactNodeRow content. Required.
classNamestringClass name for the row.

ChartTooltip.Indicator

The per-series colour marker.

PropTypeDefaultDescription
colorstringAny CSS colour. Prefer a series token, e.g. var(--chart-1).
classNamestringClass name for the indicator.

ChartTooltip.Label

The series name. Takes the row's free space, so the value sits flush right.

PropTypeDefaultDescription
childrenReactNodeThe series name. Required.
classNamestringClass name for the label.

ChartTooltip.Value

The series value. The panel sets tabular-nums, so digits stay aligned as the hovered point changes.

PropTypeDefaultDescription
childrenReactNodeThe value. Required.
classNamestringClass name for the value.

CSS classes

The panel is styled through semantic BEM classes in the components layer, so any utility you pass overrides them.

  • .chart-tooltip — the panel. Border, radius, surface, overlay shadow, tabular-nums.
  • .chart-tooltip__header — the title row. 12px medium, muted.
  • .chart-tooltip__item — a series row.
  • .chart-tooltip__indicator — the colour marker, plus --dot and --line modifiers.
  • .chart-tooltip__label — the series name; takes the row's free space.
  • .chart-tooltip__value — the value. 12px semibold, full-strength foreground.

On this page