BulletBar
SLO bullet rows — a measure bar against qualitative zones with a vertical target tick.
Source
"use client"
import { BulletBar, type BulletItem } from "@/registry/warren/bullet-bar/bullet-bar"
const ITEMS: BulletItem[] = [
{
label: "API AVAILABILITY",
value: 99.2,
target: 99.9,
bands: [
{ limit: 99, tone: "danger" },
{ limit: 99.5, tone: "warning" },
{ limit: 100, tone: "success" },
],
unit: "%",
burnRate: 2.1,
},
{
label: "P99 LATENCY BUDGET",
value: 310,
target: 250,
bands: [
{ limit: 200, tone: "success" },
{ limit: 400, tone: "warning" },
{ limit: 500, tone: "danger" },
],
unit: "ms",
},
{
label: "ERROR RATE",
value: 0.4,
bands: [
{ limit: 0.1, tone: "success" },
{ limit: 1, tone: "warning" },
],
unit: "%",
},
]
export default function BulletBarDemo() {
return (
<div className="flex flex-col gap-3 border-2 border-border bg-panel p-2">
<span className="font-mono text-[10px] uppercase tracking-wide text-muted-foreground">
SERVICE SLO WALL · TARGETS + QUALITY ZONES
</span>
<BulletBar items={ITEMS} />
</div>
)
}
Installation
npx shadcn@latest add https://warren.eduard3v.com/r/bullet-bar.jsonUsage
import { BulletBar } from "@/components/ui/bullet-bar"<BulletBar
max={100}
items={[
{
label: "API AVAILABILITY",
value: 99.2,
target: 99.9,
bands: [
{ limit: 99, tone: "danger" },
{ limit: 99.5, tone: "warning" },
{ limit: 100, tone: "success" },
],
unit: "%",
burnRate: 2.1,
},
]}
/>Encoding
Stephen Few's bullet chart, console-grade: each row stacks a mono uppercase label, the value
(+ optional unit) in mono tabular numerals, and one flat bar — qualitative zones from
ascending bands[].limit edges rendered as *-soft washes, the measure as a saturated fill,
and target as a 2px ink tick punched through the track (zones() / scaleMax() in
zones.ts).
The measure tone is state, not decoration: it takes the tone of the zone the value lands in,
flips to danger once the value escapes every zone, and stays primary for tone-less bands.
The shared max pins the scale across rows; without it (or per-row item.max) each row
scales to its own largest edge.
burnRate renders a 2.1× annotation before the value — danger text above 1, muted at or
below.
Interactive
Source
"use client"
import { useState } from "react"
import { BulletBar, type BulletItem } from "@/registry/warren/bullet-bar/bullet-bar"
const ITEMS: BulletItem[] = [
{
label: "API AVAILABILITY",
value: 99.2,
target: 99.9,
bands: [
{ limit: 99, tone: "danger" },
{ limit: 99.5, tone: "warning" },
{ limit: 100, tone: "success" },
],
},
{
label: "WORKER THROUGHPUT",
value: 6400,
target: 7000,
bands: [
{ limit: 5000, tone: "danger" },
{ limit: 8000, tone: "success" },
],
unit: "msg/s",
},
]
export default function BulletBarInteractive() {
const [last, setLast] = useState<string | null>(null)
const onItemClick = (item: BulletItem) => setLast(String(item.label))
return (
<div className="flex flex-col gap-3 border-2 border-border bg-panel p-2">
<span className="font-mono text-[10px] uppercase tracking-wide text-muted-foreground">
SLO WALL · CLICK A ROW
</span>
<BulletBar items={ITEMS} onItemClick={onItemClick} />
<span className="font-mono text-[10px] uppercase tracking-wide text-muted-foreground">
LAST CLICK: {last ?? "—"}
</span>
</div>
)
}
With onItemClick(item), each row's bar becomes a real <button> whose accessible name is
the row summary ("<label>: <value><unit> · target <t> · <n>× burn") and the container flips
from role="img" to role="group". Set showTooltips for native title tooltips.
API Reference
Prop
Type
Prop
Type
Prop
Type