feat: Improve prompt picker keyboard navigation
This commit is contained in:
parent
c5fa3634bc
commit
5fe03b2bdc
|
|
@ -270,8 +270,8 @@
|
|||
|
||||
if (event.key === KeyboardKey.ARROW_DOWN) {
|
||||
event.preventDefault();
|
||||
if (selectedIndex < filteredPrompts.length - 1) {
|
||||
selectedIndex++;
|
||||
if (filteredPrompts.length > 0) {
|
||||
selectedIndex = (selectedIndex + 1) % filteredPrompts.length;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -279,8 +279,8 @@
|
|||
|
||||
if (event.key === KeyboardKey.ARROW_UP) {
|
||||
event.preventDefault();
|
||||
if (selectedIndex > 0) {
|
||||
selectedIndex--;
|
||||
if (filteredPrompts.length > 0) {
|
||||
selectedIndex = selectedIndex === 0 ? filteredPrompts.length - 1 : selectedIndex - 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,24 @@
|
|||
getServerLabel,
|
||||
onPromptClick
|
||||
}: Props = $props();
|
||||
|
||||
let listContainer = $state<HTMLDivElement | null>(null);
|
||||
|
||||
$effect(() => {
|
||||
if (listContainer && selectedIndex >= 0 && selectedIndex < prompts.length) {
|
||||
const selectedElement = listContainer.querySelector(
|
||||
`[data-prompt-index="${selectedIndex}"]`
|
||||
) as HTMLElement;
|
||||
|
||||
if (selectedElement) {
|
||||
selectedElement.scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
block: 'nearest',
|
||||
inline: 'nearest'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<ScrollArea>
|
||||
|
|
@ -36,7 +54,7 @@
|
|||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="max-h-64 p-2" class:pt-13={showSearchInput}>
|
||||
<div bind:this={listContainer} class="max-h-64 p-2" class:pt-13={showSearchInput}>
|
||||
{#if isLoading}
|
||||
<ChatFormPromptPickerListItemSkeleton />
|
||||
{:else if prompts.length === 0}
|
||||
|
|
@ -49,6 +67,7 @@
|
|||
{@const serverLabel = server ? getServerLabel(server) : prompt.serverName}
|
||||
|
||||
<ChatFormPromptPickerListItem
|
||||
data-prompt-index={index}
|
||||
{prompt}
|
||||
{server}
|
||||
{serverLabel}
|
||||
|
|
|
|||
|
|
@ -8,13 +8,22 @@
|
|||
serverLabel: string;
|
||||
isSelected?: boolean;
|
||||
onClick: () => void;
|
||||
'data-prompt-index'?: number;
|
||||
}
|
||||
|
||||
let { prompt, server, serverLabel, isSelected = false, onClick }: Props = $props();
|
||||
let {
|
||||
prompt,
|
||||
server,
|
||||
serverLabel,
|
||||
isSelected = false,
|
||||
onClick,
|
||||
'data-prompt-index': dataPromptIndex
|
||||
}: Props = $props();
|
||||
</script>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
data-prompt-index={dataPromptIndex}
|
||||
onclick={onClick}
|
||||
class="flex w-full cursor-pointer items-start gap-3 rounded-lg px-3 py-2 text-left hover:bg-accent/50 {isSelected
|
||||
? 'bg-accent/50'
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
'aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40',
|
||||
className
|
||||
)}
|
||||
style="backdrop-filter: blur(0.5rem);"
|
||||
{type}
|
||||
bind:value
|
||||
{...restProps}
|
||||
|
|
|
|||
Loading…
Reference in New Issue