2 import { FileText, Music, Video } from '@lucide/svelte';
3 import { HorizontalScrollCarousel } from '$lib/components/app/misc';
4 import { ICON_CLASS_DEFAULT } from '$lib/constants';
6 interface PreviewItem {
18 onNavigate: (index: number) => void;
21 let { currentIndex, items, onNavigate }: Props = $props();
23 function getFileExtension(name: string): string {
24 const parts = name.split('.');
26 if (parts.length > 1) {
27 return parts.pop()?.toUpperCase() ?? '';
34 {#if items.length > 1}
35 <div class="sticky bottom-0 z-10 mt-4 flex-shrink-0">
36 <HorizontalScrollCarousel class="max-w-full">
37 {#each items as item, index (item.id)}
39 data-thumbnail-index={index}
41 'relative flex-shrink-0 cursor-pointer overflow-hidden rounded border-2 bg-black/80 backdrop-blur-sm transition-all hover:opacity-90',
42 index === currentIndex ? 'border-white' : 'border-transparent opacity-60',
43 '[&:not(:first-child)]:last:mr-4 [&:not(:last-child)]:first:ml-4'
45 onclick={() => onNavigate(index)}
46 aria-label={`Go to ${item.name}`}
48 {#if item.isImage && item.preview}
49 <img src={item.preview} alt={item.name} class="h-12 w-12 object-cover" />
52 class="bg-foreground-muted/50 flex h-12 w-12 flex-col items-center justify-center gap-0.5 py-1"
55 <Music class="{ICON_CLASS_DEFAULT} text-white/70" />
56 {:else if item.isVideo}
57 <Video class="{ICON_CLASS_DEFAULT} text-white/70" />
59 <FileText class="{ICON_CLASS_DEFAULT} text-white/70" />
62 <span class="font-mono text-[9px] text-white/60">{getFileExtension(item.name)}</span>
67 </HorizontalScrollCarousel>