@searchspring/snap-preact-components 0.65.1 → 0.65.2

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 (27) hide show
  1. package/dist/cjs/components/Organisms/Results/Results.d.ts.map +1 -1
  2. package/dist/cjs/components/Organisms/Results/Results.js +1 -1
  3. package/dist/cjs/components/Trackers/Recommendation/ProfileTracker/RecommendationProfileTracker.d.ts +3 -0
  4. package/dist/cjs/components/Trackers/Recommendation/ProfileTracker/RecommendationProfileTracker.d.ts.map +1 -1
  5. package/dist/cjs/components/Trackers/Recommendation/ProfileTracker/RecommendationProfileTracker.js +3 -0
  6. package/dist/cjs/components/Trackers/ResultTracker/ResultTracker.d.ts.map +1 -1
  7. package/dist/cjs/components/Trackers/ResultTracker/ResultTracker.js +16 -15
  8. package/dist/cjs/hooks/index.d.ts +1 -0
  9. package/dist/cjs/hooks/index.d.ts.map +1 -1
  10. package/dist/cjs/hooks/index.js +1 -0
  11. package/dist/cjs/hooks/useIntersectionAdvanced.d.ts +12 -0
  12. package/dist/cjs/hooks/useIntersectionAdvanced.d.ts.map +1 -0
  13. package/dist/cjs/hooks/useIntersectionAdvanced.js +91 -0
  14. package/dist/esm/components/Organisms/Results/Results.d.ts.map +1 -1
  15. package/dist/esm/components/Organisms/Results/Results.js +1 -1
  16. package/dist/esm/components/Trackers/Recommendation/ProfileTracker/RecommendationProfileTracker.d.ts +3 -0
  17. package/dist/esm/components/Trackers/Recommendation/ProfileTracker/RecommendationProfileTracker.d.ts.map +1 -1
  18. package/dist/esm/components/Trackers/Recommendation/ProfileTracker/RecommendationProfileTracker.js +3 -0
  19. package/dist/esm/components/Trackers/ResultTracker/ResultTracker.d.ts.map +1 -1
  20. package/dist/esm/components/Trackers/ResultTracker/ResultTracker.js +17 -14
  21. package/dist/esm/hooks/index.d.ts +1 -0
  22. package/dist/esm/hooks/index.d.ts.map +1 -1
  23. package/dist/esm/hooks/index.js +1 -0
  24. package/dist/esm/hooks/useIntersectionAdvanced.d.ts +12 -0
  25. package/dist/esm/hooks/useIntersectionAdvanced.d.ts.map +1 -0
  26. package/dist/esm/hooks/useIntersectionAdvanced.js +85 -0
  27. package/package.json +11 -11
@@ -1 +1 @@
1
- {"version":3,"file":"Results.d.ts","sourceRoot":"","sources":["../../../../../src/components/Organisms/Results/Results.tsx"],"names":[],"mappings":";AAQA,OAAO,KAAK,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACxH,OAAO,KAAK,EAAE,iBAAiB,EAAmB,MAAM,+BAA+B,CAAC;AAIxF,OAAO,EAAE,cAAc,EAAU,UAAU,EAAE,gBAAgB,EAAc,MAAM,gBAAgB,CAAC;AA+BlG,eAAO,MAAM,OAAO,eAAyB,WAAW,KAAG,WA8GzD,CAAC;AAEH,MAAM,WAAW,WAAY,SAAQ,cAAc;IAClD,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAC/B,UAAU,CAAC,EAAE,gBAAgB,GAAG,sBAAsB,GAAG,wBAAwB,CAAC;CAClF"}
1
+ {"version":3,"file":"Results.d.ts","sourceRoot":"","sources":["../../../../../src/components/Organisms/Results/Results.tsx"],"names":[],"mappings":";AAQA,OAAO,KAAK,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACxH,OAAO,KAAK,EAAE,iBAAiB,EAAmB,MAAM,+BAA+B,CAAC;AAIxF,OAAO,EAAE,cAAc,EAAU,UAAU,EAAE,gBAAgB,EAAc,MAAM,gBAAgB,CAAC;AA+BlG,eAAO,MAAM,OAAO,eAAyB,WAAW,KAAG,WAkHzD,CAAC;AAEH,MAAM,WAAW,WAAY,SAAQ,cAAc;IAClD,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAC/B,UAAU,CAAC,EAAE,gBAAgB,GAAG,sBAAsB,GAAG,wBAAwB,CAAC;CAClF"}
@@ -105,7 +105,7 @@ exports.Results = (0, mobx_react_1.observer)(function (properties) {
105
105
  styling.css = [style];
106
106
  }
107
107
  return (results === null || results === void 0 ? void 0 : results.length) ? ((0, react_1.jsx)(providers_1.CacheProvider, null,
108
- (0, react_1.jsx)("div", __assign({}, styling, { className: (0, classnames_1.default)('ss__results', "ss__results-".concat(props.layout), className) }), results.map(function (result) { return ((0, react_1.jsx)(ResultTracker_1.ResultTracker, { result: result, controller: controller }, (function () {
108
+ (0, react_1.jsx)("div", __assign({}, styling, { className: (0, classnames_1.default)('ss__results', "ss__results-".concat(props.layout), className) }), results.map(function (result) { return ((0, react_1.jsx)(ResultTracker_1.ResultTracker, { key: result.id, result: result, controller: controller }, (function () {
109
109
  switch (result.type) {
110
110
  case snap_store_mobx_1.ContentType.BANNER:
111
111
  return (0, react_1.jsx)(InlineBanner_1.InlineBanner, __assign({}, subProps.inlineBanner, { key: result.id, banner: result, layout: props.layout }));
@@ -3,6 +3,9 @@
3
3
  import { ComponentChildren } from 'preact';
4
4
  import type { RecommendationController } from '@searchspring/snap-controller';
5
5
  import { ComponentProps } from '../../../../types';
6
+ /**
7
+ * @deprecated RecommendationProfileTracker is deprecated and is no longer functional
8
+ */
6
9
  export declare const RecommendationProfileTracker: (properties: RecommendationProfileTrackerProps) => JSX.Element;
7
10
  export interface RecommendationProfileTrackerProps extends ComponentProps {
8
11
  children: ComponentChildren;
@@ -1 +1 @@
1
- {"version":3,"file":"RecommendationProfileTracker.d.ts","sourceRoot":"","sources":["../../../../../../src/components/Trackers/Recommendation/ProfileTracker/RecommendationProfileTracker.tsx"],"names":[],"mappings":";AAAA,eAAe;AACf,OAAO,EAAE,iBAAiB,EAA6B,MAAM,QAAQ,CAAC;AAItE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAc,MAAM,mBAAmB,CAAC;AAO/D,eAAO,MAAM,4BAA4B,eAAyB,iCAAiC,KAAG,WA8BpG,CAAC;AAEH,MAAM,WAAW,iCAAkC,SAAQ,cAAc;IACxE,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,UAAU,EAAE,wBAAwB,CAAC;CACrC"}
1
+ {"version":3,"file":"RecommendationProfileTracker.d.ts","sourceRoot":"","sources":["../../../../../../src/components/Trackers/Recommendation/ProfileTracker/RecommendationProfileTracker.tsx"],"names":[],"mappings":";AAAA,eAAe;AACf,OAAO,EAAE,iBAAiB,EAA6B,MAAM,QAAQ,CAAC;AAItE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAc,MAAM,mBAAmB,CAAC;AAO/D;;GAEG;AACH,eAAO,MAAM,4BAA4B,eAAyB,iCAAiC,KAAG,WA8BpG,CAAC;AAEH,MAAM,WAAW,iCAAkC,SAAQ,cAAc;IACxE,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,UAAU,EAAE,wBAAwB,CAAC;CACrC"}
@@ -24,6 +24,9 @@ var classnames_1 = __importDefault(require("classnames"));
24
24
  var CSS = {
25
25
  RecommendationProfileTracker: function () { return (0, react_1.css)({}); },
26
26
  };
27
+ /**
28
+ * @deprecated RecommendationProfileTracker is deprecated and is no longer functional
29
+ */
27
30
  exports.RecommendationProfileTracker = (0, mobx_react_1.observer)(function (properties) {
28
31
  var _a, _b, _c;
29
32
  var globalTheme = (0, providers_1.useTheme)();
@@ -1 +1 @@
1
- {"version":3,"file":"ResultTracker.d.ts","sourceRoot":"","sources":["../../../../../src/components/Trackers/ResultTracker/ResultTracker.tsx"],"names":[],"mappings":";AAAA,eAAe;AACf,OAAO,EAAK,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAM9C,OAAO,KAAK,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACxH,OAAO,EAAE,cAAc,EAAc,MAAM,gBAAgB,CAAC;AAC5D,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AAOrE,eAAO,MAAM,aAAa,eAAyB,kBAAkB,KAAG,WA+DtE,CAAC;AAEH,MAAM,WAAW,kBAAmB,SAAQ,cAAc;IACzD,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC;IACzB,UAAU,EAAE,gBAAgB,GAAG,sBAAsB,GAAG,wBAAwB,CAAC;IACjF,KAAK,CAAC,EAAE;QACP,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,KAAK,CAAC,EAAE,OAAO,CAAC;KAChB,CAAC;CACF"}
1
+ {"version":3,"file":"ResultTracker.d.ts","sourceRoot":"","sources":["../../../../../src/components/Trackers/ResultTracker/ResultTracker.tsx"],"names":[],"mappings":";AAAA,eAAe;AACf,OAAO,EAAK,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAM9C,OAAO,KAAK,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACxH,OAAO,EAAE,cAAc,EAAc,MAAM,gBAAgB,CAAC;AAC5D,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AAOrE,eAAO,MAAM,aAAa,eAAyB,kBAAkB,KAAG,WAgEtE,CAAC;AAEH,MAAM,WAAW,kBAAmB,SAAQ,cAAc;IACzD,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC;IACzB,UAAU,EAAE,gBAAgB,GAAG,sBAAsB,GAAG,wBAAwB,CAAC;IACjF,KAAK,CAAC,EAAE;QACP,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,KAAK,CAAC,EAAE,OAAO,CAAC;KAChB,CAAC;CACF"}
@@ -25,7 +25,7 @@ var CSS = {
25
25
  ResultTracker: function () { return (0, react_1.css)({}); },
26
26
  };
27
27
  exports.ResultTracker = (0, mobx_react_1.observer)(function (properties) {
28
- var _a, _b, _c, _d, _e;
28
+ var _a, _b, _c;
29
29
  var globalTheme = (0, providers_1.useTheme)();
30
30
  var defaultTrack = {
31
31
  render: true,
@@ -36,18 +36,20 @@ exports.ResultTracker = (0, mobx_react_1.observer)(function (properties) {
36
36
  var children = props.children, result = props.result, track = props.track, controller = props.controller, className = props.className, disableStyles = props.disableStyles, style = props.style;
37
37
  var mergedTrack = __assign(__assign({}, defaultTrack), track);
38
38
  var resultRef = (0, hooks_1.useRef)(null);
39
- var resultInViewport = (0, hooks_2.useIntersection)(resultRef, '0px', true);
40
- (0, hooks_1.useEffect)(function () {
41
- var _a, _b;
42
- if (mergedTrack.render) {
43
- if (result.type === 'product') {
44
- (_b = (_a = controller === null || controller === void 0 ? void 0 : controller.track) === null || _a === void 0 ? void 0 : _a.product) === null || _b === void 0 ? void 0 : _b.render(result);
45
- }
46
- }
47
- }, [result]);
39
+ var resultInViewport = (0, hooks_2.useIntersectionAdvanced)(resultRef, {
40
+ key: result.id,
41
+ rootMargin: '0px',
42
+ fireOnce: true,
43
+ threshold: 0.75,
44
+ startDelay: 2000, // TODO: look into dynamically setting this to a lower value for first row of products
45
+ minVisibleTime: 150,
46
+ });
48
47
  if (resultInViewport && mergedTrack.impression) {
49
- if (result.type === 'product' && (controller === null || controller === void 0 ? void 0 : controller.track)) {
50
- (_e = (_d = controller === null || controller === void 0 ? void 0 : controller.track) === null || _d === void 0 ? void 0 : _d.product) === null || _e === void 0 ? void 0 : _e.impression(result);
48
+ if (result.type === 'product') {
49
+ controller === null || controller === void 0 ? void 0 : controller.track.product.impression(result);
50
+ }
51
+ else {
52
+ // track banner in future
51
53
  }
52
54
  }
53
55
  var styling = {};
@@ -57,11 +59,10 @@ exports.ResultTracker = (0, mobx_react_1.observer)(function (properties) {
57
59
  else if (style) {
58
60
  styling.css = [style];
59
61
  }
60
- return ((0, react_1.jsx)("div", __assign({ className: (0, classnames_1.default)('ss__result-tracker', "ss__".concat(controller === null || controller === void 0 ? void 0 : controller.type, "-result-tracker"), className), onClick: function (e) {
61
- var _a, _b;
62
+ return ((0, react_1.jsx)("div", __assign({ key: result.id, className: (0, classnames_1.default)('ss__result-tracker', "ss__".concat(controller === null || controller === void 0 ? void 0 : controller.type, "-result-tracker"), className), onClick: function (e) {
62
63
  if (mergedTrack.click) {
63
64
  if (result.type === 'product') {
64
- (_b = (_a = controller === null || controller === void 0 ? void 0 : controller.track) === null || _a === void 0 ? void 0 : _a.product) === null || _b === void 0 ? void 0 : _b.click(e, result);
65
+ controller === null || controller === void 0 ? void 0 : controller.track.product.click(e, result);
65
66
  }
66
67
  }
67
68
  }, ref: resultRef }, styling), children));
@@ -2,6 +2,7 @@ export * from './useClickOutside';
2
2
  export * from './useConstructor';
3
3
  export * from './useMediaQuery';
4
4
  export * from './useIntersection';
5
+ export * from './useIntersectionAdvanced';
5
6
  export * from './useDisplaySettings';
6
7
  export * from './useA11y';
7
8
  export * from './useDeepCompareEffect';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,WAAW,CAAC;AAC1B,cAAc,wBAAwB,CAAC;AACvC,cAAc,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,sBAAsB,CAAC;AACrC,cAAc,WAAW,CAAC;AAC1B,cAAc,wBAAwB,CAAC;AACvC,cAAc,gBAAgB,CAAC"}
@@ -18,6 +18,7 @@ __exportStar(require("./useClickOutside"), exports);
18
18
  __exportStar(require("./useConstructor"), exports);
19
19
  __exportStar(require("./useMediaQuery"), exports);
20
20
  __exportStar(require("./useIntersection"), exports);
21
+ __exportStar(require("./useIntersectionAdvanced"), exports);
21
22
  __exportStar(require("./useDisplaySettings"), exports);
22
23
  __exportStar(require("./useA11y"), exports);
23
24
  __exportStar(require("./useDeepCompareEffect"), exports);
@@ -0,0 +1,12 @@
1
+ import { MutableRef } from 'preact/hooks';
2
+ interface UseIntersectionOptions {
3
+ key?: string;
4
+ rootMargin?: string;
5
+ fireOnce?: boolean;
6
+ threshold?: number | number[];
7
+ startDelay?: number;
8
+ minVisibleTime?: number;
9
+ }
10
+ export declare const useIntersectionAdvanced: (ref: MutableRef<HTMLElement | null>, options?: UseIntersectionOptions) => boolean;
11
+ export {};
12
+ //# sourceMappingURL=useIntersectionAdvanced.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useIntersectionAdvanced.d.ts","sourceRoot":"","sources":["../../../src/hooks/useIntersectionAdvanced.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA+B,UAAU,EAAE,MAAM,cAAc,CAAC;AAEvE,UAAU,sBAAsB;IAC/B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,eAAO,MAAM,uBAAuB,QAAS,WAAW,WAAW,GAAG,IAAI,CAAC,YAAW,sBAAsB,YAiG3G,CAAC"}
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useIntersectionAdvanced = void 0;
4
+ var hooks_1 = require("preact/hooks");
5
+ var useIntersectionAdvanced = function (ref, options) {
6
+ if (options === void 0) { options = {}; }
7
+ var _a = options.key, key = _a === void 0 ? '' : _a, _b = options.rootMargin, rootMargin = _b === void 0 ? '0px' : _b, _c = options.fireOnce, fireOnce = _c === void 0 ? false : _c, _d = options.threshold, threshold = _d === void 0 ? 0 : _d, _e = options.startDelay, startDelay = _e === void 0 ? 0 : _e, _f = options.minVisibleTime, minVisibleTime = _f === void 0 ? 0 : _f;
8
+ // State and setter for storing whether element is visible
9
+ var _g = (0, hooks_1.useState)(false), isIntersecting = _g[0], setIntersecting = _g[1];
10
+ // Timer reference to track visibility duration
11
+ var visibleTimerRef = (0, hooks_1.useRef)(null);
12
+ // Track when the element started being visible
13
+ var visibleStartRef = (0, hooks_1.useRef)(null);
14
+ (0, hooks_1.useEffect)(function () {
15
+ setIntersecting(false);
16
+ var startDelayTimeout = null;
17
+ var observer = null;
18
+ // Function to create and start the observer
19
+ var startObserver = function () {
20
+ if (!ref.current)
21
+ return;
22
+ observer = new IntersectionObserver(function (_a) {
23
+ var entry = _a[0];
24
+ // If element becomes visible
25
+ if (entry.isIntersecting) {
26
+ // Start tracking visibility time if minVisibleTime is set
27
+ if (minVisibleTime > 0) {
28
+ visibleStartRef.current = Date.now();
29
+ // Clear any existing timer
30
+ if (visibleTimerRef.current) {
31
+ window.clearTimeout(visibleTimerRef.current);
32
+ }
33
+ // Set up a timer for the minimum visibility duration
34
+ visibleTimerRef.current = window.setTimeout(function () {
35
+ setIntersecting(true);
36
+ if (fireOnce && ref.current && observer) {
37
+ observer.unobserve(ref.current);
38
+ }
39
+ }, minVisibleTime);
40
+ }
41
+ else {
42
+ // If no minimum time required, update state immediately
43
+ setIntersecting(true);
44
+ if (fireOnce && ref.current && observer) {
45
+ observer.unobserve(ref.current);
46
+ }
47
+ }
48
+ }
49
+ else {
50
+ // Element is no longer visible
51
+ if (visibleTimerRef.current) {
52
+ // Clear the timer if element goes out of view before minimum time
53
+ window.clearTimeout(visibleTimerRef.current);
54
+ }
55
+ visibleTimerRef.current = null;
56
+ visibleStartRef.current = null;
57
+ setIntersecting(false);
58
+ }
59
+ }, {
60
+ rootMargin: rootMargin,
61
+ threshold: threshold,
62
+ });
63
+ if (ref.current) {
64
+ observer.observe(ref.current);
65
+ }
66
+ };
67
+ // Handle start delay
68
+ if (startDelay > 0) {
69
+ startDelayTimeout = setTimeout(startObserver, startDelay);
70
+ }
71
+ else {
72
+ startObserver();
73
+ }
74
+ return function () {
75
+ setIntersecting(false);
76
+ // Clean up timers
77
+ if (startDelayTimeout) {
78
+ window.clearTimeout(startDelayTimeout);
79
+ }
80
+ if (visibleTimerRef.current) {
81
+ window.clearTimeout(visibleTimerRef.current);
82
+ }
83
+ // Clean up observer
84
+ if (observer && ref.current) {
85
+ observer.unobserve(ref.current);
86
+ }
87
+ };
88
+ }, [key]); // Dependencies for effect
89
+ return isIntersecting;
90
+ };
91
+ exports.useIntersectionAdvanced = useIntersectionAdvanced;
@@ -1 +1 @@
1
- {"version":3,"file":"Results.d.ts","sourceRoot":"","sources":["../../../../../src/components/Organisms/Results/Results.tsx"],"names":[],"mappings":";AAQA,OAAO,KAAK,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACxH,OAAO,KAAK,EAAE,iBAAiB,EAAmB,MAAM,+BAA+B,CAAC;AAIxF,OAAO,EAAE,cAAc,EAAU,UAAU,EAAE,gBAAgB,EAAc,MAAM,gBAAgB,CAAC;AA+BlG,eAAO,MAAM,OAAO,eAAyB,WAAW,KAAG,WA8GzD,CAAC;AAEH,MAAM,WAAW,WAAY,SAAQ,cAAc;IAClD,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAC/B,UAAU,CAAC,EAAE,gBAAgB,GAAG,sBAAsB,GAAG,wBAAwB,CAAC;CAClF"}
1
+ {"version":3,"file":"Results.d.ts","sourceRoot":"","sources":["../../../../../src/components/Organisms/Results/Results.tsx"],"names":[],"mappings":";AAQA,OAAO,KAAK,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACxH,OAAO,KAAK,EAAE,iBAAiB,EAAmB,MAAM,+BAA+B,CAAC;AAIxF,OAAO,EAAE,cAAc,EAAU,UAAU,EAAE,gBAAgB,EAAc,MAAM,gBAAgB,CAAC;AA+BlG,eAAO,MAAM,OAAO,eAAyB,WAAW,KAAG,WAkHzD,CAAC;AAEH,MAAM,WAAW,WAAY,SAAQ,cAAc;IAClD,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAC/B,UAAU,CAAC,EAAE,gBAAgB,GAAG,sBAAsB,GAAG,wBAAwB,CAAC;CAClF"}
@@ -108,7 +108,7 @@ export const Results = observer((properties) => {
108
108
  styling.css = [style];
109
109
  }
110
110
  return results?.length ? (jsx(CacheProvider, null,
111
- jsx("div", { ...styling, className: classnames('ss__results', `ss__results-${props.layout}`, className) }, results.map((result) => (jsx(ResultTracker, { result: result, controller: controller }, (() => {
111
+ jsx("div", { ...styling, className: classnames('ss__results', `ss__results-${props.layout}`, className) }, results.map((result) => (jsx(ResultTracker, { key: result.id, result: result, controller: controller }, (() => {
112
112
  switch (result.type) {
113
113
  case ContentType.BANNER:
114
114
  return jsx(InlineBanner, { ...subProps.inlineBanner, key: result.id, banner: result, layout: props.layout });
@@ -3,6 +3,9 @@
3
3
  import { ComponentChildren } from 'preact';
4
4
  import type { RecommendationController } from '@searchspring/snap-controller';
5
5
  import { ComponentProps } from '../../../../types';
6
+ /**
7
+ * @deprecated RecommendationProfileTracker is deprecated and is no longer functional
8
+ */
6
9
  export declare const RecommendationProfileTracker: (properties: RecommendationProfileTrackerProps) => JSX.Element;
7
10
  export interface RecommendationProfileTrackerProps extends ComponentProps {
8
11
  children: ComponentChildren;
@@ -1 +1 @@
1
- {"version":3,"file":"RecommendationProfileTracker.d.ts","sourceRoot":"","sources":["../../../../../../src/components/Trackers/Recommendation/ProfileTracker/RecommendationProfileTracker.tsx"],"names":[],"mappings":";AAAA,eAAe;AACf,OAAO,EAAE,iBAAiB,EAA6B,MAAM,QAAQ,CAAC;AAItE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAc,MAAM,mBAAmB,CAAC;AAO/D,eAAO,MAAM,4BAA4B,eAAyB,iCAAiC,KAAG,WA8BpG,CAAC;AAEH,MAAM,WAAW,iCAAkC,SAAQ,cAAc;IACxE,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,UAAU,EAAE,wBAAwB,CAAC;CACrC"}
1
+ {"version":3,"file":"RecommendationProfileTracker.d.ts","sourceRoot":"","sources":["../../../../../../src/components/Trackers/Recommendation/ProfileTracker/RecommendationProfileTracker.tsx"],"names":[],"mappings":";AAAA,eAAe;AACf,OAAO,EAAE,iBAAiB,EAA6B,MAAM,QAAQ,CAAC;AAItE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAc,MAAM,mBAAmB,CAAC;AAO/D;;GAEG;AACH,eAAO,MAAM,4BAA4B,eAAyB,iCAAiC,KAAG,WA8BpG,CAAC;AAEH,MAAM,WAAW,iCAAkC,SAAQ,cAAc;IACxE,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,UAAU,EAAE,wBAAwB,CAAC;CACrC"}
@@ -7,6 +7,9 @@ import classnames from 'classnames';
7
7
  const CSS = {
8
8
  RecommendationProfileTracker: () => css({}),
9
9
  };
10
+ /**
11
+ * @deprecated RecommendationProfileTracker is deprecated and is no longer functional
12
+ */
10
13
  export const RecommendationProfileTracker = observer((properties) => {
11
14
  const globalTheme = useTheme();
12
15
  const props = {
@@ -1 +1 @@
1
- {"version":3,"file":"ResultTracker.d.ts","sourceRoot":"","sources":["../../../../../src/components/Trackers/ResultTracker/ResultTracker.tsx"],"names":[],"mappings":";AAAA,eAAe;AACf,OAAO,EAAK,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAM9C,OAAO,KAAK,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACxH,OAAO,EAAE,cAAc,EAAc,MAAM,gBAAgB,CAAC;AAC5D,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AAOrE,eAAO,MAAM,aAAa,eAAyB,kBAAkB,KAAG,WA+DtE,CAAC;AAEH,MAAM,WAAW,kBAAmB,SAAQ,cAAc;IACzD,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC;IACzB,UAAU,EAAE,gBAAgB,GAAG,sBAAsB,GAAG,wBAAwB,CAAC;IACjF,KAAK,CAAC,EAAE;QACP,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,KAAK,CAAC,EAAE,OAAO,CAAC;KAChB,CAAC;CACF"}
1
+ {"version":3,"file":"ResultTracker.d.ts","sourceRoot":"","sources":["../../../../../src/components/Trackers/ResultTracker/ResultTracker.tsx"],"names":[],"mappings":";AAAA,eAAe;AACf,OAAO,EAAK,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAM9C,OAAO,KAAK,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACxH,OAAO,EAAE,cAAc,EAAc,MAAM,gBAAgB,CAAC;AAC5D,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AAOrE,eAAO,MAAM,aAAa,eAAyB,kBAAkB,KAAG,WAgEtE,CAAC;AAEH,MAAM,WAAW,kBAAmB,SAAQ,cAAc;IACzD,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC;IACzB,UAAU,EAAE,gBAAgB,GAAG,sBAAsB,GAAG,wBAAwB,CAAC;IACjF,KAAK,CAAC,EAAE;QACP,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,KAAK,CAAC,EAAE,OAAO,CAAC;KAChB,CAAC;CACF"}
@@ -1,8 +1,8 @@
1
1
  import { jsx, css } from '@emotion/react';
2
- import { useRef, useEffect } from 'preact/hooks';
2
+ import { useRef } from 'preact/hooks';
3
3
  import { observer } from 'mobx-react';
4
4
  import { useTheme } from '../../../providers';
5
- import { useIntersection } from '../../../hooks';
5
+ import { useIntersectionAdvanced } from '../../../hooks';
6
6
  import classnames from 'classnames';
7
7
  const CSS = {
8
8
  ResultTracker: () => css({}),
@@ -28,17 +28,20 @@ export const ResultTracker = observer((properties) => {
28
28
  ...track,
29
29
  };
30
30
  const resultRef = useRef(null);
31
- const resultInViewport = useIntersection(resultRef, '0px', true);
32
- useEffect(() => {
33
- if (mergedTrack.render) {
34
- if (result.type === 'product') {
35
- controller?.track?.product?.render(result);
36
- }
37
- }
38
- }, [result]);
31
+ const resultInViewport = useIntersectionAdvanced(resultRef, {
32
+ key: result.id,
33
+ rootMargin: '0px',
34
+ fireOnce: true,
35
+ threshold: 0.75,
36
+ startDelay: 2000, // TODO: look into dynamically setting this to a lower value for first row of products
37
+ minVisibleTime: 150,
38
+ });
39
39
  if (resultInViewport && mergedTrack.impression) {
40
- if (result.type === 'product' && controller?.track) {
41
- controller?.track?.product?.impression(result);
40
+ if (result.type === 'product') {
41
+ controller?.track.product.impression(result);
42
+ }
43
+ else {
44
+ // track banner in future
42
45
  }
43
46
  }
44
47
  const styling = {};
@@ -48,10 +51,10 @@ export const ResultTracker = observer((properties) => {
48
51
  else if (style) {
49
52
  styling.css = [style];
50
53
  }
51
- return (jsx("div", { className: classnames('ss__result-tracker', `ss__${controller?.type}-result-tracker`, className), onClick: (e) => {
54
+ return (jsx("div", { key: result.id, className: classnames('ss__result-tracker', `ss__${controller?.type}-result-tracker`, className), onClick: (e) => {
52
55
  if (mergedTrack.click) {
53
56
  if (result.type === 'product') {
54
- controller?.track?.product?.click(e, result);
57
+ controller?.track.product.click(e, result);
55
58
  }
56
59
  }
57
60
  }, ref: resultRef, ...styling }, children));
@@ -2,6 +2,7 @@ export * from './useClickOutside';
2
2
  export * from './useConstructor';
3
3
  export * from './useMediaQuery';
4
4
  export * from './useIntersection';
5
+ export * from './useIntersectionAdvanced';
5
6
  export * from './useDisplaySettings';
6
7
  export * from './useA11y';
7
8
  export * from './useDeepCompareEffect';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,WAAW,CAAC;AAC1B,cAAc,wBAAwB,CAAC;AACvC,cAAc,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,sBAAsB,CAAC;AACrC,cAAc,WAAW,CAAC;AAC1B,cAAc,wBAAwB,CAAC;AACvC,cAAc,gBAAgB,CAAC"}
@@ -2,6 +2,7 @@ export * from './useClickOutside';
2
2
  export * from './useConstructor';
3
3
  export * from './useMediaQuery';
4
4
  export * from './useIntersection';
5
+ export * from './useIntersectionAdvanced';
5
6
  export * from './useDisplaySettings';
6
7
  export * from './useA11y';
7
8
  export * from './useDeepCompareEffect';
@@ -0,0 +1,12 @@
1
+ import { MutableRef } from 'preact/hooks';
2
+ interface UseIntersectionOptions {
3
+ key?: string;
4
+ rootMargin?: string;
5
+ fireOnce?: boolean;
6
+ threshold?: number | number[];
7
+ startDelay?: number;
8
+ minVisibleTime?: number;
9
+ }
10
+ export declare const useIntersectionAdvanced: (ref: MutableRef<HTMLElement | null>, options?: UseIntersectionOptions) => boolean;
11
+ export {};
12
+ //# sourceMappingURL=useIntersectionAdvanced.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useIntersectionAdvanced.d.ts","sourceRoot":"","sources":["../../../src/hooks/useIntersectionAdvanced.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA+B,UAAU,EAAE,MAAM,cAAc,CAAC;AAEvE,UAAU,sBAAsB;IAC/B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,eAAO,MAAM,uBAAuB,QAAS,WAAW,WAAW,GAAG,IAAI,CAAC,YAAW,sBAAsB,YAiG3G,CAAC"}
@@ -0,0 +1,85 @@
1
+ import { useState, useEffect, useRef } from 'preact/hooks';
2
+ export const useIntersectionAdvanced = (ref, options = {}) => {
3
+ const { key = '', rootMargin = '0px', fireOnce = false, threshold = 0, startDelay = 0, minVisibleTime = 0 } = options;
4
+ // State and setter for storing whether element is visible
5
+ const [isIntersecting, setIntersecting] = useState(false);
6
+ // Timer reference to track visibility duration
7
+ const visibleTimerRef = useRef(null);
8
+ // Track when the element started being visible
9
+ const visibleStartRef = useRef(null);
10
+ useEffect(() => {
11
+ setIntersecting(false);
12
+ let startDelayTimeout = null;
13
+ let observer = null;
14
+ // Function to create and start the observer
15
+ const startObserver = () => {
16
+ if (!ref.current)
17
+ return;
18
+ observer = new IntersectionObserver(([entry]) => {
19
+ // If element becomes visible
20
+ if (entry.isIntersecting) {
21
+ // Start tracking visibility time if minVisibleTime is set
22
+ if (minVisibleTime > 0) {
23
+ visibleStartRef.current = Date.now();
24
+ // Clear any existing timer
25
+ if (visibleTimerRef.current) {
26
+ window.clearTimeout(visibleTimerRef.current);
27
+ }
28
+ // Set up a timer for the minimum visibility duration
29
+ visibleTimerRef.current = window.setTimeout(() => {
30
+ setIntersecting(true);
31
+ if (fireOnce && ref.current && observer) {
32
+ observer.unobserve(ref.current);
33
+ }
34
+ }, minVisibleTime);
35
+ }
36
+ else {
37
+ // If no minimum time required, update state immediately
38
+ setIntersecting(true);
39
+ if (fireOnce && ref.current && observer) {
40
+ observer.unobserve(ref.current);
41
+ }
42
+ }
43
+ }
44
+ else {
45
+ // Element is no longer visible
46
+ if (visibleTimerRef.current) {
47
+ // Clear the timer if element goes out of view before minimum time
48
+ window.clearTimeout(visibleTimerRef.current);
49
+ }
50
+ visibleTimerRef.current = null;
51
+ visibleStartRef.current = null;
52
+ setIntersecting(false);
53
+ }
54
+ }, {
55
+ rootMargin,
56
+ threshold,
57
+ });
58
+ if (ref.current) {
59
+ observer.observe(ref.current);
60
+ }
61
+ };
62
+ // Handle start delay
63
+ if (startDelay > 0) {
64
+ startDelayTimeout = setTimeout(startObserver, startDelay);
65
+ }
66
+ else {
67
+ startObserver();
68
+ }
69
+ return () => {
70
+ setIntersecting(false);
71
+ // Clean up timers
72
+ if (startDelayTimeout) {
73
+ window.clearTimeout(startDelayTimeout);
74
+ }
75
+ if (visibleTimerRef.current) {
76
+ window.clearTimeout(visibleTimerRef.current);
77
+ }
78
+ // Clean up observer
79
+ if (observer && ref.current) {
80
+ observer.unobserve(ref.current);
81
+ }
82
+ };
83
+ }, [key]); // Dependencies for effect
84
+ return isIntersecting;
85
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@searchspring/snap-preact-components",
3
- "version": "0.65.1",
3
+ "version": "0.65.2",
4
4
  "description": "Snap Preact Component Library",
5
5
  "author": "Searchspring",
6
6
  "license": "MIT",
@@ -29,7 +29,7 @@
29
29
  "dependencies": {
30
30
  "@cypress/react": "^8.0.0",
31
31
  "@emotion/react": "11.9.0",
32
- "@searchspring/snap-toolbox": "^0.65.1",
32
+ "@searchspring/snap-toolbox": "^0.65.2",
33
33
  "classnames": "^2.3.2",
34
34
  "cypress": "^13.7.1",
35
35
  "cypress-wait-until": "^1.7.2",
@@ -52,14 +52,14 @@
52
52
  "@babel/preset-env": "^7.21.4",
53
53
  "@babel/preset-react": "^7.18.6",
54
54
  "@babel/runtime": "^7.21.0",
55
- "@searchspring/snap-client": "^0.65.1",
56
- "@searchspring/snap-controller": "^0.65.1",
57
- "@searchspring/snap-event-manager": "^0.65.1",
58
- "@searchspring/snap-logger": "^0.65.1",
59
- "@searchspring/snap-profiler": "^0.65.1",
60
- "@searchspring/snap-store-mobx": "^0.65.1",
61
- "@searchspring/snap-tracker": "^0.65.1",
62
- "@searchspring/snap-url-manager": "^0.65.1",
55
+ "@searchspring/snap-client": "^0.65.2",
56
+ "@searchspring/snap-controller": "^0.65.2",
57
+ "@searchspring/snap-event-manager": "^0.65.2",
58
+ "@searchspring/snap-logger": "^0.65.2",
59
+ "@searchspring/snap-profiler": "^0.65.2",
60
+ "@searchspring/snap-store-mobx": "^0.65.2",
61
+ "@searchspring/snap-tracker": "^0.65.2",
62
+ "@searchspring/snap-url-manager": "^0.65.2",
63
63
  "@storybook/addon-actions": "6.4.22",
64
64
  "@storybook/addon-controls": "6.4.22",
65
65
  "@storybook/addon-docs": "6.4.22",
@@ -84,5 +84,5 @@
84
84
  "webpack-merge": "^5.8.0"
85
85
  },
86
86
  "sideEffects": false,
87
- "gitHead": "cd33cd87ad8d51302000b31bce6aa90b4b25ba89"
87
+ "gitHead": "3e80b62664af7e3104e578d6c2596c439d5dfd78"
88
88
  }