Stat
Un número grande con una etiqueta corta y un cambio con signo, donde la importancia se ve en tamaño, peso y color.
Monthly visitors
24,608
+2,140 since September
Refunds
38
+6 since September
Instalación
$ pnpm dlx shadcn@latest add @ssntl/statUso
import { Stat, StatDelta, StatLabel, StatValue } from "@/components/ui/stat"
<Stat>
<StatLabel>Visitas mensuales</StatLabel>
<StatValue>24,608</StatValue>
<StatDelta trend="up">+2,140 desde septiembre</StatDelta>
</Stat>- Importancia: el valor manda en tamaño (48px, lg 64px), peso (bold) y color (foreground); la etiqueta y la nota pasan a muted.
- Más allá del tamaño: la jerarquía también viene del peso y el color, así el número sigue mandando en una tarjeta pequeña.
- Escribe el signo y el periodo en el cambio; el verde y el rojo solo acompañan las palabras.
- Las estadísticas pares comparten tamaño, peso y posición de la etiqueta. Los dígitos tabulares las mantienen alineadas.
Código
import * as React from "react"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
// Essential Design `es-stat`: when the number is the point, it gets the space.
// Importance shows in more than size: the value is large, heavy and full
// foreground; the label and the note step back in caption size and muted
// color. Tabular figures so peer stats line up.
const statValueVariants = cva("font-bold tabular-nums", {
variants: {
size: {
md: "text-headline",
lg: "text-stat",
},
},
defaultVariants: { size: "md" },
})
function Stat({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="stat"
className={cn("grid content-start gap-1", className)}
{...props}
/>
)
}
function StatLabel({ className, ...props }: React.ComponentProps<"p">) {
return (
<p
data-slot="stat-label"
className={cn("text-label font-normal text-muted-foreground", className)}
{...props}
/>
)
}
function StatValue({
size,
className,
...props
}: React.ComponentProps<"p"> & VariantProps<typeof statValueVariants>) {
return (
<p
data-slot="stat-value"
className={cn(statValueVariants({ size, className }))}
{...props}
/>
)
}
// Write the sign and the period ("+2,140 this month"): the color only
// supports a change the words already state.
function StatDelta({
trend = "neutral",
className,
...props
}: React.ComponentProps<"p"> & { trend?: "up" | "down" | "neutral" }) {
return (
<p
data-slot="stat-delta"
data-trend={trend}
className={cn(
"text-caption",
trend === "up" && "text-green-600 dark:text-green-400",
trend === "down" && "text-destructive",
trend === "neutral" && "text-muted-foreground",
className
)}
{...props}
/>
)
}
export { Stat, StatDelta, StatLabel, StatValue, statValueVariants }