import { type ReactNode } from "react"; import { type ColorTokens, type StyleProp, type ViewStyle, type TextStyle } from "../../style/index.js"; import { type Surface } from "./stats.styles.js"; export interface StatItem { /** Small caption above the value (e.g. "Total users"). */ label: string; /** The headline figure, pre-formatted (e.g. "12,847", "$48.2k", "3.6%"). */ value: string; /** Optional change indicator (e.g. "+12.5%"). Omit to hide. */ delta?: string; /** Color the delta red (a decline) instead of the default green (a rise). */ down?: boolean; /** Render the delta MUTED rather than as a rise or a decline, for a line that * qualifies the value instead of reporting a change ("last 30 days", * "3 M2M / 1 user"). Green would read as good news that is not being claimed. * Takes precedence over `down`. */ steady?: boolean; /** Optional trend series; when set (and non-empty), the metric renders a * Sparkline strip below the value that plots these points. Omit for no trend. */ spark?: number[]; /** A glyph shown opposite the label, naming what the metric counts. */ icon?: ReactNode; /** A control in the metric's header, opposite the label (a period selector, a * filter). Sits beside `icon` when both are given. */ actions?: ReactNode; /** Accent for the headline value, drawn from the categorical chart ramp so a * dashboard's tiles are tellable apart at a glance. * * Mutually exclusive; first match wins in the order listed. Omit for the * default foreground, which is what every existing call site gets. The slots * are the same eight the charts use, so a metric and the series it summarises * can carry one identity. */ chart1?: boolean; chart2?: boolean; chart3?: boolean; chart4?: boolean; chart5?: boolean; chart6?: boolean; chart7?: boolean; chart8?: boolean; } export interface StatsProps { /** The metrics to render, in order. */ items: StatItem[]; /** Borderless metric stacks on a shared surface, for nesting inside a card. */ plain?: boolean; /** Optional heading shown above the metrics (mainly for the plain surface). */ title?: string; /** Make each metric a tappable target (drill into the underlying detail). When * set, every metric renders as a Pressable with a button role and a pressed * affordance, so a tappable stat needs no hand-rolled Pressable. */ onPressItem?: (index: number) => void; /** E2E hook forwarded to the root element. */ testID?: string; /** Outer layout composition only (width/flex within a parent), never a restyle hook. */ style?: StyleProp; } export interface StatsSkin { /** The bordered card surface each metric sits in (shape, border, padding, shadow). */ cardSurface: (tokens: ColorTokens) => ViewStyle; /** The parent surface the plain variant nests on. */ plainContainer: (tokens: ColorTokens) => ViewStyle; /** Row gap by surface (cards pack tighter, plain stacks sit roomier). */ rowGap: Record; /** Title type + spacing, by surface. */ title: (tokens: ColorTokens, surface: Surface) => TextStyle; /** The small caption above the value. */ labelText: (tokens: ColorTokens) => TextStyle; /** The headline figure type. */ valueText: (tokens: ColorTokens) => TextStyle; /** The delta type base (the tone color is layered on top by the shell). */ deltaBase: TextStyle; /** iOS/web dim on a pressed tappable item; Android uses a ripple instead (null). */ pressedOpacity: number | null; /** Android ripple over a tappable item; null on iOS/web. */ ripple: ((tokens: ColorTokens) => { color: string; borderless: boolean; }) | null; } export declare function createStats(skin: StatsSkin): (props: StatsProps) => import("react").JSX.Element; //# sourceMappingURL=stats.shared.d.ts.map