@seekora-ai/ui-sdk-react 0.2.7 → 0.2.8

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.
package/dist/src/index.js CHANGED
@@ -4536,15 +4536,16 @@ function parseHighlight(highlighted) {
4536
4536
  .replace(/__\/ais-highlight__/g, '</mark>');
4537
4537
  }
4538
4538
  function transformProduct(raw) {
4539
+ const meta = raw.metadata || {};
4539
4540
  return {
4540
4541
  id: raw.id || raw.objectID,
4541
4542
  objectID: raw.objectID || raw.id,
4542
- title: raw.title || raw.name || raw.productName,
4543
- name: raw.name || raw.title,
4544
- image: raw.image || raw.imageUrl || raw.metadata?.image,
4545
- price: raw.price || raw.sellPrice || raw.metadata?.sellPrice,
4546
- currency: raw.currency || raw.metadata?.currency || '',
4547
- url: raw.url || raw.productId || raw.metadata?.url,
4543
+ title: raw.title || raw.name || raw.productName || meta.name || meta.productName || '',
4544
+ name: raw.name || raw.title || meta.name || meta.productName || '',
4545
+ image: raw.image || raw.imageUrl || meta.image || meta.image_url || meta.images?.[0] || '',
4546
+ price: raw.price ?? raw.sellPrice ?? meta.sellPrice ?? meta.price,
4547
+ currency: raw.currency || meta.currency || '',
4548
+ url: raw.url || raw.productId || meta.url || meta.productId || '',
4548
4549
  clicks: raw.clicks,
4549
4550
  conversions: raw.conversions,
4550
4551
  revenue: raw.revenue,
@@ -4594,7 +4595,10 @@ function useQuerySuggestionsEnhanced(options) {
4594
4595
  }, [enableRecentSearches, recentSearchesKey, maxRecentSearches]);
4595
4596
  // Fetch suggestions
4596
4597
  const fetchSuggestions = React.useCallback(async (searchQuery) => {
4597
- if (!client || !searchQuery.trim()) {
4598
+ if (!client)
4599
+ return;
4600
+ // When minQueryLength is 0, allow empty query so overlay can show default/trending recommendations on open
4601
+ if (!searchQuery.trim() && minQueryLength > 0) {
4598
4602
  setSuggestions([]);
4599
4603
  setDropdownRecommendations(null);
4600
4604
  return;
@@ -4629,12 +4633,17 @@ function useQuerySuggestionsEnhanced(options) {
4629
4633
  setSuggestions(transformedSuggestions);
4630
4634
  // Extract dropdown recommendations from extensions
4631
4635
  const extensions = (response.extensions || {});
4636
+ const rawResults = response.results;
4637
+ const secondResultHits = Array.isArray(rawResults?.[1]?.hits) ? rawResults[1].hits : [];
4638
+ // Multi-index response: results[0]=suggestions, results[1]=product hits; expose results[1].hits as product_hits for fallback when extensions have no products
4639
+ const productHits = secondResultHits.length > 0 ? secondResultHits.map((h) => transformProduct(h)) : [];
4632
4640
  const recommendations = {
4633
4641
  trending_searches: Array.isArray(extensions.trending_searches) ? extensions.trending_searches : [],
4634
4642
  top_searches: Array.isArray(extensions.top_searches) ? extensions.top_searches : [],
4635
4643
  related_searches: Array.isArray(extensions.related_searches) ? extensions.related_searches : [],
4636
4644
  trending_products: Array.isArray(extensions.trending_products) ? extensions.trending_products.map(transformProduct) : [],
4637
4645
  item_recommendations: Array.isArray(extensions.item_recommendations) ? extensions.item_recommendations.map(transformProduct) : [],
4646
+ product_hits: productHits.length > 0 ? productHits : undefined,
4638
4647
  popular_brands: Array.isArray(extensions.popular_brands) ? extensions.popular_brands : [],
4639
4648
  filtered_tabs: Array.isArray(extensions.filtered_tabs) ? extensions.filtered_tabs.map(transformFilteredTab) : [],
4640
4649
  processing_time_ms: typeof extensions.processing_time_ms === 'number' ? extensions.processing_time_ms : undefined,
@@ -4694,6 +4703,7 @@ function useQuerySuggestionsEnhanced(options) {
4694
4703
  }
4695
4704
  }, [
4696
4705
  client,
4706
+ minQueryLength,
4697
4707
  maxSuggestions,
4698
4708
  includeDropdownRecommendations,
4699
4709
  includeCategories,
@@ -4770,7 +4780,19 @@ function useQuerySuggestionsEnhanced(options) {
4770
4780
  const relatedSearches = dropdownRecommendations?.related_searches || [];
4771
4781
  const popularBrands = dropdownRecommendations?.popular_brands || [];
4772
4782
  const filteredTabsResult = dropdownRecommendations?.filtered_tabs || [];
4773
- const trendingProducts = dropdownRecommendations?.trending_products || [];
4783
+ // Use trending_products, then item_recommendations, then first filtered_tab's products, then results[1].hits (product_hits) so grid shows for any API shape
4784
+ const trendingProducts = React.useMemo(() => {
4785
+ const fromTrending = dropdownRecommendations?.trending_products;
4786
+ if (fromTrending && fromTrending.length > 0)
4787
+ return fromTrending;
4788
+ const fromItemRecs = dropdownRecommendations?.item_recommendations;
4789
+ if (fromItemRecs && fromItemRecs.length > 0)
4790
+ return fromItemRecs;
4791
+ const firstTab = dropdownRecommendations?.filtered_tabs?.[0];
4792
+ if (firstTab?.products && firstTab.products.length > 0)
4793
+ return firstTab.products;
4794
+ return dropdownRecommendations?.product_hits ?? [];
4795
+ }, [dropdownRecommendations?.trending_products, dropdownRecommendations?.item_recommendations, dropdownRecommendations?.filtered_tabs, dropdownRecommendations?.product_hits]);
4774
4796
  const hasContent = React.useMemo(() => {
4775
4797
  return (suggestions.length > 0 ||
4776
4798
  recentSearches.length > 0 ||
@@ -6971,15 +6993,17 @@ const inputStyles = {
6971
6993
  color: 'var(--seekora-text-primary, #111827)',
6972
6994
  fontFamily: 'inherit',
6973
6995
  };
6974
- function SearchInput({ placeholder = 'Search...', autoFocus = false, showClearButton = true, className, style, inputClassName, inputStyle, ariaLabel = 'Search', }) {
6996
+ function SearchInput({ placeholder = 'Search...', autoFocus = false, showClearButton = true, closeOnBlur = true, leftIcon, className, style, inputClassName, inputStyle, ariaLabel = 'Search', }) {
6975
6997
  const { query, setQuery, isOpen, setIsOpen, navigateNext, navigatePrev, selectActive, close, } = useSuggestionsContext();
6976
6998
  const inputRef = React.useRef(null);
6977
6999
  const handleFocus = React.useCallback(() => {
6978
7000
  setIsOpen(true);
6979
7001
  }, [setIsOpen]);
6980
7002
  const handleBlur = React.useCallback(() => {
7003
+ if (!closeOnBlur)
7004
+ return;
6981
7005
  setTimeout(() => close(), 200);
6982
- }, [close]);
7006
+ }, [close, closeOnBlur]);
6983
7007
  const handleChange = React.useCallback((e) => {
6984
7008
  setQuery(e.target.value);
6985
7009
  }, [setQuery]);
@@ -7012,6 +7036,7 @@ function SearchInput({ placeholder = 'Search...', autoFocus = false, showClearBu
7012
7036
  }, [setQuery]);
7013
7037
  return (React.createElement("div", { className: clsx('seekora-suggestions-search-input-wrapper', className), style: { ...defaultStyles, ...style } },
7014
7038
  React.createElement("div", { className: "seekora-suggestions-input-wrapper", style: inputWrapperStyles },
7039
+ leftIcon ? (React.createElement("span", { className: "seekora-suggestions-input-left-icon", style: { display: 'flex', flexShrink: 0, color: 'var(--seekora-text-secondary, #6b7280)' } }, leftIcon)) : null,
7015
7040
  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 } }),
7016
7041
  showClearButton && query ? (React.createElement("button", { type: "button", onClick: handleClear, className: "seekora-suggestions-input-clear", "aria-label": "Clear search", style: {
7017
7042
  padding: 4,