Skip to content

Commit 47f85e3

Browse files
allozaurServeurpersoCom
authored andcommitted
feat: Use Popover component + improve interactions
1 parent 7825c45 commit 47f85e3

File tree

11 files changed

+364
-310
lines changed

11 files changed

+364
-310
lines changed

tools/server/webui/package-lock.json

Lines changed: 22 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tools/server/webui/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
"@tailwindcss/vite": "^4.0.0",
4444
"@types/node": "^22",
4545
"@vitest/browser": "^3.2.3",
46-
"bits-ui": "^2.8.11",
46+
"bits-ui": "^2.14.4",
4747
"clsx": "^2.1.1",
4848
"dexie": "^4.0.11",
4949
"eslint": "^9.18.0",

tools/server/webui/src/lib/components/app/chat/ChatForm/ChatForm.svelte

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,7 @@
331331
class="{INPUT_CLASSES} border-radius-bottom-none mx-auto max-w-[48rem] overflow-hidden rounded-3xl backdrop-blur-md {disabled
332332
? 'cursor-not-allowed opacity-60'
333333
: ''} {className}"
334+
data-slot="chat-form"
334335
>
335336
<ChatAttachmentsList
336337
bind:uploadedFiles
Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
<script lang="ts">
22
import { Input } from '$lib/components/ui/input';
3-
import { Search } from '@lucide/svelte';
3+
import { Search, X } from '@lucide/svelte';
44
55
interface Props {
66
value?: string;
77
placeholder?: string;
88
onInput?: (value: string) => void;
9+
onClose?: () => void;
10+
onKeyDown?: (event: KeyboardEvent) => void;
911
class?: string;
1012
id?: string;
1113
ref?: HTMLInputElement | null;
@@ -15,23 +17,57 @@
1517
value = $bindable(''),
1618
placeholder = 'Search...',
1719
onInput,
20+
onClose,
21+
onKeyDown,
1822
class: className,
1923
id,
2024
ref = $bindable(null)
2125
}: Props = $props();
2226
27+
let showClearButton = $derived(!!value || !!onClose);
28+
2329
function handleInput(event: Event) {
2430
const target = event.target as HTMLInputElement;
2531
2632
value = target.value;
2733
onInput?.(target.value);
2834
}
35+
36+
function handleClear() {
37+
if (value) {
38+
value = '';
39+
onInput?.('');
40+
ref?.focus();
41+
} else {
42+
onClose?.();
43+
}
44+
}
2945
</script>
3046

3147
<div class="relative {className}">
3248
<Search
3349
class="absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 transform text-muted-foreground"
3450
/>
3551

36-
<Input {id} bind:value bind:ref class="pl-9" oninput={handleInput} {placeholder} type="search" />
52+
<Input
53+
{id}
54+
bind:value
55+
bind:ref
56+
class="pl-9 {showClearButton ? 'pr-9' : ''}"
57+
oninput={handleInput}
58+
onkeydown={onKeyDown}
59+
{placeholder}
60+
type="search"
61+
/>
62+
63+
{#if showClearButton}
64+
<button
65+
type="button"
66+
class="absolute top-1/2 right-3 -translate-y-1/2 transform text-muted-foreground transition-colors hover:text-foreground"
67+
onclick={handleClear}
68+
aria-label={value ? 'Clear search' : 'Close'}
69+
>
70+
<X class="h-4 w-4" />
71+
</button>
72+
{/if}
3773
</div>

0 commit comments

Comments
 (0)