Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Sparkline

A compact trend line rendered as a smooth (Catmull-Rom) SVG path with a subtle gradient fill. When interactive, pointer hover scrubs the line: a binary search over the SVG path length finds the point under the cursor, moving an indicator dot and a thin vertical scrub line while a colored overlay reveals the path up to the cursor. An optional formatValue label tracks the cursor and reports the interpolated value.

Import

import { Sparkline } from "@roger-emerson/ploxum-primitives";

Usage

<div className="w-72">
  <Sparkline
    data={[42, 44, 45, 43, 47, 48, 49, 51, 53, 58]}
    formatValue={(n) => `${n.toFixed(1)} GB/s`}
    onValueChange={(value, index) => console.log(value, index)}
  />
</div>

A static, non-interactive line — the same renderer KpiTile uses inline:

<Sparkline data={trend} height={120} interactive={false} />

Props

PropTypeDefaultDescription
datanumber[]Y values, evenly spaced along the X axis.
colorstringvar(--ploxum-color-chart-series1)Line + fill hue. The muted base path uses the tertiary text token.
heightnumber160SVG height in px. The internal viewBox is 400 × height with preserveAspectRatio="none".
interactivebooleantrueEnables cursor scrubbing. Falls back to a static line when falsy.
formatValue(n: number) => stringMaps the scrubbed value to a label that tracks the cursor. Omit to hide the label.
onValueChange(value: number, index: number) => voidFired on scrub enter/move with the interpolated value and nearest data index.
onActiveChange(active: boolean) => voidFired on scrub enter (true) and leave (false).
classNamestringMerged onto the root wrapper.
refRef<HTMLDivElement>Forwarded to the root wrapper.

Behavior

  • Static fallback. When interactive={false} — or when data has fewer than 2 points — the component renders a plain role="img" line with no scrub UI. The scrubbing layer is a progressive enhancement, never a hard dependency on pointer input.
  • Dual-path reveal. A muted base path (tertiary text token at low opacity) is always visible; a colored overlay is clipped via clip-path: inset(...) to the cursor's X percentage, so the line reads as "colored up to here, muted beyond."
  • Pixel-accurate scrubbing. The cursor's X is mapped to a point on the curve by a ~25-iteration binary search over path.getPointAtLength, so the indicator dot sits exactly on the line regardless of curvature.

Reduced motion

When prefers-reduced-motion: reduce is set (via usePrefersReducedMotion), the draw-in animation is suppressed — no @keyframes spark-draw, no scrub-layer transitions. Scrubbing stays fully functional; it simply snaps instantly with no easing.

Storybook

Open Sparkline in Storybook ↗