SearchBox
Description
A search component with optional autocomplete suggestions. Displays a search icon that opens a fullscreen search input with dropdown results. Supports custom rendering and search functions.
Import
import { SearchBox } from '@components/frontStore/catalog/SearchBox';
Usage
import { SearchBox } from '@components/frontStore/catalog/SearchBox';
function Header() {
return (
<SearchBox searchPageUrl="/search" />
);
}
Props
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| searchPageUrl | string | Yes | - | Search results page URL |
| enableAutocomplete | boolean | No | false | Enable autocomplete dropdown |
| autocompleteDelay | number | No | 300 | Debounce delay in ms |
| minSearchLength | number | No | 2 | Minimum characters to search |
| maxResults | number | No | 10 | Maximum results to show |
| onSearch | (query) => Promise<SearchResult[]> | No | - | Custom search function |
| renderSearchInput | RenderFunction | No | - | Custom input renderer |
| renderSearchResults | RenderFunction | No | - | Custom results renderer |
| renderSearchIcon | () => ReactNode | No | - | Custom search icon |
| renderCloseIcon | () => ReactNode | No | - | Custom close icon |
Type Definitions
SearchResult
interface SearchResult {
id: string;
title: string;
url?: string;
image?: string;
price?: string;
type?: 'product' | 'category' | 'page';
[key: string]: any; // Extended fields
}
Examples
Basic Search
import { SearchBox } from '@components/frontStore/catalog/SearchBox';
function Header() {
return (
<header>
<div className="logo">My Store</div>
<SearchBox searchPageUrl="/search" />
</header>
);
}
With Autocomplete
import { SearchBox } from '@components/frontStore/catalog/SearchBox';
function Header() {
return (
<SearchBox
searchPageUrl="/search"
enableAutocomplete={true}
minSearchLength={3}
maxResults={8}
autocompleteDelay={400}
/>
);
}
Custom Search Function
import { SearchBox } from '@components/frontStore/catalog/SearchBox';
function CustomSearch() {
const handleSearch = async (query: string) => {
const response = await fetch(`/api/search?q=${query}`);
const data = await response.json();
return data.results.map(item => ({
id: item.id,
title: item.name,
url: item.url,
image: item.thumbnail,
price: item.price,
type: 'product'
}));
};
return (
<SearchBox
searchPageUrl="/search"
enableAutocomplete={true}
onSearch={handleSearch}
/>
);
}
Custom Input Renderer
import { SearchBox } from '@components/frontStore/catalog/SearchBox';
function StyledSearch() {
return (
<SearchBox
searchPageUrl="/search"
enableAutocomplete={true}
renderSearchInput={({ value, onChange, onKeyDown, placeholder, ref }) => (
<div className="custom-search-input">
<input
ref={ref}
type="text"
value={value}
onChange={(e) => onChange(e.target.value)}
onKeyDown={onKeyDown}
placeholder={placeholder}
className="styled-input"
/>
</div>
)}
/>
);
}
Custom Results Renderer
import { SearchBox } from '@components/frontStore/catalog/SearchBox';
function CustomResults() {
return (
<SearchBox
searchPageUrl="/search"
enableAutocomplete={true}
renderSearchResults={({ results, query, onSelect, isLoading }) => (
<div className="custom-results">
{isLoading && <div>Loading...</div>}
{!isLoading && results.length === 0 && (
<div>No results for "{query}"</div>
)}
{!isLoading && results.map(result => (
<div
key={result.id}
onClick={() => onSelect(result)}
className="result-item"
>
<img src={result.image} alt={result.title} />
<div>
<h4>{result.title}</h4>
<p>{result.price}</p>
</div>
</div>
))}
</div>
)}
/>
);
}
Custom Icons
import { SearchBox } from '@components/frontStore/catalog/SearchBox';
import { MagnifyingGlassIcon, XMarkIcon } from '@heroicons/react/24/outline';
function IconSearch() {
return (
<SearchBox
searchPageUrl="/search"
renderSearchIcon={() => (
<MagnifyingGlassIcon className="w-6 h-6" />
)}
renderCloseIcon={() => (
<XMarkIcon className="w-6 h-6" />
)}
/>
);
}
Complete Example
import { SearchBox } from '@components/frontStore/catalog/SearchBox';
import { useState } from 'react';
function SiteHeader() {
return (
<header className="site-header">
<div className="container">
<div className="logo">
<a href="/">My Store</a>
</div>
<nav className="main-nav">
<a href="/products">Products</a>
<a href="/categories">Categories</a>
</nav>
<div className="header-actions">
<SearchBox
searchPageUrl="/search"
enableAutocomplete={true}
minSearchLength={2}
maxResults={10}
autocompleteDelay={300}
/>
<a href="/cart">Cart</a>
</div>
</div>
</header>
);
}
Related Components
- SearchContext - Search results page context
- ProductList - Product listing display
- Image - Image component