import React from "react"; import { View } from "react-native"; import { cn } from "../utils/cn"; import { Card } from "./card"; import { MutedText, Text } from "./text"; /** Direction of a stat's delta — drives the trend colour. */ export type StatTrend = "up" | "down" | "neutral"; export interface StatCardProps { /** Short label describing the metric (e.g. "Active users"). */ label: string; /** The headline value. Numbers are rendered as-is; format upstream. */ value: string | number; /** Optional leading icon slot (e.g. a lucide / Ionicons element). */ icon?: React.ReactNode; /** Optional change indicator text (e.g. "+12% this week"). */ delta?: string; /** Trend direction — colours the delta. Defaults to "neutral". */ trend?: StatTrend; className?: string; } // Trend → delta text colour. Tokens only (success/destructive/muted) so each // consuming app's palette flows through; no hardcoded hex. const trendClass: Record = { up: "text-success", down: "text-destructive", neutral: "text-muted-foreground dark:text-neutral-400", }; /** * Map a trend direction to its delta text colour class. Pure so the * trend→colour contract is unit-testable without a render host. */ export function trendColorClass(trend: StatTrend): string { return trendClass[trend]; } /** * Dashboard stat tile: a label, a prominent value, an optional leading icon, * and an optional trend/delta line. Composes `Card` + `Text` so the surface, * border, and typography stay in lockstep with the rest of the system rather * than duplicating styles. */ export function StatCard({ label, value, icon, delta, trend = "neutral", className, }: StatCardProps) { return ( {label} {icon ? {icon} : null} {value} {delta ? {delta} : null} ); }