A search input component with search icon, clear button, and search-specific styling
npm install @choice-ui/search-inputA specialized search input component built on top of TextField, featuring a search icon prefix and clear button suffix. It provides an intuitive search experience with proper internationalization support and accessible interactions.
``tsx`
import { SearchInput } from "@choice-ui/react"
- Built on TextField for consistent behavior and styling
- Search icon prefix for clear visual indication
- Clear button that appears when input has content
- Internationalization support for labels and tooltips
- Multiple visual variants (default, light, dark, reset)
- All TextField features: sizes, states, and accessibility
- Automatic focus management and keyboard navigation
- Tooltip support on clear button
`tsx`
onChange={setSearchQuery}
/>
`tsx`
onChange={setSearchQuery}
placeholder="Search products..."
/>
`tsx
// Default - follows page theme
// Light - fixed light appearance
// Dark - fixed dark appearance
// Reset - no variant styling
`
`tsx`
onChange={setSearchQuery}
placeholder="Search..."
i18n={{
clear: "Clear search",
placeholder: "Search for anything...",
}}
/>
`tsx`
value={searchQuery}
onChange={setSearchQuery}
placeholder="Search disabled..."
/>
`tsx`
value={searchQuery}
onChange={setSearchQuery}
placeholder="Large search input..."
/>
`ts`
interface SearchInputProps extends TextFieldProps {
/* Internationalization configuration /
i18n?: {
clear: string
placeholder: string
}
}
Inherits all props from TextFieldProps, including:
- value?: string - Current search valueonChange?: (value: string) => void
- - Callback when value changesplaceholder?: string
- - Placeholder text (defaults to "Search...")variant?: "default" | "light" | "dark" | "reset"
- - Visual style variantsize?: "default" | "large"
- - Input sizedisabled?: boolean
- - Whether the input is disabled
- All other standard HTML input attributes
- Defaults:
- placeholder: "Search..."variant
- : "default" (follows page theme)i18n.clear
- : "Clear"
- Variant options:
- default: Follows the page theme dynamically (light/dark mode)light
- : Fixed light appearance regardless of themedark
- : Fixed dark appearance regardless of themereset
- : Removes variant styling, no variant settings applied
- Behavior:
- Search icon is always visible in the prefix position
- Clear button appears only when there's content to clear
- Clear button includes tooltip for accessibility
- All TextField behaviors are inherited (focus selection, editing states, etc.)
- This component uses Tailwind CSS via tailwind-variants in tv.ts with slots.icon
- Built on TextField, so inherits all TextField styling capabilities
- Slots available: , action
- Search icon color adapts based on variant and interaction states
- Clear button integrates seamlessly with the input design
- Search icon provides visual context for screen readers
- Clear button includes tooltip with descriptive text
- Supports all TextField accessibility features
- Keyboard navigation works seamlessly (Tab to clear button)
- Clear button is focusable and clickable
- Proper ARIA attributes inherited from TextField
The component supports customizing text through the i18n prop:
`tsx`
onChange={setQuery}
i18n={{
clear: "Effacer", // French
placeholder: "Rechercher...",
}}
/>
- Use clear, descriptive placeholder text that matches your search context
- Provide appropriate internationalization for multi-language applications
- Consider debouncing the onChange callback for performance with large datasets
- Use the appropriate variant to match your application's theme
- Ensure the clear functionality provides immediate visual feedback
`tsx
import { useDebouncedCallback } from 'use-debounce'
const [query, setQuery] = useState("")
const [results, setResults] = useState([])
const debouncedSearch = useDebouncedCallback(
async (searchQuery: string) => {
if (searchQuery.trim()) {
const results = await searchProducts(searchQuery)
setResults(results)
} else {
setResults([])
}
},
300
)
onChange={(value) => {
setQuery(value)
debouncedSearch(value)
}}
placeholder="Search products..."
/>
`
`tsx`
size="large"
value={searchQuery}
onChange={setSearchQuery}
placeholder="Search documentation..."
i18n={{
clear: "Clear search query",
}}
/>
`tsx
const [query, setQuery] = useState("")
$3
`tsx
const [query, setQuery] = useState("")
const [isValid, setIsValid] = useState(true) value={query}
onChange={(value) => {
setQuery(value)
setIsValid(value.length === 0 || value.length >= 3)
}}
selected={!isValid}
placeholder="Search (minimum 3 characters)..."
/>
`Integration with TextField
Since SearchInput is built on TextField, you can use it with all TextField features:
`tsx
value={query}
onChange={setQuery}
>
Search Query
Enter keywords to find relevant content
`Notes
- The clear button uses IconButton with ghost variant for consistent styling
- Search icon color automatically adapts to hover and focus states
- Component is fully controlled - always provide both
value and onChange
- Clear functionality calls onChange` with an empty string