'use client'; import { forwardRef, HTMLAttributes } from 'react'; export interface Track { number: number | string; name: string; artist?: string; duration: string; active?: boolean; } export interface TracklistProps extends HTMLAttributes { tracks: Track[]; variant?: 'silver' | 'blood' | 'gold' | 'bone'; showHeader?: boolean; compact?: boolean; numbered?: boolean; onTrackClick?: (track: Track, index: number) => void; } const variantStyles = { silver: { accent: 'text-gray-400', bar: 'bg-gray-400', activeBg: 'bg-gray-400/10' }, blood: { accent: 'text-red-800', bar: 'bg-red-800', activeBg: 'bg-red-800/20' }, gold: { accent: 'text-amber-600', bar: 'bg-amber-600', activeBg: 'bg-amber-600/20' }, bone: { accent: 'text-stone-400', bar: 'bg-stone-400', activeBg: 'bg-stone-400/20' }, }; export const Tracklist = forwardRef( ({ tracks, variant = 'silver', showHeader = false, compact = false, numbered = false, onTrackClick, className = '', ...props }, ref) => { const colors = variantStyles[variant]; return (
{showHeader && (
# Title Duration
)} {tracks.map((track, index) => (
onTrackClick?.(track, index)} className={` grid gap-6 items-center border-b border-white/5 cursor-pointer transition-all duration-300 hover:bg-white/5 group ${compact ? 'grid-cols-[auto_1fr_auto] py-3 px-4 gap-4' : 'grid-cols-[auto_1fr_auto_auto] py-4 px-6'} ${track.active ? colors.activeBg : ''} `} > {track.active && } {String(track.number).padStart(2, '0')}
{track.name} {track.artist && ( {track.artist} )}
{!compact && (
)} {track.duration}
))}
); } ); Tracklist.displayName = 'Tracklist'; export default Tracklist;