import { memo } from "react"; interface SegmentedProgressBarProps { totalSegments: number; currentIndex: number; segmentProgress: number; onSeek: (ratio: number) => void; } const SegmentBarItem = memo(function SegmentBarItem({ index, fill, }: { index: number; fill: number; }) { return (
); }); export const SegmentedProgressBar = memo(function SegmentedProgressBar({ totalSegments, currentIndex, segmentProgress, onSeek, }: SegmentedProgressBarProps) { const seekFromClientX = (clientX: number, element: HTMLElement): void => { const rect = element.getBoundingClientRect(); if (rect.width <= 0) return; onSeek((clientX - rect.left) / rect.width); }; return (
{ seekFromClientX(e.clientX, e.currentTarget as HTMLElement); }} onPointerDown={(e) => { if (e.pointerType === "mouse" && e.button !== 0) return; e.currentTarget.setPointerCapture(e.pointerId); seekFromClientX(e.clientX, e.currentTarget); }} onPointerMove={(e) => { if (!e.currentTarget.hasPointerCapture(e.pointerId)) return; seekFromClientX(e.clientX, e.currentTarget); }} onPointerUp={(e) => { if (e.currentTarget.hasPointerCapture(e.pointerId)) { e.currentTarget.releasePointerCapture(e.pointerId); } }} onPointerCancel={(e) => { if (e.currentTarget.hasPointerCapture(e.pointerId)) { e.currentTarget.releasePointerCapture(e.pointerId); } }} >
{Array.from({ length: totalSegments }).map((_, i) => { let fill = 0; if (i < currentIndex) fill = 1; else if (i === currentIndex) fill = segmentProgress; return ; })}
); });