Reputation: 390
I'm trying to create a search component using Svelte
and shadcn-svelte
UI component library,
Where I'll have a dropdown visible below the search input, when the user type a text that does exist in the data
array, otherwise the dropdown should be hidden.
<script lang="ts">
import { Input } from '$lib/components/ui/input';
import * as DropdownMenu from '$lib/components/ui/dropdown-menu';
let searchValue = '';
let filteredResults: string[] = [];
let isDropdownOpen = false;
const data = [
'California',
'North Carolina',
'North Dakota',
'South Carolina',
'South Dakota',
'Michigan',
'Tennessee',
'Nevada',
'New Hampshire',
'New Jersey'
];
function handleInput() {
filteredResults = data.filter((item) =>
item.toLowerCase().includes(searchValue.toLowerCase())
);
isDropdownOpen = (filteredResults.length > 0 && searchValue !== '');
}
function handleItemSelection(item: string) {
console.log(`${item} selected`);
}
</script>
<Input bind:value={searchValue} on:input={handleInput} placeholder="Search..." />
<DropdownMenu.Root open={isDropdownOpen} disableFocusFirstItem={true}>
<DropdownMenu.Trigger asChild let:builder>
<Button builders={[builder]} class="h-0 m-0 p-0" variant="outline"></Button>
</DropdownMenu.Trigger>
<DropdownMenu.Content>
<DropdownMenu.Group>
{#each filteredResults as item}
<DropdownMenu.Item on:click={() => handleItemSelection(item)}>{item}</DropdownMenu.Item>
{/each}
</DropdownMenu.Group>
</DropdownMenu.Content>
</DropdownMenu.Root>
My issue is once I start typing, the drop-down menu will show up but, the focus will transfer to the drop-down menu and that will prevent me from typing.
Upvotes: 1
Views: 2336
Reputation: 1
I was able to resolve a similar issue I was having with shadcn's <Popover/>
component. The solution was utilizing onOpenAutoFocus={(e) => e.preventDefault()}
on <PopoverContent/>
.
It doesnt look like <DropdownMenuContent/>
has access to the onOpenAutoFocus
prop, but if your content would work in a <Popover/>
this could be an alternative solution.
<FormField
control={form.control}
name="search"
render={({ field }) => (
<FormItem className="basis-2/3 grow">
<FormControl>
<>
<Popover open={!!field.value}>
<PopoverTrigger asChild>
<SearchInput
{...field}
type="search"
id="menubar-record-search"
placeholder="Search records..."
/>
</PopoverTrigger>
<PopoverContent onOpenAutoFocus={(e) => e.preventDefault()}>
Place content for the popover here.
</PopoverContent>
</Popover>
</>
</FormControl>
</FormItem>
)}
/>
Upvotes: 0