KPI statFree

One number with its change in words, an optional target meter and sparkline. Plain SVG: no chart engine.

npx shadcn@latest add https://beautifulcharts.dev/r/kpi-stat.json

Code

"use client";

import { KpiStat } from "@/components/beautiful-charts/themes/instrument/kpi-stat";

// A change from a zero base is shown as an amount, never as an infinite percentage.
export function ActiveTeams() {
  return (
    <KpiStat
      title="Active teams"
      value={74}
      previous={38}
      previousLabel="last week"
      target={80}
      trend={[38, 42, 40, 47, 51, null, 55, 61, 63, 64, 69, 74]}
      unit="teams with a weekly session"
    />
  );
}

Props

  • value*

    number | null

    The number. null or undefined shows the empty state.

  • previous

    number | null

    The comparison value, e.g. last period.

  • previousLabel

    string

    What the comparison is, e.g. "last month".

  • target

    number | null

    A goal. Adds a meter showing progress toward it.

  • trend

    (number | null)[]

    Recent values, oldest first, for the sparkline. Missing values break the line.

  • polarity

    "up" | "down"

    "up" when a rise is good (default), "down" for costs, churn, latency.

  • valueFormatter

    (value: number) => string

    Formats the number, change and target.

  • motion

    MotionPreference

    "full" (default), "subtle" or "off". Reduced-motion settings always win.

  • eyebrow

    ReactNode

    Small label above the title.

  • footer

    ReactNode

    A line or action at the bottom of the card.

  • title

    ReactNode

    Card title. A string also names the stat for screen readers.

  • description

    ReactNode

    A line under the title.

  • unit

    ReactNode

    Small unit or context under the number, e.g. "active teams".

  • loading

    boolean

    Show the loading state.

  • error

    string | null

    An error message; shows the error state.

  • density

    Density

    "comfortable" (default) or "compact".

  • className

    string

    Classes on the card.

  • palette

    "theme" | "shadcn"

    "theme" (default) or "shadcn" to use your --chart-N colours.

  • trendHeight

    number

    Sparkline height in px.

Props every chart shares (2): data, config, header, states, legend, tooltip, formatting, motion and selection
  • locale

    string

    BCP 47 locale. Defaults to "en-US" so server and client render the same text.

  • timeZone

    string

    IANA time zone for dates. Defaults to "UTC" so server and client agree.

Accessibility, keyboard and motion

Pointer
Not interactive.
Keyboard
Not focusable: there's nothing to move between.
Screen readers
A labelled group: the value, its change in words and the target are read as one sentence.
Motion
The value rolls in digit by digit, the trend line draws, then the change fades in. With reduced motion it appears settled at once.