Hazine

Metric Card

A dashboard stat card with animated value and delta indicator.

Revenue$012.4%vs last month
Active users03.1%vs last month

Installation

npx shadcn@latest add @hazine/metric-card

Source

import * as React from "react"
import { ArrowDownRightIcon, ArrowUpRightIcon } from "lucide-react"

import { cn } from "@/lib/utils"
import { Card, CardContent } from "@/components/ui/card"
import { AnimatedCounter } from "@/components/hazine/animated-counter"

interface MetricCardProps extends React.ComponentProps<typeof Card> {
  label: string
  value: number
  delta?: number
  format?: (value: number) => string
}

export function MetricCard({
  label,
  value,
  delta,
  format,
  className,
  ...props
}: MetricCardProps) {
  const positive = delta !== undefined && delta >= 0
  return (
    <Card className={cn("py-4", className)} {...props}>
      <CardContent className="flex flex-col gap-1 px-4">
        <span className="text-sm text-muted-foreground">{label}</span>
        <span className="text-2xl font-semibold tracking-tight">
          <AnimatedCounter value={value} format={format} />
        </span>
        {delta !== undefined && (
          <span
            className={cn(
              "inline-flex items-center gap-0.5 text-xs font-medium",
              positive
                ? "text-emerald-600 dark:text-emerald-400"
                : "text-red-600 dark:text-red-400"
            )}
          >
            {positive ? (
              <ArrowUpRightIcon className="size-3.5" />
            ) : (
              <ArrowDownRightIcon className="size-3.5" />
            )}
            {Math.abs(delta)}%
            <span className="font-normal text-muted-foreground">
              vs last month
            </span>
          </span>
        )}
      </CardContent>
    </Card>
  )
}

Dependencies