# Awesome Stats URL: /docs/web/components/awesome-stats Data-driven metric cards with grid, flex, and animated tabs layouts. **Demo:** ```tsx 'use client'; // @custom-demo import { useState } from 'react'; import { AwesomeStats, type AwesomeStatItem, type AwesomeStatsLayout } from '@docyrus/ui/components/awesome-stats'; import { Button } from '@docyrus/ui/primitives/ui/button'; import { DollarSign, Package, Users } from 'lucide-react'; type LayoutMode = 'grid' | 'scroll' | 'tabs'; type ClickMode = 'off' | 'card' | 'title'; const DEMO_ITEMS: AwesomeStatItem[] = [ { id: 'revenue', eyebrow: 'Growth', title: 'Monthly revenue', subtitle: 'Closed won across all active pipelines', icon: , color: 'emerald-500', value: 2840000, format: { style: 'currency', currency: 'USD', notation: 'compact', maximumFractionDigits: 1 }, comparison: { previousValue: 2470000, period: 'last-month' }, menuItems: [ { id: 'inspect', label: 'Inspect revenue', onSelect: stat => console.info('Inspect stat', stat) }, { id: 'pin', label: 'Pin card', onSelect: stat => console.info('Pin stat', stat) } ], miniChart: { type: 'area', data: [ 1.72, 1.98, 2.14, 2.08, 2.31, 2.54, 2.84 ], dataKey: 'value', position: 'right' } }, { id: 'accounts', eyebrow: 'Pipeline', title: 'Active accounts', subtitle: 'Paying customers with usage in the last 30 days', icon: , color: 'blue-500', value: 1284, format: { notation: 'compact', maximumFractionDigits: 1 }, comparison: { previousValue: 1198, period: 'last-week' }, miniChart: { type: 'sparkline', data: [ 920, 980, 1015, 1090, 1160, 1210, 1284 ], position: 'right' } }, { id: 'returns', eyebrow: 'Health', title: 'Return rate', subtitle: 'Lower is better for this metric', icon: 'fal rotate-left', color: 'rose-500', value: 3.4, format: { style: 'percent', maximumFractionDigits: 1 }, comparison: { previousValue: 4.2, period: 'last-month', positiveDirection: 'down' }, menuItems: [ { id: 'benchmark', label: 'Open benchmark', onSelect: stat => console.info('Benchmark stat', stat) }, { id: 'archive', label: 'Archive card', variant: 'destructive', onSelect: stat => console.info('Archive stat', stat) } ], miniChart: { type: 'area', data: [ 5.1, 4.7, 4.4, 4.2, 4.1, 3.8, 3.4 ], position: 'bottom' } }, { id: 'orders', eyebrow: 'Ops', title: 'Fulfilled orders', subtitle: 'Shipped successfully this week', icon: , color: 'amber-500', value: 8492, format: { notation: 'compact' }, unitLabel: 'orders', comparison: { previousValue: 7784, period: 'yesterday' }, miniChart: { type: 'bar', data: [ 5.8, 6.1, 6.4, 6.2, 7.0, 7.6, 8.49 ], position: 'right' } } ]; export function AwesomeStatsDemo() { const [layoutMode, setLayoutMode] = useState
Card shell
Click target
{lastClicked ? (
Last clicked: {lastClicked}
) : null} setLastClicked(typeof item.title === 'string' ? item.title : item.id)} awesomeCardProps={cardVariant === 'awesome' ? { pattern: true, patternStyle: 'stripes' } : undefined} /> ); } ``` ## Installation ```bash pnpm dlx @docyrus/cli add @docyrus/ui-awesome-stats ``` ## Usage ```tsx import { AwesomeStats } from '@docyrus/ui/components/awesome-stats'; const items = [ { id: 'revenue', eyebrow: 'Growth', title: 'Monthly revenue', value: 2840000, format: { style: 'currency', currency: 'USD', notation: 'compact', maximumFractionDigits: 1 }, comparison: { previousValue: 2470000, period: 'last-month' }, miniChart: { type: 'area', data: [1.72, 1.98, 2.14, 2.08, 2.31, 2.54, 2.84], position: 'right' } }, { id: 'returns', title: 'Return rate', value: 3.4, format: { style: 'percent', maximumFractionDigits: 1 }, comparison: { previousValue: 4.2, period: 'last-month', positiveDirection: 'down' }, miniChart: { type: 'bar', data: [5.1, 4.7, 4.4, 4.2, 4.1, 3.8, 3.4], position: 'bottom' } } ]; ``` ## Layouts | Layout | Config | Use when | |--------|--------|----------| | `grid` | `columns`, optional `maxCardWidth`, optional `gap` | You want a responsive dashboard-style stat grid. | | `flex` | `cardWidth`, `behavior`, optional `gap` | You need fixed-width cards that either wrap or scroll horizontally. | | `tabs` | optional `defaultTabId` | You want multiple stats to share a single card surface with animated tab switching. | ## Card Features | Prop | Purpose | |------|---------| | `eyebrow` | Small light label above the title. | | `icon` | Supports either a React node or a Docyrus icon string such as `"fal chart-line"`. | | `color` | Tailwind-style color token or raw CSS color used for icon and chart accents. | | `comparison` | Computes the delta against a previous period and styles it as positive or negative. | | `miniChart` | Renders `sparkline`, `bar`, or `area` charts at the right edge or docked to the bottom. | | `unitLabel` | Appends a small unit label next to the formatted value. | | `sortable` | Enables drag-and-drop reordering for cards and tab items. | | `onClick` | Per-item click handler. Takes precedence over the top-level `onItemClick`. | ## Awesome Card Mode Set `cardVariant="awesome"` to render every stat with `AwesomeCard`. Use `awesomeCardProps` for the safe shared subset: ```tsx ``` ## Clickable Cards Pass `onItemClick` to make every card actionable, or set a per-item `onClick` for individual handlers (per-item wins when both are present). Use `clickTarget` to choose what the user clicks: | `clickTarget` | Behavior | |---------------|----------| | `card` (default) | The entire card is clickable — `cursor-pointer` over the whole surface, keyboard-focusable (Enter / Space activate it). | | `title` | Only the title is clickable and underlines on hover. | ```tsx router.push(`/metrics/${item.id}`)} layout={{ type: 'grid', columns: 2 }} /> // Or per-item handlers with a title-only target: const items = [ { id: 'revenue', title: 'Monthly revenue', value: 2840000, onClick: (item) => openDrawer(item.id) } ]; ``` The card menu button and drag handle stop propagation, so they never trigger the card/title click handler.