shadcn.io is not affiliated with official shadcn/ui
Connected KPI Bar Stats Block for React
Four headline figures for a subscription analytics tool in cells that share their hairlines from rail to rail, each with its change on the month before and a tiny sparkline of the last twelve months.
Installation
Overview
A connected KPI bar for React with Base UI. A compact header says what the month was, "Revenue grew 8.4% in March", with the period, its comparison and what the lines cover at the end of the row. Under it, four figures (monthly recurring revenue, paying customers, revenue per customer and revenue churn) sit in cells that share their hairlines, in a band that runs from rail to rail and ends the block, so the next section's top rule closes it. Each cell shows the value large, its label, the change on February as an arrow and a signed number, and a word-sized sparkline of the last twelve months whose latest segment, the one the change describes, is drawn at full weight and ends on a dot. Every figure, change, headline number and line is computed from the same monthly readings, so the text and the drawings can't disagree. The sparklines are hand-drawn SVG in your theme's foreground colour at two weights, with no chart library and no colour for good or bad. Four cells sit in a row from lg and two by two below it. The block has no state: it's Guides, Lucide icons, one small inline SVG per figure and CSS transitions for the entrance. For the numbers section of a SaaS, analytics or finance page, between a hero and pricing.
FAQ
How do I change the figures?
Edit MONTHS, REVENUE, CUSTOMERS and KPIS at the top of the file. Each KPI is a label, a series of monthly readings (oldest first, one per month), a write function that formats a reading, and a change kind: percent for a share of the month before (+8.4%), count for a difference (+126) or points for rates (−0.4 pts). The cell's value, its change, the sparkline and the headline's number are all read from the series. Revenue per customer is computed from the two series before it, so the four figures always agree. The month names have no year, so the copy never goes stale.
How are the sparklines drawn?
Each line is an SVG path computed when the module loads: the readings are scaled into a 100 by 100 box with a tenth left clear above and below, and the box stretches to the cell (preserveAspectRatio="none" with a non-scaling stroke, so the line stays 1.5 pixels at any width). The months before are drawn at 35% of the text colour and the last month at full strength, so the eye goes to the change the cell reports. The end dot is an HTML element positioned from the same numbers, so it stays round. The lines run from the start to the end in every language: the chart box is dir="ltr", the way time series read.
Why aren't rises green and falls red?
Whether a change is good depends on the figure: churn going down is good news, revenue going down isn't. The block shows the direction with an arrow and a sign, in the text colour, and leaves the judgement to the reader. That also keeps it correct in every theme preset, light and dark, and readable without colour. If one figure needs to raise an alarm (a breached target), give that cell a status icon rather than tinting the numbers.
Is the KPI bar accessible?
Yes. The figures are a description list: each label is a term and its value, change and trend are its descriptions. The value is shown first but read after its label, so a screen reader hears "Monthly recurring revenue, $184,320, +8.4% vs February". The arrows are hidden from assistive technology because the sign says the same; the minus is a true minus sign, read as "minus". Each sparkline is an image whose name gives its first and last readings and its low and high. Values sit in bdi elements and signed changes are kept left to right, so a right-to-left page doesn't move a sign or a percent to the wrong side.
Why is there no line under the figures?
The band ends the block. On a page, the next section draws its own top rule along the band's foot, so a bottom border here would double it, and the column has no bottom padding for the same reason. The band's top rule comes from the Guides component, with a + mark where it meets each rail. If nothing follows the block, add a bottom border to the list's wrapper.
What moves, and how does it fit on a phone?
The header and the band fade up once when the page loads, and each sparkline draws from start to end with a CSS clip-path transition. With reduced motion the transitions are off and everything simply appears. Below lg the four cells sit two by two, meeting at a hairline cross, and on a phone each comparison takes its own line under its change. Each cell lays its parts on rows it shares with the cells beside it (a CSS subgrid), so when one label wraps, the changes and the sparklines of that row still line up. Nothing scrolls sideways at 320 pixels.
Related
- Pro
Minimal KPI Bar Stats
KPI bands and tilesFour figures for a bookkeeping tool in cells that share their hairlines from rail to rail, each only a label and a value, under a one-line header that names the period.
- Pro
KPI Bar with Trends Stats
KPI bands and tilesFour figures for a garden-centre analytics tool in cells that share their hairlines, each with its change on the week before and an area chart that runs to the cell's edges and foot.
- Pro
Delta Pill KPI Tiles Stats
KPI bands and tilesFour raised KPI tiles for a checkout analytics tool, each with its change as a pill: filled for a rise, outlined for a fall and muted for none, with an arrow or a dash and a sign.
- Pro
Metric Tile Row Stats
Hero metricAn asymmetric band of four figures for a property-management tool: one double-width hero cell for rent collected and three small cells for occupancy, arrears and renewals, each with its change on the month before.
- Pro
Command Center Metric Board Features
Metrics and chartsA metrics console in a card in a card that follows your theme: six metric tiles with a value, a signed change and a sparkline are the tabs of one tablist, and choosing one opens a larger chart of its series in a strip below.
- $48,110Pro
A revenue banner for a sales dashboard, as a card in card: the figure, a change badge and the comparison at the start, a 24 h and 7 d switch and a bar sparkline at the end, swapping in place.