@searchspring/snap-preact-components 0.39.3 → 0.41.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 (79) hide show
  1. package/dist/cjs/components/Molecules/Carousel/Carousel.d.ts +2 -1
  2. package/dist/cjs/components/Molecules/Carousel/Carousel.d.ts.map +1 -1
  3. package/dist/cjs/components/Molecules/Carousel/Carousel.js +13 -2
  4. package/dist/cjs/components/Molecules/Carousel/Carousel.stories.js +3 -3
  5. package/dist/cjs/components/Molecules/Slideout/Slideout.d.ts +1 -0
  6. package/dist/cjs/components/Molecules/Slideout/Slideout.d.ts.map +1 -1
  7. package/dist/cjs/components/Molecules/Slideout/Slideout.js +4 -31
  8. package/dist/cjs/components/Molecules/Slideout/Slideout.stories.d.ts +14 -0
  9. package/dist/cjs/components/Molecules/Slideout/Slideout.stories.d.ts.map +1 -1
  10. package/dist/cjs/components/Molecules/Slideout/Slideout.stories.js +9 -0
  11. package/dist/cjs/components/Organisms/Autocomplete/Autocomplete.d.ts +7 -2
  12. package/dist/cjs/components/Organisms/Autocomplete/Autocomplete.d.ts.map +1 -1
  13. package/dist/cjs/components/Organisms/Autocomplete/Autocomplete.js +81 -27
  14. package/dist/cjs/components/Organisms/Autocomplete/Autocomplete.stories.d.ts +75 -0
  15. package/dist/cjs/components/Organisms/Autocomplete/Autocomplete.stories.d.ts.map +1 -1
  16. package/dist/cjs/components/Organisms/Autocomplete/Autocomplete.stories.js +51 -1
  17. package/dist/cjs/components/Organisms/Recommendation/Recommendation.d.ts.map +1 -1
  18. package/dist/cjs/components/Organisms/Recommendation/Recommendation.js +10 -48
  19. package/dist/cjs/components/Trackers/Recommendation/ProfileTracker/RecommendationProfileTracker.d.ts +10 -0
  20. package/dist/cjs/components/Trackers/Recommendation/ProfileTracker/RecommendationProfileTracker.d.ts.map +1 -0
  21. package/dist/cjs/components/Trackers/Recommendation/ProfileTracker/RecommendationProfileTracker.js +51 -0
  22. package/dist/cjs/components/Trackers/Recommendation/ProfileTracker/RecommendationProfileTracker.stories.d.ts +94 -0
  23. package/dist/cjs/components/Trackers/Recommendation/ProfileTracker/RecommendationProfileTracker.stories.d.ts.map +1 -0
  24. package/dist/cjs/components/Trackers/Recommendation/ProfileTracker/RecommendationProfileTracker.stories.js +106 -0
  25. package/dist/cjs/components/Trackers/Recommendation/ProfileTracker/index.d.ts +2 -0
  26. package/dist/cjs/components/Trackers/Recommendation/ProfileTracker/index.d.ts.map +1 -0
  27. package/dist/cjs/components/Trackers/Recommendation/ProfileTracker/index.js +17 -0
  28. package/dist/cjs/components/Trackers/Recommendation/ResultTracker/RecommendationResultTracker.d.ts +12 -0
  29. package/dist/cjs/components/Trackers/Recommendation/ResultTracker/RecommendationResultTracker.d.ts.map +1 -0
  30. package/dist/cjs/components/Trackers/Recommendation/ResultTracker/RecommendationResultTracker.js +54 -0
  31. package/dist/cjs/components/Trackers/Recommendation/ResultTracker/RecommendationResultTracker.stories.d.ts +109 -0
  32. package/dist/cjs/components/Trackers/Recommendation/ResultTracker/RecommendationResultTracker.stories.d.ts.map +1 -0
  33. package/dist/cjs/components/Trackers/Recommendation/ResultTracker/RecommendationResultTracker.stories.js +116 -0
  34. package/dist/cjs/components/Trackers/Recommendation/ResultTracker/index.d.ts +2 -0
  35. package/dist/cjs/components/Trackers/Recommendation/ResultTracker/index.d.ts.map +1 -0
  36. package/dist/cjs/components/Trackers/Recommendation/ResultTracker/index.js +17 -0
  37. package/dist/cjs/index.d.ts +2 -0
  38. package/dist/cjs/index.d.ts.map +1 -1
  39. package/dist/cjs/index.js +2 -0
  40. package/dist/esm/components/Molecules/Carousel/Carousel.d.ts +2 -1
  41. package/dist/esm/components/Molecules/Carousel/Carousel.d.ts.map +1 -1
  42. package/dist/esm/components/Molecules/Carousel/Carousel.js +16 -2
  43. package/dist/esm/components/Molecules/Carousel/Carousel.stories.js +3 -3
  44. package/dist/esm/components/Molecules/Slideout/Slideout.d.ts +1 -0
  45. package/dist/esm/components/Molecules/Slideout/Slideout.d.ts.map +1 -1
  46. package/dist/esm/components/Molecules/Slideout/Slideout.js +4 -31
  47. package/dist/esm/components/Molecules/Slideout/Slideout.stories.d.ts +14 -0
  48. package/dist/esm/components/Molecules/Slideout/Slideout.stories.d.ts.map +1 -1
  49. package/dist/esm/components/Molecules/Slideout/Slideout.stories.js +10 -0
  50. package/dist/esm/components/Organisms/Autocomplete/Autocomplete.d.ts +7 -2
  51. package/dist/esm/components/Organisms/Autocomplete/Autocomplete.d.ts.map +1 -1
  52. package/dist/esm/components/Organisms/Autocomplete/Autocomplete.js +80 -25
  53. package/dist/esm/components/Organisms/Autocomplete/Autocomplete.stories.d.ts +75 -0
  54. package/dist/esm/components/Organisms/Autocomplete/Autocomplete.stories.d.ts.map +1 -1
  55. package/dist/esm/components/Organisms/Autocomplete/Autocomplete.stories.js +56 -1
  56. package/dist/esm/components/Organisms/Recommendation/Recommendation.d.ts.map +1 -1
  57. package/dist/esm/components/Organisms/Recommendation/Recommendation.js +9 -47
  58. package/dist/esm/components/Trackers/Recommendation/ProfileTracker/RecommendationProfileTracker.d.ts +10 -0
  59. package/dist/esm/components/Trackers/Recommendation/ProfileTracker/RecommendationProfileTracker.d.ts.map +1 -0
  60. package/dist/esm/components/Trackers/Recommendation/ProfileTracker/RecommendationProfileTracker.js +40 -0
  61. package/dist/esm/components/Trackers/Recommendation/ProfileTracker/RecommendationProfileTracker.stories.d.ts +94 -0
  62. package/dist/esm/components/Trackers/Recommendation/ProfileTracker/RecommendationProfileTracker.stories.d.ts.map +1 -0
  63. package/dist/esm/components/Trackers/Recommendation/ProfileTracker/RecommendationProfileTracker.stories.js +48 -0
  64. package/dist/esm/components/Trackers/Recommendation/ProfileTracker/index.d.ts +2 -0
  65. package/dist/esm/components/Trackers/Recommendation/ProfileTracker/index.d.ts.map +1 -0
  66. package/dist/esm/components/Trackers/Recommendation/ProfileTracker/index.js +1 -0
  67. package/dist/esm/components/Trackers/Recommendation/ResultTracker/RecommendationResultTracker.d.ts +12 -0
  68. package/dist/esm/components/Trackers/Recommendation/ResultTracker/RecommendationResultTracker.d.ts.map +1 -0
  69. package/dist/esm/components/Trackers/Recommendation/ResultTracker/RecommendationResultTracker.js +43 -0
  70. package/dist/esm/components/Trackers/Recommendation/ResultTracker/RecommendationResultTracker.stories.d.ts +109 -0
  71. package/dist/esm/components/Trackers/Recommendation/ResultTracker/RecommendationResultTracker.stories.d.ts.map +1 -0
  72. package/dist/esm/components/Trackers/Recommendation/ResultTracker/RecommendationResultTracker.stories.js +58 -0
  73. package/dist/esm/components/Trackers/Recommendation/ResultTracker/index.d.ts +2 -0
  74. package/dist/esm/components/Trackers/Recommendation/ResultTracker/index.d.ts.map +1 -0
  75. package/dist/esm/components/Trackers/Recommendation/ResultTracker/index.js +1 -0
  76. package/dist/esm/index.d.ts +2 -0
  77. package/dist/esm/index.d.ts.map +1 -1
  78. package/dist/esm/index.js +2 -0
  79. package/package.json +11 -11
@@ -33,7 +33,7 @@ const CSS = {
33
33
  '&.ss__autocomplete--only-terms': {
34
34
  width: `${vertical || horizontalTerms || contentSlotExists ? width : '150px'}`,
35
35
  },
36
- '.ss__autocomplete__title--trending': {
36
+ '.ss__autocomplete__title--trending, .ss__autocomplete__title--history, .ss__autocomplete__title--terms': {
37
37
  fontWeight: 'normal',
38
38
  margin: 0,
39
39
  color: '#c5c5c5',
@@ -48,6 +48,8 @@ const CSS = {
48
48
  order: vertical ? 2 : undefined,
49
49
  },
50
50
  '& .ss__autocomplete__terms': {
51
+ display: 'flex',
52
+ flexDirection: 'column',
51
53
  flex: `1 1 auto`,
52
54
  maxWidth: `${vertical || horizontalTerms ? 'auto' : '150px'}`,
53
55
  order: 1,
@@ -136,6 +138,7 @@ export const Autocomplete = observer((properties) => {
136
138
  // default props
137
139
  termsTitle: '',
138
140
  trendingTitle: 'Popular Searches',
141
+ historyTitle: 'Previously Searched',
139
142
  facetsTitle: '',
140
143
  contentTitle: '',
141
144
  width: '100%',
@@ -152,11 +155,15 @@ export const Autocomplete = observer((properties) => {
152
155
  rows: 1,
153
156
  hideFacets: props.hideFacets || true,
154
157
  vertical: props.vertical || true,
158
+ hideHistory: props.hideHistory || true,
159
+ hideTrending: props.hideTrending || true,
155
160
  },
156
161
  540: {
157
162
  columns: 3,
158
163
  rows: 1,
159
164
  vertical: props.vertical || true,
165
+ hideHistory: props.hideHistory || true,
166
+ hideTrending: props.hideTrending || true,
160
167
  },
161
168
  768: {
162
169
  columns: 2,
@@ -176,6 +183,16 @@ export const Autocomplete = observer((properties) => {
176
183
  clearTimeout(delayTimeout);
177
184
  },
178
185
  };
186
+ const facetClickEvent = (e) => {
187
+ properties.onFacetOptionClick && properties.onFacetOptionClick(e);
188
+ // remove focus from input (close the autocomplete)
189
+ controller?.setFocused && controller?.setFocused();
190
+ };
191
+ const termClickEvent = (e) => {
192
+ properties.onTermClick && properties.onTermClick(e);
193
+ // remove focus from input (close the autocomplete)
194
+ controller?.setFocused && controller?.setFocused();
195
+ };
179
196
  const themeOverride = {
180
197
  components: {
181
198
  facet: {
@@ -187,21 +204,21 @@ export const Autocomplete = observer((properties) => {
187
204
  },
188
205
  facetGridOptions: {
189
206
  columns: 3,
190
- onClick: properties.onFacetOptionClick,
207
+ onClick: facetClickEvent,
191
208
  },
192
209
  facetHierarchyOptions: {
193
210
  hideCount: true,
194
- onClick: properties.onFacetOptionClick,
211
+ onClick: facetClickEvent,
195
212
  },
196
213
  facetListOptions: {
197
214
  hideCheckbox: true,
198
215
  hideCount: true,
199
- onClick: properties.onFacetOptionClick,
216
+ onClick: facetClickEvent,
200
217
  },
201
218
  facetPaletteOptions: {
202
219
  hideLabel: true,
203
220
  columns: 3,
204
- onClick: properties.onFacetOptionClick,
221
+ onClick: facetClickEvent,
205
222
  },
206
223
  result: {
207
224
  hideBadge: true,
@@ -224,7 +241,7 @@ export const Autocomplete = observer((properties) => {
224
241
  const rect = input?.getBoundingClientRect();
225
242
  inputViewportOffsetBottom = rect?.bottom || 0;
226
243
  }
227
- const { hideTerms, hideFacets, hideContent, hideBanners, hideLink, horizontalTerms, vertical, termsTitle, trendingTitle, facetsTitle, contentTitle, viewportMaxHeight, termsSlot, facetsSlot, contentSlot, resultsSlot, noResultsSlot, linkSlot, onTermClick, disableStyles, className, width, style, controller, } = props;
244
+ const { hideTerms, hideFacets, hideContent, hideBanners, hideLink, hideHistory, hideTrending, retainTrending, retainHistory, horizontalTerms, vertical, termsTitle, trendingTitle, historyTitle, facetsTitle, contentTitle, viewportMaxHeight, termsSlot, facetsSlot, contentSlot, resultsSlot, noResultsSlot, linkSlot, onTermClick, disableStyles, className, width, style, controller, } = props;
228
245
  const subProps = {
229
246
  facets: {
230
247
  // default props
@@ -278,6 +295,7 @@ export const Autocomplete = observer((properties) => {
278
295
  },
279
296
  };
280
297
  const { search, terms, trending, results, merchandising, pagination, loaded, filters, facets, state } = controller.store;
298
+ const history = controller.store.history || [];
281
299
  // you can pass in a selector or the actual input element,
282
300
  // if its the selector, we need to bind it to the controller here.
283
301
  if (controller && typeof input == 'string') {
@@ -287,17 +305,33 @@ export const Autocomplete = observer((properties) => {
287
305
  controller.bind();
288
306
  }, []);
289
307
  }
290
- const visible = Boolean(input === state.focusedInput) && (terms.length > 0 || trending?.length > 0 || (state.input && controller.store.loaded));
308
+ const visible = Boolean(input === state.focusedInput) &&
309
+ (terms.length > 0 || trending?.length > 0 || history?.length > 0 || (state.input && controller.store.loaded));
291
310
  let showTrending = false;
292
- if (!results.length && !state.input && trending?.length) {
311
+ if (trending?.length && (retainTrending || (!results.length && !state.input))) {
293
312
  showTrending = true;
294
313
  }
295
314
  else if (trending?.length && !terms.length) {
296
315
  // has results and trending -> show trending terms while term load
297
316
  showTrending = true;
298
317
  }
318
+ let showHistory = false;
319
+ if (history?.length && (retainHistory || (!results.length && !state.input))) {
320
+ showHistory = true;
321
+ }
322
+ else if (history?.length && !terms.length) {
323
+ // has results and trending -> show trending terms while term load
324
+ showHistory = true;
325
+ }
299
326
  const facetsToShow = facets.length ? facets.filter((facet) => facet.display !== FacetDisplay.SLIDER) : [];
300
- const onlyTerms = trending?.length && !loaded;
327
+ const onlyTerms = (trending?.length || history.length) && !loaded;
328
+ // results logic
329
+ let showResults = Boolean(results.length > 0 || Object.keys(merchandising.content).length > 0 || search?.query?.string);
330
+ const trendingActive = trending?.filter((term) => term.active).pop();
331
+ const historyActive = history?.filter((term) => term.active).pop();
332
+ if ((hideTrending && trendingActive) || (hideHistory && historyActive)) {
333
+ showResults = false;
334
+ }
301
335
  const styling = {};
302
336
  if (!disableStyles) {
303
337
  styling.css = [
@@ -320,21 +354,40 @@ export const Autocomplete = observer((properties) => {
320
354
  }
321
355
  return visible ? (jsx(CacheProvider, null,
322
356
  jsx("div", { ...styling, className: classnames('ss__autocomplete', className, { 'ss__autocomplete--only-terms': onlyTerms }), onClick: (e) => e.stopPropagation() },
323
- !hideTerms && (showTrending || terms.length > 0 || termsSlot) && (jsx("div", { className: classnames('ss__autocomplete__terms', { 'ss__autocomplete__terms-trending': showTrending }) }, termsSlot ? (cloneWithProps(termsSlot, { terms, trending, termsTitle, trendingTitle, showTrending, valueProps, emIfy, onTermClick, controller })) : (jsx(Fragment, null,
324
- terms.length > 0 ? (jsx(Fragment, null,
325
- termsTitle ? (jsx("div", { className: "ss__autocomplete__title ss__autocomplete__title--terms" },
357
+ !hideTerms && (showTrending || terms.length > 0 || termsSlot || (!hideHistory && history.length > 0)) && (jsx("div", { className: classnames('ss__autocomplete__terms', { 'ss__autocomplete__terms-trending': showTrending }) }, termsSlot ? (cloneWithProps(termsSlot, {
358
+ terms,
359
+ trending,
360
+ termsTitle,
361
+ trendingTitle,
362
+ showTrending,
363
+ history,
364
+ historyTitle,
365
+ valueProps,
366
+ emIfy,
367
+ onTermClick,
368
+ controller,
369
+ })) : (jsx(Fragment, null,
370
+ terms.length > 0 ? (jsx("div", { className: "ss__autocomplete__terms__suggestions" },
371
+ termsTitle ? (jsx("div", { className: "ss__autocomplete__title ss__autocomplete__title--terms ss__autocomplete__title--suggestions" },
326
372
  jsx("h5", null, termsTitle))) : null,
327
373
  jsx("div", { className: "ss__autocomplete__terms__options" }, terms.map((term) => (jsx("div", { className: classnames('ss__autocomplete__terms__option', {
328
374
  'ss__autocomplete__terms__option--active': term.active,
329
375
  }) },
330
- jsx("a", { onClick: (e) => onTermClick && onTermClick(e), href: term.url.href, ...valueProps, onFocus: () => term.preview() }, emIfy(term.value, state.input || '')))))))) : null,
331
- showTrending ? (jsx(Fragment, null,
376
+ jsx("a", { onClick: (e) => termClickEvent(e), href: term.url.href, ...valueProps, onFocus: () => term.preview() }, emIfy(term.value, state.input || '')))))))) : null,
377
+ showTrending && !hideTrending ? (jsx("div", { className: "ss__autocomplete__terms__trending" },
332
378
  trendingTitle ? (jsx("div", { className: "ss__autocomplete__title ss__autocomplete__title--trending" },
333
379
  jsx("h5", null, trendingTitle))) : null,
334
380
  jsx("div", { className: "ss__autocomplete__terms__options" }, trending.map((term) => (jsx("div", { className: classnames('ss__autocomplete__terms__option', {
335
381
  'ss__autocomplete__terms__option--active': term.active,
336
382
  }) },
337
- jsx("a", { onClick: (e) => onTermClick && onTermClick(e), href: term.url.href, ...valueProps, onFocus: () => term.preview() }, emIfy(term.value, state.input || '')))))))) : null)))),
383
+ jsx("a", { onClick: (e) => termClickEvent(e), href: term.url.href, ...valueProps, onFocus: () => term.preview() }, emIfy(term.value, state.input || '')))))))) : null,
384
+ showHistory && !hideHistory ? (jsx("div", { className: "ss__autocomplete__terms__history" },
385
+ historyTitle ? (jsx("div", { className: "ss__autocomplete__title ss__autocomplete__title--history" },
386
+ jsx("h5", null, historyTitle))) : null,
387
+ jsx("div", { className: "ss__autocomplete__terms__options" }, history.map((term) => (jsx("div", { className: classnames('ss__autocomplete__terms__option', {
388
+ 'ss__autocomplete__terms__option--active': term.active,
389
+ }) },
390
+ jsx("a", { onClick: (e) => termClickEvent(e), href: term.url.href, ...valueProps, onFocus: () => term.preview() }, emIfy(term.value, state.input || '')))))))) : null)))),
338
391
  !hideFacets &&
339
392
  (facetsSlot ? (jsx("div", { className: "ss__autocomplete__facets" }, cloneWithProps(facetsSlot, { facets: facetsToShow, merchandising, facetsTitle, hideBanners, controller, valueProps }))) : (facetsToShow.length > 0 && (jsx(Fragment, null,
340
393
  facetsTitle && vertical ? (jsx("div", { className: classnames('ss__autocomplete__title', 'ss__autocomplete__title--facets') },
@@ -344,7 +397,7 @@ export const Autocomplete = observer((properties) => {
344
397
  jsx("h5", null, facetsTitle))) : null,
345
398
  jsx(Facets, { ...subProps.facets, facets: facetsToShow }),
346
399
  !hideBanners ? jsx(Banner, { ...subProps.banner, content: merchandising.content, type: ContentType.LEFT }) : null))))),
347
- !hideContent ? (contentSlot ? (jsx("div", { className: "ss__autocomplete__content" }, cloneWithProps(contentSlot, { results, merchandising, search, pagination, filters, controller }))) : results.length > 0 || Object.keys(merchandising.content).length > 0 || search?.query?.string ? (jsx("div", { className: "ss__autocomplete__content" },
400
+ !hideContent ? (contentSlot ? (jsx("div", { className: "ss__autocomplete__content" }, cloneWithProps(contentSlot, { results, merchandising, search, pagination, filters, controller }))) : showResults ? (jsx("div", { className: "ss__autocomplete__content" },
348
401
  jsx(Fragment, null,
349
402
  !hideBanners ? jsx(Banner, { ...subProps.banner, content: merchandising.content, type: ContentType.HEADER }) : null,
350
403
  !hideBanners ? jsx(Banner, { ...subProps.banner, content: merchandising.content, type: ContentType.BANNER }) : null,
@@ -359,7 +412,7 @@ export const Autocomplete = observer((properties) => {
359
412
  jsx("p", null, "Please try another search."))))),
360
413
  !hideBanners ? jsx(Banner, { ...subProps.banner, content: merchandising.content, type: ContentType.FOOTER }) : null,
361
414
  !hideLink ? (linkSlot ? (cloneWithProps(linkSlot, { search, results, pagination, filters, controller })) : search?.query?.string && results.length > 0 ? (jsx("div", { className: "ss__autocomplete__content__info" },
362
- jsx("a", { href: state.url.href },
415
+ jsx("a", { href: state.url.href, onClick: () => controller?.setFocused && controller.setFocused() },
363
416
  "See ",
364
417
  pagination.totalResults,
365
418
  " ",
@@ -372,14 +425,16 @@ export const Autocomplete = observer((properties) => {
372
425
  jsx(Icon, { ...subProps.icon })))) : null) : null))) : null) : null))) : (jsx(Fragment, null));
373
426
  });
374
427
  const emIfy = (term, search) => {
375
- const match = term.match(escapeRegExp(search));
376
- if (search && term && match && match.index) {
377
- const beforeMatch = term.slice(0, match.index);
378
- const afterMatch = term.slice(match.index + search.length, term.length);
379
- return (jsx(Fragment, null,
380
- beforeMatch ? jsx("em", null, beforeMatch) : '',
381
- search,
382
- afterMatch ? jsx("em", null, afterMatch) : ''));
428
+ if (term && search) {
429
+ const match = term.match(escapeRegExp(search));
430
+ if (search && term && match && match.index) {
431
+ const beforeMatch = term.slice(0, match.index);
432
+ const afterMatch = term.slice(match.index + search.length, term.length);
433
+ return (jsx(Fragment, null,
434
+ beforeMatch ? jsx("em", null, beforeMatch) : '',
435
+ search,
436
+ afterMatch ? jsx("em", null, afterMatch) : ''));
437
+ }
383
438
  }
384
439
  return (jsx(Fragment, null,
385
440
  jsx("em", null, term)));
@@ -123,6 +123,66 @@ declare const _default: {
123
123
  type: string;
124
124
  };
125
125
  };
126
+ hideHistory: {
127
+ defaultValue: boolean;
128
+ description: string;
129
+ table: {
130
+ type: {
131
+ summary: string;
132
+ };
133
+ defaultValue: {
134
+ summary: boolean;
135
+ };
136
+ };
137
+ control: {
138
+ type: string;
139
+ };
140
+ };
141
+ hideTrending: {
142
+ defaultValue: boolean;
143
+ description: string;
144
+ table: {
145
+ type: {
146
+ summary: string;
147
+ };
148
+ defaultValue: {
149
+ summary: boolean;
150
+ };
151
+ };
152
+ control: {
153
+ type: string;
154
+ };
155
+ };
156
+ retainHistory: {
157
+ defaultValue: boolean;
158
+ description: string;
159
+ table: {
160
+ type: {
161
+ summary: string;
162
+ };
163
+ defaultValue: {
164
+ summary: boolean;
165
+ };
166
+ };
167
+ control: {
168
+ type: string;
169
+ };
170
+ };
171
+ retainTrending: {
172
+ defaultValue: boolean;
173
+ description: string;
174
+ table: {
175
+ type: {
176
+ summary: string;
177
+ };
178
+ defaultValue: {
179
+ summary: boolean;
180
+ };
181
+ };
182
+ control: {
183
+ type: string;
184
+ };
185
+ };
126
186
  hideFacets: {
127
187
  defaultValue: boolean;
128
188
  description: string;
@@ -243,6 +303,21 @@ declare const _default: {
243
303
  type: string;
244
304
  };
245
305
  };
306
+ historyTitle: {
307
+ defaultValue: string;
308
+ description: string;
309
+ table: {
310
+ type: {
311
+ summary: string;
312
+ };
313
+ defaultValue: {
314
+ summary: string;
315
+ };
316
+ };
317
+ control: {
318
+ type: string;
319
+ };
320
+ };
246
321
  facetsTitle: {
247
322
  defaultValue: string;
248
323
  description: string;
@@ -1 +1 @@
1
- {"version":3,"file":"Autocomplete.stories.d.ts","sourceRoot":"","sources":["../../../../../src/components/Organisms/Autocomplete/Autocomplete.stories.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,CAAC,EAAY,MAAM,QAAQ,CAAC;AAIrC,OAAO,EAAgB,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAIjE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;;;;;;;;;;;yBAgBlE,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAdb,wBAwRE;AAeF,eAAO,MAAM,OAAO;WAAU,iBAAiB;;wBAAsD,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;CAM1H,CAAC"}
1
+ {"version":3,"file":"Autocomplete.stories.d.ts","sourceRoot":"","sources":["../../../../../src/components/Organisms/Autocomplete/Autocomplete.stories.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,CAAC,EAAY,MAAM,QAAQ,CAAC;AAIrC,OAAO,EAAgB,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAIjE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;;;;;;;;;;;yBAgBlE,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAdb,wBA+UE;AAeF,eAAO,MAAM,OAAO;WAAU,iBAAiB;;wBAAsD,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;CAM1H,CAAC"}
@@ -61,7 +61,51 @@ export default {
61
61
  },
62
62
  hideTerms: {
63
63
  defaultValue: false,
64
- description: 'prevent terms from rendering (also applicable to trending terms)',
64
+ description: 'prevent all terms from rendering (also applicable to trending and history terms)',
65
+ table: {
66
+ type: {
67
+ summary: 'boolean',
68
+ },
69
+ defaultValue: { summary: false },
70
+ },
71
+ control: { type: 'boolean' },
72
+ },
73
+ hideHistory: {
74
+ defaultValue: false,
75
+ description: 'prevent historical terms and results from rendering',
76
+ table: {
77
+ type: {
78
+ summary: 'boolean',
79
+ },
80
+ defaultValue: { summary: false },
81
+ },
82
+ control: { type: 'boolean' },
83
+ },
84
+ hideTrending: {
85
+ defaultValue: false,
86
+ description: 'prevent trending terms and results from rendering',
87
+ table: {
88
+ type: {
89
+ summary: 'boolean',
90
+ },
91
+ defaultValue: { summary: false },
92
+ },
93
+ control: { type: 'boolean' },
94
+ },
95
+ retainHistory: {
96
+ defaultValue: false,
97
+ description: 'allow history terms to render even when there is a query in the input',
98
+ table: {
99
+ type: {
100
+ summary: 'boolean',
101
+ },
102
+ defaultValue: { summary: false },
103
+ },
104
+ control: { type: 'boolean' },
105
+ },
106
+ retainTrending: {
107
+ defaultValue: false,
108
+ description: 'allow trending terms to render even when there is a query in the input',
65
109
  table: {
66
110
  type: {
67
111
  summary: 'boolean',
@@ -158,6 +202,17 @@ export default {
158
202
  },
159
203
  control: { type: 'text' },
160
204
  },
205
+ historyTitle: {
206
+ defaultValue: 'Previously Searched',
207
+ description: 'Change historical terms header title',
208
+ table: {
209
+ type: {
210
+ summary: 'string',
211
+ },
212
+ defaultValue: { summary: 'Previously Searched' },
213
+ },
214
+ control: { type: 'text' },
215
+ },
161
216
  facetsTitle: {
162
217
  defaultValue: '',
163
218
  description: 'Change facets header title',
@@ -1 +1 @@
1
- {"version":3,"file":"Recommendation.d.ts","sourceRoot":"","sources":["../../../../../src/components/Organisms/Recommendation/Recommendation.tsx"],"names":[],"mappings":";AAAA,eAAe;AACf,OAAO,EAAe,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAQxD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAC9E,OAAO,KAAK,EAAE,iBAAiB,EAAW,MAAM,+BAA+B,CAAC;AAMhF,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAc,MAAM,gBAAgB,CAAC;AAc9E,eAAO,MAAM,cAAc,gBAAyB,mBAAmB,KAAG,WAAW;;CAyKnF,CAAC;AAEH,MAAM,WAAW,mBAAoB,SAAQ,cAAc;IAC1D,KAAK,CAAC,EAAE,GAAG,CAAC,OAAO,GAAG,MAAM,CAAC;IAC7B,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAC/B,UAAU,CAAC,EAAE,GAAG,CAAC,OAAO,GAAG,MAAM,CAAC;IAClC,UAAU,CAAC,EAAE,GAAG,CAAC,OAAO,GAAG,MAAM,CAAC;IAClC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,wBAAwB,CAAC;IACrC,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB"}
1
+ {"version":3,"file":"Recommendation.d.ts","sourceRoot":"","sources":["../../../../../src/components/Organisms/Recommendation/Recommendation.tsx"],"names":[],"mappings":";AAAA,eAAe;AACf,OAAO,EAAe,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAMxD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAC9E,OAAO,KAAK,EAAE,iBAAiB,EAAW,MAAM,+BAA+B,CAAC;AAMhF,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAc,MAAM,gBAAgB,CAAC;AAe9E,eAAO,MAAM,cAAc,gBAAyB,mBAAmB,KAAG,WAAW;;CA+HnF,CAAC;AAEH,MAAM,WAAW,mBAAoB,SAAQ,cAAc;IAC1D,KAAK,CAAC,EAAE,GAAG,CAAC,OAAO,GAAG,MAAM,CAAC;IAC7B,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAC/B,UAAU,CAAC,EAAE,GAAG,CAAC,OAAO,GAAG,MAAM,CAAC;IAClC,UAAU,CAAC,EAAE,GAAG,CAAC,OAAO,GAAG,MAAM,CAAC;IAClC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,wBAAwB,CAAC;IACrC,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB"}
@@ -1,6 +1,5 @@
1
1
  /** @jsx jsx */
2
2
  import { Fragment } from 'preact';
3
- import { useState, useRef } from 'preact/hooks';
4
3
  import { jsx, css } from '@emotion/react';
5
4
  import classnames from 'classnames';
6
5
  import { observer } from 'mobx-react-lite';
@@ -9,8 +8,9 @@ import { Carousel, defaultCarouselBreakpoints, defaultVerticalCarouselBreakpoint
9
8
  import { Result } from '../../Molecules/Result';
10
9
  import { defined } from '../../../utilities';
11
10
  import { useTheme, CacheProvider } from '../../../providers';
12
- import { useIntersection } from '../../../hooks';
13
11
  import { useDisplaySettings } from '../../../hooks/useDisplaySettings';
12
+ import { RecommendationProfileTracker } from '../../Trackers/Recommendation/ProfileTracker';
13
+ import { RecommendationResultTracker } from '../../Trackers/Recommendation/ResultTracker';
14
14
  const CSS = {
15
15
  recommendation: ({ vertical }) => css({
16
16
  height: vertical ? '100%' : undefined,
@@ -79,31 +79,6 @@ export const Recommendation = observer((properties) => {
79
79
  theme: props?.theme,
80
80
  },
81
81
  };
82
- const rootComponentRef = useRef(null);
83
- const [initialIndexes, setInitialIndexes] = useState([0, 0]);
84
- const inViewport = useIntersection(rootComponentRef, '0px', true);
85
- const sendProductImpression = (index, count) => {
86
- if (!inViewport)
87
- return;
88
- let resultLoopCount = [index, index + count];
89
- let resultLoopOverCount;
90
- if (index + count > resultsToRender.length - 1) {
91
- resultLoopCount = [index];
92
- resultLoopOverCount = [0, index + count - resultsToRender.length];
93
- }
94
- let resultsImpressions = resultsToRender.slice(...resultLoopCount);
95
- if (resultLoopOverCount) {
96
- resultsImpressions = resultsImpressions.concat(resultsToRender.slice(...resultLoopOverCount));
97
- }
98
- resultsImpressions.map((result) => {
99
- controller.track.product.impression(result);
100
- });
101
- };
102
- if (inViewport) {
103
- controller.track.impression();
104
- sendProductImpression(initialIndexes[0], initialIndexes[1]);
105
- }
106
- (children || resultsToRender.length) && controller?.track?.render();
107
82
  const styling = {};
108
83
  if (!disableStyles) {
109
84
  styling.css = [CSS.recommendation({ vertical }), style];
@@ -112,24 +87,11 @@ export const Recommendation = observer((properties) => {
112
87
  styling.css = [style];
113
88
  }
114
89
  return children || resultsToRender?.length ? (jsx(CacheProvider, null,
115
- jsx("div", { ref: rootComponentRef, ...styling, className: classnames('ss__recommendation', className) },
116
- title && jsx("h3", { className: "ss__recommendation__title" }, title),
117
- jsx(Carousel, { onInit: (swiper) => {
118
- //@ts-ignore
119
- setInitialIndexes([swiper.realIndex, swiper.passedParams.slidesPerView]);
120
- }, onBreakpoint: (swiper) => {
121
- //@ts-ignore
122
- sendProductImpression(swiper.realIndex, swiper.passedParams.slidesPerView);
123
- }, onSlideChange: (swiper) => {
124
- //@ts-ignore
125
- sendProductImpression(swiper.realIndex, swiper.passedParams.slidesPerView);
126
- }, prevButton: prevButton, nextButton: nextButton, hideButtons: hideButtons, onNextButtonClick: (e) => controller.track.click(e), onPrevButtonClick: (e) => controller.track.click(e), onClick: (swiper, e) => {
127
- const clickedIndex = swiper.realIndex + (swiper.clickedIndex - swiper.activeIndex);
128
- controller.track.click(e);
129
- if (!Number.isNaN(clickedIndex)) {
130
- controller.track.product.click(e, resultsToRender[clickedIndex]);
131
- }
132
- }, loop: loop, pagination: pagination, breakpoints: breakpoints, ...subProps.carousel, ...additionalProps, ...displaySettings }, Array.isArray(children) && children.length
133
- ? children.map((child) => child)
134
- : resultsToRender.map((result) => jsx(Result, { ...subProps.result, controller: controller, result: result })))))) : (jsx(Fragment, null));
90
+ jsx("div", { ...styling, className: classnames('ss__recommendation', className) },
91
+ jsx(RecommendationProfileTracker, { controller: controller },
92
+ title && jsx("h3", { className: "ss__recommendation__title" }, title),
93
+ jsx(Carousel, { prevButton: prevButton, nextButton: nextButton, hideButtons: hideButtons, loop: loop, pagination: pagination, breakpoints: breakpoints, ...subProps.carousel, ...additionalProps, ...displaySettings }, Array.isArray(children) && children.length
94
+ ? children.map((child, idx) => (jsx(RecommendationResultTracker, { controller: controller, result: resultsToRender[idx] }, child)))
95
+ : resultsToRender.map((result) => (jsx(RecommendationResultTracker, { controller: controller, result: result },
96
+ jsx(Result, { ...subProps.result, controller: controller, result: result }))))))))) : (jsx(Fragment, null));
135
97
  });
@@ -0,0 +1,10 @@
1
+ import type { RecommendationController } from '@searchspring/snap-controller';
2
+ import { ComponentProps } from '../../../../types';
3
+ export declare const RecommendationProfileTracker: ((properties: RecommendationProfileTrackerProps) => JSX.Element) & {
4
+ displayName: string;
5
+ };
6
+ export interface RecommendationProfileTrackerProps extends ComponentProps {
7
+ children: any;
8
+ controller: RecommendationController;
9
+ }
10
+ //# sourceMappingURL=RecommendationProfileTracker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RecommendationProfileTracker.d.ts","sourceRoot":"","sources":["../../../../../../src/components/Trackers/Recommendation/ProfileTracker/RecommendationProfileTracker.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAc,MAAM,mBAAmB,CAAC;AAO/D,eAAO,MAAM,4BAA4B,gBAAyB,iCAAiC,KAAG,WAAW;;CA+C/G,CAAC;AAEH,MAAM,WAAW,iCAAkC,SAAQ,cAAc;IACxE,QAAQ,EAAE,GAAG,CAAC;IACd,UAAU,EAAE,wBAAwB,CAAC;CACrC"}
@@ -0,0 +1,40 @@
1
+ /** @jsx jsx */
2
+ import { Fragment, toChildArray } from 'preact';
3
+ import { jsx, css } from '@emotion/react';
4
+ import { useRef } from 'preact/hooks';
5
+ import { observer } from 'mobx-react-lite';
6
+ import { useTheme } from '../../../../providers';
7
+ import { useIntersection } from '../../../../hooks';
8
+ import classnames from 'classnames';
9
+ const CSS = {
10
+ RecommendationProfileTracker: () => css({}),
11
+ };
12
+ export const RecommendationProfileTracker = observer((properties) => {
13
+ const globalTheme = useTheme();
14
+ const props = {
15
+ // default props
16
+ // global theme
17
+ ...globalTheme?.components?.RecommendationProfileTracker,
18
+ // props
19
+ ...properties,
20
+ ...properties.theme?.components?.RecommendationProfileTracker,
21
+ };
22
+ const { children, controller, className, style, disableStyles } = props;
23
+ const childs = toChildArray(children);
24
+ // do impression tracking for "profile"
25
+ const componentRef = useRef(null);
26
+ const inViewport = useIntersection(componentRef, '0px');
27
+ if (inViewport) {
28
+ controller.track.impression();
29
+ }
30
+ // takes care of rendering profile
31
+ childs.length && controller.track.render();
32
+ const styling = {};
33
+ if (!disableStyles) {
34
+ styling.css = [CSS.RecommendationProfileTracker(), style];
35
+ }
36
+ else if (style) {
37
+ styling.css = [style];
38
+ }
39
+ return childs.length ? (jsx("div", { className: classnames('ss__recommendation-profile-tracker', className), onClick: (e) => controller.track.click(e), ref: componentRef, ...styling }, children)) : (jsx(Fragment, null));
40
+ });
@@ -0,0 +1,94 @@
1
+ /// <reference types="react" />
2
+ import { h } from 'preact';
3
+ import { RecommendationProfileTrackerProps } from './RecommendationProfileTracker';
4
+ import type { RecommendationController } from '@searchspring/snap-controller';
5
+ declare const _default: {
6
+ title: string;
7
+ component: ((properties: RecommendationProfileTrackerProps) => JSX.Element) & {
8
+ displayName: string;
9
+ };
10
+ parameters: {
11
+ docs: {
12
+ page: () => h.JSX.Element;
13
+ };
14
+ };
15
+ argTypes: {
16
+ className: {
17
+ description: string;
18
+ table: {
19
+ type: {
20
+ summary: string;
21
+ };
22
+ defaultValue: {
23
+ summary: string;
24
+ };
25
+ };
26
+ control: {
27
+ type: string;
28
+ };
29
+ };
30
+ disableStyles: {
31
+ defaultValue: boolean;
32
+ description: string;
33
+ table: {
34
+ type: {
35
+ summary: string;
36
+ };
37
+ defaultValue: {
38
+ summary: boolean;
39
+ };
40
+ };
41
+ control: {
42
+ type: string;
43
+ };
44
+ };
45
+ style: {
46
+ description: string;
47
+ table: {
48
+ type: {
49
+ summary: string;
50
+ };
51
+ };
52
+ control: {
53
+ type: string;
54
+ };
55
+ };
56
+ theme: {
57
+ description: string;
58
+ table: {
59
+ type: {
60
+ summary: string;
61
+ };
62
+ };
63
+ control: {
64
+ type: string;
65
+ };
66
+ };
67
+ controller: {
68
+ description: string;
69
+ type: {
70
+ required: boolean;
71
+ };
72
+ table: {
73
+ type: {
74
+ summary: string;
75
+ };
76
+ };
77
+ control: {
78
+ type: string;
79
+ };
80
+ };
81
+ };
82
+ };
83
+ export default _default;
84
+ export declare const Default: {
85
+ (props: RecommendationProfileTrackerProps, { loaded: { controller } }: {
86
+ loaded: {
87
+ controller: RecommendationController;
88
+ };
89
+ }): h.JSX.Element;
90
+ loaders: (() => Promise<{
91
+ controller: RecommendationController;
92
+ }>)[];
93
+ };
94
+ //# sourceMappingURL=RecommendationProfileTracker.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RecommendationProfileTracker.stories.d.ts","sourceRoot":"","sources":["../../../../../../src/components/Trackers/Recommendation/ProfileTracker/RecommendationProfileTracker.stories.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAI3B,OAAO,EAAgC,iCAAiC,EAAE,MAAM,gCAAgC,CAAC;AAIjH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAI9E,wBA2BE;AAIF,eAAO,MAAM,OAAO;YACZ,iCAAiC;;wBACY,wBAAwB;;;;;;CAY5E,CAAC"}