A global edge-region grid with a fast-to-slow latency heat scale and p50/p99 figures in tabular numerals.
npx shadcn@latest add @paragon/region-latency-grid"use client";
import * as React from "react";
import { cn } from "@/lib/utils";
export interface RegionLatency {
code: string;
city: string;
p50: number;
p99: number;
}
export interface RegionLatencyGridProps extends React.ComponentProps<"div"> {
regions?: RegionLatency[];
/** Latency (ms) that maps to the hottest color. */
scaleMax?: number;
}
const DEFAULT_REGIONS: RegionLatency[] = [
{ code: "iad1", city: "Washington", p50: 12, p99: 38 },
{ code: "sfo1", city: "San Francisco", p50: 24, p99: 61 },
{ code: "lhr1", city: "London", p50: 41, p99: 96 },
{ code: "fra1", city: "Frankfurt", p50: 44, p99: 108 },
{ code: "sin1", city: "Singapore", p50: 88, p99: 214 },
{ code: "syd1", city: "Sydney", p50: 132, p99: 288 },
{ code: "gru1", city: "São Paulo", p50: 96, p99: 176 },
{ code: "hnd1", city: "Tokyo", p50: 74, p99: 168 },
];
/** Green (fast) → warning → destructive (slow). */
function heatColor(ms: number, max: number) {
const t = Math.max(0, Math.min(1, ms / max));
const from = t < 0.5 ? "var(--color-success)" : "var(--color-warning)";
const to = t < 0.5 ? "var(--color-warning)" : "var(--color-destructive)";
const local = t < 0.5 ? t * 2 : (t - 0.5) * 2;
return `color-mix(in oklch, ${to} ${Math.round(local * 100)}%, ${from})`;
}
export function RegionLatencyGrid({
regions = DEFAULT_REGIONS,
scaleMax = 300,
className,
...props
}: RegionLatencyGridProps) {
return (
<div
className={cn(
"w-full max-w-2xl rounded-xl bg-card p-4 text-card-foreground shadow-border",
className,
)}
{...props}
>
<div className="mb-3 flex items-center justify-between">
<span className="text-sm font-medium">Edge latency by region</span>
<div className="flex items-center gap-1.5 text-[11px] text-muted-foreground">
<span>fast</span>
<span
className="h-2 w-16 rounded-full"
style={{
background:
"linear-gradient(90deg, var(--color-success), var(--color-warning), var(--color-destructive))",
}}
/>
<span>slow</span>
</div>
</div>
<div className="grid grid-cols-2 gap-2 sm:grid-cols-4">
{regions.map((r) => {
const c = heatColor(r.p99, scaleMax);
return (
<div
key={r.code}
className="relative overflow-hidden rounded-lg border border-border bg-background p-2.5"
>
<span
aria-hidden
className="absolute inset-x-0 top-0 h-0.5"
style={{ background: c }}
/>
<div className="flex items-baseline justify-between">
<span className="font-mono text-xs font-medium">{r.code}</span>
<span
className="size-2 rounded-full"
style={{ background: c }}
aria-hidden
/>
</div>
<p className="truncate text-[11px] text-muted-foreground">
{r.city}
</p>
<div className="mt-2 flex items-center justify-between text-xs tabular-nums">
<span className="text-muted-foreground">
p50{" "}
<span className="font-medium text-foreground">{r.p50}</span>
</span>
<span className="text-muted-foreground">
p99 <span className="font-medium" style={{ color: c }}>
{r.p99}
</span>
</span>
</div>
</div>
);
})}
</div>
</div>
);
}