• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

terrestris / react-geo / 21908535432

11 Feb 2026 02:12PM UTC coverage: 67.847% (-0.6%) from 68.478%
21908535432

Pull #4501

github

web-flow
Merge 9a6181476 into 7c0f7bfdd
Pull Request #4501: Feat(MapComponent) : Add pointermove map event

692 of 1111 branches covered (62.29%)

Branch coverage included in aggregate %.

14 of 32 new or added lines in 2 files covered. (43.75%)

1281 of 1797 relevant lines covered (71.29%)

14.47 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

44.44
/src/Map/MapComponent/MapComponent.tsx
1
import React, {
2
  useCallback, JSX, FC, ComponentProps, useState, useEffect
3
} from 'react';
4

5
import {
6
  DebouncedFunc
7
} from 'lodash';
8
import _debounce from 'lodash/debounce';
9

10
import OlMap from 'ol/Map';
11
import {
12
  Pixel
13
} from 'ol/pixel';
14
import OlMapBrowserEvent from 'ol/MapBrowserEvent';
15

16
export type MapComponentProps = ComponentProps<'div'> & {
17
  firePointerRest?: boolean;
18
  map: OlMap;
19
  mapDivId?: string;
20
  pointerRestInterval?: number;
21
  pointerRestTolerance?: number;
22
};
23

24
export const MapComponent: FC<MapComponentProps> = ({
4✔
25
  firePointerRest = true,
41✔
26
  pointerRestInterval = 1,
41✔
27
  pointerRestTolerance = 1,
41✔
28
  map,
29
  mapDivId = 'map',
1✔
30
  ...passThroughProps
31
}): JSX.Element => {
32

33
  const [lastPointerPixel, setLastPointerPixel] = useState<Pixel>([-Infinity, -Infinity]);
41✔
34
  const [isMouseOverMapEl, setIsMouseOverMapEl] = useState<boolean>(false);
41✔
35

36
  const refCallback = useCallback((ref: HTMLDivElement) => {
41✔
37
    if (!map) {
64!
38
      return;
×
39
    }
40
    if (ref === null) {
64✔
41
      map.setTarget(undefined);
32✔
42
    } else {
43
      map.setTarget(ref);
32✔
44
    }
45
  }, [map]);
46

47
  useEffect(() => {
41✔
48
    if (!map) {
32!
NEW
49
      return;
×
50
    }
51

52
    const checkPointerRest = (olEvt: OlMapBrowserEvent<PointerEvent | KeyboardEvent | WheelEvent>): void => {
32✔
53

NEW
54
      if (olEvt.dragging || !isMouseOverMapEl) {
×
NEW
55
        return;
×
56
      }
NEW
57
      const target: EventTarget | null = olEvt?.originalEvent?.target;
×
NEW
58
      if (target && (target as HTMLElement).tagName?.toLowerCase() !== 'canvas') {
×
NEW
59
        return;
×
60
      }
61

NEW
62
      const pixel: Pixel = olEvt.pixel;
×
63

NEW
64
      if (lastPointerPixel) {
×
NEW
65
        const deltaX: number = Math.abs(lastPointerPixel[0] - pixel[0]);
×
NEW
66
        const deltaY: number = Math.abs(lastPointerPixel[1] - pixel[1]);
×
67

NEW
68
        if (deltaX > pointerRestTolerance || deltaY > pointerRestTolerance) {
×
NEW
69
          setLastPointerPixel(pixel);
×
70
        } else {
NEW
71
          return;
×
72
        }
73
      } else {
NEW
74
        setLastPointerPixel(pixel);
×
75
      }
76

NEW
77
      olEvt.type = 'pointerrest';
×
NEW
78
      map.dispatchEvent(olEvt);
×
79
    };
80

81
    const debouncedCheckPointerRest: DebouncedFunc<(
82
      evt: OlMapBrowserEvent<PointerEvent | KeyboardEvent | WheelEvent>
83
    ) => void> =
84
      _debounce(
32✔
85
        checkPointerRest,
86
        pointerRestInterval
87
      );
88

89
    if (map) {
32!
90
      if (firePointerRest) {
32!
91
        map.on('pointermove', debouncedCheckPointerRest);
32✔
92
      }
93
    }
94
    return () => {
32✔
95
      if (firePointerRest) {
32!
96
        map.un('pointermove', debouncedCheckPointerRest);
32✔
97
      }
98
    };
99

100
  }, [map, firePointerRest, isMouseOverMapEl, pointerRestInterval, lastPointerPixel, pointerRestTolerance]);
101

102
  if (!map) {
41!
103
    return <></>;
×
104
  }
105

106
  return (
41✔
107
    <div
108
      id={mapDivId}
109
      ref={refCallback}
110
      className="map"
NEW
111
      onMouseOver={() => setIsMouseOverMapEl(true)}
×
NEW
112
      onMouseOut={() => setIsMouseOverMapEl(false)}
×
113
      role="presentation"
114
      {...passThroughProps}
115
    />
116
  );
117
};
118

119
export default MapComponent;
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc