Skip to main content

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

NameTypeRequiredDefaultDescription
searchPageUrlstringYes-Search results page URL
enableAutocompletebooleanNofalseEnable autocomplete dropdown
autocompleteDelaynumberNo300Debounce delay in ms
minSearchLengthnumberNo2Minimum characters to search
maxResultsnumberNo10Maximum results to show
onSearch(query) => Promise<SearchResult[]>No-Custom search function
renderSearchInputRenderFunctionNo-Custom input renderer
renderSearchResultsRenderFunctionNo-Custom results renderer
renderSearchIcon() => ReactNodeNo-Custom search icon
renderCloseIcon() => ReactNodeNo-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

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>
);
}