Skip to main content

React Components

Complete reference for all React components in the Seekora UI SDK.

SearchProvider​

The root component that provides context to all child components.

Props​

PropTypeDefaultDescription
clientSeekoraClientRequiredSeekora client instance
themeThemeConfig-Custom theme configuration
enableAnalyticsbooleantrueEnable/disable analytics
autoTrackSearchbooleantrueAuto-track search events
stateManagerSearchStateManagerConfig-State manager config
childrenReactNodeRequiredChild components

Example​

import { SeekoraClient } from '@seekora-ai/search-sdk';
import { SearchProvider } from '@seekora-ai/ui-sdk-react';

const client = new SeekoraClient({
storeId: 'your-store-id',
readSecret: 'your-read-secret',
});

function App() {
return (
<SearchProvider
client={client}
enableAnalytics={true}
autoTrackSearch={true}
>
{/* Child components */}
</SearchProvider>
);
}

Interactive search input with integrated query suggestions.

Props​

PropTypeDefaultDescription
placeholderstring"Search..."Input placeholder
showSuggestionsbooleantrueShow suggestions dropdown
debounceMsnumber300Debounce delay in ms
minQueryLengthnumber2Min characters for suggestions
maxSuggestionsnumber10Max suggestions to show
onSearch(query, results) => void-Search callback
onQueryChange(query) => void-Query change callback
onSuggestionSelect(suggestion) => void-Suggestion select callback
searchOptionsSearchOptions-Additional search options
classNamestring-CSS class name
styleCSSProperties-Inline styles
themeSearchBarTheme-Component theme
renderSuggestion(suggestion, index) => ReactNode-Custom suggestion render
renderLoading() => ReactNode-Custom loading render

Example​

<SearchBar
placeholder="Search products..."
showSuggestions={true}
debounceMs={300}
minQueryLength={2}
maxSuggestions={8}
onSearch={(query, results) => {
console.log(`Found ${results.totalResults} results for "${query}"`);
}}
onSuggestionSelect={(suggestion) => {
console.log('Selected:', suggestion);
}}
searchOptions={{
facet_by: 'category,brand',
}}
renderSuggestion={(suggestion, index) => (
<div className="custom-suggestion">
<span>{suggestion}</span>
</div>
)}
/>

SearchResults​

Displays search results with customizable rendering.

Props​

PropTypeDefaultDescription
resultsSearchResponse-Search results (auto from context)
loadingboolean-Loading state
errorError-Error state
onResultClick(result, index) => void-Result click callback
renderResult(result, index, isActive) => ReactNode-Custom result render
renderEmpty() => ReactNode-Empty state render
renderLoading() => ReactNode-Loading state render
renderError(error) => ReactNode-Error state render
classNamestring-CSS class name
styleCSSProperties-Inline styles
themeSearchResultsTheme-Component theme
itemsPerPagenumber20Items per page
showPaginationbooleanfalseShow pagination
viewMode'list' | 'card' | 'grid''list'Display mode
fieldMappingFieldMapping-Field mapping
extractResults(response) => any[]-Custom result extraction
enableKeyboardNavigationbooleantrueKeyboard nav support
autoFocusbooleanfalseAuto focus first result

Example​

<SearchResults
viewMode="grid"
itemsPerPage={24}
fieldMapping={{
title: 'document.name',
image: 'document.imageUrl',
price: 'document.price',
}}
onResultClick={(result, index) => {
navigate(`/product/${result.id}`);
}}
renderResult={(result, index) => (
<div className="product-card">
<img src={result.image} alt={result.title} />
<h3>{result.title}</h3>
<span className="price">${result.price}</span>
</div>
)}
renderEmpty={() => (
<div className="empty-state">
<p>No results found</p>
</div>
)}
renderLoading={() => (
<div className="skeleton-grid">
{[...Array(8)].map((_, i) => (
<div key={i} className="skeleton-card" />
))}
</div>
)}
/>

QuerySuggestions​

Standalone component for displaying query suggestions.

Props​

PropTypeDefaultDescription
querystring''Current query
maxSuggestionsnumber10Max suggestions
debounceMsnumber300Debounce delay
minQueryLengthnumber2Min query length
onSuggestionClick(suggestion) => void-Click callback
renderSuggestion(suggestion, index) => ReactNode-Custom render
renderLoading() => ReactNode-Loading render
renderEmpty() => ReactNode-Empty render
showTitlebooleanfalseShow title
titlestring'Suggestions'Title text
classNamestring-CSS class
styleCSSProperties-Inline styles
themeQuerySuggestionsTheme-Component theme

Example​

<QuerySuggestions
query={searchQuery}
maxSuggestions={5}
showTitle={true}
title="Popular searches"
onSuggestionClick={(suggestion) => {
setSearchQuery(suggestion);
performSearch(suggestion);
}}
/>

Facets​

Display and manage facet filters.

Props​

PropTypeDefaultDescription
facetsRecord<string, FacetData>-Facet data (auto from context)
onRefinementAdd(field, value) => void-Add refinement callback
onRefinementRemove(field, value) => void-Remove refinement callback
showCountbooleantrueShow value counts
sortBy'count' | 'alpha''count'Sort order
limitnumber10Values per facet
showMorebooleantrueShow "show more" button
showSearchbooleanfalseShow facet search
classNamestring-CSS class

Example​

<Facets
showCount={true}
sortBy="count"
limit={10}
showMore={true}
showSearch={true}
onRefinementAdd={(field, value) => {
console.log(`Added filter: ${field}=${value}`);
}}
/>

CurrentRefinements​

Display active refinements/filters.

Props​

PropTypeDefaultDescription
refinementsRefinement[]-Active refinements
onRemove(refinement) => void-Remove callback
renderRefinement(refinement) => ReactNode-Custom render
classNamestring-CSS class

Example​

<CurrentRefinements
renderRefinement={(refinement) => (
<span className="refinement-tag">
{refinement.label}: {refinement.value}
<button onClick={() => removeRefinement(refinement)}>×</button>
</span>
)}
/>

ClearRefinements​

Button to clear all active refinements.

Props​

PropTypeDefaultDescription
onClear() => void-Clear callback
labelstring'Clear all'Button label
disabledboolean-Disabled state
classNamestring-CSS class

Example​

<ClearRefinements
label="Clear all filters"
onClear={() => {
console.log('Filters cleared');
}}
/>

Pagination​

Page navigation component.

Props​

PropTypeDefaultDescription
currentPagenumber-Current page (from context)
totalPagesnumber-Total pages (from context)
onPageChange(page) => void-Page change callback
showFirstbooleantrueShow first page button
showLastbooleantrueShow last page button
showPrevNextbooleantrueShow prev/next buttons
siblingCountnumber1Pages to show around current
classNamestring-CSS class

Example​

<Pagination
showFirst={true}
showLast={true}
siblingCount={2}
onPageChange={(page) => {
window.scrollTo({ top: 0, behavior: 'smooth' });
}}
/>

SortBy​

Sort options dropdown.

Props​

PropTypeDefaultDescription
itemsSortOption[]RequiredSort options
valuestring-Current value
onChange(value) => void-Change callback
labelstring'Sort by'Label text
classNamestring-CSS class

SortOption​

interface SortOption {
label: string;
value: string;
}

Example​

<SortBy
label="Sort by"
items={[
{ label: 'Relevance', value: 'relevance:desc' },
{ label: 'Price: Low to High', value: 'price:asc' },
{ label: 'Price: High to Low', value: 'price:desc' },
{ label: 'Newest First', value: 'created_at:desc' },
{ label: 'Best Selling', value: 'sales:desc' },
]}
onChange={(value) => {
console.log('Sort changed to:', value);
}}
/>

HitsPerPage​

Results per page selector.

Props​

PropTypeDefaultDescription
itemsnumber[][10, 20, 50]Options
valuenumber-Current value
onChange(value) => void-Change callback
labelstring'Show'Label text
classNamestring-CSS class

Example​

<HitsPerPage
items={[12, 24, 48, 96]}
label="Products per page"
/>

Stats​

Search statistics display.

Props​

PropTypeDefaultDescription
totalResultsnumber-Total results (from context)
processingTimeMsnumber-Processing time
renderStats(stats) => ReactNode-Custom render
classNamestring-CSS class

Example​

<Stats
renderStats={({ totalResults, processingTimeMs }) => (
<span>
{totalResults.toLocaleString()} results
({processingTimeMs}ms)
</span>
)}
/>

RangeSlider​

Numeric range filter slider.

Props​

PropTypeDefaultDescription
attributestringRequiredField name
minnumber-Minimum value
maxnumber-Maximum value
stepnumber1Step increment
onChange(range) => void-Change callback
formatValue(value) => string-Value formatter
classNamestring-CSS class

Example​

<RangeSlider
attribute="price"
min={0}
max={1000}
step={10}
formatValue={(value) => `$${value}`}
onChange={({ min, max }) => {
addFilter('price', `${min}-${max}`);
}}
/>

Highlight​

Highlight matching text in results.

Props​

PropTypeDefaultDescription
hitobjectRequiredResult object
attributestringRequiredField to highlight
tagNamestring'mark'Highlight tag
classNamestring-CSS class

Example​

<Highlight 
hit={result}
attribute="title"
tagName="mark"
/>

InfiniteHits​

Infinite scroll results display.

Props​

PropTypeDefaultDescription
thresholdnumber200Load threshold in px
renderResult(result, index) => ReactNode-Result render
renderLoading() => ReactNode-Loading render
renderEnd() => ReactNode-End of results render
classNamestring-CSS class

Example​

<InfiniteHits
threshold={300}
renderResult={(result) => (
<ProductCard product={result} />
)}
renderLoading={() => (
<div className="loading-spinner" />
)}
renderEnd={() => (
<p>You've reached the end!</p>
)}
/>

Field Mapping​

Configure how component fields map to your data:

interface FieldMapping {
title?: string; // e.g., 'document.productName'
description?: string; // e.g., 'document.brandDesc'
image?: string; // e.g., 'document.image'
price?: string; // e.g., 'document.mrp'
url?: string; // e.g., 'document.url'
id?: string; // e.g., 'id'
primaryText?: string; // Widget view field
secondaryText?: string; // Widget view field
tertiaryText?: string; // Widget view field
imageUrl?: string; // Widget view field
custom?: Record<string, string>; // Custom fields
}

Example with Nested Fields​

<SearchProvider
client={client}
fieldMapping={{
title: 'document.product.name',
description: 'document.product.description',
image: 'document.images[0].url',
price: 'document.pricing.current',
id: 'id',
}}
>
<SearchResults />
</SearchProvider>

Next Steps​