import { MetricCard, MetricCardGroup } from "@cloudflare/kumo";
export function MetricCardGroupDemo() {
return (
<MetricCardGroup title="Workers Analytics">
<MetricCard
label="Requests"
value="1.2"
unit="M"
trend={{ direction: "up", label: "12%", isPositive: true }}
/>
<MetricCard
label="CPU Time (P90)"
value="3.2"
unit="ms"
trend={{ direction: "down", label: "8%", isPositive: true }}
sparkline={{
data: [
4.1, 3.9, 4.2, 3.8, 3.5, 3.9, 3.6, 3.4, 3.7, 3.3, 3.5, 3.1, 3.4,
3.0, 3.3, 3.2,
],
}}
/>
<MetricCard
label="Errors"
value="842"
trend={{ direction: "up", label: "13.8%", isPositive: false }}
/>
<MetricCard label="Wall Time" value="24" unit="ms" />
</MetricCardGroup>
);
} Installation
Barrel
import { MetricCard, MetricCardGroup } from "@cloudflare/kumo";Granular
import { MetricCard } from "@cloudflare/kumo/components/metric-card";
import { MetricCardGroup } from "@cloudflare/kumo/components/metric-card-group"; Usage
import { MetricCard, MetricCardGroup } from "@cloudflare/kumo";
export default function Example() {
return (
<MetricCardGroup title="Overview">
<MetricCard label="Requests" value="1.2M" />
<MetricCard label="Error Rate" value="0.3" unit="%" />
</MetricCardGroup>
);
} Examples
Horizontal Group
The default layout arranges metric cards in a horizontal row with vertical dividers.
import { MetricCard, MetricCardGroup } from "@cloudflare/kumo";
export function MetricCardHorizontalGroupDemo() {
return (
<MetricCardGroup title="Summary">
<MetricCard
label="Total requests"
value="2.8"
unit="M"
trend={{ direction: "up", label: "9%", isPositive: true }}
sparkline={{
data: [
1.9, 2.1, 2.0, 2.3, 2.1, 2.4, 2.2, 2.5, 2.3, 2.6, 2.4, 2.7, 2.6,
2.8,
],
color: "var(--color-kumo-brand)",
}}
/>
<MetricCard label="Successful requests" value="2.7" unit="M" />
<MetricCard label="Failed requests" value="12.4" unit="k" />
</MetricCardGroup>
);
} Vertical Group
Use orientation="vertical" for sidebar or narrow container layouts.
import { MetricCard, MetricCardGroup } from "@cloudflare/kumo";
export function MetricCardGroupVerticalDemo() {
return (
<div className="max-w-xs">
<MetricCardGroup orientation="vertical" title="Registrar">
<MetricCard label="Active domains" value="142" />
<MetricCard label="Expiring soon" value="3" />
<MetricCard label="Pending transfers" value="2" />
</MetricCardGroup>
</div>
);
} Without Title
Omit the title prop for a minimal layout without a header.
import { MetricCard, MetricCardGroup } from "@cloudflare/kumo";
export function MetricCardGroupWithoutTitleDemo() {
return (
<MetricCardGroup>
<MetricCard
label="Web traffic"
value="2.4"
unit="M"
sparkline={{
data: [1.8, 2.1, 1.9, 2.3, 2.0, 2.4, 2.2, 2.5, 2.1, 2.6, 2.3, 2.4],
}}
/>
<MetricCard
label="Total bandwidth"
value="1.8"
unit="PB"
sparkline={{
data: [
1.2, 1.25, 1.3, 1.28, 1.35, 1.4, 1.38, 1.45, 1.5, 1.48, 1.55, 1.6,
1.8,
],
}}
/>
<MetricCard
label="Cache rate"
value="89.2"
unit="%"
sparkline={{
data: [
85, 86.5, 84, 87, 85.5, 88, 86, 89, 87.5, 88.5, 86.5, 88, 89, 89.2,
],
}}
/>
</MetricCardGroup>
);
} Sparklines
Add sparkline visualizations with themed or custom colors.
import { MetricCard, MetricCardGroup } from "@cloudflare/kumo";
export function MetricCardSparklineDemo() {
return (
<MetricCardGroup title="Traffic Overview">
<MetricCard
label="Bandwidth"
value="3.5"
unit="GB"
sparkline={{
data: [
2.1, 2.4, 2.2, 2.7, 2.5, 2.9, 2.6, 3.1, 2.8, 3.2, 3.0, 3.4, 3.3,
3.5,
],
theme: "success",
}}
/>
<MetricCard
label="Visits"
value="48.2"
unit="k"
sparkline={{
data: [32, 35, 33, 38, 36, 40, 37, 42, 39, 44, 41, 48.2],
theme: "neutral",
}}
/>
<MetricCard
label="Page views"
value="126"
unit="k"
sparkline={{
data: [85, 90, 82, 95, 88, 102, 92, 108, 97, 115, 105, 120, 110, 126],
theme: "danger",
}}
/>
<MetricCard
label="Cached requests"
value="92.1"
unit="%"
sparkline={{
data: [
88, 89.5, 87, 90, 88.5, 91, 89, 91.5, 90, 92, 90.5, 91.8, 91, 92.1,
],
color: "var(--text-color-kumo-brand)",
}}
/>
</MetricCardGroup>
);
} Color Variants
Use semantic color variants to convey status at a glance.
import { MetricCard, MetricCardGroup } from "@cloudflare/kumo";
export function MetricCardVariantsDemo() {
return (
<MetricCardGroup title="Health">
<MetricCard
label="CPU Time (P90)"
value="4.1"
unit="ms"
variant="default"
/>
<MetricCard
label="Request duration"
value="45"
unit="ms"
variant="success"
/>
<MetricCard
label="Workers errors"
value="2.3"
unit="k"
variant="danger"
trend={{ direction: "up", label: "0.8%", isPositive: false }}
/>
<MetricCard
label="Subrequests"
value="847"
unit="k"
variant="warning"
trend={{ direction: "up", label: "23%", isPositive: false }}
/>
</MetricCardGroup>
);
} Interactive Cards
Cards become clickable when given an href or onClick prop. Use tooltip
to add contextual information, and tooltipIcon to override the default icon.
The title prop accepts JSX content for custom header layouts such as a title
with an action button.
import { MetricCard, MetricCardGroup, Button } from "@cloudflare/kumo";
import { ArrowRightIcon, QuestionIcon } from "@phosphor-icons/react";
export function MetricCardInteractiveDemo() {
return (
<MetricCardGroup
title={
<div className="flex w-full items-center justify-between">
<div>Workers Overview</div>
<Button
variant="ghost"
size="sm"
shape="square"
aria-label="View all workers"
>
<ArrowRightIcon size={16} />
</Button>
</div>
}
>
<MetricCard
label="Requests"
value="1.2"
unit="M"
tooltip="Total HTTP requests in the selected period"
href="#"
/>
<MetricCard
label="CPU Time (P90)"
value="3.2"
unit="ms"
tooltip="90th percentile CPU time per invocation"
tooltipIcon={QuestionIcon}
href="#"
/>
<MetricCard
label="Errors"
value="842"
tooltip="Failed invocations returning non-2xx status"
onClick={() => {}}
/>
</MetricCardGroup>
);
} Loading and Error States
MetricCard supports loading and error states for async data.
import { MetricCard, MetricCardGroup } from "@cloudflare/kumo";
export function MetricCardStatesDemo() {
return (
<MetricCardGroup title="Dashboard">
<MetricCard
label="Workers invocations"
value="12.4"
unit="k"
trend={{ direction: "up", label: "8%", isPositive: true }}
/>
<MetricCard label="Build minutes" value="" loading />
<MetricCard label="Logins blocked" value="" error />
</MetricCardGroup>
);
} API Reference
MetricCard
Compact card displaying a single metric value with optional trend, sparkline, and loading/error states.
| Prop | Type | Default | Description |
|---|---|---|---|
| className | string | - | - |
| id | string | - | - |
| title | string | - | - |
| children | ReactNode | - | - |
| variant | "default" | "success" | "danger" | "warning" | "default" | Color variant for the metric value text. |
| label* | string | - | Label text displayed above the value. |
| value* | string | - | Pre-formatted metric value, e.g. "1.2M", "99.9". |
| unit | string | - | Unit displayed after the value in smaller text, e.g. "%", "ms". |
| trend | MetricCardTrend | - | Trend indicator with direction arrow and label. |
| sparkline | MetricCardSparkline | - | Sparkline chart rendered at the bottom of the card. |
| href | string | - | When set, renders the card as an anchor element. |
| loading | boolean | - | Shows skeleton loading state for the value. |
| error | boolean | - | Shows an em-dash placeholder in place of the value. |
| tooltip | ReactNode | - | Content displayed in a tooltip next to the label. |
| tooltipIcon | React.ComponentType<MetricCardTooltipIconProps> | - | Custom icon component for the tooltip trigger. Defaults to Info icon from Phosphor. |
MetricCardGroup
Groups MetricCard children inside a card with an optional header and configurable orientation.
| Prop | Type | Default | Description |
|---|---|---|---|
| className | string | - | - |
| id | string | - | - |
| children | ReactNode | - | MetricCard children to render inside the group. |
| orientation | "horizontal" | "vertical" | "horizontal" | Layout direction for child metric cards. - `"horizontal"` — Cards in a row with vertical dividers - `"vertical"` — Cards stacked with horizontal dividers |
| title | ReactNode | - | Optional header text rendered in a LayerCard.Secondary section. |