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

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.
Files changed (31) hide show
  1. package/dist/components/RichQuerySuggestions.d.ts +4 -0
  2. package/dist/components/RichQuerySuggestions.d.ts.map +1 -1
  3. package/dist/components/RichQuerySuggestions.js +3 -1
  4. package/dist/components/suggestions/SuggestionSearchBar.d.ts +4 -0
  5. package/dist/components/suggestions/SuggestionSearchBar.d.ts.map +1 -1
  6. package/dist/components/suggestions/SuggestionSearchBar.js +6 -2
  7. package/dist/components/suggestions-primitives/SuggestionItem.d.ts +15 -2
  8. package/dist/components/suggestions-primitives/SuggestionItem.d.ts.map +1 -1
  9. package/dist/components/suggestions-primitives/SuggestionItem.js +11 -3
  10. package/dist/components/suggestions-primitives/SuggestionList.d.ts +13 -2
  11. package/dist/components/suggestions-primitives/SuggestionList.d.ts.map +1 -1
  12. package/dist/components/suggestions-primitives/SuggestionList.js +5 -3
  13. package/dist/components/suggestions-primitives/highlightMarkup.d.ts +19 -0
  14. package/dist/components/suggestions-primitives/highlightMarkup.d.ts.map +1 -0
  15. package/dist/components/suggestions-primitives/highlightMarkup.js +32 -0
  16. package/dist/components/suggestions-primitives/index.d.ts +2 -0
  17. package/dist/components/suggestions-primitives/index.d.ts.map +1 -1
  18. package/dist/components/suggestions-primitives/index.js +1 -0
  19. package/dist/hooks/useQuerySuggestionsEnhanced.d.ts +4 -0
  20. package/dist/hooks/useQuerySuggestionsEnhanced.d.ts.map +1 -1
  21. package/dist/hooks/useQuerySuggestionsEnhanced.js +5 -1
  22. package/dist/index.d.ts +2 -2
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +1 -1
  25. package/dist/index.umd.js +1 -1
  26. package/dist/src/index.d.ts +56 -5
  27. package/dist/src/index.esm.js +62 -11
  28. package/dist/src/index.esm.js.map +1 -1
  29. package/dist/src/index.js +62 -10
  30. package/dist/src/index.js.map +1 -1
  31. package/package.json +5 -5
package/dist/src/index.js CHANGED
@@ -4567,7 +4567,7 @@ function transformFilteredTab(raw) {
4567
4567
  // Main Hook
4568
4568
  // ============================================================================
4569
4569
  function useQuerySuggestionsEnhanced(options) {
4570
- const { client, query, enabled = true, debounceMs = 200, maxSuggestions = 10, minQueryLength = 1, includeDropdownRecommendations = false, includeCategories = true, includeFacets = false, maxCategories = 3, maxFacets = 5, filteredTabs, minPopularity, timeRange, disableTypoTolerance, analyticsTags, enableRecentSearches = true, maxRecentSearches = MAX_RECENT_SEARCHES_DEFAULT, recentSearchesKey = RECENT_SEARCHES_DEFAULT_KEY, onSuggestionsLoaded, onError, } = options;
4570
+ const { client, query, enabled = true, debounceMs = 200, maxSuggestions = 10, minQueryLength = 1, includeDropdownRecommendations = false, includeDropdownProductList = true, includeFilteredTabs = true, includeCategories = true, includeFacets = false, maxCategories = 3, maxFacets = 5, filteredTabs, minPopularity, timeRange, disableTypoTolerance, analyticsTags, enableRecentSearches = true, maxRecentSearches = MAX_RECENT_SEARCHES_DEFAULT, recentSearchesKey = RECENT_SEARCHES_DEFAULT_KEY, onSuggestionsLoaded, onError, } = options;
4571
4571
  // State
4572
4572
  const [suggestions, setSuggestions] = React.useState([]);
4573
4573
  const [loading, setLoading] = React.useState(false);
@@ -4614,6 +4614,8 @@ function useQuerySuggestionsEnhanced(options) {
4614
4614
  const response = await client.getSuggestions?.(searchQuery, {
4615
4615
  hitsPerPage: maxSuggestions,
4616
4616
  include_dropdown_recommendations: includeDropdownRecommendations || (filteredTabs && filteredTabs.length > 0),
4617
+ include_dropdown_product_list: includeDropdownProductList,
4618
+ include_filtered_tabs: includeFilteredTabs,
4617
4619
  include_categories: includeCategories,
4618
4620
  include_facets: includeFacets,
4619
4621
  max_categories: maxCategories,
@@ -4706,6 +4708,8 @@ function useQuerySuggestionsEnhanced(options) {
4706
4708
  minQueryLength,
4707
4709
  maxSuggestions,
4708
4710
  includeDropdownRecommendations,
4711
+ includeDropdownProductList,
4712
+ includeFilteredTabs,
4709
4713
  includeCategories,
4710
4714
  includeFacets,
4711
4715
  maxCategories,
@@ -5475,7 +5479,7 @@ const CloseIcon = () => (React.createElement("svg", { viewBox: "0 0 20 20", fill
5475
5479
  // Component
5476
5480
  // ============================================================================
5477
5481
  const RichQuerySuggestions = React.forwardRef(function RichQuerySuggestions(props, ref) {
5478
- const { query, isOpen = true, sections = DEFAULT_SECTIONS, maxSuggestionsPerSection = 8, minQueryLength = 0, debounceMs = 200, includeDropdownRecommendations = true, includeCategories = true, maxCategories = 3, showCounts = true, showCategoryCounts = true, showSectionHeaders = true, classNames = {}, style, renderSuggestion, renderCategory, renderTrendingItem, renderRecentItem, header, footer, width = '100%', maxHeight = '480px', zIndex = 1000, ariaLabel = 'Search suggestions', analyticsTags, onSuggestionSelect, onCategoryClick, onRecentSearchClick, onRecentSearchRemove, onViewAllClick, onOpen, onClose, } = props;
5482
+ const { query, isOpen = true, sections = DEFAULT_SECTIONS, maxSuggestionsPerSection = 8, minQueryLength = 0, debounceMs = 200, includeDropdownRecommendations = true, includeDropdownProductList = true, includeFilteredTabs = true, includeCategories = true, maxCategories = 3, showCounts = true, showCategoryCounts = true, showSectionHeaders = true, classNames = {}, style, renderSuggestion, renderCategory, renderTrendingItem, renderRecentItem, header, footer, width = '100%', maxHeight = '480px', zIndex = 1000, ariaLabel = 'Search suggestions', analyticsTags, onSuggestionSelect, onCategoryClick, onRecentSearchClick, onRecentSearchRemove, onViewAllClick, onOpen, onClose, } = props;
5479
5483
  const { client } = useSearchContext();
5480
5484
  const containerRef = React.useRef(null);
5481
5485
  const [activeIndex, setActiveIndex] = React.useState(-1);
@@ -5489,6 +5493,8 @@ const RichQuerySuggestions = React.forwardRef(function RichQuerySuggestions(prop
5489
5493
  maxSuggestions: maxSuggestionsPerSection,
5490
5494
  minQueryLength,
5491
5495
  includeDropdownRecommendations,
5496
+ includeDropdownProductList,
5497
+ includeFilteredTabs,
5492
5498
  includeCategories,
5493
5499
  maxCategories,
5494
5500
  analyticsTags,
@@ -7107,10 +7113,45 @@ function DropdownPanel({ children, position = 'absolute', top = '100%', left = 0
7107
7113
  return (React.createElement("div", { ref: panelRef, role: "listbox", className: clsx('seekora-suggestions-dropdown-panel', className), style: { ...panelStyle, ...style } }, children));
7108
7114
  }
7109
7115
 
7116
+ /**
7117
+ * Parses suggestion text containing <mark>...</mark> and returns React nodes
7118
+ * with the marked segments rendered as <mark> elements. Safe: inner content
7119
+ * is rendered as text, not HTML.
7120
+ */
7121
+ const defaultMarkStyle = {
7122
+ backgroundColor: 'var(--seekora-highlight-bg, rgba(251, 191, 36, 0.4))',
7123
+ fontWeight: 500,
7124
+ borderRadius: '2px',
7125
+ padding: '0 2px',
7126
+ };
7127
+ /**
7128
+ * Converts a string like "lined <mark>blue</mark>" into React nodes with
7129
+ * the marked part rendered as a <mark> element. When no <mark> tags are
7130
+ * present, returns the string as-is.
7131
+ */
7132
+ function parseHighlightMarkup(text, options = {}) {
7133
+ if (text == null || typeof text !== 'string')
7134
+ return text;
7135
+ const parts = text.split(/(<mark>[\s\S]*?<\/mark>)/g);
7136
+ if (parts.length <= 1)
7137
+ return text;
7138
+ const { markClassName, markStyle } = options;
7139
+ return (React.createElement(React.Fragment, null, parts.map((part, i) => {
7140
+ const m = part.match(/^<mark>([\s\S]*)<\/mark>$/);
7141
+ if (m) {
7142
+ return (React.createElement("mark", { key: i, className: markClassName, style: { ...defaultMarkStyle, ...markStyle } }, m[1]));
7143
+ }
7144
+ return part;
7145
+ })));
7146
+ }
7147
+
7110
7148
  /**
7111
7149
  * SuggestionItem – single text suggestion row (primitive)
7112
7150
  *
7113
- * Highlights when isActive; onClick calls context selectSuggestion. Overridable via className/style.
7151
+ * Highlights when isActive; onClick calls context selectSuggestion.
7152
+ * When enableHighlightMarkup is true (default), parses <mark>...</mark> in
7153
+ * suggestion text and renders as highlighted <mark> elements. Overridable via
7154
+ * renderHighlight, className/style.
7114
7155
  */
7115
7156
  const defaultItemStyle = {
7116
7157
  padding: '10px 12px',
@@ -7125,9 +7166,13 @@ const defaultItemStyle = {
7125
7166
  color: 'var(--seekora-text-primary, #111827)',
7126
7167
  transition: 'background-color 120ms ease',
7127
7168
  };
7128
- function SuggestionItem({ suggestion, index, isActive, onSelect, className, style, renderHighlight, }) {
7169
+ function SuggestionItem({ suggestion, index, isActive, onSelect, className, style, enableHighlightMarkup = true, highlightMarkupOptions, renderHighlight, }) {
7129
7170
  const displayText = suggestion.highlightedQuery ?? suggestion.query;
7130
- const content = renderHighlight ? renderHighlight(displayText) : displayText;
7171
+ const content = renderHighlight != null
7172
+ ? renderHighlight(displayText)
7173
+ : enableHighlightMarkup
7174
+ ? parseHighlightMarkup(displayText ?? '', highlightMarkupOptions)
7175
+ : (suggestion.query ?? displayText ?? '');
7131
7176
  return (React.createElement("li", { role: "option", "aria-selected": isActive, id: `seekora-suggestion-${index}`, className: clsx('seekora-suggestions-item', isActive && 'seekora-suggestions-item--active', className), style: {
7132
7177
  ...defaultItemStyle,
7133
7178
  ...(isActive ? { backgroundColor: 'var(--seekora-bg-hover, #f3f4f6)' } : {}),
@@ -7158,13 +7203,15 @@ function SuggestionsLoading({ className, style, text = 'Loading...' }) {
7158
7203
  /**
7159
7204
  * SuggestionList – container for text suggestions (primitive)
7160
7205
  *
7161
- * Renders list of SuggestionItem from context; uses activeIndex for highlight. Optional renderItem.
7206
+ * Renders list of SuggestionItem from context; uses activeIndex for highlight.
7207
+ * Optional renderItem. When not using renderItem, enableHighlightMarkup and
7208
+ * highlightMarkupOptions control parsing of <mark>...</mark> in suggestion text.
7162
7209
  */
7163
7210
  const listStyle = {
7164
7211
  margin: 0,
7165
7212
  padding: '4px 0',
7166
7213
  };
7167
- function SuggestionList({ maxItems = 10, className, style, listClassName, renderItem, }) {
7214
+ function SuggestionList({ maxItems = 10, className, style, listClassName, enableHighlightMarkup = true, highlightMarkupOptions, renderItem, }) {
7168
7215
  const { suggestions, activeIndex, loading, selectSuggestion, getAllNavigableItems, } = useSuggestionsContext();
7169
7216
  const items = suggestions.slice(0, maxItems);
7170
7217
  const navigableItems = getAllNavigableItems();
@@ -7183,7 +7230,7 @@ function SuggestionList({ maxItems = 10, className, style, listClassName, render
7183
7230
  if (renderItem) {
7184
7231
  return (React.createElement("li", { key: suggestion.objectID ?? suggestion.query ?? i, role: "option" }, renderItem(suggestion, globalIndex, isActive, onSelect)));
7185
7232
  }
7186
- return (React.createElement(SuggestionItem, { key: suggestion.objectID ?? suggestion.query ?? i, suggestion: suggestion, index: globalIndex, isActive: isActive, onSelect: onSelect }));
7233
+ return (React.createElement(SuggestionItem, { key: suggestion.objectID ?? suggestion.query ?? i, suggestion: suggestion, index: globalIndex, isActive: isActive, onSelect: onSelect, enableHighlightMarkup: enableHighlightMarkup, highlightMarkupOptions: highlightMarkupOptions }));
7187
7234
  }))));
7188
7235
  }
7189
7236
 
@@ -11792,7 +11839,7 @@ const createStyles = (isMobile) => ({
11792
11839
  // Component
11793
11840
  // ============================================================================
11794
11841
  const SuggestionSearchBar = React.forwardRef(function SuggestionSearchBar(props, ref) {
11795
- const { client, variant = 'amazon', autoMobileVariant = true, placeholder = 'Search...', defaultQuery = '', value, minQueryLength = 1, maxSuggestions = 8, debounceMs = 200, includeDropdownRecommendations = true, includeCategories = true, filteredTabs, analyticsTags, enableRecentSearches = true, maxRecentSearches = 10, showProducts = true, showTrendingOnEmpty = true, enableAnalytics = true, analyticsConfig, suggestionFields, productFields, theme, onSearch, onQueryChange, onSuggestionSelect, onProductClick, onCategoryClick, onTabChange, className, style, inputClassName, dropdownWidth, dropdownMaxHeight = '500px', zIndex = 1000, enableCache = true, cacheTtlMs = 30000, cacheMaxSize = 100, } = props;
11842
+ const { client, variant = 'amazon', autoMobileVariant = true, placeholder = 'Search...', defaultQuery = '', value, minQueryLength = 1, maxSuggestions = 8, debounceMs = 200, includeDropdownRecommendations = true, includeDropdownProductList = true, includeFilteredTabs = true, includeCategories = true, filteredTabs, analyticsTags, enableRecentSearches = true, maxRecentSearches = 10, showProducts = true, showTrendingOnEmpty = true, enableAnalytics = true, analyticsConfig, suggestionFields, productFields, theme, onSearch, onQueryChange, onSuggestionSelect, onProductClick, onCategoryClick, onTabChange, className, style, inputClassName, dropdownWidth, dropdownMaxHeight = '500px', zIndex = 1000, enableCache = true, cacheTtlMs = 30000, cacheMaxSize = 100, } = props;
11796
11843
  // Theme: prop overrides context (SearchProvider theme)
11797
11844
  const searchContext = useSearchContext();
11798
11845
  const effectiveTheme = theme ?? searchContext.theme;
@@ -11875,6 +11922,8 @@ const SuggestionSearchBar = React.forwardRef(function SuggestionSearchBar(props,
11875
11922
  const cacheOptions = {
11876
11923
  maxSuggestions,
11877
11924
  includeDropdownRecommendations,
11925
+ includeDropdownProductList,
11926
+ includeFilteredTabs,
11878
11927
  includeCategories,
11879
11928
  filteredTabs: filteredTabs?.map(t => t.filter).join(','),
11880
11929
  };
@@ -11895,6 +11944,8 @@ const SuggestionSearchBar = React.forwardRef(function SuggestionSearchBar(props,
11895
11944
  const response = await client.getSuggestions?.(searchQuery, {
11896
11945
  hitsPerPage: maxSuggestions,
11897
11946
  include_dropdown_recommendations: includeDropdownRecommendations,
11947
+ include_dropdown_product_list: includeDropdownProductList,
11948
+ include_filtered_tabs: includeFilteredTabs,
11898
11949
  include_categories: includeCategories,
11899
11950
  filtered_tabs: filteredTabs,
11900
11951
  analytics_tags: analyticsTags,
@@ -11933,7 +11984,7 @@ const SuggestionSearchBar = React.forwardRef(function SuggestionSearchBar(props,
11933
11984
  finally {
11934
11985
  setLoading(false);
11935
11986
  }
11936
- }, [client, minQueryLength, maxSuggestions, includeDropdownRecommendations, includeCategories, filteredTabs, analyticsTags, enableAnalytics, analytics, cache]);
11987
+ }, [client, minQueryLength, maxSuggestions, includeDropdownRecommendations, includeDropdownProductList, includeFilteredTabs, includeCategories, filteredTabs, analyticsTags, enableAnalytics, analytics, cache]);
11937
11988
  // Parse API response - handles multiple response formats
11938
11989
  const parseAndSetData = React.useCallback((response) => {
11939
11990
  // Handle different response structures from the API/SDK
@@ -14460,6 +14511,7 @@ exports.mediaQueries = mediaQueries;
14460
14511
  exports.mergeThemes = mergeThemes;
14461
14512
  exports.minimalTheme = minimalTheme;
14462
14513
  exports.minimalThemeVariables = minimalThemeVariables;
14514
+ exports.parseHighlightMarkup = parseHighlightMarkup;
14463
14515
  exports.removeRecentSearch = removeRecentSearch;
14464
14516
  exports.touchTargets = touchTargets;
14465
14517
  exports.updateSuggestionsStyles = updateSuggestionsStyles;