Bar list
Ranked list of values as proportional bars.
npx shadcn@latest add https://ui.thjsecurity.tech/r/bar-list.jsonPulls the component into components/ui/bar-list.tsx and its token dependencies. The app owns the copy from then on.
import * as React from "react"
import { cn } from "@/lib/utils"
export interface BarListItem {
/** Left-aligned label (truncated if long). */
label: React.ReactNode
/** Numeric magnitude that sizes the bar. */
value: number
/** Optional muted hint shown right of the label. */
hint?: React.ReactNode
/** Bar color (CSS color or hsl(var(--…))). Defaults to primary. */
color?: string
/** Optional click target for the whole row. */
href?: string
}
interface BarListProps {
items: BarListItem[]
/** Override the denominator; defaults to the max value in items. */
max?: number
/** Cap rendered rows. */
limit?: number
className?: string
}
/**
* Scannable horizontal bar-list (PD-style): label over a subtle track with a
* filled bar, right-aligned count. Pure CSS - no chart library.
*/
function BarList({ items, max, limit, className }: BarListProps) {
const rows = limit ? items.slice(0, limit) : items
const denom = Math.max(1, max ?? Math.max(...rows.map((r) => r.value), 1))
if (rows.length === 0) {
return (
<p className="py-8 text-center text-sm text-muted-foreground">
No data available
</p>
)
}
return (
<div className={cn("space-y-2.5", className)}>
{rows.map((row, i) => {
const pct = Math.max(2, Math.round((row.value / denom) * 100))
return (
<div key={i} className="group">
<div className="mb-1 flex items-center justify-between gap-3 text-sm">
<div className="flex min-w-0 items-center gap-2">
<span className="truncate font-medium">{row.label}</span>
{row.hint != null && (
<span className="shrink-0 text-xs text-muted-foreground">
{row.hint}
</span>
)}
</div>
<span className="shrink-0 tabular-nums text-muted-foreground">
{row.value.toLocaleString()}
</span>
</div>
<div className="h-2 w-full overflow-hidden rounded-full bg-muted">
<div
className="h-full rounded-full transition-all"
style={{
width: `${pct}%`,
backgroundColor: row.color ?? "hsl(var(--sev-low))",
}}
/>
</div>
</div>
)
})}
</div>
)
}
export { BarList }