Componentcharts0.93 KB gzipZero dependencies
Bar Chart
Mini data bar chart with dashed guideline grids and hover zoom.
Preview
Live Preview
35
48
65
54
92
MON
TUE
WED
THU
FRI
Installation
Tokens guide →Add to your project via CLI (zero dependencies, code you own):
npx bigbullui add bar-chartOr install the full npm package:
npm install bigbulluiUsage
Open in StackBlitzimport { BarChart } from "@/components/ui/bar-chart";
<BarChart
data={[
{ label: "A", value: 40 },
{ label: "B", value: 80, tone: "accent" },
]}
/>Usage guidance
Use Bar Chart when a ticket stub surface needs Mini data bar chart with dashed guideline grids and hover zoom. Keep props minimal and prefer composition with sibling stubs.
Avoid Bar Chart for long form flows or dense data grids where a dedicated layout block fits better.
Source code
bar-chart.tsxZero dependencies (only React + utils). Copy and paste directly into your project:
import * as React from "react";
import { cn } from "./lib/utils";
export interface BarChartItem {
label: string;
value: number;
tone?: "default" | "accent";
}
export interface BarChartProps extends React.HTMLAttributes<HTMLDivElement> {
data: BarChartItem[];
height?: number;
showValues?: boolean;
className?: string;
}
export function BarChart({
data,
height = 160,
showValues = true,
className,
...props
}: BarChartProps) {
const maxValue = Math.max(...data.map((d) => d.value), 1);
return (
<div className={cn("w-full space-y-2 select-none", className)} {...props}>
<div
style={{ height }}
className="relative flex items-end justify-between gap-3 border-b-2 border-dashed border-border px-2 pb-2"
>
{/* Dashed background guide lines */}
<div className="absolute inset-x-0 top-1/4 border-b border-dashed border-border/40 pointer-events-none" />
<div className="absolute inset-x-0 top-2/4 border-b border-dashed border-border/40 pointer-events-none" />
<div className="absolute inset-x-0 top-3/4 border-b border-dashed border-border/40 pointer-events-none" />
{data.map((item, idx) => {
const heightPercent = Math.max((item.value / maxValue) * 100, 4);
const isAccent = item.tone === "accent";
return (
<div
key={idx}
className="group relative flex flex-1 flex-col items-center justify-end h-full"
>
{showValues ? (
<span className="mb-1.5 font-mono text-[10px] text-muted-foreground transition-opacity group-hover:font-bold group-hover:text-foreground">
{item.value}
</span>
) : null}
<div
style={{ height: `${heightPercent}%` }}
className={cn(
"w-full max-w-[40px] rounded-t-sm border border-b-0 transition-all duration-200 group-hover:scale-x-105",
isAccent
? "border-accent bg-accent text-accent-foreground"
: "border-foreground bg-primary text-primary-foreground"
)}
/>
</div>
);
})}
</div>
{/* X-axis labels */}
<div className="flex justify-between gap-3 px-2">
{data.map((item, idx) => (
<div key={idx} className="flex-1 text-center font-mono text-[11px] text-muted-foreground truncate">
{item.label}
</div>
))}
</div>
</div>
);
}
Props
| Prop | Type | Description |
|---|---|---|
| data | BarChartItem[] | |
| height? | number | |
| showValues? | boolean | |
| className? | string |