Getting Started
Components
- Agent Status
- Agent Template Card
- API Key Card
- Audio Player
- Bar Visualizer
- Channel Status Card
- Chat Composer
- Code Editor
- Condition Builder
- Confirm Dialog
- Conversation
- Conversation Bar
- Dataset Card
- Document Status Badge
- Extraction Strategy Select
- File Icon
- File Upload
- Indexing Progress
- Live Waveform
- Matrix
- Message
- Mic Selector
- Model Diff View
- Model Selector
- Model Type Filter
- Node Catalog
- Option Editor
- Orb
- Output Variables View
- Package Card
- Prompt Editor
- Provider Status Card
- Radio Card
- Resource Card
- Resource Sidebar
- Response
- Run Node List
- Scrub Bar
- Segment Card
- Shimmering Text
- Speech Input
- Token Trend Chart
- Tool Call Card
- Transcript Viewer
- Usage Stat Card
- Variable Binding Editor
- Variable Selector
- Voice Button
- Voice Picker
- Waveform
- Workflow Node Card
- Workspace Selector
Requests
42.8k
+12%last 24 hours
Token spend
$318
on pacebudget used
Avg. response
1.4s
-180msp95 2.8s
import { ActivityIcon, CoinsIcon, MessageSquareTextIcon } from "lucide-react"
import { UsageStatCard } from "@/components/ui/usage-stat-card"
export function UsageStatCardDemo() {
return (
<div className="grid w-full max-w-3xl gap-3 sm:grid-cols-3">
<UsageStatCard
label="Requests"
value="42.8k"
description="last 24 hours"
trend="up"
trendLabel="+12%"
tone="good"
icon={<ActivityIcon />}
/>
<UsageStatCard
label="Token spend"
value="$318"
description="budget used"
trend="flat"
trendLabel="on pace"
tone="warning"
icon={<CoinsIcon />}
/>
<UsageStatCard
label="Avg. response"
value="1.4s"
description="p95 2.8s"
trend="down"
trendLabel="-180ms"
tone="good"
icon={<MessageSquareTextIcon />}
/>
</div>
)
}
Installation
pnpm dlx shadcn@latest add https://ui.zgi.ai/r/usage-stat-card.jsonpnpm dlx shadcn@latest add https://ui.zgi.ai/r/usage-stat-card.json
yarn dlx shadcn@latest add https://ui.zgi.ai/r/usage-stat-card.jsonComponent
"use client"
import * as React from "react"
import { ArrowDownIcon, ArrowRightIcon, ArrowUpIcon } from "lucide-react"
import { cn } from "@/lib/utils"
import { Badge } from "@/components/ui/badge"
import { Card, CardContent } from "@/components/ui/card"
export type UsageStatTone = "neutral" | "good" | "warning" | "danger"
export type UsageStatTrend = "up" | "down" | "flat"
export interface UsageStatCardProps
extends Omit<React.ComponentProps<typeof Card>, "title"> {
label: React.ReactNode
value: React.ReactNode
description?: React.ReactNode
icon?: React.ReactNode
trend?: UsageStatTrend
trendLabel?: React.ReactNode
tone?: UsageStatTone
footer?: React.ReactNode
}
const toneClassName: Record<UsageStatTone, string> = {
neutral: "bg-muted text-muted-foreground",
good: "bg-emerald-500/10 text-emerald-700 dark:text-emerald-300",
warning: "bg-amber-500/10 text-amber-700 dark:text-amber-300",
danger: "bg-destructive/10 text-destructive",
}
const trendIcon = {
up: ArrowUpIcon,
down: ArrowDownIcon,
flat: ArrowRightIcon,
}
export function UsageStatCard({
label,
value,
description,
icon,
trend,
trendLabel,
tone = "neutral",
footer,
className,
...props
}: UsageStatCardProps) {
const TrendIcon = trend ? trendIcon[trend] : null
return (
<Card className={cn("rounded-lg py-0", className)} {...props}>
<CardContent className="space-y-4 p-4">
<div className="flex items-start justify-between gap-3">
<div className="min-w-0">
<p className="text-muted-foreground text-xs font-medium">{label}</p>
<div className="mt-2 text-2xl font-semibold tracking-normal tabular-nums">
{value}
</div>
</div>
{icon ? (
<div
className={cn(
"flex size-9 shrink-0 items-center justify-center rounded-lg",
toneClassName[tone]
)}
>
<span className="[&_svg]:size-4">{icon}</span>
</div>
) : null}
</div>
<div className="flex min-h-6 flex-wrap items-center gap-2">
{TrendIcon && trendLabel ? (
<Badge
variant="secondary"
className={cn("h-6 rounded-md border-0", toneClassName[tone])}
>
<TrendIcon className="size-3.5" />
{trendLabel}
</Badge>
) : null}
{description ? (
<span className="text-muted-foreground text-xs leading-5">
{description}
</span>
) : null}
</div>
{footer ? (
<div className="text-muted-foreground border-t pt-3 text-xs">
{footer}
</div>
) : null}
</CardContent>
</Card>
)
}
Usage
import { ActivityIcon } from "lucide-react"
import { UsageStatCard } from "@/components/ui/usage-stat-card"
export function Example() {
return (
<UsageStatCard
label="Requests"
value="42.8k"
trend="up"
trendLabel="+12%"
tone="good"
icon={<ActivityIcon />}
/>
)
}Props
| Prop | Type | Default |
|---|---|---|
| label | ReactNode | required |
| value | ReactNode | required |
| description | ReactNode | - |
| icon | ReactNode | - |
| trend | "up" | "down" | "flat" | - |
| trendLabel | ReactNode | - |
| tone | "neutral" | "good" | "warning" | "danger" | "neutral" |
| footer | ReactNode | - |
Deploy and Scale Agents with ZGI
ZGI delivers the infrastructure and developer experience you need to ship reliable audio & agent applications at scale.
Talk to an expert