@seekora-ai/ui-sdk-react 1.0.0
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/Breadcrumb.d.ts +43 -0
- package/dist/components/Breadcrumb.d.ts.map +1 -0
- package/dist/components/Breadcrumb.js +119 -0
- package/dist/components/ClearRefinements.d.ts +42 -0
- package/dist/components/ClearRefinements.d.ts.map +1 -0
- package/dist/components/ClearRefinements.js +80 -0
- package/dist/components/CurrentRefinements.d.ts +41 -0
- package/dist/components/CurrentRefinements.d.ts.map +1 -0
- package/dist/components/CurrentRefinements.js +83 -0
- package/dist/components/Facets.d.ts +53 -0
- package/dist/components/Facets.d.ts.map +1 -0
- package/dist/components/Facets.js +195 -0
- package/dist/components/FederatedDropdown.d.ts +92 -0
- package/dist/components/FederatedDropdown.d.ts.map +1 -0
- package/dist/components/FederatedDropdown.js +510 -0
- package/dist/components/HierarchicalMenu.d.ts +55 -0
- package/dist/components/HierarchicalMenu.d.ts.map +1 -0
- package/dist/components/HierarchicalMenu.js +168 -0
- package/dist/components/Highlight.d.ts +51 -0
- package/dist/components/Highlight.d.ts.map +1 -0
- package/dist/components/Highlight.js +155 -0
- package/dist/components/HitsPerPage.d.ts +41 -0
- package/dist/components/HitsPerPage.d.ts.map +1 -0
- package/dist/components/HitsPerPage.js +72 -0
- package/dist/components/InfiniteHits.d.ts +56 -0
- package/dist/components/InfiniteHits.d.ts.map +1 -0
- package/dist/components/InfiniteHits.js +181 -0
- package/dist/components/MobileFilters.d.ts +71 -0
- package/dist/components/MobileFilters.d.ts.map +1 -0
- package/dist/components/MobileFilters.js +242 -0
- package/dist/components/Pagination.d.ts +44 -0
- package/dist/components/Pagination.d.ts.map +1 -0
- package/dist/components/Pagination.js +142 -0
- package/dist/components/QuerySuggestions.d.ts +38 -0
- package/dist/components/QuerySuggestions.d.ts.map +1 -0
- package/dist/components/QuerySuggestions.js +86 -0
- package/dist/components/QuerySuggestionsDropdown.d.ts +86 -0
- package/dist/components/QuerySuggestionsDropdown.d.ts.map +1 -0
- package/dist/components/QuerySuggestionsDropdown.js +395 -0
- package/dist/components/RangeInput.d.ts +58 -0
- package/dist/components/RangeInput.d.ts.map +1 -0
- package/dist/components/RangeInput.js +203 -0
- package/dist/components/RangeSlider.d.ts +51 -0
- package/dist/components/RangeSlider.d.ts.map +1 -0
- package/dist/components/RangeSlider.js +193 -0
- package/dist/components/Recommendations.d.ts +90 -0
- package/dist/components/Recommendations.d.ts.map +1 -0
- package/dist/components/Recommendations.js +270 -0
- package/dist/components/RichQuerySuggestions.d.ts +77 -0
- package/dist/components/RichQuerySuggestions.d.ts.map +1 -0
- package/dist/components/RichQuerySuggestions.js +492 -0
- package/dist/components/SearchBar.d.ts +40 -0
- package/dist/components/SearchBar.d.ts.map +1 -0
- package/dist/components/SearchBar.js +217 -0
- package/dist/components/SearchBarWithSuggestions.d.ts +99 -0
- package/dist/components/SearchBarWithSuggestions.d.ts.map +1 -0
- package/dist/components/SearchBarWithSuggestions.js +275 -0
- package/dist/components/SearchLayout.d.ts +35 -0
- package/dist/components/SearchLayout.d.ts.map +1 -0
- package/dist/components/SearchLayout.js +56 -0
- package/dist/components/SearchProvider.d.ts +28 -0
- package/dist/components/SearchProvider.d.ts.map +1 -0
- package/dist/components/SearchProvider.js +43 -0
- package/dist/components/SearchResults.d.ts +51 -0
- package/dist/components/SearchResults.d.ts.map +1 -0
- package/dist/components/SearchResults.js +485 -0
- package/dist/components/SortBy.d.ts +44 -0
- package/dist/components/SortBy.d.ts.map +1 -0
- package/dist/components/SortBy.js +61 -0
- package/dist/components/Stats.d.ts +37 -0
- package/dist/components/Stats.d.ts.map +1 -0
- package/dist/components/Stats.js +52 -0
- package/dist/components/suggestions/AmazonDropdown.d.ts +30 -0
- package/dist/components/suggestions/AmazonDropdown.d.ts.map +1 -0
- package/dist/components/suggestions/AmazonDropdown.js +529 -0
- package/dist/components/suggestions/GoogleDropdown.d.ts +31 -0
- package/dist/components/suggestions/GoogleDropdown.d.ts.map +1 -0
- package/dist/components/suggestions/GoogleDropdown.js +370 -0
- package/dist/components/suggestions/MinimalDropdown.d.ts +24 -0
- package/dist/components/suggestions/MinimalDropdown.d.ts.map +1 -0
- package/dist/components/suggestions/MinimalDropdown.js +314 -0
- package/dist/components/suggestions/MobileSheetDropdown.d.ts +31 -0
- package/dist/components/suggestions/MobileSheetDropdown.d.ts.map +1 -0
- package/dist/components/suggestions/MobileSheetDropdown.js +485 -0
- package/dist/components/suggestions/PinterestDropdown.d.ts +29 -0
- package/dist/components/suggestions/PinterestDropdown.d.ts.map +1 -0
- package/dist/components/suggestions/PinterestDropdown.js +450 -0
- package/dist/components/suggestions/ShopifyDropdown.d.ts +27 -0
- package/dist/components/suggestions/ShopifyDropdown.d.ts.map +1 -0
- package/dist/components/suggestions/ShopifyDropdown.js +451 -0
- package/dist/components/suggestions/SpotlightDropdown.d.ts +33 -0
- package/dist/components/suggestions/SpotlightDropdown.d.ts.map +1 -0
- package/dist/components/suggestions/SpotlightDropdown.js +547 -0
- package/dist/components/suggestions/SuggestionSearchBar.d.ts +123 -0
- package/dist/components/suggestions/SuggestionSearchBar.d.ts.map +1 -0
- package/dist/components/suggestions/SuggestionSearchBar.js +652 -0
- package/dist/components/suggestions/index.d.ts +37 -0
- package/dist/components/suggestions/index.d.ts.map +1 -0
- package/dist/components/suggestions/index.js +59 -0
- package/dist/components/suggestions/styles/index.d.ts +11 -0
- package/dist/components/suggestions/styles/index.d.ts.map +1 -0
- package/dist/components/suggestions/styles/index.js +289 -0
- package/dist/components/suggestions/styles/responsive.d.ts +107 -0
- package/dist/components/suggestions/styles/responsive.d.ts.map +1 -0
- package/dist/components/suggestions/styles/responsive.js +237 -0
- package/dist/components/suggestions/types.d.ts +489 -0
- package/dist/components/suggestions/types.d.ts.map +1 -0
- package/dist/components/suggestions/types.js +6 -0
- package/dist/components/suggestions/utils.d.ts +213 -0
- package/dist/components/suggestions/utils.d.ts.map +1 -0
- package/dist/components/suggestions/utils.js +514 -0
- package/dist/hooks/useAnalytics.d.ts +20 -0
- package/dist/hooks/useAnalytics.d.ts.map +1 -0
- package/dist/hooks/useAnalytics.js +62 -0
- package/dist/hooks/useNaturalLanguageFilters.d.ts +48 -0
- package/dist/hooks/useNaturalLanguageFilters.d.ts.map +1 -0
- package/dist/hooks/useNaturalLanguageFilters.js +221 -0
- package/dist/hooks/useQuerySuggestions.d.ts +21 -0
- package/dist/hooks/useQuerySuggestions.d.ts.map +1 -0
- package/dist/hooks/useQuerySuggestions.js +68 -0
- package/dist/hooks/useQuerySuggestionsEnhanced.d.ts +114 -0
- package/dist/hooks/useQuerySuggestionsEnhanced.d.ts.map +1 -0
- package/dist/hooks/useQuerySuggestionsEnhanced.js +376 -0
- package/dist/hooks/useSearchState.d.ts +35 -0
- package/dist/hooks/useSearchState.d.ts.map +1 -0
- package/dist/hooks/useSearchState.js +68 -0
- package/dist/hooks/useSeekoraSearch.d.ts +20 -0
- package/dist/hooks/useSeekoraSearch.d.ts.map +1 -0
- package/dist/hooks/useSeekoraSearch.js +63 -0
- package/dist/hooks/useSmartSuggestions.d.ts +55 -0
- package/dist/hooks/useSmartSuggestions.d.ts.map +1 -0
- package/dist/hooks/useSmartSuggestions.js +236 -0
- package/dist/hooks/useSuggestionsAnalytics.d.ts +91 -0
- package/dist/hooks/useSuggestionsAnalytics.d.ts.map +1 -0
- package/dist/hooks/useSuggestionsAnalytics.js +226 -0
- package/dist/index.d.ts +80 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +86 -0
- package/dist/index.umd.js +1 -0
- package/dist/src/index.d.ts +2849 -0
- package/dist/src/index.esm.js +11679 -0
- package/dist/src/index.esm.js.map +1 -0
- package/dist/src/index.js +11761 -0
- package/dist/src/index.js.map +1 -0
- package/dist/themes/createTheme.d.ts +8 -0
- package/dist/themes/createTheme.d.ts.map +1 -0
- package/dist/themes/createTheme.js +10 -0
- package/dist/themes/dark.d.ts +6 -0
- package/dist/themes/dark.d.ts.map +1 -0
- package/dist/themes/dark.js +34 -0
- package/dist/themes/default.d.ts +6 -0
- package/dist/themes/default.d.ts.map +1 -0
- package/dist/themes/default.js +71 -0
- package/dist/themes/mergeThemes.d.ts +7 -0
- package/dist/themes/mergeThemes.d.ts.map +1 -0
- package/dist/themes/mergeThemes.js +6 -0
- package/dist/themes/minimal.d.ts +6 -0
- package/dist/themes/minimal.d.ts.map +1 -0
- package/dist/themes/minimal.js +34 -0
- package/dist/themes/suggestions.d.ts +216 -0
- package/dist/themes/suggestions.d.ts.map +1 -0
- package/dist/themes/suggestions.js +546 -0
- package/dist/themes/types.d.ts +7 -0
- package/dist/themes/types.d.ts.map +1 -0
- package/dist/themes/types.js +6 -0
- package/dist/types/index.d.ts +33 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +4 -0
- package/package.json +65 -0
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useSmartSuggestions Hook
|
|
3
|
+
*
|
|
4
|
+
* AI-enhanced query suggestions with intent understanding
|
|
5
|
+
* Provides context-aware suggestions based on user behavior and query patterns
|
|
6
|
+
*/
|
|
7
|
+
import { useState, useEffect, useCallback, useMemo, useRef } from 'react';
|
|
8
|
+
import { useSearchContext } from '../components/SearchProvider';
|
|
9
|
+
/**
|
|
10
|
+
* Pattern-based intent detection (client-side fallback)
|
|
11
|
+
*/
|
|
12
|
+
function detectIntent(query) {
|
|
13
|
+
const patterns = [
|
|
14
|
+
{ pattern: /^(buy|purchase|order|get)\s+/i, intent: 'purchase' },
|
|
15
|
+
{ pattern: /^(find|search|looking for|where)\s+/i, intent: 'search' },
|
|
16
|
+
{ pattern: /^(compare|vs|versus)\s+/i, intent: 'compare' },
|
|
17
|
+
{ pattern: /^(how (to|do)|what is|why)\s+/i, intent: 'informational' },
|
|
18
|
+
{ pattern: /under\s*\$?\d+|less than\s*\$?\d+|cheap|affordable/i, intent: 'price_sensitive' },
|
|
19
|
+
{ pattern: /best|top|recommended|popular/i, intent: 'recommendation' },
|
|
20
|
+
{ pattern: /\d+\s*(gb|tb|inch|cm|mm|kg|lb)/i, intent: 'specification' },
|
|
21
|
+
{ pattern: /(red|blue|green|black|white|pink|purple|yellow)\s+/i, intent: 'color_preference' },
|
|
22
|
+
{ pattern: /(size|small|medium|large|xl|xxl)\s+/i, intent: 'size_preference' },
|
|
23
|
+
];
|
|
24
|
+
for (const { pattern, intent } of patterns) {
|
|
25
|
+
if (pattern.test(query)) {
|
|
26
|
+
return { intent, confidence: 0.8 };
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Simple Levenshtein distance for spell checking
|
|
33
|
+
*/
|
|
34
|
+
function levenshteinDistance(a, b) {
|
|
35
|
+
const matrix = [];
|
|
36
|
+
for (let i = 0; i <= b.length; i++) {
|
|
37
|
+
matrix[i] = [i];
|
|
38
|
+
}
|
|
39
|
+
for (let j = 0; j <= a.length; j++) {
|
|
40
|
+
matrix[0][j] = j;
|
|
41
|
+
}
|
|
42
|
+
for (let i = 1; i <= b.length; i++) {
|
|
43
|
+
for (let j = 1; j <= a.length; j++) {
|
|
44
|
+
if (b.charAt(i - 1) === a.charAt(j - 1)) {
|
|
45
|
+
matrix[i][j] = matrix[i - 1][j - 1];
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, matrix[i][j - 1] + 1, matrix[i - 1][j] + 1);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return matrix[b.length][a.length];
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Find potential corrections from a dictionary
|
|
56
|
+
*/
|
|
57
|
+
function findCorrections(query, dictionary, maxDistance = 2) {
|
|
58
|
+
const words = query.toLowerCase().split(/\s+/);
|
|
59
|
+
const corrections = [];
|
|
60
|
+
words.forEach(word => {
|
|
61
|
+
if (word.length < 3)
|
|
62
|
+
return;
|
|
63
|
+
dictionary.forEach(dictWord => {
|
|
64
|
+
const distance = levenshteinDistance(word, dictWord.toLowerCase());
|
|
65
|
+
if (distance > 0 && distance <= maxDistance && distance < word.length / 2) {
|
|
66
|
+
const corrected = query.replace(new RegExp(word, 'gi'), dictWord);
|
|
67
|
+
if (!corrections.includes(corrected)) {
|
|
68
|
+
corrections.push(corrected);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
return corrections.slice(0, 3);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Expand query with synonyms and related terms
|
|
77
|
+
*/
|
|
78
|
+
function expandQuery(query) {
|
|
79
|
+
const expansions = {
|
|
80
|
+
phone: ['smartphone', 'mobile', 'cellphone'],
|
|
81
|
+
laptop: ['notebook', 'computer', 'pc'],
|
|
82
|
+
tv: ['television', 'smart tv', 'monitor'],
|
|
83
|
+
headphones: ['earbuds', 'earphones', 'headset'],
|
|
84
|
+
shoes: ['footwear', 'sneakers', 'boots'],
|
|
85
|
+
shirt: ['top', 'blouse', 'tee'],
|
|
86
|
+
pants: ['trousers', 'jeans', 'bottoms'],
|
|
87
|
+
cheap: ['affordable', 'budget', 'inexpensive'],
|
|
88
|
+
best: ['top-rated', 'popular', 'recommended'],
|
|
89
|
+
};
|
|
90
|
+
const queryLower = query.toLowerCase();
|
|
91
|
+
const expanded = [];
|
|
92
|
+
Object.entries(expansions).forEach(([term, synonyms]) => {
|
|
93
|
+
if (queryLower.includes(term)) {
|
|
94
|
+
synonyms.forEach(syn => {
|
|
95
|
+
const exp = query.replace(new RegExp(term, 'gi'), syn);
|
|
96
|
+
if (!expanded.includes(exp)) {
|
|
97
|
+
expanded.push(exp);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
return expanded.slice(0, 3);
|
|
103
|
+
}
|
|
104
|
+
export function useSmartSuggestions(query, options = {}) {
|
|
105
|
+
const { minQueryLength = 1, maxSuggestions = 10, debounceMs = 200, enableSpellCorrection = true, enableQueryExpansion = true, enableIntentDetection = true, includeTrending = true, userContext, } = options;
|
|
106
|
+
const { stateManager } = useSearchContext();
|
|
107
|
+
const [suggestions, setSuggestions] = useState([]);
|
|
108
|
+
const [loading, setLoading] = useState(false);
|
|
109
|
+
const [error, setError] = useState(null);
|
|
110
|
+
const [detectedIntent, setDetectedIntent] = useState(null);
|
|
111
|
+
const [corrections, setCorrections] = useState([]);
|
|
112
|
+
const [expansions, setExpansions] = useState([]);
|
|
113
|
+
const debounceTimer = useRef(null);
|
|
114
|
+
// Sample dictionary for spell checking (in production, this would come from the API)
|
|
115
|
+
const dictionary = useMemo(() => [
|
|
116
|
+
'phone', 'laptop', 'computer', 'tablet', 'headphones', 'camera',
|
|
117
|
+
'television', 'speaker', 'watch', 'keyboard', 'mouse', 'monitor',
|
|
118
|
+
'shirt', 'pants', 'shoes', 'jacket', 'dress', 'skirt', 'sweater',
|
|
119
|
+
'electronics', 'clothing', 'accessories', 'furniture', 'appliances',
|
|
120
|
+
], []);
|
|
121
|
+
const processQuery = useCallback(async (q) => {
|
|
122
|
+
const results = [];
|
|
123
|
+
// Detect intent
|
|
124
|
+
if (enableIntentDetection) {
|
|
125
|
+
const intent = detectIntent(q);
|
|
126
|
+
if (intent) {
|
|
127
|
+
setDetectedIntent(intent.intent);
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
setDetectedIntent(null);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
// Find spell corrections
|
|
134
|
+
if (enableSpellCorrection && q.length >= 3) {
|
|
135
|
+
const correctionResults = findCorrections(q, dictionary);
|
|
136
|
+
setCorrections(correctionResults);
|
|
137
|
+
correctionResults.forEach(correction => {
|
|
138
|
+
results.push({
|
|
139
|
+
text: correction,
|
|
140
|
+
type: 'correction',
|
|
141
|
+
confidence: 0.9,
|
|
142
|
+
metadata: { correctedFrom: q },
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
// Expand query
|
|
147
|
+
if (enableQueryExpansion) {
|
|
148
|
+
const expansionResults = expandQuery(q);
|
|
149
|
+
setExpansions(expansionResults);
|
|
150
|
+
expansionResults.forEach(exp => {
|
|
151
|
+
results.push({
|
|
152
|
+
text: exp,
|
|
153
|
+
type: 'expansion',
|
|
154
|
+
confidence: 0.7,
|
|
155
|
+
metadata: { expandedTo: [exp] },
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
// Add the original query as a suggestion
|
|
160
|
+
results.unshift({
|
|
161
|
+
text: q,
|
|
162
|
+
type: 'query',
|
|
163
|
+
confidence: 1.0,
|
|
164
|
+
});
|
|
165
|
+
// Add related suggestions based on context
|
|
166
|
+
if (userContext?.recentSearches) {
|
|
167
|
+
userContext.recentSearches
|
|
168
|
+
.filter(s => s.toLowerCase().includes(q.toLowerCase()) && s !== q)
|
|
169
|
+
.slice(0, 2)
|
|
170
|
+
.forEach(s => {
|
|
171
|
+
results.push({
|
|
172
|
+
text: s,
|
|
173
|
+
type: 'related',
|
|
174
|
+
confidence: 0.6,
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
return results.slice(0, maxSuggestions);
|
|
179
|
+
}, [dictionary, enableIntentDetection, enableSpellCorrection, enableQueryExpansion, maxSuggestions, userContext]);
|
|
180
|
+
const getSuggestions = useCallback(async (q) => {
|
|
181
|
+
if (q.length < minQueryLength) {
|
|
182
|
+
return [];
|
|
183
|
+
}
|
|
184
|
+
return processQuery(q);
|
|
185
|
+
}, [minQueryLength, processQuery]);
|
|
186
|
+
// Debounced effect
|
|
187
|
+
useEffect(() => {
|
|
188
|
+
if (debounceTimer.current) {
|
|
189
|
+
clearTimeout(debounceTimer.current);
|
|
190
|
+
}
|
|
191
|
+
if (query.length < minQueryLength) {
|
|
192
|
+
setSuggestions([]);
|
|
193
|
+
setCorrections([]);
|
|
194
|
+
setExpansions([]);
|
|
195
|
+
setDetectedIntent(null);
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
setLoading(true);
|
|
199
|
+
debounceTimer.current = setTimeout(async () => {
|
|
200
|
+
try {
|
|
201
|
+
const results = await processQuery(query);
|
|
202
|
+
setSuggestions(results);
|
|
203
|
+
setError(null);
|
|
204
|
+
}
|
|
205
|
+
catch (err) {
|
|
206
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
207
|
+
setSuggestions([]);
|
|
208
|
+
}
|
|
209
|
+
finally {
|
|
210
|
+
setLoading(false);
|
|
211
|
+
}
|
|
212
|
+
}, debounceMs);
|
|
213
|
+
return () => {
|
|
214
|
+
if (debounceTimer.current) {
|
|
215
|
+
clearTimeout(debounceTimer.current);
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
}, [query, minQueryLength, debounceMs, processQuery]);
|
|
219
|
+
const clear = useCallback(() => {
|
|
220
|
+
setSuggestions([]);
|
|
221
|
+
setCorrections([]);
|
|
222
|
+
setExpansions([]);
|
|
223
|
+
setDetectedIntent(null);
|
|
224
|
+
setError(null);
|
|
225
|
+
}, []);
|
|
226
|
+
return {
|
|
227
|
+
suggestions,
|
|
228
|
+
loading,
|
|
229
|
+
error,
|
|
230
|
+
detectedIntent,
|
|
231
|
+
corrections,
|
|
232
|
+
expansions,
|
|
233
|
+
getSuggestions,
|
|
234
|
+
clear,
|
|
235
|
+
};
|
|
236
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Suggestions Analytics Hook
|
|
3
|
+
*
|
|
4
|
+
* Provides analytics tracking for query suggestions components:
|
|
5
|
+
* - Suggestion clicks/selections
|
|
6
|
+
* - Suggestion impressions
|
|
7
|
+
* - Product clicks from dropdown
|
|
8
|
+
* - Category/brand clicks
|
|
9
|
+
* - Search submissions from suggestions
|
|
10
|
+
*/
|
|
11
|
+
import type { SeekoraClient } from '@seekora-ai/search-sdk';
|
|
12
|
+
import type { SuggestionItem, ProductItem, SuggestionCategory, PopularBrand, FilteredTab, RecentSearch, TrendingSearch } from '@seekora-ai/ui-sdk-types';
|
|
13
|
+
export interface UseSuggestionsAnalyticsOptions {
|
|
14
|
+
/** Seekora client instance */
|
|
15
|
+
client: SeekoraClient;
|
|
16
|
+
/** Enable analytics tracking */
|
|
17
|
+
enabled?: boolean;
|
|
18
|
+
/** Analytics tags to include with all events */
|
|
19
|
+
analyticsTags?: string[];
|
|
20
|
+
/** Debounce impression events (ms) */
|
|
21
|
+
impressionDebounce?: number;
|
|
22
|
+
/** Track suggestion impressions automatically */
|
|
23
|
+
trackImpressions?: boolean;
|
|
24
|
+
/** Track clicks automatically */
|
|
25
|
+
trackClicks?: boolean;
|
|
26
|
+
}
|
|
27
|
+
export interface SuggestionClickEventData {
|
|
28
|
+
/** The clicked suggestion */
|
|
29
|
+
suggestion: SuggestionItem;
|
|
30
|
+
/** Position in the list (0-indexed) */
|
|
31
|
+
position: number;
|
|
32
|
+
/** Section where the suggestion appeared */
|
|
33
|
+
section?: 'suggestions' | 'trending' | 'recent' | 'related';
|
|
34
|
+
/** Original query that triggered suggestions */
|
|
35
|
+
query?: string;
|
|
36
|
+
/** Total suggestions shown */
|
|
37
|
+
totalSuggestions?: number;
|
|
38
|
+
}
|
|
39
|
+
export interface ProductClickEventData {
|
|
40
|
+
/** The clicked product */
|
|
41
|
+
product: ProductItem;
|
|
42
|
+
/** Position in the list (0-indexed) */
|
|
43
|
+
position: number;
|
|
44
|
+
/** Section where the product appeared */
|
|
45
|
+
section?: 'products' | 'trending' | 'recommendations' | 'filtered_tab';
|
|
46
|
+
/** Tab ID if from filtered tab */
|
|
47
|
+
tabId?: string;
|
|
48
|
+
/** Original query */
|
|
49
|
+
query?: string;
|
|
50
|
+
}
|
|
51
|
+
export interface SuggestionImpressionEventData {
|
|
52
|
+
/** Suggestions that were shown */
|
|
53
|
+
suggestions: SuggestionItem[];
|
|
54
|
+
/** Products that were shown */
|
|
55
|
+
products?: ProductItem[];
|
|
56
|
+
/** Categories that were shown */
|
|
57
|
+
categories?: SuggestionCategory[];
|
|
58
|
+
/** Brands that were shown */
|
|
59
|
+
brands?: PopularBrand[];
|
|
60
|
+
/** Original query */
|
|
61
|
+
query: string;
|
|
62
|
+
/** Timestamp when impressions occurred */
|
|
63
|
+
timestamp: number;
|
|
64
|
+
}
|
|
65
|
+
export interface UseSuggestionsAnalyticsReturn {
|
|
66
|
+
/** Track a suggestion click */
|
|
67
|
+
trackSuggestionClick: (data: SuggestionClickEventData) => void;
|
|
68
|
+
/** Track a product click from suggestions dropdown */
|
|
69
|
+
trackProductClick: (data: ProductClickEventData) => void;
|
|
70
|
+
/** Track a category click */
|
|
71
|
+
trackCategoryClick: (category: SuggestionCategory, query?: string) => void;
|
|
72
|
+
/** Track a brand click */
|
|
73
|
+
trackBrandClick: (brand: PopularBrand, query?: string) => void;
|
|
74
|
+
/** Track a tab selection */
|
|
75
|
+
trackTabSelect: (tab: FilteredTab, query?: string) => void;
|
|
76
|
+
/** Track recent search click */
|
|
77
|
+
trackRecentSearchClick: (search: RecentSearch) => void;
|
|
78
|
+
/** Track trending search click */
|
|
79
|
+
trackTrendingClick: (trending: TrendingSearch, position: number) => void;
|
|
80
|
+
/** Track suggestions impression */
|
|
81
|
+
trackImpression: (data: SuggestionImpressionEventData) => void;
|
|
82
|
+
/** Track search submission from suggestion */
|
|
83
|
+
trackSearchSubmit: (query: string, fromSuggestion: boolean, suggestion?: SuggestionItem) => void;
|
|
84
|
+
/** Track dropdown open */
|
|
85
|
+
trackDropdownOpen: (query: string) => void;
|
|
86
|
+
/** Track dropdown close */
|
|
87
|
+
trackDropdownClose: (query: string, selectedSuggestion?: string) => void;
|
|
88
|
+
}
|
|
89
|
+
export declare function useSuggestionsAnalytics(options: UseSuggestionsAnalyticsOptions): UseSuggestionsAnalyticsReturn;
|
|
90
|
+
export default useSuggestionsAnalytics;
|
|
91
|
+
//# sourceMappingURL=useSuggestionsAnalytics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSuggestionsAnalytics.d.ts","sourceRoot":"","sources":["../../src/hooks/useSuggestionsAnalytics.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Suggestions Analytics Hook
|
|
3
|
+
*
|
|
4
|
+
* Provides analytics tracking for query suggestions components:
|
|
5
|
+
* - Suggestion clicks/selections
|
|
6
|
+
* - Suggestion impressions
|
|
7
|
+
* - Product clicks from dropdown
|
|
8
|
+
* - Category/brand clicks
|
|
9
|
+
* - Search submissions from suggestions
|
|
10
|
+
*/
|
|
11
|
+
import { useCallback, useRef, useEffect } from 'react';
|
|
12
|
+
import { log } from '@seekora-ai/ui-sdk-core';
|
|
13
|
+
// ============================================================================
|
|
14
|
+
// Event Names
|
|
15
|
+
// ============================================================================
|
|
16
|
+
const EVENTS = {
|
|
17
|
+
SUGGESTION_CLICK: 'suggestions.click',
|
|
18
|
+
SUGGESTION_IMPRESSION: 'suggestions.impression',
|
|
19
|
+
PRODUCT_CLICK: 'suggestions.product_click',
|
|
20
|
+
CATEGORY_CLICK: 'suggestions.category_click',
|
|
21
|
+
BRAND_CLICK: 'suggestions.brand_click',
|
|
22
|
+
TAB_SELECT: 'suggestions.tab_select',
|
|
23
|
+
RECENT_CLICK: 'suggestions.recent_click',
|
|
24
|
+
TRENDING_CLICK: 'suggestions.trending_click',
|
|
25
|
+
SEARCH_SUBMIT: 'suggestions.search_submit',
|
|
26
|
+
DROPDOWN_OPEN: 'suggestions.dropdown_open',
|
|
27
|
+
DROPDOWN_CLOSE: 'suggestions.dropdown_close',
|
|
28
|
+
};
|
|
29
|
+
// ============================================================================
|
|
30
|
+
// Hook Implementation
|
|
31
|
+
// ============================================================================
|
|
32
|
+
export function useSuggestionsAnalytics(options) {
|
|
33
|
+
const { client, enabled = true, analyticsTags = [], impressionDebounce = 500, trackImpressions = true, trackClicks = true, } = options;
|
|
34
|
+
// Refs for debouncing and tracking
|
|
35
|
+
const impressionTimerRef = useRef(null);
|
|
36
|
+
const lastImpressionRef = useRef(null);
|
|
37
|
+
const dropdownOpenTimeRef = useRef(null);
|
|
38
|
+
// Cleanup on unmount
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
return () => {
|
|
41
|
+
if (impressionTimerRef.current) {
|
|
42
|
+
clearTimeout(impressionTimerRef.current);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
}, []);
|
|
46
|
+
// Helper to send event
|
|
47
|
+
const sendEvent = useCallback(async (eventName, metadata) => {
|
|
48
|
+
if (!enabled || !client)
|
|
49
|
+
return;
|
|
50
|
+
try {
|
|
51
|
+
await client.trackEvent?.({
|
|
52
|
+
event_name: eventName,
|
|
53
|
+
analytics_tags: analyticsTags,
|
|
54
|
+
metadata: {
|
|
55
|
+
...metadata,
|
|
56
|
+
timestamp: Date.now(),
|
|
57
|
+
source: 'suggestions_dropdown',
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
log.verbose(`Analytics: ${eventName}`, metadata);
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
log.warn(`Failed to track ${eventName}`, { error });
|
|
64
|
+
}
|
|
65
|
+
}, [client, enabled, analyticsTags]);
|
|
66
|
+
// Track suggestion click
|
|
67
|
+
const trackSuggestionClick = useCallback((data) => {
|
|
68
|
+
if (!trackClicks)
|
|
69
|
+
return;
|
|
70
|
+
sendEvent(EVENTS.SUGGESTION_CLICK, {
|
|
71
|
+
suggestion_query: data.suggestion.query,
|
|
72
|
+
suggestion_id: data.suggestion.objectID,
|
|
73
|
+
suggestion_popularity: data.suggestion.popularity,
|
|
74
|
+
position: data.position,
|
|
75
|
+
section: data.section || 'suggestions',
|
|
76
|
+
original_query: data.query,
|
|
77
|
+
total_suggestions: data.totalSuggestions,
|
|
78
|
+
});
|
|
79
|
+
}, [sendEvent, trackClicks]);
|
|
80
|
+
// Track product click
|
|
81
|
+
const trackProductClick = useCallback((data) => {
|
|
82
|
+
if (!trackClicks)
|
|
83
|
+
return;
|
|
84
|
+
sendEvent(EVENTS.PRODUCT_CLICK, {
|
|
85
|
+
product_id: data.product.id || data.product.objectID,
|
|
86
|
+
product_title: data.product.title || data.product.name,
|
|
87
|
+
product_price: data.product.price,
|
|
88
|
+
position: data.position,
|
|
89
|
+
section: data.section || 'products',
|
|
90
|
+
tab_id: data.tabId,
|
|
91
|
+
original_query: data.query,
|
|
92
|
+
});
|
|
93
|
+
// Also track as a general product click for analytics
|
|
94
|
+
if (client) {
|
|
95
|
+
Promise.resolve(client.trackClick?.(data.product.id || data.product.objectID || '', data.position + 1)).catch(() => { });
|
|
96
|
+
}
|
|
97
|
+
}, [client, sendEvent, trackClicks]);
|
|
98
|
+
// Track category click
|
|
99
|
+
const trackCategoryClick = useCallback((category, query) => {
|
|
100
|
+
if (!trackClicks)
|
|
101
|
+
return;
|
|
102
|
+
sendEvent(EVENTS.CATEGORY_CLICK, {
|
|
103
|
+
category_value: category.value,
|
|
104
|
+
category_count: category.count,
|
|
105
|
+
category_path: category.path,
|
|
106
|
+
original_query: query,
|
|
107
|
+
});
|
|
108
|
+
}, [sendEvent, trackClicks]);
|
|
109
|
+
// Track brand click
|
|
110
|
+
const trackBrandClick = useCallback((brand, query) => {
|
|
111
|
+
if (!trackClicks)
|
|
112
|
+
return;
|
|
113
|
+
sendEvent(EVENTS.BRAND_CLICK, {
|
|
114
|
+
brand_name: brand.name,
|
|
115
|
+
brand_count: brand.count,
|
|
116
|
+
original_query: query,
|
|
117
|
+
});
|
|
118
|
+
}, [sendEvent, trackClicks]);
|
|
119
|
+
// Track tab selection
|
|
120
|
+
const trackTabSelect = useCallback((tab, query) => {
|
|
121
|
+
sendEvent(EVENTS.TAB_SELECT, {
|
|
122
|
+
tab_id: tab.id,
|
|
123
|
+
tab_label: tab.label,
|
|
124
|
+
tab_filter: tab.filter,
|
|
125
|
+
products_count: tab.products?.length || 0,
|
|
126
|
+
nb_hits: tab.nb_hits,
|
|
127
|
+
original_query: query,
|
|
128
|
+
});
|
|
129
|
+
}, [sendEvent]);
|
|
130
|
+
// Track recent search click
|
|
131
|
+
const trackRecentSearchClick = useCallback((search) => {
|
|
132
|
+
if (!trackClicks)
|
|
133
|
+
return;
|
|
134
|
+
sendEvent(EVENTS.RECENT_CLICK, {
|
|
135
|
+
query: search.query,
|
|
136
|
+
original_timestamp: search.timestamp,
|
|
137
|
+
results_count: search.resultsCount,
|
|
138
|
+
});
|
|
139
|
+
}, [sendEvent, trackClicks]);
|
|
140
|
+
// Track trending click
|
|
141
|
+
const trackTrendingClick = useCallback((trending, position) => {
|
|
142
|
+
if (!trackClicks)
|
|
143
|
+
return;
|
|
144
|
+
sendEvent(EVENTS.TRENDING_CLICK, {
|
|
145
|
+
query: trending.query,
|
|
146
|
+
count: trending.count,
|
|
147
|
+
trend_score: trending.trend_score,
|
|
148
|
+
position,
|
|
149
|
+
});
|
|
150
|
+
}, [sendEvent, trackClicks]);
|
|
151
|
+
// Track impression (debounced)
|
|
152
|
+
const trackImpression = useCallback((data) => {
|
|
153
|
+
if (!trackImpressions)
|
|
154
|
+
return;
|
|
155
|
+
// Create a hash of the impression to avoid duplicates
|
|
156
|
+
const impressionHash = `${data.query}:${data.suggestions.length}:${data.products?.length || 0}`;
|
|
157
|
+
if (impressionHash === lastImpressionRef.current)
|
|
158
|
+
return;
|
|
159
|
+
// Clear existing timer
|
|
160
|
+
if (impressionTimerRef.current) {
|
|
161
|
+
clearTimeout(impressionTimerRef.current);
|
|
162
|
+
}
|
|
163
|
+
// Debounce the impression
|
|
164
|
+
impressionTimerRef.current = setTimeout(() => {
|
|
165
|
+
lastImpressionRef.current = impressionHash;
|
|
166
|
+
sendEvent(EVENTS.SUGGESTION_IMPRESSION, {
|
|
167
|
+
query: data.query,
|
|
168
|
+
suggestions_count: data.suggestions.length,
|
|
169
|
+
suggestions: data.suggestions.slice(0, 10).map((s, i) => ({
|
|
170
|
+
query: s.query,
|
|
171
|
+
position: i,
|
|
172
|
+
popularity: s.popularity,
|
|
173
|
+
})),
|
|
174
|
+
products_count: data.products?.length || 0,
|
|
175
|
+
categories_count: data.categories?.length || 0,
|
|
176
|
+
brands_count: data.brands?.length || 0,
|
|
177
|
+
impression_timestamp: data.timestamp,
|
|
178
|
+
});
|
|
179
|
+
}, impressionDebounce);
|
|
180
|
+
}, [sendEvent, trackImpressions, impressionDebounce]);
|
|
181
|
+
// Track search submit
|
|
182
|
+
const trackSearchSubmit = useCallback((query, fromSuggestion, suggestion) => {
|
|
183
|
+
sendEvent(EVENTS.SEARCH_SUBMIT, {
|
|
184
|
+
query,
|
|
185
|
+
from_suggestion: fromSuggestion,
|
|
186
|
+
suggestion_query: suggestion?.query,
|
|
187
|
+
suggestion_id: suggestion?.objectID,
|
|
188
|
+
suggestion_popularity: suggestion?.popularity,
|
|
189
|
+
});
|
|
190
|
+
}, [sendEvent]);
|
|
191
|
+
// Track dropdown open
|
|
192
|
+
const trackDropdownOpen = useCallback((query) => {
|
|
193
|
+
dropdownOpenTimeRef.current = Date.now();
|
|
194
|
+
sendEvent(EVENTS.DROPDOWN_OPEN, {
|
|
195
|
+
query,
|
|
196
|
+
has_query: query.length > 0,
|
|
197
|
+
});
|
|
198
|
+
}, [sendEvent]);
|
|
199
|
+
// Track dropdown close
|
|
200
|
+
const trackDropdownClose = useCallback((query, selectedSuggestion) => {
|
|
201
|
+
const duration = dropdownOpenTimeRef.current
|
|
202
|
+
? Date.now() - dropdownOpenTimeRef.current
|
|
203
|
+
: null;
|
|
204
|
+
sendEvent(EVENTS.DROPDOWN_CLOSE, {
|
|
205
|
+
query,
|
|
206
|
+
selected_suggestion: selectedSuggestion,
|
|
207
|
+
had_selection: !!selectedSuggestion,
|
|
208
|
+
duration_ms: duration,
|
|
209
|
+
});
|
|
210
|
+
dropdownOpenTimeRef.current = null;
|
|
211
|
+
}, [sendEvent]);
|
|
212
|
+
return {
|
|
213
|
+
trackSuggestionClick,
|
|
214
|
+
trackProductClick,
|
|
215
|
+
trackCategoryClick,
|
|
216
|
+
trackBrandClick,
|
|
217
|
+
trackTabSelect,
|
|
218
|
+
trackRecentSearchClick,
|
|
219
|
+
trackTrendingClick,
|
|
220
|
+
trackImpression,
|
|
221
|
+
trackSearchSubmit,
|
|
222
|
+
trackDropdownOpen,
|
|
223
|
+
trackDropdownClose,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
export default useSuggestionsAnalytics;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Seekora UI SDK
|
|
3
|
+
*
|
|
4
|
+
* Main entry point for the UI Components Library
|
|
5
|
+
*/
|
|
6
|
+
export { SearchBar } from './components/SearchBar';
|
|
7
|
+
export { SearchResults } from './components/SearchResults';
|
|
8
|
+
export { SearchProvider, useSearchContext } from './components/SearchProvider';
|
|
9
|
+
export { Stats } from './components/Stats';
|
|
10
|
+
export { Pagination } from './components/Pagination';
|
|
11
|
+
export { SortBy } from './components/SortBy';
|
|
12
|
+
export { Facets } from './components/Facets';
|
|
13
|
+
export { CurrentRefinements } from './components/CurrentRefinements';
|
|
14
|
+
export { ClearRefinements } from './components/ClearRefinements';
|
|
15
|
+
export { SearchLayout } from './components/SearchLayout';
|
|
16
|
+
export { RangeInput } from './components/RangeInput';
|
|
17
|
+
export { HitsPerPage } from './components/HitsPerPage';
|
|
18
|
+
export { InfiniteHits } from './components/InfiniteHits';
|
|
19
|
+
export { Highlight, Snippet } from './components/Highlight';
|
|
20
|
+
export { HierarchicalMenu } from './components/HierarchicalMenu';
|
|
21
|
+
export { RangeSlider } from './components/RangeSlider';
|
|
22
|
+
export { Breadcrumb } from './components/Breadcrumb';
|
|
23
|
+
export { MobileFilters, MobileFiltersButton } from './components/MobileFilters';
|
|
24
|
+
export { RelatedProducts, TrendingItems, FrequentlyBoughtTogether, RecentlyViewed, addToRecentlyViewed, } from './components/Recommendations';
|
|
25
|
+
export { QuerySuggestions } from './components/QuerySuggestions';
|
|
26
|
+
export { QuerySuggestionsDropdown } from './components/QuerySuggestionsDropdown';
|
|
27
|
+
export { RichQuerySuggestions } from './components/RichQuerySuggestions';
|
|
28
|
+
export { FederatedDropdown } from './components/FederatedDropdown';
|
|
29
|
+
export { SearchBarWithSuggestions } from './components/SearchBarWithSuggestions';
|
|
30
|
+
export { SuggestionSearchBar, // All-in-one: input + dropdown + data fetching
|
|
31
|
+
type SuggestionSearchBarProps, type SuggestionSearchBarRef, } from './components/suggestions';
|
|
32
|
+
export { AmazonDropdown, // Amazon-style with department scoping
|
|
33
|
+
GoogleDropdown, // Google-style clean search
|
|
34
|
+
PinterestDropdown, // Visual discovery style
|
|
35
|
+
SpotlightDropdown, // macOS Spotlight / Command palette
|
|
36
|
+
ShopifyDropdown, // Modern e-commerce
|
|
37
|
+
MobileSheetDropdown, // Mobile-first bottom sheet
|
|
38
|
+
MinimalDropdown, // Ultra-clean editorial style
|
|
39
|
+
SuggestionDropdownVariants, type SuggestionDropdownVariant, type BaseDropdownProps, type DropdownRef, type SuggestionFieldMapping, type ProductFieldMapping, type CategoryFieldMapping, type BrandFieldMapping, type SectionConfig, type ProductDisplayConfig, type SuggestionDisplayConfig, type DropdownThemeConfig, type AnalyticsConfig, type DropdownEventHandlers, type DropdownClassNames, extractSuggestion, extractProduct, extractCategory, extractBrand, formatPrice as formatSuggestionPrice, highlightText, getRecentSearches, addRecentSearch, removeRecentSearch, clearRecentSearches, useResponsive, breakpoints, mediaQueries, touchTargets, injectGlobalResponsiveStyles, useInjectResponsiveStyles, type ResponsiveState, } from './components/suggestions';
|
|
40
|
+
export { useSeekoraSearch } from './hooks/useSeekoraSearch';
|
|
41
|
+
export { useQuerySuggestions } from './hooks/useQuerySuggestions';
|
|
42
|
+
export { useQuerySuggestionsEnhanced } from './hooks/useQuerySuggestionsEnhanced';
|
|
43
|
+
export { useSuggestionsAnalytics } from './hooks/useSuggestionsAnalytics';
|
|
44
|
+
export { useAnalytics } from './hooks/useAnalytics';
|
|
45
|
+
export { useSearchState } from './hooks/useSearchState';
|
|
46
|
+
export { useSmartSuggestions } from './hooks/useSmartSuggestions';
|
|
47
|
+
export { useNaturalLanguageFilters, formatParsedFilters } from './hooks/useNaturalLanguageFilters';
|
|
48
|
+
export type { SearchBarProps, SearchBarTheme, } from './components/SearchBar';
|
|
49
|
+
export type { SearchResultsProps, SearchResultsTheme } from './components/SearchResults';
|
|
50
|
+
export type { ResultItem, FieldMapping, ViewMode } from '@seekora-ai/ui-sdk-types';
|
|
51
|
+
export type { QuerySuggestionsProps, QuerySuggestionsTheme, SuggestionItem, } from './components/QuerySuggestions';
|
|
52
|
+
export type { QuerySuggestionsDropdownProps, QuerySuggestionsDropdownRef, } from './components/QuerySuggestionsDropdown';
|
|
53
|
+
export type { RichQuerySuggestionsProps, RichQuerySuggestionsRef, } from './components/RichQuerySuggestions';
|
|
54
|
+
export type { FederatedDropdownProps, FederatedDropdownRef, } from './components/FederatedDropdown';
|
|
55
|
+
export type { SearchBarWithSuggestionsProps, SearchBarWithSuggestionsRef, } from './components/SearchBarWithSuggestions';
|
|
56
|
+
export type { SearchProviderProps, } from './components/SearchProvider';
|
|
57
|
+
export type { ClearRefinementsProps, ClearRefinementsTheme, } from './components/ClearRefinements';
|
|
58
|
+
export type { HitsPerPageProps, HitsPerPageTheme, HitsPerPageItem, } from './components/HitsPerPage';
|
|
59
|
+
export type { InfiniteHitsProps, InfiniteHitsTheme, } from './components/InfiniteHits';
|
|
60
|
+
export type { HighlightProps, HighlightTheme, SnippetProps, SnippetTheme, } from './components/Highlight';
|
|
61
|
+
export type { HierarchicalMenuProps, HierarchicalMenuTheme, HierarchicalMenuItem, } from './components/HierarchicalMenu';
|
|
62
|
+
export type { RangeSliderProps, RangeSliderTheme, } from './components/RangeSlider';
|
|
63
|
+
export type { BreadcrumbProps, BreadcrumbTheme, BreadcrumbItem, } from './components/Breadcrumb';
|
|
64
|
+
export type { MobileFiltersProps, MobileFiltersTheme, MobileFiltersButtonProps, } from './components/MobileFilters';
|
|
65
|
+
export type { RelatedProductsProps, TrendingItemsProps, FrequentlyBoughtTogetherProps, RecentlyViewedProps, RecommendationItem, RecommendationTheme, } from './components/Recommendations';
|
|
66
|
+
export type { UseQuerySuggestionsEnhancedOptions, UseQuerySuggestionsEnhancedReturn, NavigableItem, } from './hooks/useQuerySuggestionsEnhanced';
|
|
67
|
+
export type { UseSuggestionsAnalyticsOptions, UseSuggestionsAnalyticsReturn, SuggestionClickEventData, ProductClickEventData, SuggestionImpressionEventData, } from './hooks/useSuggestionsAnalytics';
|
|
68
|
+
export type { SmartSuggestion, SmartSuggestionsOptions, UseSmartSuggestionsReturn, } from './hooks/useSmartSuggestions';
|
|
69
|
+
export type { ParsedFilter, NaturalLanguageResult, NaturalLanguageFiltersOptions, } from './hooks/useNaturalLanguageFilters';
|
|
70
|
+
export type { Theme, ThemeConfig, } from './themes/types';
|
|
71
|
+
export { defaultTheme } from './themes/default';
|
|
72
|
+
export { darkTheme } from './themes/dark';
|
|
73
|
+
export { minimalTheme } from './themes/minimal';
|
|
74
|
+
export { lightThemeVariables, darkThemeVariables, minimalThemeVariables, brandPresets, createSuggestionsTheme, generateSuggestionsStylesheet, injectSuggestionsStyles, updateSuggestionsStyles, } from './themes/suggestions';
|
|
75
|
+
export type { SuggestionsThemeVariables } from './themes/suggestions';
|
|
76
|
+
export { createTheme } from './themes/createTheme';
|
|
77
|
+
export { mergeThemes } from './themes/mergeThemes';
|
|
78
|
+
export { getSuggestionsCache, createSuggestionsCache, clearSuggestionsCache, } from './components/suggestions/utils';
|
|
79
|
+
export type { SuggestionsCache } from './components/suggestions/utils';
|
|
80
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|