@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.
- package/dist/components/RichQuerySuggestions.d.ts +4 -0
- package/dist/components/RichQuerySuggestions.d.ts.map +1 -1
- package/dist/components/RichQuerySuggestions.js +3 -1
- package/dist/components/suggestions/SuggestionSearchBar.d.ts +4 -0
- package/dist/components/suggestions/SuggestionSearchBar.d.ts.map +1 -1
- package/dist/components/suggestions/SuggestionSearchBar.js +6 -2
- package/dist/components/suggestions-primitives/SuggestionItem.d.ts +15 -2
- package/dist/components/suggestions-primitives/SuggestionItem.d.ts.map +1 -1
- package/dist/components/suggestions-primitives/SuggestionItem.js +11 -3
- package/dist/components/suggestions-primitives/SuggestionList.d.ts +13 -2
- package/dist/components/suggestions-primitives/SuggestionList.d.ts.map +1 -1
- package/dist/components/suggestions-primitives/SuggestionList.js +5 -3
- package/dist/components/suggestions-primitives/highlightMarkup.d.ts +19 -0
- package/dist/components/suggestions-primitives/highlightMarkup.d.ts.map +1 -0
- package/dist/components/suggestions-primitives/highlightMarkup.js +32 -0
- package/dist/components/suggestions-primitives/index.d.ts +2 -0
- package/dist/components/suggestions-primitives/index.d.ts.map +1 -1
- package/dist/components/suggestions-primitives/index.js +1 -0
- package/dist/hooks/useQuerySuggestionsEnhanced.d.ts +4 -0
- package/dist/hooks/useQuerySuggestionsEnhanced.d.ts.map +1 -1
- package/dist/hooks/useQuerySuggestionsEnhanced.js +5 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/src/index.d.ts +56 -5
- package/dist/src/index.esm.js +62 -11
- package/dist/src/index.esm.js.map +1 -1
- package/dist/src/index.js +62 -10
- package/dist/src/index.js.map +1 -1
- 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.
|
|
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
|
|
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.
|
|
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;
|