Skip to main content

Styling Guide & Demo Stores

This guide shows how to style Search UI components and Query Suggestions with CSS so you can match your site’s look or build multiple demo stores (e-commerce, minimal, dark, etc.) using the same components.

How styling works

You can style components in three ways:

MethodUse when
1. CSS variablesOne stylesheet drives colors, fonts, spacing for all components. Best for brand-wide or theme switching.
2. Theme / classNames propsYou pass class names per component (or per slot). Components render those classes; you style them in your CSS.
3. className & styleYou add a root class or inline style to a component. Good for one-off overrides or wrapper-based styling.

For demo stores, combine 1 (variables per store) with 2 (wire components to the core CSS classes or your own classes).


Setup

1. Import the core stylesheet

The SDK ships a CSS file that defines variables and optional BEM classes. Import it once (e.g. in your app entry or layout):

// App.tsx or layout
import '@seekora-ai/ui-sdk-core/styles/seekora.css';

Or via CDN:

<link rel="stylesheet" href="https://unpkg.com/@seekora-ai/ui-sdk-core/styles/seekora.css" />

2. Wrap your app with SearchProvider

Pass a theme (or rely on defaults). Theme drives inline styles (e.g. colors, spacing) when you don’t pass custom theme (class names) to individual components.

import { SearchProvider, defaultTheme } from '@seekora-ai/ui-sdk-react';

<SearchProvider client={client} theme={defaultTheme}>
<YourSearchUI />
</SearchProvider>

3. Optionally enable core CSS classes on components

By default, React components use the theme from context for inline styles and only use class names if you pass a theme (or classNames) prop. To style with the built-in BEM classes from seekora.css, pass the class names below in each component’s theme (or classNames) prop. Then your CSS (or the same seekora.css) will apply.


CSS variables reference

Override these in :root or on a wrapper (e.g. [data-demo-store="fashion"]) to restyle everything that uses them.

Colors

--seekora-color-primary
--seekora-color-secondary
--seekora-color-background
--seekora-color-surface
--seekora-color-text
--seekora-color-textSecondary
--seekora-color-border
--seekora-color-hover
--seekora-color-focus
--seekora-color-error
--seekora-color-success
--seekora-color-warning

Typography

--seekora-font-family
--seekora-font-size-small /* e.g. 0.875rem */
--seekora-font-size-medium /* e.g. 1rem */
--seekora-font-size-large /* e.g. 1.25rem */
--seekora-font-weight-normal
--seekora-font-weight-medium
--seekora-font-weight-semibold
--seekora-font-weight-bold
--seekora-line-height-tight
--seekora-line-height-normal
--seekora-line-height-relaxed

Spacing & layout

--seekora-spacing-small   /* e.g. 0.5rem */
--seekora-spacing-medium /* e.g. 1rem */
--seekora-spacing-large /* e.g. 1.5rem */

Border radius

--seekora-border-radius
--seekora-border-radius-none
--seekora-border-radius-small
--seekora-border-radius-medium
--seekora-border-radius-large
--seekora-border-radius-full

Shadows & motion

--seekora-shadow-small
--seekora-shadow-medium
--seekora-shadow-large
--seekora-transition-fast
--seekora-transition-normal
--seekora-transition-slow

Z-index

--seekora-z-index-dropdown
--seekora-z-index-modal
--seekora-z-index-tooltip

Built-in theme switches

You can switch the whole look by setting a data attribute (the stylesheet already defines these):

<html data-seekora-theme="light">   <!-- default -->
<html data-seekora-theme="dark">
<html data-seekora-theme="minimal">
<html data-seekora-theme="high-contrast">

Search UI components

For each component you can:

  • Pass theme with class names that match the core BEM classes below (so seekora.css applies), or your own classes.
  • Pass className and style on the root for overrides.

Props: className, style, theme?: SearchBarTheme

Theme slots (class names):

SlotPurposeCore BEM class (optional)
containerWrapperseekora-search-bar
inputInput fieldseekora-search-bar__input
inputFocusedInput when focusedseekora-search-bar--focused (on container)
suggestionsContainerSuggestions dropdown(custom)
suggestionItemOne suggestion(custom)
suggestionItemActiveSelected suggestion(custom)
loadingIndicatorLoading UI(custom)

Example – use core CSS + your overrides:

<SearchBar
className="my-store-search-bar"
theme={{
container: 'seekora-search-bar',
input: 'seekora-search-bar__input',
suggestionsContainer: 'seekora-search-bar-suggestions',
suggestionItem: 'seekora-search-bar-suggestion',
suggestionItemActive: 'seekora-search-bar-suggestion--active',
}}
/>
/* Your CSS: override variables for this block only */
.my-store-search-bar {
--seekora-color-primary: #c41e3a;
--seekora-border-radius-medium: 24px;
}
.my-store-search-bar.seekora-search-bar {
border-radius: 24px;
border-width: 2px;
}

SearchResults

Props: className, style, theme?: SearchResultsTheme

Theme slots:

SlotPurposeCore BEM class
containerRootseekora-results
headerHeader row(custom)
resultsListListseekora-results__list
resultItemOne result rowseekora-results__item
resultItemHoverHover/active stateseekora-results__item--active
resultTitleTitleseekora-results__title
resultDescriptionDescriptionseekora-results__description
resultImageImageseekora-results__image
resultPricePriceseekora-results__price
emptyStateNo resultsseekora-results__empty
loadingStateLoadingseekora-results__loading
errorStateErrorseekora-results__error

Example:

<SearchResults
className="my-store-results"
theme={{
container: 'seekora-results',
resultsList: 'seekora-results__list',
resultItem: 'seekora-results__item',
resultItemHover: 'seekora-results__item--active',
resultTitle: 'seekora-results__title',
resultDescription: 'seekora-results__description',
resultImage: 'seekora-results__image',
resultPrice: 'seekora-results__price',
emptyState: 'seekora-results__empty',
loadingState: 'seekora-results__loading',
errorState: 'seekora-results__error',
}}
/>
.my-store-results .seekora-results__item {
border-radius: 8px;
margin-bottom: 8px;
}
.my-store-results .seekora-results__price {
color: var(--seekora-color-primary);
font-size: 1.125rem;
}

Pagination

Props: className, style, theme?: PaginationTheme

Theme slots:

SlotCore BEM class
containerseekora-pagination
list(wrapper for items)
itemseekora-pagination__item
itemActiveseekora-pagination__item--active
itemDisabledseekora-pagination__item--disabled
link(inside item)
ellipsisseekora-pagination__ellipsis

Example:

<Pagination
theme={{
container: 'seekora-pagination',
list: 'seekora-pagination__list',
item: 'seekora-pagination__item',
itemActive: 'seekora-pagination__item--active',
itemDisabled: 'seekora-pagination__item--disabled',
ellipsis: 'seekora-pagination__ellipsis',
}}
/>

Facets

Props: className, style, theme?: FacetsTheme

Theme slots:

SlotCore BEM class
container(root)
facetseekora-facets__facet
facetTitleseekora-facets__title
facetListseekora-facets__list
facetItemseekora-facets__item
checkboxseekora-facets__checkbox
facetItemLabelseekora-facets__label
facetItemCountseekora-facets__count

Core container class: seekora-facets.

Example:

<Facets
className="my-store-facets"
theme={{
container: 'seekora-facets',
facet: 'seekora-facets__facet',
facetTitle: 'seekora-facets__title',
facetList: 'seekora-facets__list',
facetItem: 'seekora-facets__item',
checkbox: 'seekora-facets__checkbox',
facetItemLabel: 'seekora-facets__label',
facetItemCount: 'seekora-facets__count',
}}
/>

Stats

Props: className, style, theme?: StatsTheme

Theme slots: container, text, highlight, separator.
Core: seekora-stats, seekora-stats__count, seekora-stats__query, seekora-stats__time.

<Stats
theme={{
container: 'seekora-stats',
text: 'seekora-stats__count',
separator: 'seekora-stats__time',
}}
/>

SortBy

Props: className, style, theme?: SortByTheme

Theme slots: container, select, option.
Core: seekora-sort-by, seekora-sort-by__label, seekora-sort-by__select.

<SortBy
options={sortOptions}
theme={{
container: 'seekora-sort-by',
select: 'seekora-sort-by__select',
option: 'seekora-sort-by__option',
}}
/>

CurrentRefinements

Props: className, style, theme?: CurrentRefinementsTheme

Theme slots: container, list, item, label, value, clearButton, clearAllButton.
Core: seekora-refinements, seekora-refinements__item, seekora-refinements__clear, seekora-refinements__clear-all.

<CurrentRefinements
theme={{
container: 'seekora-refinements',
item: 'seekora-refinements__item',
clearButton: 'seekora-refinements__clear',
clearAllButton: 'seekora-refinements__clear-all',
}}
/>

ClearRefinements

Props: className, style, theme?: ClearRefinementsTheme

Theme slots: root, button, buttonDisabled.
Core: seekora-clear-refinements, seekora-clear-refinements__button, seekora-clear-refinements__button--disabled.

<ClearRefinements
theme={{
root: 'seekora-clear-refinements',
button: 'seekora-clear-refinements__button',
buttonDisabled: 'seekora-clear-refinements__button--disabled',
}}
/>

RangeInput

Theme slots: container, label, inputGroup, input, separator, button.
Core: seekora-range-input, seekora-range-input__label, seekora-range-input__input, seekora-range-input__button, etc.

RangeSlider

Theme slots: root, label, slider, track, trackFilled, thumb, values, value.

HitsPerPage

Theme slots: root, select, option.
Core: seekora-hits-per-page, seekora-hits-per-page__select.

InfiniteHits

Theme slots: root, list, item, loadMore, loadMoreDisabled, loading, empty, sentinel.
Core: seekora-infinite-hits, seekora-infinite-hits__show-more.

Theme slots: root, list, item, link, separator, current.

HierarchicalMenu

Theme slots: root, list, item, itemSelected, itemParent, link, label, count, showMore.

Highlight / Snippet

Theme slots (Highlight): root, highlighted, nonHighlighted.
Snippet: same + ellipsis.
Core for highlight: seekora-highlight, seekora-highlight__highlighted, seekora-snippet, seekora-snippet__highlighted.

SearchLayout

Theme slots: container, sidebar, main, header, footer.
Core: seekora-layout, seekora-layout__sidebar, seekora-layout__main, seekora-layout__header, seekora-layout__footer.

MobileFilters

Theme slots: overlay, drawer, header, title, closeButton, content, footer, applyButton, clearButton, filterCount.

Recommendations

Theme slots: root, title, list, item, image, content, name, price, loading, empty.


Query suggestions components

These components support classNames (and often className / style) so you can target every part with CSS.

SearchBarWithSuggestions

Combines an input with a suggestions dropdown. You can pass classNames (and className / style) to the underlying dropdown; the wrapper also accepts classNames.wrapper (e.g. seekora-search-bar-with-suggestions).

Example:

import { SearchBarWithSuggestions } from '@seekora-ai/ui-sdk-react';

<SearchBarWithSuggestions
variant="minimal" // or "google" | "amazon" | "shopify" | "pinterest" | "spotlight" | "federated" | "mobile-sheet"
placeholder="Search products..."
className="my-store-search-bar-with-suggestions"
classNames={{
root: 'my-store-suggestions-root',
container: 'my-store-suggestions-container',
section: 'my-store-suggestions-section',
sectionTitle: 'my-store-suggestions-section-title',
suggestionsList: 'my-store-suggestions-list',
suggestionItem: 'my-store-suggestion-item',
suggestionItemActive: 'my-store-suggestion-item--active',
recentSearches: 'my-store-recent-searches',
recentItem: 'my-store-recent-item',
productsList: 'my-store-products-list',
productItem: 'my-store-product-item',
productImage: 'my-store-product-image',
productTitle: 'my-store-product-title',
productPrice: 'my-store-product-price',
tabsList: 'my-store-tabs-list',
tabItem: 'my-store-tab-item',
tabActive: 'my-store-tab-item--active',
brandsList: 'my-store-brands-list',
brandItem: 'my-store-brand-item',
trendingSearches: 'my-store-trending',
trendingItem: 'my-store-trending-item',
}}
/>

Then in your CSS:

.my-store-search-bar-with-suggestions .my-store-suggestion-item {
padding: 12px 16px;
border-radius: 8px;
}
.my-store-search-bar-with-suggestions .my-store-suggestion-item--active {
background: var(--seekora-color-hover);
}
.my-store-search-bar-with-suggestions .my-store-product-item {
border: 1px solid var(--seekora-color-border);
border-radius: 8px;
}

QuerySuggestionsDropdown

Props: classNames?: QuerySuggestionsClassNames, className, style.

Same classNames shape as above: root, container, section, sectionTitle, suggestionsList, suggestionItem, suggestionItemActive, recentSearches, recentItem, productsList, productItem, productImage, productTitle, productPrice, tabsList, tabItem, tabActive, brandsList, brandItem, trendingSearches, trendingItem, etc.

RichQuerySuggestions

Props: classNames?: QuerySuggestionsClassNames, style.

Use the same QuerySuggestionsClassNames keys. Root/container get merged with seekora-rich-suggestions and your classNames.root / classNames.container.

FederatedDropdown

Props: classNames?: QuerySuggestionsClassNames, style.

Same classNames as above. Root uses seekora-federated-dropdown plus your classNames.

QuerySuggestions (standalone list)

Props: className, style, theme?: QuerySuggestionsTheme (container, title, suggestionsList, suggestionItem, suggestionItemHover, suggestionItemActive, loadingState, emptyState).

Use theme to pass class names for the list and items so you can style them with CSS.


Demo store themes (CSS-only)

You can define one CSS file per “store” and switch by body class or data attribute.

Store 1: Minimal / editorial

[data-demo-store="minimal"] {
--seekora-color-primary: #000;
--seekora-color-text: #1a1a1a;
--seekora-color-textSecondary: #666;
--seekora-color-border: #e0e0e0;
--seekora-font-family: Georgia, "Times New Roman", serif;
--seekora-font-size-medium: 15px;
--seekora-font-size-large: 18px;
--seekora-border-radius-none: 0;
--seekora-border-radius-small: 0;
--seekora-border-radius-medium: 0;
--seekora-shadow-small: none;
--seekora-shadow-medium: none;
--seekora-shadow-large: none;
}
<html data-demo-store="minimal">
<SearchProvider client={client} theme={minimalTheme}>
<SearchBar theme={{ container: 'seekora-search-bar', input: 'seekora-search-bar__input' }} />
<SearchResults theme={{ container: 'seekora-results', resultItem: 'seekora-results__item', /* ... */ }} />
</SearchProvider>
</html>

Store 2: E-commerce (warm)

[data-demo-store="ecommerce"] {
--seekora-color-primary: #f59e0b;
--seekora-color-secondary: #10b981;
--seekora-color-background: #ffffff;
--seekora-color-surface: #fafafa;
--seekora-color-text: #1f2937;
--seekora-color-textSecondary: #6b7280;
--seekora-color-border: #e5e7eb;
--seekora-font-family: "Inter", sans-serif;
--seekora-border-radius-medium: 8px;
--seekora-border-radius-large: 16px;
--seekora-shadow-medium: 0 4px 6px rgba(0, 0, 0, 0.07);
}

Store 3: Dark / tech

[data-demo-store="dark"] {
--seekora-color-primary: #6366f1;
--seekora-color-background: #0f172a;
--seekora-color-surface: #1e293b;
--seekora-color-text: #f1f5f9;
--seekora-color-textSecondary: #94a3b8;
--seekora-color-border: #334155;
--seekora-color-hover: #334155;
--seekora-font-family: "JetBrains Mono", "Fira Code", monospace;
--seekora-border-radius-medium: 10px;
--seekora-shadow-small: 0 0 10px rgba(99, 102, 241, 0.1);
--seekora-shadow-medium: 0 0 20px rgba(99, 102, 241, 0.15);
}

Store 4: Fashion / luxury (custom brand)

[data-demo-store="fashion"] {
--seekora-color-primary: #c41e3a;
--seekora-color-secondary: #8b7355;
--seekora-color-background: #faf9f7;
--seekora-color-surface: #ffffff;
--seekora-color-text: #2c2c2c;
--seekora-color-textSecondary: #6b6b6b;
--seekora-font-family: "Cormorant Garamond", "Times New Roman", serif;
--seekora-font-size-medium: 15px;
--seekora-font-size-large: 20px;
--seekora-border-radius-medium: 0;
--seekora-border-radius-large: 0;
--seekora-shadow-small: 0 1px 3px rgba(0,0,0,0.06);
}

Switch store in JS:

const [store, setStore] = useState('ecommerce');
useEffect(() => {
document.documentElement.setAttribute('data-demo-store', store);
}, [store]);

Quick reference

ComponentRoot className/styleTheme / classNames
SearchBar✅ className, styletheme: SearchBarTheme (container, input, suggestionsContainer, suggestionItem, …)
SearchResults✅ className, styletheme: SearchResultsTheme (container, resultsList, resultItem, resultTitle, …)
Pagination✅ className, styletheme: PaginationTheme (container, list, item, itemActive, ellipsis)
Facets✅ className, styletheme: FacetsTheme (container, facet, facetTitle, facetList, facetItem, …)
Stats✅ className, styletheme: StatsTheme (container, text, highlight, separator)
SortBy✅ className, styletheme: SortByTheme (container, select, option)
CurrentRefinements✅ className, styletheme: CurrentRefinementsTheme (container, item, clearButton, clearAllButton)
ClearRefinements✅ className, styletheme: ClearRefinementsTheme (root, button, buttonDisabled)
RangeInput✅ className, styletheme: RangeInputTheme
RangeSlider✅ className, styletheme: RangeSliderTheme
HitsPerPage✅ className, styletheme: HitsPerPageTheme
InfiniteHits✅ className, styletheme: InfiniteHitsTheme
Breadcrumb✅ className, styletheme: BreadcrumbTheme
HierarchicalMenu✅ className, styletheme: HierarchicalMenuTheme
Highlight / Snippet✅ className, styletheme: HighlightTheme / SnippetTheme
SearchLayout✅ className, styletheme: SearchLayoutTheme (container, sidebar, main, header, footer)
MobileFilters✅ className, styletheme: MobileFiltersTheme
Recommendations✅ className, styletheme: RecommendationTheme
QuerySuggestions✅ className, styletheme: QuerySuggestionsTheme
SearchBarWithSuggestions✅ className, style, classNamesclassNames: QuerySuggestionsClassNames (root, container, section, suggestionItem, productItem, …)
QuerySuggestionsDropdown✅ className, styleclassNames: QuerySuggestionsClassNames
RichQuerySuggestions✅ styleclassNames: QuerySuggestionsClassNames
FederatedDropdown✅ styleclassNames: QuerySuggestionsClassNames

Checklist for a new demo store

  1. Import @seekora-ai/ui-sdk-core/styles/seekora.css.
  2. Define a store selector (e.g. data-demo-store="store-id") and override --seekora-* variables in CSS for that selector.
  3. For each Search UI component you use, pass theme with either the core BEM class names from this guide or your own classes, and style those classes in your CSS.
  4. For SearchBarWithSuggestions (or any query suggestions dropdown), pass classNames with your own class names (or a mix with core), then style those in CSS.
  5. Optionally add className on the root of components for wrapper-level overrides (e.g. .my-store-results .seekora-results__item { ... }).

With this, every component can be styled to match each website or demo store using CSS only, plus minimal props (theme/classNames) to attach your classes.