@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.
Files changed (169) hide show
  1. package/dist/components/Breadcrumb.d.ts +43 -0
  2. package/dist/components/Breadcrumb.d.ts.map +1 -0
  3. package/dist/components/Breadcrumb.js +119 -0
  4. package/dist/components/ClearRefinements.d.ts +42 -0
  5. package/dist/components/ClearRefinements.d.ts.map +1 -0
  6. package/dist/components/ClearRefinements.js +80 -0
  7. package/dist/components/CurrentRefinements.d.ts +41 -0
  8. package/dist/components/CurrentRefinements.d.ts.map +1 -0
  9. package/dist/components/CurrentRefinements.js +83 -0
  10. package/dist/components/Facets.d.ts +53 -0
  11. package/dist/components/Facets.d.ts.map +1 -0
  12. package/dist/components/Facets.js +195 -0
  13. package/dist/components/FederatedDropdown.d.ts +92 -0
  14. package/dist/components/FederatedDropdown.d.ts.map +1 -0
  15. package/dist/components/FederatedDropdown.js +510 -0
  16. package/dist/components/HierarchicalMenu.d.ts +55 -0
  17. package/dist/components/HierarchicalMenu.d.ts.map +1 -0
  18. package/dist/components/HierarchicalMenu.js +168 -0
  19. package/dist/components/Highlight.d.ts +51 -0
  20. package/dist/components/Highlight.d.ts.map +1 -0
  21. package/dist/components/Highlight.js +155 -0
  22. package/dist/components/HitsPerPage.d.ts +41 -0
  23. package/dist/components/HitsPerPage.d.ts.map +1 -0
  24. package/dist/components/HitsPerPage.js +72 -0
  25. package/dist/components/InfiniteHits.d.ts +56 -0
  26. package/dist/components/InfiniteHits.d.ts.map +1 -0
  27. package/dist/components/InfiniteHits.js +181 -0
  28. package/dist/components/MobileFilters.d.ts +71 -0
  29. package/dist/components/MobileFilters.d.ts.map +1 -0
  30. package/dist/components/MobileFilters.js +242 -0
  31. package/dist/components/Pagination.d.ts +44 -0
  32. package/dist/components/Pagination.d.ts.map +1 -0
  33. package/dist/components/Pagination.js +142 -0
  34. package/dist/components/QuerySuggestions.d.ts +38 -0
  35. package/dist/components/QuerySuggestions.d.ts.map +1 -0
  36. package/dist/components/QuerySuggestions.js +86 -0
  37. package/dist/components/QuerySuggestionsDropdown.d.ts +86 -0
  38. package/dist/components/QuerySuggestionsDropdown.d.ts.map +1 -0
  39. package/dist/components/QuerySuggestionsDropdown.js +395 -0
  40. package/dist/components/RangeInput.d.ts +58 -0
  41. package/dist/components/RangeInput.d.ts.map +1 -0
  42. package/dist/components/RangeInput.js +203 -0
  43. package/dist/components/RangeSlider.d.ts +51 -0
  44. package/dist/components/RangeSlider.d.ts.map +1 -0
  45. package/dist/components/RangeSlider.js +193 -0
  46. package/dist/components/Recommendations.d.ts +90 -0
  47. package/dist/components/Recommendations.d.ts.map +1 -0
  48. package/dist/components/Recommendations.js +270 -0
  49. package/dist/components/RichQuerySuggestions.d.ts +77 -0
  50. package/dist/components/RichQuerySuggestions.d.ts.map +1 -0
  51. package/dist/components/RichQuerySuggestions.js +492 -0
  52. package/dist/components/SearchBar.d.ts +40 -0
  53. package/dist/components/SearchBar.d.ts.map +1 -0
  54. package/dist/components/SearchBar.js +217 -0
  55. package/dist/components/SearchBarWithSuggestions.d.ts +99 -0
  56. package/dist/components/SearchBarWithSuggestions.d.ts.map +1 -0
  57. package/dist/components/SearchBarWithSuggestions.js +275 -0
  58. package/dist/components/SearchLayout.d.ts +35 -0
  59. package/dist/components/SearchLayout.d.ts.map +1 -0
  60. package/dist/components/SearchLayout.js +56 -0
  61. package/dist/components/SearchProvider.d.ts +28 -0
  62. package/dist/components/SearchProvider.d.ts.map +1 -0
  63. package/dist/components/SearchProvider.js +43 -0
  64. package/dist/components/SearchResults.d.ts +51 -0
  65. package/dist/components/SearchResults.d.ts.map +1 -0
  66. package/dist/components/SearchResults.js +485 -0
  67. package/dist/components/SortBy.d.ts +44 -0
  68. package/dist/components/SortBy.d.ts.map +1 -0
  69. package/dist/components/SortBy.js +61 -0
  70. package/dist/components/Stats.d.ts +37 -0
  71. package/dist/components/Stats.d.ts.map +1 -0
  72. package/dist/components/Stats.js +52 -0
  73. package/dist/components/suggestions/AmazonDropdown.d.ts +30 -0
  74. package/dist/components/suggestions/AmazonDropdown.d.ts.map +1 -0
  75. package/dist/components/suggestions/AmazonDropdown.js +529 -0
  76. package/dist/components/suggestions/GoogleDropdown.d.ts +31 -0
  77. package/dist/components/suggestions/GoogleDropdown.d.ts.map +1 -0
  78. package/dist/components/suggestions/GoogleDropdown.js +370 -0
  79. package/dist/components/suggestions/MinimalDropdown.d.ts +24 -0
  80. package/dist/components/suggestions/MinimalDropdown.d.ts.map +1 -0
  81. package/dist/components/suggestions/MinimalDropdown.js +314 -0
  82. package/dist/components/suggestions/MobileSheetDropdown.d.ts +31 -0
  83. package/dist/components/suggestions/MobileSheetDropdown.d.ts.map +1 -0
  84. package/dist/components/suggestions/MobileSheetDropdown.js +485 -0
  85. package/dist/components/suggestions/PinterestDropdown.d.ts +29 -0
  86. package/dist/components/suggestions/PinterestDropdown.d.ts.map +1 -0
  87. package/dist/components/suggestions/PinterestDropdown.js +450 -0
  88. package/dist/components/suggestions/ShopifyDropdown.d.ts +27 -0
  89. package/dist/components/suggestions/ShopifyDropdown.d.ts.map +1 -0
  90. package/dist/components/suggestions/ShopifyDropdown.js +451 -0
  91. package/dist/components/suggestions/SpotlightDropdown.d.ts +33 -0
  92. package/dist/components/suggestions/SpotlightDropdown.d.ts.map +1 -0
  93. package/dist/components/suggestions/SpotlightDropdown.js +547 -0
  94. package/dist/components/suggestions/SuggestionSearchBar.d.ts +123 -0
  95. package/dist/components/suggestions/SuggestionSearchBar.d.ts.map +1 -0
  96. package/dist/components/suggestions/SuggestionSearchBar.js +652 -0
  97. package/dist/components/suggestions/index.d.ts +37 -0
  98. package/dist/components/suggestions/index.d.ts.map +1 -0
  99. package/dist/components/suggestions/index.js +59 -0
  100. package/dist/components/suggestions/styles/index.d.ts +11 -0
  101. package/dist/components/suggestions/styles/index.d.ts.map +1 -0
  102. package/dist/components/suggestions/styles/index.js +289 -0
  103. package/dist/components/suggestions/styles/responsive.d.ts +107 -0
  104. package/dist/components/suggestions/styles/responsive.d.ts.map +1 -0
  105. package/dist/components/suggestions/styles/responsive.js +237 -0
  106. package/dist/components/suggestions/types.d.ts +489 -0
  107. package/dist/components/suggestions/types.d.ts.map +1 -0
  108. package/dist/components/suggestions/types.js +6 -0
  109. package/dist/components/suggestions/utils.d.ts +213 -0
  110. package/dist/components/suggestions/utils.d.ts.map +1 -0
  111. package/dist/components/suggestions/utils.js +514 -0
  112. package/dist/hooks/useAnalytics.d.ts +20 -0
  113. package/dist/hooks/useAnalytics.d.ts.map +1 -0
  114. package/dist/hooks/useAnalytics.js +62 -0
  115. package/dist/hooks/useNaturalLanguageFilters.d.ts +48 -0
  116. package/dist/hooks/useNaturalLanguageFilters.d.ts.map +1 -0
  117. package/dist/hooks/useNaturalLanguageFilters.js +221 -0
  118. package/dist/hooks/useQuerySuggestions.d.ts +21 -0
  119. package/dist/hooks/useQuerySuggestions.d.ts.map +1 -0
  120. package/dist/hooks/useQuerySuggestions.js +68 -0
  121. package/dist/hooks/useQuerySuggestionsEnhanced.d.ts +114 -0
  122. package/dist/hooks/useQuerySuggestionsEnhanced.d.ts.map +1 -0
  123. package/dist/hooks/useQuerySuggestionsEnhanced.js +376 -0
  124. package/dist/hooks/useSearchState.d.ts +35 -0
  125. package/dist/hooks/useSearchState.d.ts.map +1 -0
  126. package/dist/hooks/useSearchState.js +68 -0
  127. package/dist/hooks/useSeekoraSearch.d.ts +20 -0
  128. package/dist/hooks/useSeekoraSearch.d.ts.map +1 -0
  129. package/dist/hooks/useSeekoraSearch.js +63 -0
  130. package/dist/hooks/useSmartSuggestions.d.ts +55 -0
  131. package/dist/hooks/useSmartSuggestions.d.ts.map +1 -0
  132. package/dist/hooks/useSmartSuggestions.js +236 -0
  133. package/dist/hooks/useSuggestionsAnalytics.d.ts +91 -0
  134. package/dist/hooks/useSuggestionsAnalytics.d.ts.map +1 -0
  135. package/dist/hooks/useSuggestionsAnalytics.js +226 -0
  136. package/dist/index.d.ts +80 -0
  137. package/dist/index.d.ts.map +1 -0
  138. package/dist/index.js +86 -0
  139. package/dist/index.umd.js +1 -0
  140. package/dist/src/index.d.ts +2849 -0
  141. package/dist/src/index.esm.js +11679 -0
  142. package/dist/src/index.esm.js.map +1 -0
  143. package/dist/src/index.js +11761 -0
  144. package/dist/src/index.js.map +1 -0
  145. package/dist/themes/createTheme.d.ts +8 -0
  146. package/dist/themes/createTheme.d.ts.map +1 -0
  147. package/dist/themes/createTheme.js +10 -0
  148. package/dist/themes/dark.d.ts +6 -0
  149. package/dist/themes/dark.d.ts.map +1 -0
  150. package/dist/themes/dark.js +34 -0
  151. package/dist/themes/default.d.ts +6 -0
  152. package/dist/themes/default.d.ts.map +1 -0
  153. package/dist/themes/default.js +71 -0
  154. package/dist/themes/mergeThemes.d.ts +7 -0
  155. package/dist/themes/mergeThemes.d.ts.map +1 -0
  156. package/dist/themes/mergeThemes.js +6 -0
  157. package/dist/themes/minimal.d.ts +6 -0
  158. package/dist/themes/minimal.d.ts.map +1 -0
  159. package/dist/themes/minimal.js +34 -0
  160. package/dist/themes/suggestions.d.ts +216 -0
  161. package/dist/themes/suggestions.d.ts.map +1 -0
  162. package/dist/themes/suggestions.js +546 -0
  163. package/dist/themes/types.d.ts +7 -0
  164. package/dist/themes/types.d.ts.map +1 -0
  165. package/dist/themes/types.js +6 -0
  166. package/dist/types/index.d.ts +33 -0
  167. package/dist/types/index.d.ts.map +1 -0
  168. package/dist/types/index.js +4 -0
  169. 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;
@@ -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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"}