1 <script lang="ts" generics="T">
2 import type { Snippet } from 'svelte';
3 import { SearchInput } from '$lib/components/app';
4 import ScrollArea from '$lib/components/ui/scroll-area/scroll-area.svelte';
5 import { CHAT_FORM_POPOVER_MAX_HEIGHT } from '$lib/constants';
10 selectedIndex: number;
12 showSearchInput: boolean;
13 searchPlaceholder?: string;
14 emptyMessage?: string;
15 itemKey: (item: T, index: number) => string;
16 item: Snippet<[T, number, boolean]>;
25 searchQuery = $bindable(),
27 searchPlaceholder = 'Search...',
28 emptyMessage = 'No items available',
35 let listContainer = $state<HTMLDivElement | null>(null);
38 if (listContainer && selectedIndex >= 0 && selectedIndex < items.length) {
39 const selectedElement = listContainer.querySelector(
40 `[data-picker-index="${selectedIndex}"]`
43 if (selectedElement) {
44 selectedElement.scrollIntoView({
56 <div class="absolute top-0 right-0 left-0 z-10 p-2 pb-0">
57 <SearchInput placeholder={searchPlaceholder} bind:value={searchQuery} />
62 bind:this={listContainer}
63 class={[`${CHAT_FORM_POPOVER_MAX_HEIGHT} p-2`, showSearchInput && 'pt-13']}
69 {:else if items.length === 0}
70 <div class="py-6 text-center text-sm text-muted-foreground">{emptyMessage}</div>
72 {#each items as itemData, index (itemKey(itemData, index))}
73 {@render item(itemData, index, index === selectedIndex)}