"use client"; import { motion, useInView, useReducedMotion } from "motion/react"; import { useRef } from "react"; import { cn } from "@/lib/utils"; type Bar = { /** Axis label under the bar (e.g. a year). */ label: string; value: number; /** Optional pre-formatted value shown above the bar. Defaults to `value`. */ display?: string; }; type BarChartProps = { data: Bar[]; /** Index that gets the solid accent fill. Default: the max-value bar. */ accentIndex?: number; /** Plot-area height in px (labels add below). Default 300. */ height?: number; className?: string; }; /** * BarChart — the event-deck native bar chart (no chart library). * * Each fill grows with scaleY from the baseline over 1.3 s (ease-strong), * staggered 120 ms per bar; the value label fades in once the bar has landed. * The reference bar (default: the tallest) takes the solid accent; the rest a * soft accent-100 → accent-200 gradient. See sd EVENT-DECK.md → bar chart. */ export function BarChart({ data, accentIndex, height = 300, className }: BarChartProps) { const ref = useRef(null); const inView = useInView(ref, { once: true, amount: 0.4 }); const reduce = useReducedMotion(); const max = Math.max(...data.map((d) => d.value), 1); const accent = accentIndex ?? data.reduce((mi, d, i, a) => (d.value > a[mi].value ? i : mi), 0); return (
{data.map((d, i) => { const h = (d.value / max) * 100; const isAccent = i === accent; const delay = 0.1 + i * 0.12; return (
{d.display ?? d.value}
{d.label}
); })}
); }