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

terrestris / react-geo / 22960711092

11 Mar 2026 03:34PM UTC coverage: 68.111% (-0.4%) from 68.478%
22960711092

Pull #4501

github

web-flow
Merge 17295d1c3 into 0e236b75f
Pull Request #4501: Feat(MapComponent) : Add pointermove map event

696 of 1111 branches covered (62.65%)

Branch coverage included in aggregate %.

16 of 31 new or added lines in 1 file covered. (51.61%)

1284 of 1796 relevant lines covered (71.49%)

14.75 hits per line

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

55.56
/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 OlMapBrowserEvent from 'ol/MapBrowserEvent';
12
import {
13
  Pixel
14
} from 'ol/pixel';
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 = false,
50✔
26
  pointerRestInterval = 1,
53✔
27
  pointerRestTolerance = 1,
53✔
28
  map,
29
  mapDivId = 'map',
14✔
30
  ...passThroughProps
31
}): JSX.Element => {
32

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

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

47
  useEffect(() => {
55✔
48
    if (!map) {
46✔
49
      return;
1✔
50
    }
51

52
    const checkPointerRest = (olEvt: OlMapBrowserEvent<PointerEvent | KeyboardEvent | WheelEvent>): void => {
45✔
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(
45✔
85
        checkPointerRest,
86
        pointerRestInterval
87
      );
88

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

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

102
  if (!map) {
55✔
103
    return <></>;
1✔
104
  }
105

106
  return (
54✔
107
    <div
108
      id={mapDivId}
109
      ref={refCallback}
110
      className="map"
111
      onMouseOver={() => setIsMouseOverMapEl(true)}
2✔
112
      onMouseOut={() => setIsMouseOverMapEl(false)}
1✔
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