Overview
InputSearch is a specialized input component designed for search interfaces. It includes a search icon, optional clear button, loading state, keyboard shortcut display, and debounced input handling.
Props
The search input value. This prop is bindable using bind:value.
Keyboard shortcut to display (e.g., “⌘K” or “Ctrl+K”). Each character is displayed in a separate key wrapper.
Placeholder text shown when the input is empty.
icon
IconSource
default:"Search"
Icon displayed on the left side of the input. Defaults to the Search icon.
When true, the input automatically receives focus when mounted.
size
'xs' | 'sm' | 'md'
default:"'md'"
Size variant of the input:
xs: Height 26px, rounded-sm
sm: Height 28px, rounded-md
md: Height 32px, rounded-lg
When true, displays a pulsing loading icon instead of the clear button.
Callback fired when the input value changes. Debounced by 750ms.
onclick
(event: MouseEvent) => void
Callback fired when the input is clicked.
onfocus
(event: FocusEvent) => void
Callback fired when the input receives focus.
onblur
(event: FocusEvent) => void
Callback fired when the input loses focus.
Exported Methods
Programmatically focus the input.
Programmatically blur the input.
Toggle focus state - if focused, blur; if blurred, focus.
Clear the input value and trigger the oninput callback with empty string.
Usage
Basic Search
<script>
import { InputSearch } from 'popui'
let searchQuery = $state('')
</script>
<InputSearch
bind:value={searchQuery}
placeholder="Search..."
/>
With Keyboard Shortcut
<script>
import { InputSearch } from 'popui'
let query = $state('')
</script>
<InputSearch
bind:value={query}
placeholder="Quick search"
shortcut="⌘K"
/>
With Search Handler
<script>
import { InputSearch } from 'popui'
let searchTerm = $state('')
let results = $state([])
async function handleSearch(value: string) {
if (!value) {
results = []
return
}
// Debounced search - only called 750ms after user stops typing
const response = await fetch(`/api/search?q=${value}`)
results = await response.json()
}
</script>
<InputSearch
bind:value={searchTerm}
placeholder="Search products..."
oninput={handleSearch}
/>
With Loading State
<script>
import { InputSearch } from 'popui'
let query = $state('')
let isSearching = $state(false)
async function search(value: string) {
if (!value) {
isSearching = false
return
}
isSearching = true
await fetch(`/api/search?q=${value}`)
isSearching = false
}
</script>
<InputSearch
bind:value={query}
placeholder="Search..."
loading={isSearching}
oninput={search}
/>
Different Sizes
<InputSearch size="xs" placeholder="Extra small search" />
<InputSearch size="sm" placeholder="Small search" />
<InputSearch size="md" placeholder="Medium search" />
With Custom Icon
<script>
import { InputSearch } from 'popui'
import { Magnifier } from '@invopop/ui-icons'
let value = $state('')
</script>
<InputSearch
bind:value
icon={Magnifier}
placeholder="Find items..."
/>
Using Exported Methods
<script>
import { InputSearch } from 'popui'
let searchInput: InputSearch
let query = $state('')
function focusSearch() {
searchInput.focus()
}
function clearAndFocus() {
searchInput.clear()
searchInput.focus()
}
</script>
<div class="space-y-4">
<InputSearch bind:this={searchInput} bind:value={query} />
<div class="flex gap-2">
<button onclick={focusSearch}>Focus Search</button>
<button onclick={clearAndFocus}>Clear & Focus</button>
</div>
</div>
Global Search with Keyboard Shortcut
<script>
import { InputSearch } from 'popui'
import { onMount } from 'svelte'
let searchInput: InputSearch
let query = $state('')
onMount(() => {
function handleKeydown(e: KeyboardEvent) {
if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
e.preventDefault()
searchInput.toggle()
}
}
window.addEventListener('keydown', handleKeydown)
return () => window.removeEventListener('keydown', handleKeydown)
})
</script>
<InputSearch
bind:this={searchInput}
bind:value={query}
placeholder="Search anything..."
shortcut="⌘K"
/>
Features
- Debounced Input: The
oninput callback is automatically debounced by 750ms to reduce API calls
- Clear Button: Displays an X button when the input has a value, allowing quick clearing
- Loading State: Shows a pulsing icon when
loading is true
- Keyboard Shortcuts: Displays keyboard shortcuts in styled key wrappers
- Auto Focus: Can automatically focus on mount with
focusOnLoad
- Programmatic Control: Exported methods for
focus(), blur(), toggle(), and clear()
- Smart Padding: Automatically adjusts right padding based on shortcut length and loading/clear button presence
- Accessible: Includes proper focus states and interactive elements