57 lines
1.4 KiB
TypeScript
57 lines
1.4 KiB
TypeScript
import { cn } from "@/lib/utils";
|
|
|
|
interface PlaybackPageIndicatorProps {
|
|
total: number;
|
|
current: number;
|
|
progress: number;
|
|
onGoTo: (index: number) => void;
|
|
}
|
|
|
|
export function PlaybackPageIndicator({
|
|
total,
|
|
current,
|
|
progress,
|
|
onGoTo,
|
|
}: PlaybackPageIndicatorProps) {
|
|
if (total === 0) return null;
|
|
|
|
return (
|
|
<div className="flex w-full items-center gap-0.5 px-1">
|
|
{Array.from({ length: total }, (_, i) => (
|
|
<button
|
|
key={i}
|
|
onClick={(e) => {
|
|
e.stopPropagation();
|
|
onGoTo(i);
|
|
}}
|
|
className="group relative h-3 flex-1"
|
|
>
|
|
{/* Dim track */}
|
|
<div
|
|
className={cn(
|
|
"absolute inset-x-0 top-0 h-1 bg-white/30 transition-all",
|
|
"group-hover:h-1.5 group-hover:top-0.5",
|
|
)}
|
|
/>
|
|
{/* Fill */}
|
|
<div
|
|
className={cn(
|
|
"absolute left-0 top-0 h-1 bg-white/90 transition-all",
|
|
"group-hover:h-1.5 group-hover:top-0.5",
|
|
)}
|
|
style={{
|
|
width:
|
|
i < current
|
|
? "100%"
|
|
: i === current
|
|
? `${progress * 100}%`
|
|
: "0%",
|
|
transition: i === current ? "width 300ms linear" : "none",
|
|
}}
|
|
/>
|
|
</button>
|
|
))}
|
|
</div>
|
|
);
|
|
}
|