@seekora-ai/ui-sdk-react 0.2.17 → 0.2.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -58,6 +58,9 @@ interface SearchBarProps {
58
58
  renderSubmitButton?: () => React__default.ReactNode;
59
59
  /** Size variant controlling padding and font size (default: 'medium') */
60
60
  size?: SearchBarSize;
61
+ /** Trigger search automatically as user types, with debounce (default: false).
62
+ * When true, uses `debounceMs` for the delay. Enter still triggers immediately. */
63
+ searchAsYouType?: boolean;
61
64
  }
62
65
  declare const SearchBar: React__default.FC<SearchBarProps>;
63
66
 
@@ -1637,6 +1640,8 @@ interface UseQuerySuggestionsEnhancedOptions {
1637
1640
  query: string;
1638
1641
  /** Enable/disable the hook */
1639
1642
  enabled?: boolean;
1643
+ /** Prefetch initial (empty-query) data on mount even if not enabled yet */
1644
+ prefetch?: boolean;
1640
1645
  /** Debounce delay in ms */
1641
1646
  debounceMs?: number;
1642
1647
  /** Max suggestions to fetch */
@@ -1753,6 +1758,8 @@ interface SuggestionsContextValue {
1753
1758
  recentSearches: RecentSearch[];
1754
1759
  trendingSearches: TrendingSearch[];
1755
1760
  trendingProducts: ProductItem[];
1761
+ /** Products prefetched on mount via client.search("*") — available before dropdown opens */
1762
+ prefetchedProducts: unknown[];
1756
1763
  filteredTabs: FilteredTab[];
1757
1764
  activeTabId: string;
1758
1765
  setActiveTabId: (id: string) => void;
@@ -1766,6 +1773,7 @@ interface SuggestionsContextValue {
1766
1773
  selectTrendingSearch: (trending: TrendingSearch, position: number) => void;
1767
1774
  setActiveTab: (tab: FilteredTab) => void;
1768
1775
  submitSearch: (query: string, fromSuggestion?: boolean, suggestion?: SuggestionItem$3) => void;
1776
+ clearRecentSearches: () => void;
1769
1777
  close: () => void;
1770
1778
  navigateNext: () => void;
1771
1779
  navigatePrev: () => void;
@@ -1685,7 +1685,7 @@ const DefaultSearchIcon = ({ size = 18 }) => (React.createElement("svg", { width
1685
1685
  const DefaultClearIcon = ({ size = 14 }) => (React.createElement("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" },
1686
1686
  React.createElement("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1687
1687
  React.createElement("line", { x1: "6", y1: "6", x2: "18", y2: "18" })));
1688
- const SearchBar = ({ placeholder = 'Powered by Seekora', showSuggestions = true, debounceMs = 300, minQueryLength = 2, maxSuggestions = 10, onSearch, onQueryChange, onSuggestionSelect, onSearchStateChange, searchOptions, className, style, theme: customTheme, renderSuggestion, renderSearchIcon, showClearButton = true, renderClearIcon, showSubmitButton = false, renderSubmitButton, size = 'medium', }) => {
1688
+ const SearchBar = ({ placeholder = 'Powered by Seekora', showSuggestions = true, debounceMs = 300, minQueryLength = 2, maxSuggestions = 10, onSearch, onQueryChange, onSuggestionSelect, onSearchStateChange, searchOptions, className, style, theme: customTheme, renderSuggestion, renderSearchIcon, showClearButton = true, renderClearIcon, showSubmitButton = false, renderSubmitButton, size = 'medium', searchAsYouType = false, }) => {
1689
1689
  const { client, theme, enableAnalytics, autoTrackSearch } = useSearchContext();
1690
1690
  const { query, setQuery, search: triggerSearch, results, loading: searchLoading, error: searchError } = useSearchState();
1691
1691
  const [isFocused, setIsFocused] = useState(false);
@@ -1693,6 +1693,14 @@ const SearchBar = ({ placeholder = 'Powered by Seekora', showSuggestions = true,
1693
1693
  const inputRef = useRef(null);
1694
1694
  const containerRef = useRef(null);
1695
1695
  const isSearchingRef = useRef(false); // Flag to prevent blur handler from interfering
1696
+ const searchAsYouTypeRef = useRef(null);
1697
+ // Cleanup searchAsYouType timer on unmount
1698
+ useEffect(() => {
1699
+ return () => {
1700
+ if (searchAsYouTypeRef.current)
1701
+ clearTimeout(searchAsYouTypeRef.current);
1702
+ };
1703
+ }, []);
1696
1704
  const { suggestions, loading: suggestionsLoading } = useQuerySuggestions({
1697
1705
  client,
1698
1706
  query,
@@ -1722,6 +1730,11 @@ const SearchBar = ({ placeholder = 'Powered by Seekora', showSuggestions = true,
1722
1730
  }
1723
1731
  }, [query, onQueryChange]);
1724
1732
  const handleSearch = useCallback(async (searchQuery) => {
1733
+ // Cancel any pending searchAsYouType debounce — user explicitly submitted
1734
+ if (searchAsYouTypeRef.current) {
1735
+ clearTimeout(searchAsYouTypeRef.current);
1736
+ searchAsYouTypeRef.current = null;
1737
+ }
1725
1738
  // Allow empty queries - use empty string for search
1726
1739
  const query = searchQuery.trim();
1727
1740
  log.info('SearchBar: Triggering search', { query, originalQuery: searchQuery, isEmpty: !query });
@@ -1758,10 +1771,18 @@ const SearchBar = ({ placeholder = 'Powered by Seekora', showSuggestions = true,
1758
1771
  const handleInputChange = useCallback((e) => {
1759
1772
  const value = e.target.value;
1760
1773
  // Update query in state manager but don't trigger search immediately
1761
- // Search will be triggered on Enter or suggestion select
1774
+ // Search will be triggered on Enter, suggestion select, or after debounce if searchAsYouType
1762
1775
  setQuery(value, false); // false = don't trigger search immediately
1763
1776
  setSelectedIndex(-1);
1764
- }, [setQuery]);
1777
+ if (searchAsYouType) {
1778
+ if (searchAsYouTypeRef.current)
1779
+ clearTimeout(searchAsYouTypeRef.current);
1780
+ searchAsYouTypeRef.current = setTimeout(() => {
1781
+ searchAsYouTypeRef.current = null;
1782
+ triggerSearch();
1783
+ }, debounceMs);
1784
+ }
1785
+ }, [setQuery, searchAsYouType, debounceMs, triggerSearch]);
1765
1786
  const handleKeyDown = useCallback((e) => {
1766
1787
  switch (e.key) {
1767
1788
  case 'ArrowDown':
@@ -1837,10 +1858,17 @@ const SearchBar = ({ placeholder = 'Powered by Seekora', showSuggestions = true,
1837
1858
  ? `0 0 0 3px var(--seekora-border-focus-alpha, ${theme.colors.focus}33)`
1838
1859
  : undefined;
1839
1860
  const handleClear = useCallback(() => {
1861
+ if (searchAsYouTypeRef.current) {
1862
+ clearTimeout(searchAsYouTypeRef.current);
1863
+ searchAsYouTypeRef.current = null;
1864
+ }
1840
1865
  setQuery('', false);
1841
1866
  setSelectedIndex(-1);
1842
1867
  inputRef.current?.focus();
1843
- }, [setQuery]);
1868
+ if (searchAsYouType) {
1869
+ triggerSearch();
1870
+ }
1871
+ }, [setQuery, searchAsYouType, triggerSearch]);
1844
1872
  const handleSubmit = useCallback(() => {
1845
1873
  const currentValue = inputRef.current?.value || query;
1846
1874
  handleSearch(currentValue);
@@ -6800,7 +6828,7 @@ function transformFilteredTab(raw) {
6800
6828
  // Main Hook
6801
6829
  // ============================================================================
6802
6830
  function useQuerySuggestionsEnhanced(options) {
6803
- const { client, query, enabled = true, debounceMs = 200, maxSuggestions = 10, minQueryLength = 1, includeDropdownRecommendations = false, includeDropdownProductList = true, includeFilteredTabs = true, includeCategories = true, includeFacets = true, // CHANGED: Enable facets by default
6831
+ const { client, query, enabled = true, prefetch = false, debounceMs = 200, maxSuggestions = 10, minQueryLength = 1, includeDropdownRecommendations = false, includeDropdownProductList = true, includeFilteredTabs = true, includeCategories = true, includeFacets = true, // CHANGED: Enable facets by default
6804
6832
  maxCategories = 3, maxFacets = 5, filteredTabs, minPopularity, timeRange, disableTypoTolerance, analyticsTags, enableRecentSearches = true, maxRecentSearches = MAX_RECENT_SEARCHES_DEFAULT, recentSearchesKey = RECENT_SEARCHES_DEFAULT_KEY, onSuggestionsLoaded, onError, } = options;
6805
6833
  // State
6806
6834
  const [suggestions, setSuggestions] = useState([]);
@@ -6973,17 +7001,41 @@ function useQuerySuggestionsEnhanced(options) {
6973
7001
  onSuggestionsLoaded,
6974
7002
  onError,
6975
7003
  ]);
7004
+ // Prefetch: fire initial empty-query fetch once client is ready (before dropdown opens)
7005
+ const prefetchedRef = useRef(false);
7006
+ useEffect(() => {
7007
+ if (!prefetch || prefetchedRef.current)
7008
+ return;
7009
+ if (minQueryLength > 0)
7010
+ return;
7011
+ if (!client?.getSuggestions)
7012
+ return;
7013
+ prefetchedRef.current = true;
7014
+ fetchSuggestions('');
7015
+ }, [prefetch, client, minQueryLength, fetchSuggestions]);
6976
7016
  // Debounced fetch effect
6977
7017
  useEffect(() => {
6978
7018
  if (debounceTimerRef.current) {
6979
7019
  clearTimeout(debounceTimerRef.current);
6980
7020
  }
6981
7021
  if (!enabled || query.length < minQueryLength) {
7022
+ // Don't clear prefetched data when dropdown is closed
7023
+ if (prefetch && prefetchedRef.current && query === '') {
7024
+ // Keep prefetched data intact
7025
+ setLoading(false);
7026
+ setError(null);
7027
+ return;
7028
+ }
6982
7029
  setSuggestions([]);
7030
+ setDropdownRecommendations(null);
6983
7031
  setLoading(false);
6984
7032
  setError(null);
6985
7033
  return;
6986
7034
  }
7035
+ // When dropdown opens with empty query and we already have prefetched data, skip re-fetch
7036
+ if (prefetch && prefetchedRef.current && query === '') {
7037
+ return;
7038
+ }
6987
7039
  setLoading(true);
6988
7040
  debounceTimerRef.current = setTimeout(() => {
6989
7041
  fetchSuggestions(query);
@@ -6993,7 +7045,7 @@ function useQuerySuggestionsEnhanced(options) {
6993
7045
  clearTimeout(debounceTimerRef.current);
6994
7046
  }
6995
7047
  };
6996
- }, [query, enabled, minQueryLength, debounceMs, fetchSuggestions]);
7048
+ }, [query, enabled, prefetch, minQueryLength, debounceMs, fetchSuggestions]);
6997
7049
  // Recent search management
6998
7050
  const addRecentSearch = useCallback((searchQuery, resultsCount) => {
6999
7051
  if (!enableRecentSearches || !searchQuery.trim())
@@ -9028,10 +9080,28 @@ function SuggestionsProvider({ children, minQueryLength = 1, debounceMs = 200, m
9028
9080
  const [isOpen, setIsOpenState] = useState(false);
9029
9081
  const [activeIndex, setActiveIndex] = useState(-1);
9030
9082
  const [activeTabId, setActiveTabId] = useState('');
9083
+ const [prefetchedProducts, setPrefetchedProducts] = useState([]);
9084
+ // Prefetch product results on mount so they're available instantly when dropdown opens
9085
+ const prefetchedProductsRef = useRef(false);
9086
+ useEffect(() => {
9087
+ if (prefetchedProductsRef.current || !client?.search)
9088
+ return;
9089
+ prefetchedProductsRef.current = true;
9090
+ client.search('*', { per_page: 12, page: 1 })
9091
+ .then((res) => {
9092
+ const data = res?.data;
9093
+ const items = data?.results || data?.data || res?.results || res?.hits || [];
9094
+ if (Array.isArray(items) && items.length > 0) {
9095
+ setPrefetchedProducts(items);
9096
+ }
9097
+ })
9098
+ .catch(() => { });
9099
+ }, [client]);
9031
9100
  const suggestionsData = useQuerySuggestionsEnhanced({
9032
9101
  client,
9033
9102
  query,
9034
9103
  enabled: isOpen,
9104
+ prefetch: minQueryLength === 0,
9035
9105
  minQueryLength,
9036
9106
  debounceMs,
9037
9107
  maxSuggestions,
@@ -9049,7 +9119,22 @@ function SuggestionsProvider({ children, minQueryLength = 1, debounceMs = 200, m
9049
9119
  trackClicks: true,
9050
9120
  trackImpressions: true,
9051
9121
  });
9052
- const { suggestions, recentSearches, trendingSearches, trendingProducts, filteredTabs: filteredTabsData, loading, error, hasContent, getAllNavigableItems, addRecentSearch, } = suggestionsData;
9122
+ const { suggestions, recentSearches, trendingSearches, trendingProducts, filteredTabs: filteredTabsData, loading, error, hasContent, getAllNavigableItems, addRecentSearch, clearRecentSearches, } = suggestionsData;
9123
+ // Wrap getAllNavigableItems to include prefetchedProducts when trendingProducts is empty
9124
+ const getAllNavigableItemsWithPrefetched = useCallback(() => {
9125
+ const items = getAllNavigableItems();
9126
+ // If there are already product items in the list, return as-is
9127
+ if (items.some(i => i.type === 'product'))
9128
+ return items;
9129
+ // Otherwise append prefetchedProducts as navigable product items
9130
+ if (prefetchedProducts.length > 0) {
9131
+ let idx = items.length;
9132
+ prefetchedProducts.forEach(product => {
9133
+ items.push({ type: 'product', index: idx++, data: product });
9134
+ });
9135
+ }
9136
+ return items;
9137
+ }, [getAllNavigableItems, prefetchedProducts]);
9053
9138
  const onSearchRef = useRef(onSearch);
9054
9139
  const onSuggestionSelectRef = useRef(onSuggestionSelect);
9055
9140
  const onProductClickRef = useRef(onProductClick);
@@ -9127,19 +9212,19 @@ function SuggestionsProvider({ children, minQueryLength = 1, debounceMs = 200, m
9127
9212
  onSearchRef.current?.(trimmed);
9128
9213
  }, [analytics, addRecentSearch, close]);
9129
9214
  const navigateNext = useCallback(() => {
9130
- const items = getAllNavigableItems();
9215
+ const items = getAllNavigableItemsWithPrefetched();
9131
9216
  if (items.length === 0)
9132
9217
  return;
9133
9218
  setActiveIndex((i) => (i < items.length - 1 ? i + 1 : 0));
9134
- }, [getAllNavigableItems]);
9219
+ }, [getAllNavigableItemsWithPrefetched]);
9135
9220
  const navigatePrev = useCallback(() => {
9136
- const items = getAllNavigableItems();
9221
+ const items = getAllNavigableItemsWithPrefetched();
9137
9222
  if (items.length === 0)
9138
9223
  return;
9139
9224
  setActiveIndex((i) => (i <= 0 ? items.length - 1 : i - 1));
9140
- }, [getAllNavigableItems]);
9225
+ }, [getAllNavigableItemsWithPrefetched]);
9141
9226
  const selectActive = useCallback(() => {
9142
- const items = getAllNavigableItems();
9227
+ const items = getAllNavigableItemsWithPrefetched();
9143
9228
  if (activeIndex < 0 || activeIndex >= items.length) {
9144
9229
  submitSearch(query);
9145
9230
  return;
@@ -9161,7 +9246,7 @@ function SuggestionsProvider({ children, minQueryLength = 1, debounceMs = 200, m
9161
9246
  default:
9162
9247
  submitSearch(query);
9163
9248
  }
9164
- }, [activeIndex, getAllNavigableItems, query, submitSearch, selectSuggestion, selectProduct, selectRecentSearch, selectTrendingSearch]);
9249
+ }, [activeIndex, getAllNavigableItemsWithPrefetched, query, submitSearch, selectSuggestion, selectProduct, selectRecentSearch, selectTrendingSearch]);
9165
9250
  // Impression when open and content changes
9166
9251
  useEffect(() => {
9167
9252
  if (!isOpen || !hasContent || !query)
@@ -9184,19 +9269,21 @@ function SuggestionsProvider({ children, minQueryLength = 1, debounceMs = 200, m
9184
9269
  recentSearches,
9185
9270
  trendingSearches,
9186
9271
  trendingProducts,
9272
+ prefetchedProducts,
9187
9273
  filteredTabs: filteredTabsData,
9188
9274
  activeTabId,
9189
9275
  setActiveTabId,
9190
9276
  loading,
9191
9277
  error,
9192
9278
  hasContent,
9193
- getAllNavigableItems,
9279
+ getAllNavigableItems: getAllNavigableItemsWithPrefetched,
9194
9280
  selectSuggestion,
9195
9281
  selectProduct,
9196
9282
  selectRecentSearch,
9197
9283
  selectTrendingSearch,
9198
9284
  setActiveTab,
9199
9285
  submitSearch,
9286
+ clearRecentSearches,
9200
9287
  close,
9201
9288
  navigateNext,
9202
9289
  navigatePrev,
@@ -9212,19 +9299,21 @@ function SuggestionsProvider({ children, minQueryLength = 1, debounceMs = 200, m
9212
9299
  recentSearches,
9213
9300
  trendingSearches,
9214
9301
  trendingProducts,
9302
+ prefetchedProducts,
9215
9303
  filteredTabsData,
9216
9304
  activeTabId,
9217
9305
  setActiveTabId,
9218
9306
  loading,
9219
9307
  error,
9220
9308
  hasContent,
9221
- getAllNavigableItems,
9309
+ getAllNavigableItemsWithPrefetched,
9222
9310
  selectSuggestion,
9223
9311
  selectProduct,
9224
9312
  selectRecentSearch,
9225
9313
  selectTrendingSearch,
9226
9314
  setActiveTab,
9227
9315
  submitSearch,
9316
+ clearRecentSearches,
9228
9317
  close,
9229
9318
  navigateNext,
9230
9319
  navigatePrev,
@@ -9315,14 +9404,14 @@ function SearchInput({ placeholder = 'Powered by Seekora', autoFocus = false, sh
9315
9404
  }, [setQuery]);
9316
9405
  return (React.createElement("div", { className: clsx('seekora-suggestions-search-input-wrapper', className), style: { ...defaultStyles, ...style } },
9317
9406
  React.createElement("div", { className: "seekora-suggestions-input-wrapper", style: inputWrapperStyles },
9318
- leftIcon ? (React.createElement("span", { className: "seekora-suggestions-input-left-icon", style: { display: 'flex', flexShrink: 0, color: 'var(--seekora-text-secondary, #6b7280)' } }, leftIcon)) : null,
9407
+ leftIcon ? (React.createElement("span", { className: "seekora-suggestions-input-left-icon", style: { display: 'flex', flexShrink: 0, color: 'inherit', opacity: 0.5 } }, leftIcon)) : null,
9319
9408
  React.createElement("input", { ref: inputRef, type: "text", value: query, onChange: handleChange, onFocus: handleFocus, onBlur: handleBlur, onKeyDown: handleKeyDown, placeholder: placeholder, autoFocus: autoFocus, autoComplete: "off", autoCorrect: "off", autoCapitalize: "off", spellCheck: false, "aria-label": ariaLabel, "aria-expanded": isOpen, "aria-haspopup": "listbox", "aria-autocomplete": "list", role: "combobox", className: clsx('seekora-suggestions-input', inputClassName), style: { ...inputStyles, ...inputStyle } }),
9320
9409
  showClearButton && query ? (React.createElement("button", { type: "button", onClick: handleClear, className: "seekora-suggestions-input-clear", "aria-label": "Clear search", style: {
9321
9410
  padding: 8,
9322
9411
  border: 'none',
9323
9412
  background: 'transparent',
9324
9413
  cursor: 'pointer',
9325
- color: 'var(--seekora-text-secondary, #6b7280)',
9414
+ color: 'inherit', opacity: 0.5,
9326
9415
  display: 'flex',
9327
9416
  alignItems: 'center',
9328
9417
  justifyContent: 'center',
@@ -9473,7 +9562,7 @@ const defaultItemStyle = {
9473
9562
  fontSize: 'inherit',
9474
9563
  fontFamily: 'inherit',
9475
9564
  backgroundColor: 'transparent',
9476
- color: 'var(--seekora-text-primary, #111827)',
9565
+ color: 'inherit',
9477
9566
  transition: 'background-color 120ms ease',
9478
9567
  overflow: 'hidden',
9479
9568
  textOverflow: 'ellipsis',
@@ -9490,14 +9579,14 @@ function SuggestionItem({ suggestion, index, isActive, onSelect, className, styl
9490
9579
  const showHighlight = isActive || isHovered;
9491
9580
  return (React.createElement("li", { role: "option", "aria-selected": isActive, id: `seekora-suggestion-${index}`, className: clsx('seekora-suggestions-item', isActive && 'seekora-suggestions-item--active', isHovered && 'seekora-suggestions-item--hover', className), style: {
9492
9581
  ...defaultItemStyle,
9493
- ...(showHighlight ? { backgroundColor: 'var(--seekora-bg-hover, #f3f4f6)' } : {}),
9582
+ ...(showHighlight ? { backgroundColor: 'var(--seekora-bg-hover, rgba(0,0,0,0.05))' } : {}),
9494
9583
  ...style,
9495
9584
  }, onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false), onMouseDown: (e) => {
9496
9585
  e.preventDefault();
9497
9586
  onSelect();
9498
9587
  } },
9499
9588
  content,
9500
- suggestion.count != null ? (React.createElement("span", { className: "seekora-suggestions-item-count", style: { marginLeft: 8, color: 'var(--seekora-text-secondary, #6b7280)', fontSize: '0.875em' } }, suggestion.count)) : null));
9589
+ suggestion.count != null ? (React.createElement("span", { className: "seekora-suggestions-item-count", style: { marginLeft: 8, color: 'inherit', opacity: 0.6, fontSize: '0.875em' } }, suggestion.count)) : null));
9501
9590
  }
9502
9591
 
9503
9592
  /**
@@ -10183,7 +10272,7 @@ const imgStyle$1 = {
10183
10272
  aspectRatio: 'var(--seekora-card-aspect-ratio, 1)',
10184
10273
  objectFit: 'cover',
10185
10274
  borderRadius: BORDER_RADIUS$3.sm,
10186
- backgroundColor: 'var(--seekora-bg-secondary, #f3f4f6)',
10275
+ backgroundColor: 'var(--seekora-bg-secondary, rgba(0,0,0,0.04))',
10187
10276
  display: 'block',
10188
10277
  overflow: 'hidden',
10189
10278
  };
@@ -10209,7 +10298,7 @@ function ItemCard({ item, position, onSelect, className, style, asLink = true, i
10209
10298
  // Hover style
10210
10299
  const cardHoverStyle = isHovered
10211
10300
  ? {
10212
- backgroundColor: 'var(--seekora-card-hover-bg, var(--seekora-bg-hover, #f9fafb))',
10301
+ backgroundColor: 'var(--seekora-card-hover-bg, var(--seekora-bg-hover, rgba(0,0,0,0.03)))',
10213
10302
  boxShadow: 'var(--seekora-card-hover-shadow, 0 2px 8px rgba(0, 0, 0, 0.08))',
10214
10303
  }
10215
10304
  : {};
@@ -10218,7 +10307,7 @@ function ItemCard({ item, position, onSelect, className, style, asLink = true, i
10218
10307
  actionButtons && actionButtons.length > 0 && actionButtonsPosition?.startsWith('overlay') && (React.createElement(ActionButtons, { buttons: actionButtons, position: actionButtonsPosition === 'overlay-top-right' ? 'top-right' : 'bottom-center', showLabels: showActionLabels, size: "small" })))) : (React.createElement("div", { className: "seekora-item-card-placeholder", style: { ...imgStyle$1, ...(isHorizontal ? { minWidth: imageMinWidth, flexBasis: imageFlex, maxWidth: imageMaxWidth, height: imageHeight, flexShrink: 0 } : {}) }, "aria-hidden": true }));
10219
10308
  const textBlock = (React.createElement("div", { style: isHorizontal ? { display: 'flex', flexDirection: 'column', gap: textGap, flex: 1, minWidth: 0 } : undefined },
10220
10309
  React.createElement("span", { className: "seekora-item-card-title", style: { fontSize: titleFontSize, fontWeight: 500, lineHeight: 1.4, overflow: 'hidden', textOverflow: 'ellipsis', display: '-webkit-box', WebkitLineClamp: isHorizontal ? 2 : 3, WebkitBoxOrient: 'vertical' } }, String(title)),
10221
- description ? (React.createElement("span", { className: "seekora-item-card-description", style: { fontSize: descriptionFontSize, color: 'var(--seekora-text-secondary, #6b7280)', lineHeight: 1.3, display: '-webkit-box', WebkitLineClamp: lineClamp, WebkitBoxOrient: 'vertical', overflow: 'hidden' } }, String(description))) : null,
10310
+ description ? (React.createElement("span", { className: "seekora-item-card-description", style: { fontSize: descriptionFontSize, color: 'inherit', opacity: 0.6, lineHeight: 1.3, display: '-webkit-box', WebkitLineClamp: lineClamp, WebkitBoxOrient: 'vertical', overflow: 'hidden' } }, String(description))) : null,
10222
10311
  actionButtons && actionButtons.length > 0 && actionButtonsPosition === 'inline' && (React.createElement(ActionButtons, { buttons: actionButtons, position: "inline", showLabels: showActionLabels, size: "small", layout: "horizontal" }))));
10223
10312
  const content = isHorizontal ? (React.createElement("div", { style: { display: 'flex', gap: horizontalGap, alignItems: 'flex-start' } },
10224
10313
  imageBlock,
@@ -11213,7 +11302,7 @@ const imgPlaceholderStyle = {
11213
11302
  aspectRatio: '1',
11214
11303
  objectFit: 'cover',
11215
11304
  borderRadius: BORDER_RADIUS$1.sm,
11216
- backgroundColor: 'var(--seekora-bg-secondary, #f3f4f6)',
11305
+ backgroundColor: 'var(--seekora-bg-secondary, rgba(0,0,0,0.04))',
11217
11306
  };
11218
11307
  function ImageBlock({ images, title, imageVariant, aspectRatio, enableZoom, zoomMode, zoomLevel }) {
11219
11308
  const ar = aspectRatio
@@ -11233,7 +11322,7 @@ function MinimalLayout({ images, title, price, product, imageVariant, displayCon
11233
11322
  return (React.createElement(React.Fragment, null,
11234
11323
  React.createElement(ImageBlock, { images: images, title: title, imageVariant: imageVariant, aspectRatio: displayConfig.imageAspectRatio, enableZoom: enableImageZoom, zoomMode: imageZoomMode, zoomLevel: imageZoomLevel }),
11235
11324
  React.createElement("span", { className: "seekora-product-card__title", style: { fontSize: titleFontSize, fontWeight: 500, lineHeight: 1.4, overflow: 'hidden', textOverflow: 'ellipsis', display: '-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient: 'vertical' } }, title),
11236
- price != null && !Number.isNaN(price) && (React.createElement("span", { className: "seekora-product-card__price seekora-suggestions-product-card-price", style: { fontSize: priceFontSize, color: 'var(--seekora-text-secondary, #6b7280)' } },
11325
+ price != null && !Number.isNaN(price) && (React.createElement("span", { className: "seekora-product-card__price seekora-suggestions-product-card-price", style: { fontSize: priceFontSize, color: 'inherit', opacity: 0.6 } },
11237
11326
  product.currency ?? '$',
11238
11327
  price.toFixed(2)))));
11239
11328
  }
@@ -11253,7 +11342,7 @@ function StandardLayout({ images, title, price, comparePrice, brand, badges, opt
11253
11342
  cfg.showBadges !== false && badges.length > 0 && (React.createElement(BadgeList, { badges: badges, position: "top-left", maxBadges: 2 })),
11254
11343
  actionButtons && actionButtons.length > 0 && isOverlayPosition && (React.createElement(ActionButtons, { buttons: actionButtons, position: actionButtonsPosition === 'overlay-top-right' ? 'top-right' : 'bottom-center', showLabels: showActionLabels, size: "small" }))),
11255
11344
  React.createElement("div", { className: "seekora-product-card__body", style: { display: 'flex', flexDirection: 'column', gap: bodyGap } },
11256
- cfg.showBrand !== false && brand && (React.createElement("span", { className: "seekora-product-card__brand", style: { fontSize: brandFontSize, color: 'var(--seekora-text-secondary, #6b7280)', textTransform: 'uppercase', letterSpacing: '0.02em' } }, brand)),
11345
+ cfg.showBrand !== false && brand && (React.createElement("span", { className: "seekora-product-card__brand", style: { fontSize: brandFontSize, color: 'inherit', opacity: 0.6, textTransform: 'uppercase', letterSpacing: '0.02em' } }, brand)),
11257
11346
  React.createElement("span", { className: "seekora-product-card__title", style: { fontSize: titleFontSize, fontWeight: 500, lineHeight: 1.4, overflow: 'hidden', textOverflow: 'ellipsis', display: '-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient: 'vertical' } }, title),
11258
11347
  React.createElement("div", { className: "seekora-product-card__price" },
11259
11348
  React.createElement(PriceDisplay, { price: price ?? undefined, comparePrice: comparePrice ?? undefined, currency: cfg.currency ?? product.currency, currencyPosition: cfg.currencyPosition, priceDecimals: cfg.priceDecimals, showDiscount: cfg.showDiscount, style: { fontSize: priceFontSize } })),
@@ -11272,7 +11361,7 @@ function DetailedLayout({ images, title, price, comparePrice, brand, badges, pri
11272
11361
  cfg.showBadges !== false && badges.length > 0 && (React.createElement(BadgeList, { badges: badges, position: "top-left" })),
11273
11362
  actionButtons && actionButtons.length > 0 && isOverlayPosition && (React.createElement(ActionButtons, { buttons: actionButtons, position: actionButtonsPosition === 'overlay-top-right' ? 'top-right' : 'bottom-center', showLabels: showActionLabels, size: "small" }))),
11274
11363
  React.createElement("div", { className: "seekora-product-card__body", style: { display: 'flex', flexDirection: 'column', gap: 4 } },
11275
- cfg.showBrand !== false && brand && (React.createElement("span", { className: "seekora-product-card__brand", style: { fontSize: '0.75rem', color: 'var(--seekora-text-secondary, #6b7280)', textTransform: 'uppercase', letterSpacing: '0.02em' } }, brand)),
11364
+ cfg.showBrand !== false && brand && (React.createElement("span", { className: "seekora-product-card__brand", style: { fontSize: '0.75rem', color: 'inherit', opacity: 0.6, textTransform: 'uppercase', letterSpacing: '0.02em' } }, brand)),
11276
11365
  React.createElement("span", { className: "seekora-product-card__title", style: { fontSize: '0.875rem', fontWeight: 500, lineHeight: 1.4, overflow: 'hidden', textOverflow: 'ellipsis' } }, title),
11277
11366
  cfg.showRating !== false && product.rating != null && (React.createElement(RatingDisplay, { rating: product.rating, reviewCount: product.reviewCount, variant: "compact", size: "small", showNumeric: false, showReviewCount: true, className: "seekora-product-card__rating" })),
11278
11367
  React.createElement("div", { className: "seekora-product-card__price" }, cfg.showPriceRange && priceRange ? (React.createElement(PriceDisplay, { priceRange: priceRange, currency: cfg.currency ?? product.currency, currencyPosition: cfg.currencyPosition, priceDecimals: cfg.priceDecimals, style: { fontSize: '0.875rem' } })) : (React.createElement(PriceDisplay, { price: price ?? undefined, comparePrice: comparePrice ?? undefined, currency: cfg.currency ?? product.currency, currencyPosition: cfg.currencyPosition, priceDecimals: cfg.priceDecimals, showDiscount: cfg.showDiscount, style: { fontSize: '0.875rem' } }))),
@@ -11294,7 +11383,7 @@ function CompactLayout({ images, title, price, product, imageVariant, displayCon
11294
11383
  textOverflow: 'ellipsis',
11295
11384
  whiteSpace: 'nowrap',
11296
11385
  } }, title),
11297
- price != null && !Number.isNaN(price) && (React.createElement("span", { className: "seekora-product-card__price", style: { fontSize: '0.8125rem', color: 'var(--seekora-text-secondary, #6b7280)' } },
11386
+ price != null && !Number.isNaN(price) && (React.createElement("span", { className: "seekora-product-card__price", style: { fontSize: '0.8125rem', color: 'inherit', opacity: 0.6 } },
11298
11387
  product.currency ?? '$',
11299
11388
  price.toFixed(2)))));
11300
11389
  }
@@ -11318,7 +11407,7 @@ function HorizontalLayout({ images, title, price, comparePrice, brand, badges, o
11318
11407
  cfg.showBadges !== false && badges.length > 0 && (React.createElement(BadgeList, { badges: badges, position: "top-left", maxBadges: 1 })),
11319
11408
  actionButtons && actionButtons.length > 0 && actionButtonsPosition?.startsWith('overlay') && (React.createElement(ActionButtons, { buttons: actionButtons, position: actionButtonsPosition === 'overlay-top-right' ? 'top-right' : 'bottom-center', showLabels: showActionLabels, size: "small" }))),
11320
11409
  React.createElement("div", { className: "seekora-product-card__body", style: { display: 'flex', flexDirection: 'column', gap: bodyGap, flex: 1, minWidth: 0 } },
11321
- cfg.showBrand !== false && brand && (React.createElement("span", { className: "seekora-product-card__brand", style: { fontSize: brandFontSize, color: 'var(--seekora-text-secondary, #6b7280)', textTransform: 'uppercase' } }, brand)),
11410
+ cfg.showBrand !== false && brand && (React.createElement("span", { className: "seekora-product-card__brand", style: { fontSize: brandFontSize, color: 'inherit', opacity: 0.6, textTransform: 'uppercase' } }, brand)),
11322
11411
  React.createElement("span", { className: "seekora-product-card__title", style: { fontSize: titleFontSize, fontWeight: 500, lineHeight: 1.4, overflow: 'hidden', textOverflow: 'ellipsis', display: '-webkit-box', WebkitLineClamp: isMobile ? 3 : 2, WebkitBoxOrient: 'vertical' } }, title),
11323
11412
  React.createElement("div", { className: "seekora-product-card__price" },
11324
11413
  React.createElement(PriceDisplay, { price: price ?? undefined, comparePrice: comparePrice ?? undefined, currency: cfg.currency ?? product.currency, currencyPosition: cfg.currencyPosition, priceDecimals: cfg.priceDecimals, showDiscount: cfg.showDiscount, style: { fontSize: priceFontSize } })),
@@ -11354,7 +11443,7 @@ const imgStyle = {
11354
11443
  aspectRatio: '1',
11355
11444
  objectFit: 'cover',
11356
11445
  borderRadius: BORDER_RADIUS.sm,
11357
- backgroundColor: 'var(--seekora-bg-secondary, #f3f4f6)',
11446
+ backgroundColor: 'var(--seekora-bg-secondary, rgba(0,0,0,0.04))',
11358
11447
  };
11359
11448
  function ProductCard({ product, position, section, tabId, onSelect, className, style, imageVariant = 'single', displayConfig, onVariantHover, onVariantClick, selectedVariants, asLink, actionButtons, actionButtonsPosition = 'inline', showActionLabels = false, enableImageZoom = false, imageZoomMode = 'both', imageZoomLevel = 2.5, }) {
11360
11449
  // Find selected variant if selections are provided
@@ -11403,7 +11492,7 @@ function ProductCard({ product, position, section, tabId, onSelect, className, s
11403
11492
  const [isHovered, setIsHovered] = React.useState(false);
11404
11493
  const cardHoverStyle = isHovered
11405
11494
  ? {
11406
- backgroundColor: 'var(--seekora-card-hover-bg, var(--seekora-bg-hover, #f9fafb))',
11495
+ backgroundColor: 'var(--seekora-card-hover-bg, var(--seekora-bg-hover, rgba(0,0,0,0.03)))',
11407
11496
  boxShadow: 'var(--seekora-card-hover-shadow, 0 2px 8px rgba(0, 0, 0, 0.08))',
11408
11497
  }
11409
11498
  : {};
@@ -11417,7 +11506,7 @@ function ProductCard({ product, position, section, tabId, onSelect, className, s
11417
11506
  }, "data-position": position, "data-section": section, "data-tab-id": tabId },
11418
11507
  images.length > 0 ? (React.createElement(ImageDisplay, { images: images, variant: imageVariant, alt: title, className: "seekora-suggestions-product-card-image", enableZoom: enableImageZoom, zoomMode: imageZoomMode, zoomLevel: imageZoomLevel })) : (React.createElement("div", { className: "seekora-suggestions-product-card-placeholder", style: imgStyle, "aria-hidden": true })),
11419
11508
  React.createElement("span", { className: "seekora-suggestions-product-card-title", style: { fontSize: '0.875rem', fontWeight: 500 } }, title),
11420
- price != null && !Number.isNaN(price) ? (React.createElement("span", { className: "seekora-suggestions-product-card-price", style: { fontSize: '0.875rem', color: 'var(--seekora-text-secondary, #6b7280)' } },
11509
+ price != null && !Number.isNaN(price) ? (React.createElement("span", { className: "seekora-suggestions-product-card-price", style: { fontSize: '0.875rem', color: 'inherit', opacity: 0.6 } },
11421
11510
  product.currency ?? '$',
11422
11511
  price.toFixed(2))) : null));
11423
11512
  }
@@ -11553,7 +11642,7 @@ function CategoriesTabs({ className, style, tabClassName }) {
11553
11642
  border: 'none',
11554
11643
  borderRadius: 'var(--seekora-border-radius, 6px)',
11555
11644
  backgroundColor: isActive ? 'var(--seekora-primary-light, rgba(59, 130, 246, 0.1))' : 'transparent',
11556
- color: isActive ? 'var(--seekora-primary, #3b82f6)' : 'var(--seekora-text-primary, #111827)',
11645
+ color: isActive ? 'var(--seekora-primary, #3b82f6)' : 'inherit',
11557
11646
  cursor: 'pointer',
11558
11647
  fontSize: '0.875rem',
11559
11648
  fontWeight: isActive ? 600 : 400,
@@ -11577,7 +11666,7 @@ const itemStyle$1 = {
11577
11666
  fontSize: 'inherit',
11578
11667
  fontFamily: 'inherit',
11579
11668
  backgroundColor: 'transparent',
11580
- color: 'var(--seekora-text-primary, #111827)',
11669
+ color: 'inherit',
11581
11670
  transition: 'background-color 120ms ease',
11582
11671
  };
11583
11672
  function RecentSearchItem({ search, onSelect }) {
@@ -11585,7 +11674,7 @@ function RecentSearchItem({ search, onSelect }) {
11585
11674
  return (React.createElement("li", null,
11586
11675
  React.createElement("button", { type: "button", className: clsx('seekora-suggestions-recent-item', isHovered && 'seekora-suggestions-recent-item--hover'), style: {
11587
11676
  ...itemStyle$1,
11588
- ...(isHovered ? { backgroundColor: 'var(--seekora-bg-hover, #f3f4f6)' } : {}),
11677
+ ...(isHovered ? { backgroundColor: 'var(--seekora-bg-hover, rgba(0,0,0,0.05))' } : {}),
11589
11678
  }, onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false), onMouseDown: (e) => {
11590
11679
  e.preventDefault();
11591
11680
  onSelect();
@@ -11597,7 +11686,7 @@ function RecentSearchesList({ title = 'Recent', maxItems = 8, className, style,
11597
11686
  if (items.length === 0)
11598
11687
  return null;
11599
11688
  return (React.createElement("div", { className: clsx('seekora-suggestions-recent-list', className), style: style },
11600
- title ? (React.createElement("div", { className: "seekora-suggestions-recent-title", style: { padding: '8px 12px', fontSize: '0.75rem', fontWeight: 600, color: 'var(--seekora-text-secondary, #6b7280)', textTransform: 'uppercase' } }, title)) : null,
11689
+ title ? (React.createElement("div", { className: "seekora-suggestions-recent-title", style: { padding: '8px 12px', fontSize: '0.75rem', fontWeight: 600, color: 'inherit', opacity: 0.6, textTransform: 'uppercase' } }, title)) : null,
11601
11690
  React.createElement("ul", { className: clsx('seekora-suggestions-recent-ul', listClassName), style: { margin: 0, padding: 0, listStyle: 'none' } }, items.map((search, i) => {
11602
11691
  const onSelect = () => selectRecentSearch(search);
11603
11692
  if (renderItem) {
@@ -11621,7 +11710,7 @@ const itemStyle = {
11621
11710
  fontSize: 'inherit',
11622
11711
  fontFamily: 'inherit',
11623
11712
  backgroundColor: 'transparent',
11624
- color: 'var(--seekora-text-primary, #111827)',
11713
+ color: 'inherit',
11625
11714
  transition: 'background-color 120ms ease',
11626
11715
  };
11627
11716
  function TrendingItem({ trending, onSelect }) {
@@ -11629,13 +11718,13 @@ function TrendingItem({ trending, onSelect }) {
11629
11718
  return (React.createElement("li", null,
11630
11719
  React.createElement("button", { type: "button", className: clsx('seekora-suggestions-trending-item', isHovered && 'seekora-suggestions-trending-item--hover'), style: {
11631
11720
  ...itemStyle,
11632
- ...(isHovered ? { backgroundColor: 'var(--seekora-bg-hover, #f3f4f6)' } : {}),
11721
+ ...(isHovered ? { backgroundColor: 'var(--seekora-bg-hover, rgba(0,0,0,0.05))' } : {}),
11633
11722
  }, onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false), onMouseDown: (e) => {
11634
11723
  e.preventDefault();
11635
11724
  onSelect();
11636
11725
  } },
11637
11726
  trending.query,
11638
- trending.count != null ? (React.createElement("span", { style: { marginLeft: 8, color: 'var(--seekora-text-secondary, #6b7280)', fontSize: '0.875em' } }, trending.count)) : null)));
11727
+ trending.count != null ? (React.createElement("span", { style: { marginLeft: 8, color: 'inherit', opacity: 0.6, fontSize: '0.875em' } }, trending.count)) : null)));
11639
11728
  }
11640
11729
  function TrendingList({ title = 'Trending', maxItems = 8, className, style, listClassName, renderItem, }) {
11641
11730
  const { trendingSearches, selectTrendingSearch } = useSuggestionsContext();
@@ -11643,7 +11732,7 @@ function TrendingList({ title = 'Trending', maxItems = 8, className, style, list
11643
11732
  if (items.length === 0)
11644
11733
  return null;
11645
11734
  return (React.createElement("div", { className: clsx('seekora-suggestions-trending-list', className), style: style },
11646
- title ? (React.createElement("div", { className: "seekora-suggestions-trending-title", style: { padding: '8px 12px', fontSize: '0.75rem', fontWeight: 600, color: 'var(--seekora-text-secondary, #6b7280)', textTransform: 'uppercase' } }, title)) : null,
11735
+ title ? (React.createElement("div", { className: "seekora-suggestions-trending-title", style: { padding: '8px 12px', fontSize: '0.75rem', fontWeight: 600, color: 'inherit', opacity: 0.6, textTransform: 'uppercase' } }, title)) : null,
11647
11736
  React.createElement("ul", { className: clsx('seekora-suggestions-trending-ul', listClassName), style: { margin: 0, padding: 0, listStyle: 'none' } }, items.map((trending, i) => {
11648
11737
  const onSelect = () => selectTrendingSearch(trending, i);
11649
11738
  if (renderItem) {