# Stats 1: headline metrics with trends

> Four large numbers in a hairline grid that count up on scroll, each with a change badge, a small trend line and one line of context. Heading and copy sit above.

A shadcn/ui block from the [@ballmac](https://ui.ballmac.com) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/ballmac/stats-1).

- Page, with a live preview: https://shadcn.exchange/r/ballmac/stats-1
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/ballmac/stats-1-light-579666e41b3f1184.png
- Registry item: https://ui.ballmac.com/r/stats-1.json
- Categories: blocks, stats
- Listed: 2026-10-14, source last changed 2026-10-14

## Install

```bash
npx shadcn@latest add https://ui.ballmac.com/r/stats-1.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Dependencies

- npm packages: `lucide-react`
- Registry items: `utils`, `https://ui.ballmac.com/r/number-ticker.json`, `https://ui.ballmac.com/r/sparkline.json`

## Files

### `registry/ballmac/components/blocks/stats-1/stats-1.tsx`

```tsx
// Ballmac UI: Stats 1. https://ui.ballmac.com/blocks/stats-1
import * as React from "react"
import { ArrowUpRight } from "lucide-react"

import { NumberTicker } from "@/components/ballmac/number-ticker"
import { Sparkline } from "@/components/ballmac/sparkline"
import { cn } from "@/lib/utils"

type Stats1Item = {
  /** What is being measured. */
  label: string
  /** The number to count up to. */
  value: number
  /** Text before the number, e.g. "$". */
  prefix?: string
  /** Text after the number, e.g. "k", "%" or "M+". */
  suffix?: string
  /** Digits after the decimal point. */
  decimals?: number
  /** Change since the last period, e.g. "+18.2%". */
  delta?: string
  /** Samples for the small trend line. */
  trend?: number[]
  /** Accessible description of the trend line. */
  trendLabel?: string
  /** One short sentence of context. */
  note?: string
}

type Stats1Props = Omit<React.ComponentProps<"section">, "title"> & {
  /** Label above the heading. */
  eyebrow?: string
  /** Section heading. */
  title?: string
  /** One or two sentences beside the heading. */
  description?: string
  /** The headline numbers. Four fit best. */
  stats?: Stats1Item[]
  /** Link under the description. Pass null to hide it. */
  link?: { label: string; href: string } | null
}

const defaults: Stats1Item[] = [
  { label: "Teams on Acme", value: 12480, suffix: "+", delta: "+18%", trend: [4, 6, 5, 8, 9, 12, 11, 15, 18], trendLabel: "Teams, last 9 months", note: "Up from 10,570 a year ago." },
  { label: "Invoices paid each month", value: 3.2, suffix: "M", decimals: 1, delta: "+24%", trend: [3, 4, 4, 6, 7, 7, 9, 11, 13], trendLabel: "Invoices, last 9 months", note: "Across 41 countries." },
  { label: "Median payout time", value: 1.8, suffix: " days", decimals: 1, delta: "−0.6 days", trend: [9, 8, 8, 6, 5, 5, 4, 3, 3], trendLabel: "Payout time, last 9 months", note: "Down from 2.4 days last quarter." },
  { label: "Uptime, last 12 months", value: 99.99, suffix: "%", decimals: 2, trend: [99, 99.5, 99.9, 99.9, 99.95, 99.99, 99.99, 99.99, 99.99], trendLabel: "Uptime, last 9 months", note: "Verified by our public status page." },
]

function Stats1({
  eyebrow = "By the numbers",
  title = "Trusted with real money, every day.",
  description = "Thousands of finance teams use Acme to get paid faster and close the books without the spreadsheet scramble.",
  stats = defaults,
  link = { label: "Read the customer stories", href: "#" },
  className,
  ...props
}: Stats1Props) {
  return (
    <section data-slot="stats-1" className={cn("mx-auto max-w-6xl px-4 py-20 sm:px-6 md:py-28", className)} {...props}>
      <div className="grid gap-6 lg:grid-cols-[1.1fr_1fr] lg:items-end lg:gap-16">
        <div>
          <p className="text-muted-foreground text-sm font-medium">{eyebrow}</p>
          <h2 className="mt-3 text-3xl font-semibold tracking-[-0.035em] text-balance sm:text-4xl lg:text-5xl">{title}</h2>
        </div>
        <div>
          <p className="text-muted-foreground text-lg text-pretty">{description}</p>
          {link && (
            <a href={link.href} className="group/link focus-visible:ring-ring/50 mt-4 inline-flex items-center gap-1 rounded-md text-sm font-medium outline-none focus-visible:ring-[3px]">
              {link.label}
              <ArrowUpRight className="size-4 transition-transform group-hover/link:translate-x-0.5 group-hover/link:translate-y-[var(--bm-lift,-2px)] motion-reduce:transition-none rtl:-scale-x-100 rtl:group-hover/link:-translate-x-0.5" aria-hidden="true" />
            </a>
          )}
        </div>
      </div>

      <dl className="bg-border mt-12 grid gap-px overflow-hidden rounded-3xl border sm:grid-cols-2 lg:mt-16 lg:grid-cols-4">
        {stats.map((s, i) => (
          <div key={s.label} className="bg-card group/stat relative flex flex-col p-6 sm:p-8">
            <dt className="text-muted-foreground text-sm">{s.label}</dt>
            <dd className="mt-4 flex flex-col">
              <span className="flex items-baseline gap-2">
                <span className="text-5xl font-semibold tracking-[-0.045em] tabular-nums">
                  {s.prefix}
                  <NumberTicker value={s.value} delay={i * 0.08} format={{ minimumFractionDigits: s.decimals ?? 0, maximumFractionDigits: s.decimals ?? 0 }} />
                  <span className="text-3xl">{s.suffix}</span>
                </span>
              </span>
              <span className="mt-2 inline-flex h-5 w-fit items-center gap-1 text-sm font-medium">
                {s.delta && (
                  <>
                    <ArrowUpRight className="text-chart-2 size-3.5 rtl:-scale-x-100" aria-hidden="true" />
                    {s.delta}
                  </>
                )}
              </span>
              {s.trend && (
                <Sparkline values={s.trend} label={s.trendLabel ?? s.label} height={44} className="text-chart-1 mt-6 w-full opacity-80 transition-opacity group-hover/stat:opacity-100" />
              )}
              {s.note && <span className="text-muted-foreground mt-4 text-sm text-pretty">{s.note}</span>}
            </dd>
          </div>
        ))}
      </dl>
    </section>
  )
}

export { Stats1, type Stats1Props, type Stats1Item }
```
