@gemx-dev/heatmap-react 3.5.79 → 3.5.80

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 (164) hide show
  1. package/dist/esm/components/Layout/HeatmapLayout.d.ts +1 -0
  2. package/dist/esm/components/Layout/HeatmapLayout.d.ts.map +1 -1
  3. package/dist/esm/components/VizDom/VizDomRenderer.d.ts.map +1 -1
  4. package/dist/esm/components/VizScrollmap/AverageFold.d.ts +8 -0
  5. package/dist/esm/components/VizScrollmap/AverageFold.d.ts.map +1 -0
  6. package/dist/esm/components/VizScrollmap/HoverZones.d.ts +1 -1
  7. package/dist/esm/components/VizScrollmap/HoverZones.d.ts.map +1 -1
  8. package/dist/esm/components/VizScrollmap/MarkerLine.d.ts +12 -0
  9. package/dist/esm/components/VizScrollmap/MarkerLine.d.ts.map +1 -0
  10. package/dist/esm/components/VizScrollmap/Minimap.d.ts +8 -0
  11. package/dist/esm/components/VizScrollmap/Minimap.d.ts.map +1 -0
  12. package/dist/esm/components/VizScrollmap/ScrollMarkers.d.ts +9 -0
  13. package/dist/esm/components/VizScrollmap/ScrollMarkers.d.ts.map +1 -0
  14. package/dist/esm/components/VizScrollmap/ScrollOverlay.d.ts +8 -0
  15. package/dist/esm/components/VizScrollmap/ScrollOverlay.d.ts.map +1 -0
  16. package/dist/esm/components/VizScrollmap/VizScrollMap.d.ts +4 -2
  17. package/dist/esm/components/VizScrollmap/VizScrollMap.d.ts.map +1 -1
  18. package/dist/esm/components/VizScrollmap/index.d.ts +1 -1
  19. package/dist/esm/components/VizScrollmap/index.d.ts.map +1 -1
  20. package/dist/esm/hooks/register/useRegisterHeatmap.d.ts +2 -1
  21. package/dist/esm/hooks/register/useRegisterHeatmap.d.ts.map +1 -1
  22. package/dist/esm/hooks/view-context/useHeatmapClickContext.d.ts +0 -13
  23. package/dist/esm/hooks/view-context/useHeatmapClickContext.d.ts.map +1 -1
  24. package/dist/esm/hooks/view-context/useHeatmapDataContext.d.ts +2 -0
  25. package/dist/esm/hooks/view-context/useHeatmapDataContext.d.ts.map +1 -1
  26. package/dist/esm/hooks/view-context/useHeatmapScrollContext.d.ts +2 -0
  27. package/dist/esm/hooks/view-context/useHeatmapScrollContext.d.ts.map +1 -1
  28. package/dist/esm/hooks/view-context/useHeatmapVizRectContext.d.ts +3 -3
  29. package/dist/esm/hooks/view-context/useHeatmapVizRectContext.d.ts.map +1 -1
  30. package/dist/esm/hooks/viz-canvas/useAttentionMap.d.ts +9 -0
  31. package/dist/esm/hooks/viz-canvas/useAttentionMap.d.ts.map +1 -0
  32. package/dist/esm/hooks/viz-canvas/useHeatmapCanvas.d.ts.map +1 -1
  33. package/dist/esm/hooks/viz-canvas/useScrollmap.d.ts.map +1 -1
  34. package/dist/esm/hooks/viz-render/useHeatmapRender.d.ts.map +1 -1
  35. package/dist/esm/hooks/viz-scroll/index.d.ts +1 -0
  36. package/dist/esm/hooks/viz-scroll/index.d.ts.map +1 -1
  37. package/dist/esm/hooks/viz-scroll/useHeatmapScroll.d.ts +7 -0
  38. package/dist/esm/hooks/viz-scroll/useHeatmapScroll.d.ts.map +1 -0
  39. package/dist/esm/hooks/viz-scroll/useScrollmapZones.d.ts +1 -1
  40. package/dist/esm/hooks/viz-scroll/useScrollmapZones.d.ts.map +1 -1
  41. package/dist/esm/hooks/viz-scroll/useZonePositions.d.ts +1 -1
  42. package/dist/esm/hooks/viz-scroll/useZonePositions.d.ts.map +1 -1
  43. package/dist/esm/index.js +382 -115
  44. package/dist/esm/index.mjs +382 -115
  45. package/dist/esm/libs/AttentionMapRenderer.d.ts +32 -0
  46. package/dist/esm/libs/AttentionMapRenderer.d.ts.map +1 -0
  47. package/dist/esm/libs/ClickHeatmapRenderer.d.ts +30 -0
  48. package/dist/esm/libs/ClickHeatmapRenderer.d.ts.map +1 -0
  49. package/dist/esm/libs/GXVisualizer.d.ts +24 -0
  50. package/dist/esm/libs/GXVisualizer.d.ts.map +1 -0
  51. package/dist/esm/libs/ScrollHeatmapRenderer.d.ts +17 -0
  52. package/dist/esm/libs/ScrollHeatmapRenderer.d.ts.map +1 -0
  53. package/dist/esm/libs/index.d.ts +4 -0
  54. package/dist/esm/libs/index.d.ts.map +1 -0
  55. package/dist/esm/libs/types.d.ts +10 -0
  56. package/dist/esm/libs/types.d.ts.map +1 -0
  57. package/dist/esm/stores/data.d.ts +2 -0
  58. package/dist/esm/stores/data.d.ts.map +1 -1
  59. package/dist/esm/stores/mode-single.d.ts +3 -3
  60. package/dist/esm/stores/mode-single.d.ts.map +1 -1
  61. package/dist/esm/stores/viz-scroll.d.ts +2 -0
  62. package/dist/esm/stores/viz-scroll.d.ts.map +1 -1
  63. package/dist/esm/types/heatmap-ref.d.ts +6 -0
  64. package/dist/esm/types/heatmap-ref.d.ts.map +1 -0
  65. package/dist/esm/types/index.d.ts +1 -0
  66. package/dist/esm/types/index.d.ts.map +1 -1
  67. package/dist/umd/components/Layout/HeatmapLayout.d.ts +1 -0
  68. package/dist/umd/components/Layout/HeatmapLayout.d.ts.map +1 -1
  69. package/dist/umd/components/VizDom/VizDomRenderer.d.ts.map +1 -1
  70. package/dist/umd/components/VizScrollmap/AverageFold.d.ts +8 -0
  71. package/dist/umd/components/VizScrollmap/AverageFold.d.ts.map +1 -0
  72. package/dist/umd/components/VizScrollmap/HoverZones.d.ts +1 -1
  73. package/dist/umd/components/VizScrollmap/HoverZones.d.ts.map +1 -1
  74. package/dist/umd/components/VizScrollmap/MarkerLine.d.ts +12 -0
  75. package/dist/umd/components/VizScrollmap/MarkerLine.d.ts.map +1 -0
  76. package/dist/umd/components/VizScrollmap/Minimap.d.ts +8 -0
  77. package/dist/umd/components/VizScrollmap/Minimap.d.ts.map +1 -0
  78. package/dist/umd/components/VizScrollmap/ScrollMarkers.d.ts +9 -0
  79. package/dist/umd/components/VizScrollmap/ScrollMarkers.d.ts.map +1 -0
  80. package/dist/umd/components/VizScrollmap/ScrollOverlay.d.ts +8 -0
  81. package/dist/umd/components/VizScrollmap/ScrollOverlay.d.ts.map +1 -0
  82. package/dist/umd/components/VizScrollmap/VizScrollMap.d.ts +4 -2
  83. package/dist/umd/components/VizScrollmap/VizScrollMap.d.ts.map +1 -1
  84. package/dist/umd/components/VizScrollmap/index.d.ts +1 -1
  85. package/dist/umd/components/VizScrollmap/index.d.ts.map +1 -1
  86. package/dist/umd/hooks/register/useRegisterHeatmap.d.ts +2 -1
  87. package/dist/umd/hooks/register/useRegisterHeatmap.d.ts.map +1 -1
  88. package/dist/umd/hooks/view-context/useHeatmapClickContext.d.ts +0 -13
  89. package/dist/umd/hooks/view-context/useHeatmapClickContext.d.ts.map +1 -1
  90. package/dist/umd/hooks/view-context/useHeatmapDataContext.d.ts +2 -0
  91. package/dist/umd/hooks/view-context/useHeatmapDataContext.d.ts.map +1 -1
  92. package/dist/umd/hooks/view-context/useHeatmapScrollContext.d.ts +2 -0
  93. package/dist/umd/hooks/view-context/useHeatmapScrollContext.d.ts.map +1 -1
  94. package/dist/umd/hooks/view-context/useHeatmapVizRectContext.d.ts +3 -3
  95. package/dist/umd/hooks/view-context/useHeatmapVizRectContext.d.ts.map +1 -1
  96. package/dist/umd/hooks/viz-canvas/useAttentionMap.d.ts +9 -0
  97. package/dist/umd/hooks/viz-canvas/useAttentionMap.d.ts.map +1 -0
  98. package/dist/umd/hooks/viz-canvas/useHeatmapCanvas.d.ts.map +1 -1
  99. package/dist/umd/hooks/viz-canvas/useScrollmap.d.ts.map +1 -1
  100. package/dist/umd/hooks/viz-render/useHeatmapRender.d.ts.map +1 -1
  101. package/dist/umd/hooks/viz-scroll/index.d.ts +1 -0
  102. package/dist/umd/hooks/viz-scroll/index.d.ts.map +1 -1
  103. package/dist/umd/hooks/viz-scroll/useHeatmapScroll.d.ts +7 -0
  104. package/dist/umd/hooks/viz-scroll/useHeatmapScroll.d.ts.map +1 -0
  105. package/dist/umd/hooks/viz-scroll/useScrollmapZones.d.ts +1 -1
  106. package/dist/umd/hooks/viz-scroll/useScrollmapZones.d.ts.map +1 -1
  107. package/dist/umd/hooks/viz-scroll/useZonePositions.d.ts +1 -1
  108. package/dist/umd/hooks/viz-scroll/useZonePositions.d.ts.map +1 -1
  109. package/dist/umd/index.js +2 -2
  110. package/dist/umd/libs/AttentionMapRenderer.d.ts +32 -0
  111. package/dist/umd/libs/AttentionMapRenderer.d.ts.map +1 -0
  112. package/dist/umd/libs/ClickHeatmapRenderer.d.ts +30 -0
  113. package/dist/umd/libs/ClickHeatmapRenderer.d.ts.map +1 -0
  114. package/dist/umd/libs/GXVisualizer.d.ts +24 -0
  115. package/dist/umd/libs/GXVisualizer.d.ts.map +1 -0
  116. package/dist/umd/libs/ScrollHeatmapRenderer.d.ts +17 -0
  117. package/dist/umd/libs/ScrollHeatmapRenderer.d.ts.map +1 -0
  118. package/dist/umd/libs/index.d.ts +4 -0
  119. package/dist/umd/libs/index.d.ts.map +1 -0
  120. package/dist/umd/libs/types.d.ts +10 -0
  121. package/dist/umd/libs/types.d.ts.map +1 -0
  122. package/dist/umd/stores/data.d.ts +2 -0
  123. package/dist/umd/stores/data.d.ts.map +1 -1
  124. package/dist/umd/stores/mode-single.d.ts +3 -3
  125. package/dist/umd/stores/mode-single.d.ts.map +1 -1
  126. package/dist/umd/stores/viz-scroll.d.ts +2 -0
  127. package/dist/umd/stores/viz-scroll.d.ts.map +1 -1
  128. package/dist/umd/types/heatmap-ref.d.ts +6 -0
  129. package/dist/umd/types/heatmap-ref.d.ts.map +1 -0
  130. package/dist/umd/types/index.d.ts +1 -0
  131. package/dist/umd/types/index.d.ts.map +1 -1
  132. package/package.json +1 -1
  133. package/dist/esm/components/VizScrollmap/AverageFoldLine.d.ts +0 -8
  134. package/dist/esm/components/VizScrollmap/AverageFoldLine.d.ts.map +0 -1
  135. package/dist/esm/components/VizScrollmap/ScrollMapMinimap.d.ts +0 -8
  136. package/dist/esm/components/VizScrollmap/ScrollMapMinimap.d.ts.map +0 -1
  137. package/dist/esm/components/VizScrollmap/ScrollMapOverlay.d.ts +0 -7
  138. package/dist/esm/components/VizScrollmap/ScrollMapOverlay.d.ts.map +0 -1
  139. package/dist/esm/components/VizScrollmap/ScrollmapMarker.d.ts +0 -7
  140. package/dist/esm/components/VizScrollmap/ScrollmapMarker.d.ts.map +0 -1
  141. package/dist/esm/components/VizScrollmapV2/ScrollmapOverlayV2.d.ts +0 -4
  142. package/dist/esm/components/VizScrollmapV2/ScrollmapOverlayV2.d.ts.map +0 -1
  143. package/dist/esm/components/VizScrollmapV2/index.d.ts +0 -2
  144. package/dist/esm/components/VizScrollmapV2/index.d.ts.map +0 -1
  145. package/dist/esm/components/VizScrollmapV2/scrollmap.types.d.ts +0 -18
  146. package/dist/esm/components/VizScrollmapV2/scrollmap.types.d.ts.map +0 -1
  147. package/dist/esm/components/VizScrollmapV2/useScrollmapOverlay.d.ts +0 -16
  148. package/dist/esm/components/VizScrollmapV2/useScrollmapOverlay.d.ts.map +0 -1
  149. package/dist/umd/components/VizScrollmap/AverageFoldLine.d.ts +0 -8
  150. package/dist/umd/components/VizScrollmap/AverageFoldLine.d.ts.map +0 -1
  151. package/dist/umd/components/VizScrollmap/ScrollMapMinimap.d.ts +0 -8
  152. package/dist/umd/components/VizScrollmap/ScrollMapMinimap.d.ts.map +0 -1
  153. package/dist/umd/components/VizScrollmap/ScrollMapOverlay.d.ts +0 -7
  154. package/dist/umd/components/VizScrollmap/ScrollMapOverlay.d.ts.map +0 -1
  155. package/dist/umd/components/VizScrollmap/ScrollmapMarker.d.ts +0 -7
  156. package/dist/umd/components/VizScrollmap/ScrollmapMarker.d.ts.map +0 -1
  157. package/dist/umd/components/VizScrollmapV2/ScrollmapOverlayV2.d.ts +0 -4
  158. package/dist/umd/components/VizScrollmapV2/ScrollmapOverlayV2.d.ts.map +0 -1
  159. package/dist/umd/components/VizScrollmapV2/index.d.ts +0 -2
  160. package/dist/umd/components/VizScrollmapV2/index.d.ts.map +0 -1
  161. package/dist/umd/components/VizScrollmapV2/scrollmap.types.d.ts +0 -18
  162. package/dist/umd/components/VizScrollmapV2/scrollmap.types.d.ts.map +0 -1
  163. package/dist/umd/components/VizScrollmapV2/useScrollmapOverlay.d.ts +0 -16
  164. package/dist/umd/components/VizScrollmapV2/useScrollmapOverlay.d.ts.map +0 -1
package/dist/esm/index.js CHANGED
@@ -106,7 +106,7 @@ const getCompareViewId = (viewId) => {
106
106
  return `compare-${viewId}`;
107
107
  };
108
108
 
109
- const Z_INDEX = {
109
+ const Z_INDEX$1 = {
110
110
  ELEMENTS: 1000,
111
111
  CALLOUT: 2000,
112
112
  MINIMAP: 3000,
@@ -324,6 +324,7 @@ const useHeatmapDataStore = create()(subscribeWithSelector((set) => {
324
324
  clickAreas: new Map([[DEFAULT_VIEW_ID, undefined]]),
325
325
  dataInfo: new Map([[DEFAULT_VIEW_ID, undefined]]),
326
326
  scrollmap: new Map([[DEFAULT_VIEW_ID, undefined]]),
327
+ attentionMap: new Map([[DEFAULT_VIEW_ID, undefined]]),
327
328
  setClickAreas: (clickAreas, viewId = DEFAULT_VIEW_ID) => set((prev) => {
328
329
  const newClickAreas = new Map(prev.clickAreas);
329
330
  newClickAreas.set(viewId, clickAreas);
@@ -336,6 +337,11 @@ const useHeatmapDataStore = create()(subscribeWithSelector((set) => {
336
337
  newClickAreas.set(viewId, filtered);
337
338
  return { clickAreas: newClickAreas };
338
339
  }),
340
+ setAttentionMap: (attentionMap, viewId = DEFAULT_VIEW_ID) => set((prev) => {
341
+ const newAttentionMap = new Map(prev.attentionMap);
342
+ newAttentionMap.set(viewId, attentionMap);
343
+ return { attentionMap: newAttentionMap };
344
+ }),
339
345
  setDataInfo: (dataInfo, viewId = DEFAULT_VIEW_ID) => set((prev) => {
340
346
  const newDataInfo = new Map(prev.dataInfo);
341
347
  newDataInfo.set(viewId, dataInfo);
@@ -372,17 +378,20 @@ const useHeatmapDataStore = create()(subscribeWithSelector((set) => {
372
378
  const newClickAreas = new Map(prev.clickAreas);
373
379
  const newDataInfo = new Map(prev.dataInfo);
374
380
  const newScrollmap = new Map(prev.scrollmap);
381
+ const newAttentionMap = new Map(prev.attentionMap);
375
382
  newData.set(toViewId, prev.data.get(fromViewId));
376
383
  newClickmap.set(toViewId, prev.clickmap.get(fromViewId));
377
384
  newClickAreas.set(toViewId, prev.clickAreas.get(fromViewId));
378
385
  newDataInfo.set(toViewId, prev.dataInfo.get(fromViewId));
379
386
  newScrollmap.set(toViewId, prev.scrollmap.get(fromViewId));
387
+ newAttentionMap.set(toViewId, prev.attentionMap.get(fromViewId));
380
388
  return {
381
389
  data: newData,
382
390
  clickmap: newClickmap,
383
391
  clickAreas: newClickAreas,
384
392
  dataInfo: newDataInfo,
385
393
  scrollmap: newScrollmap,
394
+ attentionMap: newAttentionMap,
386
395
  };
387
396
  }),
388
397
  clearView: (viewId) => set((prev) => {
@@ -391,17 +400,20 @@ const useHeatmapDataStore = create()(subscribeWithSelector((set) => {
391
400
  const newClickAreas = new Map(prev.clickAreas);
392
401
  const newDataInfo = new Map(prev.dataInfo);
393
402
  const newScrollmap = new Map(prev.scrollmap);
403
+ const newAttentionMap = new Map(prev.attentionMap);
394
404
  newData.delete(viewId);
395
405
  newClickmap.delete(viewId);
396
406
  newClickAreas.delete(viewId);
397
407
  newDataInfo.delete(viewId);
398
408
  newScrollmap.delete(viewId);
409
+ newAttentionMap.delete(viewId);
399
410
  return {
400
411
  data: newData,
401
412
  clickmap: newClickmap,
402
413
  clickAreas: newClickAreas,
403
414
  dataInfo: newDataInfo,
404
415
  scrollmap: newScrollmap,
416
+ attentionMap: newAttentionMap,
405
417
  };
406
418
  }),
407
419
  resetAll: () => set({
@@ -410,6 +422,7 @@ const useHeatmapDataStore = create()(subscribeWithSelector((set) => {
410
422
  clickAreas: new Map([[DEFAULT_VIEW_ID, undefined]]),
411
423
  dataInfo: new Map([[DEFAULT_VIEW_ID, undefined]]),
412
424
  scrollmap: new Map([[DEFAULT_VIEW_ID, undefined]]),
425
+ attentionMap: new Map([[DEFAULT_VIEW_ID, undefined]]),
413
426
  }),
414
427
  };
415
428
  }));
@@ -864,6 +877,7 @@ const useHeatmapVizScrollStore = create()(subscribeWithSelector((set) => {
864
877
  zones: new Map([[DEFAULT_VIEW_ID, []]]),
865
878
  hoveredZone: new Map([[DEFAULT_VIEW_ID, null]]),
866
879
  showMinimap: new Map([[DEFAULT_VIEW_ID, true]]),
880
+ selectedScrollY: new Map([[DEFAULT_VIEW_ID, null]]),
867
881
  setZones: (zones, viewId = DEFAULT_VIEW_ID) => set((prev) => {
868
882
  const newZones = new Map(prev.zones);
869
883
  newZones.set(viewId, zones);
@@ -879,6 +893,11 @@ const useHeatmapVizScrollStore = create()(subscribeWithSelector((set) => {
879
893
  newShowMinimap.set(viewId, showMinimap);
880
894
  return { showMinimap: newShowMinimap };
881
895
  }),
896
+ setSelectedScrollY: (selectedScrollY, viewId = DEFAULT_VIEW_ID) => set((prev) => {
897
+ const newSelectedScrollY = new Map(prev.selectedScrollY);
898
+ newSelectedScrollY.set(viewId, selectedScrollY);
899
+ return { selectedScrollY: newSelectedScrollY };
900
+ }),
882
901
  copyView: (fromViewId, toViewId) => set((prev) => {
883
902
  const newZones = new Map(prev.zones);
884
903
  const newHoveredZone = new Map(prev.hoveredZone);
@@ -1130,26 +1149,7 @@ const useHeatmapAreaClickContext = createViewContextHook({
1130
1149
  }),
1131
1150
  });
1132
1151
 
1133
- // ===========================
1134
- // Constants
1135
- // ===========================
1136
1152
  const DEFAULT_STATE = { hideSidebar: false };
1137
- // ===========================
1138
- // Hook
1139
- // ===========================
1140
- /**
1141
- * Hook to access heatmap click state and actions with optional selector
1142
- *
1143
- * @example
1144
- * ```tsx
1145
- * // Get everything
1146
- * const { state, selectedElement, setSelectedElement } = useHeatmapClickContext();
1147
- *
1148
- * // Get only what you need (no unnecessary re-renders)
1149
- * const setSelectedElement = useHeatmapClickContext(s => s.setSelectedElement);
1150
- * const selectedElement = useHeatmapClickContext(s => s.selectedElement);
1151
- * ```
1152
- */
1153
1153
  const useHeatmapClickContext = createViewContextHook({
1154
1154
  useStore: useHeatmapVizClickStore,
1155
1155
  getState: (store, viewId) => ({
@@ -1187,6 +1187,7 @@ const useHeatmapDataContext = createViewContextHook({
1187
1187
  clickmap: store.clickmap.get(viewId),
1188
1188
  clickAreas: store.clickAreas.get(viewId),
1189
1189
  scrollmap: store.scrollmap.get(viewId),
1190
+ attentionMap: store.attentionMap.get(viewId),
1190
1191
  dataInfo: store.dataInfo.get(viewId),
1191
1192
  }),
1192
1193
  getActions: (store, viewId) => ({
@@ -1195,6 +1196,7 @@ const useHeatmapDataContext = createViewContextHook({
1195
1196
  setClickAreas: (newClickAreas) => store.setClickAreas(newClickAreas, viewId),
1196
1197
  setDataInfoByKey: (key, value) => store.setDataInfoByKey(key, value, viewId),
1197
1198
  setScrollmap: (newScrollmap) => store.setScrollmap(newScrollmap, viewId),
1199
+ setAttentionMap: (newAttentionMap) => store.setAttentionMap(newAttentionMap, viewId),
1198
1200
  setDataInfo: (newDataInfo) => store.setDataInfo(newDataInfo, viewId),
1199
1201
  removeClickArea: (areaId) => store.removeClickArea(areaId, viewId),
1200
1202
  clearView: (viewId) => store.clearView(viewId),
@@ -1218,11 +1220,13 @@ const useHeatmapScrollContext = createViewContextHook({
1218
1220
  zones: store.zones.get(viewId) ?? [],
1219
1221
  hoveredZone: store.hoveredZone.get(viewId) ?? null,
1220
1222
  showMinimap: store.showMinimap.get(viewId) ?? true,
1223
+ selectedScrollY: store.selectedScrollY.get(viewId) ?? 0,
1221
1224
  }),
1222
1225
  getActions: (store, viewId) => ({
1223
1226
  setZones: (zones) => store.setZones(zones, viewId),
1224
1227
  setHoveredZone: (zone) => store.setHoveredZone(zone, viewId),
1225
1228
  setShowMinimap: (value) => store.setShowMinimap(value, viewId),
1229
+ setSelectedScrollY: (value) => store.setSelectedScrollY(value, viewId),
1226
1230
  }),
1227
1231
  });
1228
1232
 
@@ -1446,10 +1450,11 @@ const useRegisterData = (data, dataInfo) => {
1446
1450
  }, []); // eslint-disable-line react-hooks/exhaustive-deps
1447
1451
  };
1448
1452
 
1449
- const useRegisterHeatmap = ({ clickmap, scrollmap, clickAreas }) => {
1453
+ const useRegisterHeatmap = ({ clickmap, scrollmap, clickAreas, attentionMap }) => {
1450
1454
  const setClickmap = useHeatmapDataContext((s) => s.setClickmap);
1451
1455
  const setScrollmap = useHeatmapDataContext((s) => s.setScrollmap);
1452
1456
  const setClickAreas = useHeatmapDataContext((s) => s.setClickAreas);
1457
+ const setAttentionMap = useHeatmapDataContext((s) => s.setAttentionMap);
1453
1458
  const isRegistered = useRef(false);
1454
1459
  useEffect(() => {
1455
1460
  if (isRegistered.current)
@@ -1463,6 +1468,9 @@ const useRegisterHeatmap = ({ clickmap, scrollmap, clickAreas }) => {
1463
1468
  if (scrollmap) {
1464
1469
  setScrollmap(scrollmap);
1465
1470
  }
1471
+ if (attentionMap) {
1472
+ setAttentionMap(attentionMap);
1473
+ }
1466
1474
  isRegistered.current = true;
1467
1475
  }, []); // eslint-disable-line react-hooks/exhaustive-deps
1468
1476
  };
@@ -2404,7 +2412,7 @@ const getStyleFromCandidate = (candidate, widthScale) => {
2404
2412
  return {
2405
2413
  top,
2406
2414
  left,
2407
- zIndex: Z_INDEX.CALLOUT,
2415
+ zIndex: Z_INDEX$1.CALLOUT,
2408
2416
  transform: `scale(${1 / widthScale})`, // TODO: remove this when we have a better way to handle the scale
2409
2417
  transformOrigin: `${xTransformAlign} ${yTransformAlign}`,
2410
2418
  };
@@ -4471,27 +4479,43 @@ const useClickmap = () => {
4471
4479
 
4472
4480
  const useScrollmap = () => {
4473
4481
  const vizRef = useHeatmapVizRectContext((s) => s.vizRef);
4482
+ const scrollType = useHeatmapSettingContext((s) => s.scrollType);
4474
4483
  const scrollmap = useHeatmapDataContext((s) => s.scrollmap);
4484
+ const attentionMap = useHeatmapDataContext((s) => s.attentionMap);
4485
+ const dataMap = useMemo(() => {
4486
+ switch (scrollType) {
4487
+ case EScrollType.Depth:
4488
+ return scrollmap;
4489
+ case EScrollType.Attention:
4490
+ return attentionMap;
4491
+ case EScrollType.Revenue:
4492
+ return [];
4493
+ default:
4494
+ return scrollmap;
4495
+ }
4496
+ }, [scrollmap, attentionMap, scrollType]);
4475
4497
  const start = useCallback(() => {
4476
- if (!vizRef || !scrollmap || scrollmap.length === 0)
4498
+ if (!vizRef || !dataMap || dataMap.length === 0)
4477
4499
  return;
4478
4500
  try {
4479
4501
  vizRef?.clearmap?.();
4480
- vizRef?.scrollmap?.(scrollmap);
4502
+ vizRef?.scrollmap?.(dataMap);
4481
4503
  }
4482
4504
  catch (error) {
4483
4505
  logger$4.error(`🚀 🐥 ~ useScrollmap ~ error:`, error);
4484
4506
  }
4485
- }, [vizRef, scrollmap]);
4507
+ }, [vizRef, dataMap]);
4486
4508
  return { start };
4487
4509
  };
4488
4510
 
4489
4511
  const useHeatmapCanvas = () => {
4490
4512
  const heatmapType = useHeatmapSettingContext((state) => state.heatmapType);
4491
4513
  const clickMode = useHeatmapSettingContext((state) => state.clickMode);
4514
+ const scrollType = useHeatmapSettingContext((state) => state.scrollType);
4492
4515
  const { start: startClickmap } = useClickmap();
4493
4516
  const { start: startAreaClickmap } = useAreaClickmap();
4494
4517
  const { start: startScrollmap } = useScrollmap();
4518
+ // const { start: startAttentionMap } = useAttentionMap();
4495
4519
  useEffect(() => {
4496
4520
  switch (heatmapType) {
4497
4521
  case EHeatmapType.Click:
@@ -4506,7 +4530,7 @@ const useHeatmapCanvas = () => {
4506
4530
  startScrollmap();
4507
4531
  break;
4508
4532
  }
4509
- }, [heatmapType, clickMode, startClickmap, startAreaClickmap, startScrollmap]);
4533
+ }, [heatmapType, clickMode, startClickmap, startAreaClickmap, startScrollmap, scrollType]);
4510
4534
  };
4511
4535
 
4512
4536
  const scrollToElementIfNeeded = (visualRef, rect, scale, onScrollComplete) => {
@@ -6431,6 +6455,260 @@ function initIframeHelper$1(iframe, rect, onSuccess) {
6431
6455
  enableNavigationBlocking();
6432
6456
  }
6433
6457
 
6458
+ const CANVAS_ID = 'clarity-heatmap-canvas';
6459
+ const ATTENTION_HUES = [240, 210, 180, 150, 120, 90, 60, 30, 0];
6460
+ const CANVAS_MAX_HEIGHT = 65535;
6461
+ const Z_INDEX = 2147483647;
6462
+ const DEFAULT_IFRAME_ID = 'clarity-snapshot-heatmap-iframe';
6463
+ const SECONDARY_IFRAME_ID = 'clarity-snapshot-heatmap-iframe-secondary';
6464
+ const DEFAULT_VISUAL_DIV_ID = 'heatmapVisual';
6465
+ const SECONDARY_VISUAL_DIV_ID = 'heatmapVisual_sec';
6466
+ class AttentionMapRenderer {
6467
+ attentionData = null;
6468
+ attentionMapData = null;
6469
+ observer = null;
6470
+ visualizer = null;
6471
+ avgFold = 0;
6472
+ heatmapIframeId = DEFAULT_IFRAME_ID;
6473
+ heatmapVisualDivId = DEFAULT_VISUAL_DIV_ID;
6474
+ state;
6475
+ constructor(state) {
6476
+ this.state = state;
6477
+ }
6478
+ reset = () => {
6479
+ this.attentionData = null;
6480
+ this.attentionMapData = null;
6481
+ this.avgFold = 0;
6482
+ this.observer?.disconnect();
6483
+ this.observer = null;
6484
+ if (this.state?.window) {
6485
+ this.state.window.removeEventListener('resize', this.reRender, true);
6486
+ }
6487
+ };
6488
+ clear = () => {
6489
+ if (!this.state?.window)
6490
+ return;
6491
+ const win = this.state.window;
6492
+ const doc = win.document;
6493
+ const de = doc.documentElement;
6494
+ const canvas = doc.getElementById(CANVAS_ID);
6495
+ if (canvas) {
6496
+ canvas.width = de.clientWidth;
6497
+ canvas.height = de.clientHeight;
6498
+ canvas.style.left = `${win.pageXOffset}px`;
6499
+ canvas.style.top = `${win.pageYOffset}px`;
6500
+ canvas.getContext('2d')?.clearRect(0, 0, canvas.width, canvas.height);
6501
+ }
6502
+ this.reset();
6503
+ };
6504
+ attention = (attentionData, avgFold, visualizer, isSecondary = false) => {
6505
+ this.attentionData = attentionData ?? this.attentionData;
6506
+ this.visualizer = visualizer ?? this.visualizer;
6507
+ this.avgFold = avgFold ?? this.avgFold;
6508
+ if (isSecondary) {
6509
+ this.heatmapIframeId = SECONDARY_IFRAME_ID;
6510
+ this.heatmapVisualDivId = SECONDARY_VISUAL_DIV_ID;
6511
+ }
6512
+ return this.renderAttentionmap();
6513
+ };
6514
+ reRender = () => {
6515
+ const doc = this.state?.window?.document;
6516
+ if (!doc)
6517
+ return;
6518
+ const canvas = this.overlay();
6519
+ if (!canvas)
6520
+ return;
6521
+ const ctx = canvas.getContext('2d');
6522
+ const body = doc.body;
6523
+ const de = doc.documentElement;
6524
+ const contentHeight = Math.max(body.scrollHeight, body.offsetHeight, de.clientHeight, de.scrollHeight, de.offsetHeight);
6525
+ canvas.height = Math.min(contentHeight, CANVAS_MAX_HEIGHT);
6526
+ canvas.style.top = '0px';
6527
+ if (canvas.width <= 0 || canvas.height <= 0 || !this.attentionMapData)
6528
+ return;
6529
+ const gradient = ctx.createLinearGradient(0, 0, 0, canvas.height);
6530
+ for (let i = 0; i < 100; i++) {
6531
+ gradient.addColorStop(i / 100, `hsla(${ATTENTION_HUES[this.attentionMapData[i].colorIndex]}, 100%, 50%, 0.6)`);
6532
+ }
6533
+ ctx.fillStyle = gradient;
6534
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
6535
+ };
6536
+ renderAttentionmap = () => {
6537
+ const doc = this.state?.window?.document;
6538
+ if (!doc)
6539
+ return null;
6540
+ const canvas = this.overlay();
6541
+ if (!canvas)
6542
+ return null;
6543
+ const ctx = canvas.getContext('2d');
6544
+ const body = doc.body;
6545
+ const de = doc.documentElement;
6546
+ const contentHeight = Math.max(body.scrollHeight, body.offsetHeight, de.clientHeight, de.scrollHeight, de.offsetHeight);
6547
+ canvas.height = Math.min(contentHeight, CANVAS_MAX_HEIGHT);
6548
+ canvas.style.top = '0px';
6549
+ let iframeEl = document.getElementById(this.heatmapIframeId);
6550
+ if (!iframeEl) {
6551
+ iframeEl = document.getElementById('clarity-snapshot-iframe');
6552
+ }
6553
+ const visualDiv = document.getElementById(this.heatmapVisualDivId);
6554
+ const visualWidth = visualDiv?.clientWidth ?? 0;
6555
+ const visualHeight = visualDiv?.clientHeight ?? 0;
6556
+ const maxCumulativeTime = this.buildAggregatedData(doc, contentHeight, iframeEl);
6557
+ const colorStops = new Array(100);
6558
+ if (canvas.width > 0 && canvas.height > 0 && this.attentionMapData) {
6559
+ const gradient = ctx.createLinearGradient(0, 0, 0, canvas.height);
6560
+ for (const point of this.attentionMapData) {
6561
+ const timePercent = Math.floor((100 * point.cumulativeTime) / maxCumulativeTime);
6562
+ const colorIndex = timePercent <= 5 ? 0 : Math.min(Math.ceil(timePercent / 10), 8);
6563
+ if (point.scrollPos / 100 <= 1) {
6564
+ point.colorIndex = colorIndex;
6565
+ colorStops[point.scrollPos] = colorIndex;
6566
+ }
6567
+ }
6568
+ // Smooth the top portion based on the fold/viewport ratio
6569
+ const foldPixels = visualWidth >= visualHeight ? 0.15 * visualHeight : 0.2 * visualHeight;
6570
+ const smoothUntil = Math.min(Math.ceil((foldPixels / canvas.height) * 100), 98);
6571
+ for (let i = 0; i < smoothUntil; i++) {
6572
+ colorStops[i] = colorStops[smoothUntil + 1];
6573
+ this.attentionMapData[i].colorIndex = colorStops[smoothUntil + 1];
6574
+ this.attentionMapData[i].cumulativeTime = this.attentionMapData[smoothUntil + 1].cumulativeTime;
6575
+ }
6576
+ // Smooth isolated single-step outliers
6577
+ for (let i = 0; i < 100; i++) {
6578
+ let colorIndex = colorStops[i];
6579
+ if (i > 0 && i < 99) {
6580
+ const prev = colorStops[i - 1];
6581
+ if (prev === colorStops[i + 1] && colorIndex !== prev && Math.abs(colorIndex - prev) === 1) {
6582
+ colorIndex = prev;
6583
+ this.attentionMapData[i].colorIndex = colorIndex;
6584
+ }
6585
+ }
6586
+ gradient.addColorStop(i / 100, `hsla(${ATTENTION_HUES[colorIndex]}, 100%, 50%, 0.6)`);
6587
+ }
6588
+ ctx.fillStyle = gradient;
6589
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
6590
+ }
6591
+ return this.attentionMapData;
6592
+ };
6593
+ buildAggregatedData = (doc, contentHeight, iframeEl) => {
6594
+ const elementCache = new Map();
6595
+ this.attentionMapData = Array.from({ length: 100 }, (_, i) => ({
6596
+ scrollPos: i,
6597
+ cumulativeTime: 0,
6598
+ colorIndex: 0,
6599
+ }));
6600
+ let maxTime = 0;
6601
+ const htmlEl = iframeEl?.contentDocument?.getElementsByTagName('HTML')?.[0] ??
6602
+ iframeEl?.ownerDocument?.getElementsByTagName('HTML')?.[0];
6603
+ const scrollTop = htmlEl?.scrollTop ?? 0;
6604
+ const foldPercent = ((this.avgFold ?? 0) / contentHeight) * 100;
6605
+ for (const dataPoint of this.attentionData ?? []) {
6606
+ const { startElementHash, endElementHash, timeSpent } = dataPoint;
6607
+ if (!startElementHash || !endElementHash)
6608
+ continue;
6609
+ let startY = elementCache.get(startElementHash);
6610
+ let endY = elementCache.get(endElementHash);
6611
+ if (startY === undefined) {
6612
+ const el = this.visualizer?.get(startElementHash) ??
6613
+ doc.querySelector(`[data-clarity-hashbeta='${startElementHash}']`);
6614
+ startY = Math.max(scrollTop + (el?.getBoundingClientRect().y ?? 0), 10);
6615
+ elementCache.set(startElementHash, startY);
6616
+ }
6617
+ if (endY === undefined) {
6618
+ const el = this.visualizer?.get(endElementHash) ??
6619
+ doc.querySelector(`[data-clarity-hashbeta='${endElementHash}']`);
6620
+ const rect = el?.getBoundingClientRect();
6621
+ endY = Math.min(scrollTop + (rect?.y ?? 0) + (rect?.height ?? 0), contentHeight);
6622
+ elementCache.set(endElementHash, endY);
6623
+ }
6624
+ if (startY && endY && endY >= startY) {
6625
+ const startPercent = Math.max(Math.floor((100 * startY) / contentHeight), 0);
6626
+ const endPercent = Math.min(Math.floor((100 * endY) / contentHeight), 99);
6627
+ if (foldPercent === 0 || endPercent - startPercent <= 2 * foldPercent) {
6628
+ for (let i = startPercent; i < endPercent; i++) {
6629
+ this.attentionMapData[i].cumulativeTime += timeSpent;
6630
+ maxTime = Math.max(maxTime, this.attentionMapData[i].cumulativeTime);
6631
+ }
6632
+ }
6633
+ }
6634
+ }
6635
+ return maxTime;
6636
+ };
6637
+ overlay = () => {
6638
+ if (!this.state?.window)
6639
+ return null;
6640
+ const win = this.state.window;
6641
+ const doc = win.document;
6642
+ const de = doc.documentElement;
6643
+ let canvas = doc.getElementById(CANVAS_ID + '-single');
6644
+ if (!canvas) {
6645
+ canvas = doc.createElement('CANVAS');
6646
+ canvas.id = CANVAS_ID + '-single';
6647
+ canvas.width = 0;
6648
+ canvas.height = 0;
6649
+ canvas.style.position = 'absolute';
6650
+ canvas.style.zIndex = `${Z_INDEX}`;
6651
+ canvas.style.display = 'block';
6652
+ de.appendChild(canvas);
6653
+ win.addEventListener('resize', this.reRender, true);
6654
+ this.observer = typeof window.ResizeObserver !== 'undefined' ? new ResizeObserver(this.reRender) : null;
6655
+ this.observer?.observe(doc.body);
6656
+ }
6657
+ canvas.width = de.clientWidth;
6658
+ canvas.height = de.clientHeight;
6659
+ canvas.style.left = `${win.pageXOffset}px`;
6660
+ canvas.style.top = `${win.pageYOffset}px`;
6661
+ canvas.getContext('2d')?.clearRect(0, 0, canvas.width, canvas.height);
6662
+ return canvas;
6663
+ };
6664
+ }
6665
+
6666
+ class GXVisualizer extends Visualizer {
6667
+ attentionMap;
6668
+ originalHtml;
6669
+ originalClearmap;
6670
+ originalSetup;
6671
+ constructor() {
6672
+ super();
6673
+ this.attentionMap = new AttentionMapRenderer(null);
6674
+ // Save references to base implementations before overriding
6675
+ this.originalHtml = this.html;
6676
+ this.originalClearmap = this.clearmap;
6677
+ this.originalSetup = this.setup;
6678
+ this.html = this.htmlOverride;
6679
+ this.clearmap = this.clearmapOverride;
6680
+ this.setup = this.setupOverride;
6681
+ }
6682
+ htmlOverride = async (decoded, target, portalCanvasId, hash, useproxy, logerror, shortCircuitStrategy) => {
6683
+ await this.originalHtml(decoded, target, portalCanvasId, hash, useproxy, logerror, shortCircuitStrategy);
6684
+ return this;
6685
+ };
6686
+ setupOverride = async (target, options) => {
6687
+ // Clear existing custom renderers before re-initializing (null-safe)
6688
+ this.attentionMap?.clear();
6689
+ // Initialize base Visualizer (sets this.state, this.heatmap, this.layout, etc.)
6690
+ await this.originalSetup(target, options);
6691
+ // Re-create custom renderers with the newly initialized PlaybackState
6692
+ const state = this.state;
6693
+ this.attentionMap = new AttentionMapRenderer(state);
6694
+ return this;
6695
+ };
6696
+ clearmapOverride = () => {
6697
+ this.originalClearmap();
6698
+ this.attentionMap?.clear();
6699
+ };
6700
+ /**
6701
+ * Render attention/engagement map.
6702
+ * @param attentionData - Array of attention data points with start/end element hashes and time spent
6703
+ * @param avgFold - Average fold pixel position (used to scale top portion)
6704
+ * @param isSecondary - Whether to use secondary comparison iframe IDs
6705
+ */
6706
+ attention = (attentionData, avgFold, isSecondary = false) => {
6707
+ this.clearmapOverride();
6708
+ this.attentionMap.attention(attentionData, avgFold, this, isSecondary);
6709
+ };
6710
+ }
6711
+
6434
6712
  const useHeatmapRender = () => {
6435
6713
  const viewId = useViewIdContext();
6436
6714
  const data = useHeatmapDataContext((s) => s.data);
@@ -6442,11 +6720,9 @@ const useHeatmapRender = () => {
6442
6720
  const renderHeatmap = useCallback(async (payloads) => {
6443
6721
  if (!payloads || payloads.length === 0)
6444
6722
  return;
6445
- let visualizer = vizRef;
6446
- if (!visualizer) {
6447
- visualizer = new Visualizer();
6723
+ const visualizer = vizRef ?? new GXVisualizer();
6724
+ if (!vizRef)
6448
6725
  setVizRef(visualizer);
6449
- }
6450
6726
  setIsRenderViz(false);
6451
6727
  const iframe = iframeRef.current;
6452
6728
  if (!iframe?.contentWindow)
@@ -6998,6 +7274,29 @@ const useWrapperRefHeight = (props) => {
6998
7274
  return {};
6999
7275
  };
7000
7276
 
7277
+ const useHeatmapScroll = ({ visualRef }) => {
7278
+ const selectedScrollY = useHeatmapScrollContext((s) => s.selectedScrollY);
7279
+ const widthScale = useHeatmapVizContext((s) => s.widthScale);
7280
+ const iframeHeight = useHeatmapVizRectContext((s) => s.iframeHeight);
7281
+ useEffect(() => {
7282
+ if (!selectedScrollY || !iframeHeight || !visualRef.current)
7283
+ return;
7284
+ const container = visualRef.current;
7285
+ // const visualRect = container.getBoundingClientRect();
7286
+ // const viewportHeight = visualRect.height;
7287
+ // selectedScrollY is a percentage (0-100) → convert to content pixels → scale to visual position
7288
+ const contentPixelY = (selectedScrollY / 100) * iframeHeight;
7289
+ const topScaled = contentPixelY * widthScale;
7290
+ // Skip if already visible in the current viewport
7291
+ // const currentScrollTop = container.scrollTop;
7292
+ // const isVisible = topScaled >= currentScrollTop && topScaled <= currentScrollTop + viewportHeight;
7293
+ // if (isVisible) return;
7294
+ // Center the target position vertically in the viewport
7295
+ const targetScrollTop = Math.max(0, topScaled);
7296
+ container.scrollTo({ top: targetScrollTop, behavior: 'smooth' });
7297
+ }, [selectedScrollY, widthScale, iframeHeight]); // eslint-disable-line react-hooks/exhaustive-deps
7298
+ };
7299
+
7001
7300
  const useZonePositions = (_options) => {
7002
7301
  const iframeHeight = useHeatmapVizRectContext((s) => s.iframeHeight);
7003
7302
  const getZonePosition = useCallback((zone) => {
@@ -7212,7 +7511,7 @@ const PopoverSidebar = () => {
7212
7511
  position: 'absolute',
7213
7512
  top: '24px',
7214
7513
  left: '24px',
7215
- zIndex: Z_INDEX.SIDEBAR_POPOVER,
7514
+ zIndex: Z_INDEX$1.SIDEBAR_POPOVER,
7216
7515
  height: `calc(100% - ${HEATMAP_CONFIG.heightToolbar}px - ${HEATMAP_CONFIG.padding}px - 24px)`,
7217
7516
  width: `calc(${sidebarWidth}px + ${HEATMAP_CONFIG.borderWidth}px)`,
7218
7517
  };
@@ -8361,11 +8660,12 @@ const VizClickmap = ({ iframeRef, visualRef, wrapperRef }) => {
8361
8660
  }
8362
8661
  };
8363
8662
 
8364
- const ScrollMapMinimap = ({ zones, maxUsers }) => {
8663
+ const IS_ENABLE_MINIMAP = false;
8664
+ const Minimap = ({ zones, maxUsers }) => {
8365
8665
  const scrollType = useHeatmapSettingContext((s) => s.scrollType);
8366
8666
  const showMinimap = useHeatmapScrollContext((s) => s.showMinimap);
8367
8667
  const isScrollType = [EScrollType.Attention].includes(scrollType ?? EScrollType.Depth);
8368
- if (!showMinimap || !isScrollType)
8668
+ if (!showMinimap || !isScrollType || !IS_ENABLE_MINIMAP)
8369
8669
  return null;
8370
8670
  return (jsx("div", { style: {
8371
8671
  position: 'fixed',
@@ -8434,10 +8734,10 @@ const HoverZones = ({ iframeRef, wrapperRef, position, currentScrollPercent }) =
8434
8734
  return null;
8435
8735
  if (!position)
8436
8736
  return null;
8437
- return (jsxs(Fragment, { children: [jsx(ScrollZoneTooltip, { position: position, currentScrollPercent: currentScrollPercent, scrollmap: scrollmap || [] }), jsx(ScrollMapMinimap, { zones: zones, maxUsers: maxUsers })] }));
8737
+ return (jsxs(Fragment, { children: [jsx(ScrollZoneTooltip, { position: position, currentScrollPercent: currentScrollPercent, scrollmap: scrollmap || [] }), jsx(Minimap, { zones: zones, maxUsers: maxUsers })] }));
8438
8738
  };
8439
8739
 
8440
- const ScrollMapOverlay = ({ wrapperRef, iframeRef }) => {
8740
+ const ScrollOverlay = ({ wrapperRef, iframeRef }) => {
8441
8741
  const widthScale = useHeatmapVizContext((s) => s.widthScale);
8442
8742
  const iframeHeight = useHeatmapVizRectContext((s) => s.iframeHeight);
8443
8743
  const overlayRef = useRef(null);
@@ -8475,71 +8775,74 @@ const ScrollMapOverlay = ({ wrapperRef, iframeRef }) => {
8475
8775
  }, children: jsx(HoverZones, { position: position, currentScrollPercent: currentScrollPercent, iframeRef: iframeRef, wrapperRef: wrapperRef }) }));
8476
8776
  };
8477
8777
 
8478
- const AverageFoldLine = ({ iframeRef, wrapperRef }) => {
8479
- const dataInfo = useHeatmapDataContext((s) => s.dataInfo);
8480
- const { getZonePosition } = useZonePositions();
8481
- const averageFold = dataInfo?.averageFold || 50;
8482
- const position = getZonePosition({
8483
- startY: averageFold,
8484
- endY: averageFold,
8485
- });
8486
- if (!position)
8487
- return null;
8778
+ const MarkerLine = ({ top, label, bgColor = 'white', lineColor = '#303030', labelColor = '#303030', variant = 'dashed', zIndex = 1, }) => {
8488
8779
  return (jsx("div", { style: {
8489
8780
  position: 'absolute',
8490
- top: `${position.top}px`,
8781
+ top: `${top}px`,
8491
8782
  left: 0,
8492
8783
  width: '100%',
8493
- height: '2px',
8494
- backgroundColor: '#0078D4',
8784
+ height: '0px',
8785
+ borderBottom: `2px ${variant} ${lineColor}`,
8786
+ // height: isSolid ? '2px' : '0px',
8787
+ // boxShadow: isSolid ? `0 0 4px ${lineColor}40` : undefined,
8495
8788
  pointerEvents: 'none',
8496
- zIndex: 2,
8497
- boxShadow: '0 0 4px rgba(0,120,212,0.5)',
8789
+ zIndex,
8498
8790
  display: 'flex',
8499
8791
  alignItems: 'center',
8500
- }, children: jsxs("div", { style: {
8792
+ }, children: jsx("div", { style: {
8501
8793
  position: 'absolute',
8502
- padding: '8px',
8503
- backgroundColor: 'rgba(0, 120, 212, 0.9)',
8504
- color: 'white',
8505
- fontSize: '16px',
8506
- fontWeight: 600,
8794
+ padding: '6px 8px',
8795
+ backgroundColor: bgColor,
8796
+ color: labelColor,
8797
+ fontSize: '14px',
8798
+ fontWeight: 500,
8507
8799
  borderRadius: '4px',
8508
8800
  whiteSpace: 'nowrap',
8509
- left: '12px',
8510
- minWidth: '120px',
8801
+ left: '16px',
8802
+ minWidth: '100px',
8511
8803
  textAlign: 'center',
8512
- }, children: ["Average fold - ", averageFold.toFixed(0), "%"] }) }));
8804
+ }, children: label }) }));
8513
8805
  };
8514
8806
 
8515
- const ScrollmapMarker = ({ iframeRef, wrapperRef }) => {
8807
+ const AverageFold = ({ iframeRef, wrapperRef }) => {
8808
+ const dataInfo = useHeatmapDataContext((s) => s.dataInfo);
8809
+ const { getZonePosition } = useZonePositions();
8810
+ const averageFold = dataInfo?.averageFold || 50;
8811
+ const position = getZonePosition({
8812
+ startY: averageFold,
8813
+ endY: averageFold,
8814
+ });
8815
+ if (!position)
8816
+ return null;
8817
+ return jsx(MarkerLine, { top: position.top, label: `Average fold`, zIndex: 2 });
8818
+ };
8819
+
8820
+ const ScrollMarkers = ({ iframeRef, wrapperRef, visualRef }) => {
8516
8821
  const scrollmap = useHeatmapDataContext((s) => s.scrollmap);
8517
8822
  const scrollType = useHeatmapSettingContext((s) => s.scrollType);
8518
8823
  const { getZonePosition } = useZonePositions();
8824
+ useHeatmapScroll({ visualRef });
8519
8825
  if (!scrollmap || scrollmap.length === 0)
8520
8826
  return null;
8521
- const findScrollPositionForUserPercent = (targetPercent) => {
8522
- for (let i = 0; i < scrollmap.length; i++) {
8523
- if (scrollmap[i].percUsers <= targetPercent) {
8524
- if (i > 0) {
8525
- return scrollmap[i - 1].scrollReachY;
8526
- }
8527
- return scrollmap[i].scrollReachY;
8528
- }
8529
- }
8530
- return scrollmap[scrollmap.length - 1]?.scrollReachY || null;
8827
+ // Matches Clarity's addInfoMarkers logic:
8828
+ // find the closest percUsers entry, then validate it's within ±MARKER_RANGE
8829
+ const MARKER_RANGE = 2;
8830
+ const findScrollReachY = (targetPercent) => {
8831
+ const closest = scrollmap.reduce((prev, curr) => Math.abs(curr.percUsers - targetPercent) < Math.abs(prev.percUsers - targetPercent) ? curr : prev);
8832
+ if (Math.abs(closest.percUsers - targetPercent) > MARKER_RANGE)
8833
+ return null;
8834
+ return closest.scrollReachY;
8531
8835
  };
8532
8836
  const boundaries = [
8533
8837
  { percent: 75, label: '75%', color: '#10B981' },
8534
8838
  { percent: 50, label: '50%', color: '#F59E0B' },
8535
8839
  { percent: 25, label: '25%', color: '#EF4444' },
8536
- { percent: 5, label: '5%', color: '#8B5CF6' },
8537
8840
  ];
8538
8841
  const isScrollDepth = scrollType === EScrollType.Depth;
8539
8842
  if (!isScrollDepth)
8540
8843
  return null;
8541
8844
  return (jsx(Fragment, { children: boundaries.map((boundary) => {
8542
- const scrollY = findScrollPositionForUserPercent(boundary.percent);
8845
+ const scrollY = findScrollReachY(boundary.percent);
8543
8846
  if (scrollY === null)
8544
8847
  return null;
8545
8848
  const position = getZonePosition({
@@ -8548,50 +8851,14 @@ const ScrollmapMarker = ({ iframeRef, wrapperRef }) => {
8548
8851
  });
8549
8852
  if (!position)
8550
8853
  return null;
8551
- return (jsx("div", { className: `marker-boundary-line-${boundary.percent}`, style: {
8552
- position: 'absolute',
8553
- top: `${position.top}px`,
8554
- left: 0,
8555
- transformOrigin: 'left center',
8556
- width: '100%',
8557
- height: '0px',
8558
- // borderBottom: `2px dashed #323130`,
8559
- borderBottom: `2px solid ${boundary.color}`,
8560
- // background: 'repeating-linear-gradient(90deg, #323130, transparent 2px 3px)',
8561
- zIndex: 1,
8562
- display: 'flex',
8563
- alignItems: 'center',
8564
- }, children: jsx("div", { style: {
8565
- position: 'absolute',
8566
- padding: '8px',
8567
- backgroundColor: boundary.color,
8568
- color: 'white',
8569
- fontSize: '16px',
8570
- fontWeight: 600,
8571
- borderRadius: '4px',
8572
- whiteSpace: 'nowrap',
8573
- left: '12px',
8574
- minWidth: '120px',
8575
- textAlign: 'center',
8576
- // textAlign: 'center',
8577
- // padding: '8px',
8578
- // paddingInline: '8px',
8579
- // fontSize: '16px',
8580
- // background: '#fff',
8581
- // width: 'auto',
8582
- // borderRadius: '4px',
8583
- // position: 'absolute',
8584
- // left: '12px',
8585
- // minWidth: '120px',
8586
- }, children: boundary.label }) }, boundary.label));
8854
+ return jsx(MarkerLine, { top: position.top, label: boundary.label }, boundary.label);
8587
8855
  }) }));
8588
8856
  };
8589
8857
 
8590
8858
  const SCROLL_TYPES = [EHeatmapType.Scroll];
8591
- const VizScrollMap = ({ iframeRef, wrapperRef }) => {
8859
+ const VizScrollMap = ({ iframeRef, wrapperRef, visualRef }) => {
8592
8860
  const heatmapType = useHeatmapSettingContext((s) => s.heatmapType);
8593
8861
  const iframeHeight = useHeatmapVizRectContext((s) => s.iframeHeight);
8594
- // useRenderCount('VizScrollMap');
8595
8862
  const isHeatmapScroll = SCROLL_TYPES.includes(heatmapType ?? EHeatmapType.Click);
8596
8863
  if (!iframeHeight || !isHeatmapScroll)
8597
8864
  return null;
@@ -8603,7 +8870,7 @@ const VizScrollMap = ({ iframeRef, wrapperRef }) => {
8603
8870
  height: '100%',
8604
8871
  transform: 'translateZ(0)',
8605
8872
  zIndex: 2,
8606
- }, children: [jsx(ScrollmapMarker, { iframeRef: iframeRef, wrapperRef: wrapperRef }), jsx(AverageFoldLine, { iframeRef: iframeRef, wrapperRef: wrapperRef }), jsx(ScrollMapOverlay, { wrapperRef: wrapperRef, iframeRef: iframeRef })] }));
8873
+ }, children: [jsx(ScrollMarkers, { iframeRef: iframeRef, wrapperRef: wrapperRef, visualRef: visualRef }), jsx(AverageFold, { iframeRef: iframeRef, wrapperRef: wrapperRef }), jsx(ScrollOverlay, { iframeRef: iframeRef, wrapperRef: wrapperRef })] }));
8607
8874
  };
8608
8875
 
8609
8876
  const VizLoadingCanvas = () => {
@@ -8674,7 +8941,7 @@ const VizDomRenderer = ({ mode = 'heatmap' }) => {
8674
8941
  const scrollTop = e.currentTarget.scrollTop;
8675
8942
  handleScroll(scrollTop);
8676
8943
  };
8677
- return (jsxs(WrapperVisual, { visualRef: visualRef, wrapperRef: wrapperRef, scaledHeight: scaledHeight, onScroll: onScroll, iframeHeight: iframeHeight, children: [jsx(VizClickmap, { iframeRef: iframeRef, visualRef: visualRef, wrapperRef: wrapperRef }), jsx("iframe", { ...HEATMAP_IFRAME, id: `clarity-iframe-${viewId}`, ref: iframeRef, width: contentWidth, height: wrapperHeight }), jsx(VizLoadingCanvas, {}), jsx(VizScrollMap, { iframeRef: iframeRef, wrapperRef: visualRef })] }));
8944
+ return (jsxs(WrapperVisual, { visualRef: visualRef, wrapperRef: wrapperRef, scaledHeight: scaledHeight, onScroll: onScroll, iframeHeight: iframeHeight, children: [jsx(VizClickmap, { iframeRef: iframeRef, visualRef: visualRef, wrapperRef: wrapperRef }), jsx("iframe", { ...HEATMAP_IFRAME, id: `clarity-iframe-${viewId}`, ref: iframeRef, width: contentWidth, height: wrapperHeight }), jsx(VizLoadingCanvas, {}), jsx(VizScrollMap, { visualRef: visualRef, iframeRef: iframeRef, wrapperRef: wrapperRef })] }));
8678
8945
  };
8679
8946
 
8680
8947
  const VizLoading = () => {
@@ -8785,10 +9052,10 @@ const ContentTopBar = () => {
8785
9052
  }, children: CompTopBar && jsx(CompTopBar, {}) }));
8786
9053
  };
8787
9054
 
8788
- const HeatmapLayout = ({ data, clickmap, clickAreas, scrollmap, controls, dataInfo, isLoading, isLoadingCanvas, }) => {
9055
+ const HeatmapLayout = ({ data, clickmap, clickAreas, scrollmap, attentionMap, controls, dataInfo, isLoading, isLoadingCanvas, }) => {
8789
9056
  useRegisterControl(controls);
8790
9057
  useRegisterData(data, dataInfo);
8791
- useRegisterHeatmap({ clickmap, scrollmap, clickAreas });
9058
+ useRegisterHeatmap({ clickmap, scrollmap, clickAreas, attentionMap });
8792
9059
  useRegisterConfig({ isLoading, isLoadingCanvas });
8793
9060
  // performanceLogger.configure({
8794
9061
  // enabled: true,
@@ -8819,4 +9086,4 @@ const HeatmapLayout = ({ data, clickmap, clickAreas, scrollmap, controls, dataIn
8819
9086
  }
8820
9087
  };
8821
9088
 
8822
- export { BACKDROP_CONFIG, DEFAULT_SIDEBAR_WIDTH, DEFAULT_VIEW_ID, DEFAULT_ZOOM_RATIO, EClickMode, EClickRankType, EClickType, EDeviceType, EHeatmapType, ELM_CALLOUT_CONFIG, EScrollType, GraphView, HEATMAP_CONFIG, HEATMAP_IFRAME, HEATMAP_STYLE, HeatmapLayout, ViewIdContext, Z_INDEX, compareViewPerformance, convertViewportToIframeCoords, createStorePerformanceTracker, createViewContextHook, downloadPerformanceReport, getCompareViewId, getMetricsByViewId, getPerformanceReportJSON, getScrollGradientColor, performanceLogger, printPerformanceSummary, scrollToElementIfNeeded, sendPerformanceReport, serializeAreas, trackStoreAction, useAreaCreation, useAreaEditMode, useAreaFilterVisible, useAreaHydration, useAreaInteraction, useAreaPositionsUpdater, useAreaRectSync, useAreaRendererContainer, useAreaTopAutoDetect, useClickedElement, useDebounceCallback, useElementCalloutVisible, useHeatmapAreaClickContext, useHeatmapCanvas, useHeatmapClickContext, useHeatmapCompareStore, useHeatmapConfigStore, useHeatmapCopyView, useHeatmapDataContext, useHeatmapEffects, useHeatmapElementPosition, useHeatmapHoverContext, useHeatmapLiveStore, useHeatmapRenderByMode, useHeatmapScale, useHeatmapScrollContext, useHeatmapSettingContext, useHeatmapVizContext, useHeatmapVizRectContext, useHeatmapWidthByDevice, useHoveredElement, useIframeHeight, useIframeHeightProcessor, useMeasureFunction, useRegisterConfig, useRegisterControl, useRegisterData, useRegisterHeatmap, useRenderCount, useScrollmapZones, useTrackHookCall, useViewIdContext, useVizLiveRender, useWhyDidYouUpdate, useWrapperRefHeight, useZonePositions, withPerformanceTracking };
9089
+ export { BACKDROP_CONFIG, DEFAULT_SIDEBAR_WIDTH, DEFAULT_VIEW_ID, DEFAULT_ZOOM_RATIO, EClickMode, EClickRankType, EClickType, EDeviceType, EHeatmapType, ELM_CALLOUT_CONFIG, EScrollType, GraphView, HEATMAP_CONFIG, HEATMAP_IFRAME, HEATMAP_STYLE, HeatmapLayout, ViewIdContext, Z_INDEX$1 as Z_INDEX, compareViewPerformance, convertViewportToIframeCoords, createStorePerformanceTracker, createViewContextHook, downloadPerformanceReport, getCompareViewId, getMetricsByViewId, getPerformanceReportJSON, getScrollGradientColor, performanceLogger, printPerformanceSummary, scrollToElementIfNeeded, sendPerformanceReport, serializeAreas, trackStoreAction, useAreaCreation, useAreaEditMode, useAreaFilterVisible, useAreaHydration, useAreaInteraction, useAreaPositionsUpdater, useAreaRectSync, useAreaRendererContainer, useAreaTopAutoDetect, useClickedElement, useDebounceCallback, useElementCalloutVisible, useHeatmapAreaClickContext, useHeatmapCanvas, useHeatmapClickContext, useHeatmapCompareStore, useHeatmapConfigStore, useHeatmapCopyView, useHeatmapDataContext, useHeatmapEffects, useHeatmapElementPosition, useHeatmapHoverContext, useHeatmapLiveStore, useHeatmapRenderByMode, useHeatmapScale, useHeatmapScroll, useHeatmapScrollContext, useHeatmapSettingContext, useHeatmapVizContext, useHeatmapVizRectContext, useHeatmapWidthByDevice, useHoveredElement, useIframeHeight, useIframeHeightProcessor, useMeasureFunction, useRegisterConfig, useRegisterControl, useRegisterData, useRegisterHeatmap, useRenderCount, useScrollmapZones, useTrackHookCall, useViewIdContext, useVizLiveRender, useWhyDidYouUpdate, useWrapperRefHeight, useZonePositions, withPerformanceTracking };