feature/comparison-slider #19
@@ -45,11 +45,7 @@ let noChildrenValue = $state('');
|
|||||||
placeholder: 'Type here...',
|
placeholder: 'Type here...',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<SearchBar bind:value={defaultSearchValue} placeholder="Type here...">
|
<SearchBar bind:value={defaultSearchValue} placeholder="Type here..."> </SearchBar>
|
||||||
Here will be the search result
|
|
||||||
<br />
|
|
||||||
Popover closes only when the user clicks outside the search bar or presses the Escape key.
|
|
||||||
</SearchBar>
|
|
||||||
</Story>
|
</Story>
|
||||||
|
|
||||||
<Story
|
<Story
|
||||||
@@ -60,11 +56,7 @@ let noChildrenValue = $state('');
|
|||||||
label: 'Search',
|
label: 'Search',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<SearchBar bind:value={withLabelValue} placeholder="Search products..." label="Search">
|
<SearchBar bind:value={withLabelValue} placeholder="Search products..." label="Search"> </SearchBar>
|
||||||
<div class="p-4">
|
|
||||||
<p class="text-sm text-muted-foreground">No results found</p>
|
|
||||||
</div>
|
|
||||||
</SearchBar>
|
|
||||||
</Story>
|
</Story>
|
||||||
|
|
||||||
<Story
|
<Story
|
||||||
@@ -74,9 +66,5 @@ let noChildrenValue = $state('');
|
|||||||
placeholder: 'Quick search...',
|
placeholder: 'Quick search...',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<SearchBar bind:value={noChildrenValue} placeholder="Quick search...">
|
<SearchBar bind:value={noChildrenValue} placeholder="Quick search..."> </SearchBar>
|
||||||
<div class="p-4 text-center text-sm text-muted-foreground">
|
|
||||||
Start typing to see results
|
|
||||||
</div>
|
|
||||||
</SearchBar>
|
|
||||||
</Story>
|
</Story>
|
||||||
|
|||||||
@@ -1,14 +1,7 @@
|
|||||||
<!--
|
<!-- Component: SearchBar -->
|
||||||
Component: SearchBar
|
|
||||||
|
|
||||||
Search input with popover dropdown for results/suggestions
|
|
||||||
- Features keyboard navigation (ArrowDown/Up/Enter) and auto-focus prevention on popover open.
|
|
||||||
- The input field serves as the popover trigger.
|
|
||||||
-->
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Input } from '$shared/shadcn/ui/input';
|
import { Input } from '$shared/shadcn/ui/input';
|
||||||
import ScanSearchIcon from '@lucide/svelte/icons/scan-search';
|
import AsteriskIcon from '@lucide/svelte/icons/asterisk';
|
||||||
import { useId } from 'bits-ui';
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
/**
|
/**
|
||||||
@@ -19,10 +12,6 @@ interface Props {
|
|||||||
* Current search value (bindable)
|
* Current search value (bindable)
|
||||||
*/
|
*/
|
||||||
value: string;
|
value: string;
|
||||||
/**
|
|
||||||
* Whether popover is open (bindable)
|
|
||||||
*/
|
|
||||||
isOpen?: boolean;
|
|
||||||
/**
|
/**
|
||||||
* Additional CSS classes for the container
|
* Additional CSS classes for the container
|
||||||
*/
|
*/
|
||||||
@@ -40,36 +29,26 @@ interface Props {
|
|||||||
let {
|
let {
|
||||||
id = 'search-bar',
|
id = 'search-bar',
|
||||||
value = $bindable(''),
|
value = $bindable(''),
|
||||||
isOpen = $bindable(false),
|
|
||||||
class: className,
|
class: className,
|
||||||
placeholder,
|
placeholder,
|
||||||
}: Props = $props();
|
}: Props = $props();
|
||||||
|
|
||||||
let triggerRef = $state<HTMLInputElement>(null!);
|
|
||||||
// svelte-ignore state_referenced_locally
|
|
||||||
const contentId = useId(id);
|
|
||||||
|
|
||||||
function handleKeyDown(event: KeyboardEvent) {
|
function handleKeyDown(event: KeyboardEvent) {
|
||||||
if (event.key === 'ArrowDown' || event.key === 'ArrowUp' || event.key === 'Enter') {
|
if (event.key === 'ArrowDown' || event.key === 'ArrowUp' || event.key === 'Enter') {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleInputClick() {
|
|
||||||
isOpen = true;
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="relative w-full">
|
<div class="relative w-full">
|
||||||
<div class="absolute left-5 top-1/2 -translate-y-1/2 pointer-events-none z-10">
|
<div class="absolute left-5 top-1/2 -translate-y-1/2 pointer-events-none z-10">
|
||||||
<ScanSearchIcon class="size-4 stroke-gray-400 stroke-[1.5]" />
|
<AsteriskIcon class="size-4 stroke-gray-400 stroke-[1.5]" />
|
||||||
</div>
|
</div>
|
||||||
<Input
|
<Input
|
||||||
id={id}
|
id={id}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
bind:value={value}
|
bind:value={value}
|
||||||
onkeydown={handleKeyDown}
|
onkeydown={handleKeyDown}
|
||||||
onclick={handleInputClick}
|
|
||||||
class="
|
class="
|
||||||
h-16 w-full text-base
|
h-16 w-full text-base
|
||||||
backdrop-blur-md bg-white/80
|
backdrop-blur-md bg-white/80
|
||||||
|
|||||||
Reference in New Issue
Block a user