metis-desk/packages/rdx-ui/src/components/statistic-card.tsx

75 lines
2.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import type { ReactNode } from "react";
const TONES = {
teal: "bg-primary/5",
rose: "bg-destructive/5",
amber: "bg-amber-500/5",
green: "bg-emerald-500/5",
violet: "bg-violet-500/5",
};
const ICON_TONES = {
teal: "text-primary",
rose: "text-destructive",
amber: "text-amber-700 dark:text-amber-400",
green: "text-emerald-700 dark:text-emerald-400",
violet: "text-violet-700 dark:text-violet-400",
};
export function StatisticCard({
icon,
label,
value,
tone = "teal",
onClick,
status,
compact = false,
}: {
compact?: boolean;
icon: ReactNode;
label: string;
value?: number | undefined;
tone?: "teal" | "rose" | "amber" | "green" | "violet";
onClick: () => void;
status?: string | undefined;
}) {
return (
<button
className={`flex items-start gap-3 rounded-xl border border-border text-left transition-colors hover:border-primary focus-visible:outline-2 focus-visible:outline-ring ${compact ? "min-h-28 p-5" : "min-h-28 p-4 shadow-sm"} ${TONES[tone]}`}
onClick={onClick}
type="button"
>
<span
aria-hidden="true"
className={`flex size-10 shrink-0 items-center justify-center rounded-full bg-background/60 [&_svg]:size-5 ${ICON_TONES[tone]}`}
>
{icon}
</span>
<span className="min-w-0">
<span
className={
compact
? "block text-sm font-medium text-foreground"
: "block text-xs font-medium text-foreground"
}
>
{label}
</span>
<strong
className={`mt-2 block font-semibold tabular-nums text-foreground ${compact ? "text-4xl tracking-tight" : "text-3xl"}`}
>
{value ?? "—"}
</strong>
{status && (
<small className="block mt-1 text-muted-foreground" role="status">
{status}
</small>
)}
</span>
<span aria-hidden="true" className="ml-auto self-center text-lg text-primary">
›
</span>
</button>
);
}