]> git.djapps.eu Git - pkg/ggml/sources/llama.cpp/blob
6647928b2bf51f576ff1392f7739a1df3e7b966a
[pkg/ggml/sources/llama.cpp] /
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';
6
7 interface Props {
8 items: T[];
9 isLoading: boolean;
10 selectedIndex: number;
11 searchQuery: string;
12 showSearchInput: boolean;
13 searchPlaceholder?: string;
14 emptyMessage?: string;
15 itemKey: (item: T, index: number) => string;
16 item: Snippet<[T, number, boolean]>;
17 skeleton?: Snippet;
18 footer?: Snippet;
19 }
20
21 let {
22 items,
23 isLoading,
24 selectedIndex,
25 searchQuery = $bindable(),
26 showSearchInput,
27 searchPlaceholder = 'Search...',
28 emptyMessage = 'No items available',
29 itemKey,
30 item,
31 skeleton,
32 footer
33 }: Props = $props();
34
35 let listContainer = $state<HTMLDivElement | null>(null);
36
37 $effect(() => {
38 if (listContainer && selectedIndex >= 0 && selectedIndex < items.length) {
39 const selectedElement = listContainer.querySelector(
40 `[data-picker-index="${selectedIndex}"]`
41 ) as HTMLElement;
42
43 if (selectedElement) {
44 selectedElement.scrollIntoView({
45 behavior: 'smooth',
46 block: 'center',
47 inline: 'nearest'
48 });
49 }
50 }
51 });
52 </script>
53
54 <ScrollArea>
55 {#if showSearchInput}
56 <div class="absolute top-0 right-0 left-0 z-10 p-2 pb-0">
57 <SearchInput placeholder={searchPlaceholder} bind:value={searchQuery} />
58 </div>
59 {/if}
60
61 <div
62 bind:this={listContainer}
63 class={[`${CHAT_FORM_POPOVER_MAX_HEIGHT} p-2`, showSearchInput && 'pt-13']}
64 >
65 {#if isLoading}
66 {#if skeleton}
67 {@render skeleton()}
68 {/if}
69 {:else if items.length === 0}
70 <div class="py-6 text-center text-sm text-muted-foreground">{emptyMessage}</div>
71 {:else}
72 {#each items as itemData, index (itemKey(itemData, index))}
73 {@render item(itemData, index, index === selectedIndex)}
74 {/each}
75 {/if}
76 </div>
77
78 {#if footer}
79 {@render footer()}
80 {/if}
81 </ScrollArea>