"use client"; import { motion } from "framer-motion"; import { ActionType } from "@/lib/types"; interface BarsProps { values: number[]; indices: number[]; action: ActionType | undefined; sorted: number[]; range?: [number, number]; pivotIndex?: number; stepDurationMs: number; height?: number; } const stateColor = { idle: "hsl(var(--state-idle))", compare: "hsl(var(--state-compare))", swap: "hsl(var(--state-swap))", sorted: "hsl(var(--state-sorted))", pivot: "hsl(var(--state-pivot))", } as const; function colorFor( i: number, indices: number[], action: ActionType | undefined, sorted: Set, range: [number, number] | undefined, pivotIndex: number | undefined ): string { if (sorted.has(i)) return stateColor.sorted; if (pivotIndex === i) return stateColor.pivot; if (indices.includes(i)) { if (action === "swap" || action === "shift" || action === "merge-write" || action === "overwrite") return stateColor.swap; return stateColor.compare; } if (range && i >= range[0] && i <= range[1]) return "hsl(var(--state-range) / 0.55)"; return stateColor.idle; } export default function Bars({ values, indices, action, sorted, range, pivotIndex, stepDurationMs, height = 320 }: BarsProps) { const max = Math.max(...values, 1); const sortedSet = new Set(sorted); const n = values.length; const showLabels = n <= 36; const barGapPct = n > 0 ? Math.min(1.2, 40 / n) : 0.6; const primary = indices[0]; const secondary = indices[1]; const pointerDuration = Math.max(0.08, Math.min(0.35, stepDurationMs / 1000)); return (
{values.map((value, i) => { const color = colorFor(i, indices, action, sortedSet, range, pivotIndex); const isFocused = indices.includes(i) || pivotIndex === i; return ( {showLabels && ( {value} )} ); })}
{/* sliding pointers: show where the algorithm's "attention" is right now */}
{n > 0 && primary !== undefined && (
)} {n > 0 && secondary !== undefined && secondary !== primary && (
)}
); }