@vinctus/react-maplibre 0.2.7 → 0.2.9

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.
package/dist/Marker.d.ts CHANGED
@@ -6,6 +6,7 @@ export type MarkerProps = {
6
6
  popup?: ReactElement;
7
7
  popupClassName?: string;
8
8
  closeOnClick?: boolean;
9
+ closeButton?: boolean;
9
10
  anchor?: PositionAnchor;
10
11
  color?: string;
11
12
  children?: ReactNode;
package/dist/Marker.js CHANGED
@@ -9,35 +9,85 @@ var __rest = (this && this.__rest) || function (s, e) {
9
9
  }
10
10
  return t;
11
11
  };
12
- import { useEffect, useState, Children } from 'react';
12
+ import { useEffect, useState, Children, useRef } from 'react';
13
13
  import maplibre from 'maplibre-gl';
14
14
  import { useMap } from './Map';
15
15
  import ReactDOM from 'react-dom';
16
- import ReactDOMServer from 'react-dom/server'; // eslint-disable-line import/no-webpack-loader-syntax
16
+ import ReactDOMServer from 'react-dom/server';
17
17
  export const Marker = (_a) => {
18
- var { children, longitude, latitude, popup, popupClassName, closeOnClick } = _a, options = __rest(_a, ["children", "longitude", "latitude", "popup", "popupClassName", "closeOnClick"]);
18
+ var { children, longitude, latitude, popup, popupClassName, closeOnClick = false, closeButton = true } = _a, options = __rest(_a, ["children", "longitude", "latitude", "popup", "popupClassName", "closeOnClick", "closeButton"]);
19
19
  const { map } = useMap();
20
20
  const [result, setResult] = useState(null);
21
+ const markerRef = useRef(null);
22
+ const popupRef = useRef(null);
23
+ const cleanupRef = useRef(null);
21
24
  const optionsString = JSON.stringify(options);
22
25
  useEffect(() => {
23
- let marker = null;
26
+ if (!map)
27
+ return;
24
28
  const isEmpty = Children.count(children) === 0;
25
- if (map) {
26
- const element = document.createElement('div');
27
- const parsedOptions = JSON.parse(optionsString);
28
- if (!isEmpty)
29
- setResult(ReactDOM.createPortal(children, element));
30
- marker = isEmpty
31
- ? new maplibre.Marker(Object.assign({}, parsedOptions))
32
- : new maplibre.Marker(Object.assign(Object.assign({}, parsedOptions), { element }));
33
- if (popup)
34
- marker.setPopup(new maplibre.Popup({ offset: [0, -15], closeOnClick, className: popupClassName }).setHTML(ReactDOMServer.renderToStaticMarkup(popup)));
35
- marker = marker.setLngLat([longitude, latitude]).addTo(map);
29
+ const element = document.createElement('div');
30
+ const parsedOptions = JSON.parse(optionsString);
31
+ if (!isEmpty) {
32
+ setResult(ReactDOM.createPortal(children, element));
33
+ }
34
+ // Create marker
35
+ const marker = isEmpty
36
+ ? new maplibre.Marker(Object.assign({}, parsedOptions))
37
+ : new maplibre.Marker(Object.assign(Object.assign({}, parsedOptions), { element }));
38
+ marker.setLngLat([longitude, latitude]).addTo(map);
39
+ markerRef.current = marker;
40
+ // Handle popup manually if provided
41
+ if (popup) {
42
+ const popupHTML = ReactDOMServer.renderToStaticMarkup(popup);
43
+ const handleMarkerClick = (e) => {
44
+ e.stopPropagation();
45
+ // Close existing popup if any
46
+ if (popupRef.current) {
47
+ popupRef.current.remove();
48
+ popupRef.current = null;
49
+ return; // Toggle behavior - close if already open
50
+ }
51
+ // Create new popup directly on the map
52
+ const newPopup = new maplibre.Popup({
53
+ offset: [0, -15],
54
+ closeOnClick,
55
+ closeButton,
56
+ className: popupClassName,
57
+ })
58
+ .setLngLat([longitude, latitude])
59
+ .setHTML(popupHTML)
60
+ .addTo(map);
61
+ popupRef.current = newPopup;
62
+ // Listen for popup close to clean up reference
63
+ newPopup.on('close', () => {
64
+ popupRef.current = null;
65
+ });
66
+ };
67
+ // Add click listener to marker element
68
+ const markerElement = marker.getElement();
69
+ markerElement.style.cursor = 'pointer';
70
+ markerElement.addEventListener('click', handleMarkerClick);
71
+ // Cleanup function
72
+ const cleanup = () => {
73
+ markerElement.removeEventListener('click', handleMarkerClick);
74
+ if (popupRef.current) {
75
+ popupRef.current.remove();
76
+ popupRef.current = null;
77
+ }
78
+ };
79
+ cleanupRef.current = cleanup;
36
80
  }
37
81
  return () => {
38
- if (marker)
39
- marker.remove();
82
+ if (cleanupRef.current) {
83
+ cleanupRef.current();
84
+ cleanupRef.current = null;
85
+ }
86
+ if (markerRef.current) {
87
+ markerRef.current.remove();
88
+ markerRef.current = null;
89
+ }
40
90
  };
41
- }, [closeOnClick, optionsString, setResult, children, latitude, longitude, map, popup]);
91
+ }, [map, optionsString, children, longitude, latitude, popup, closeOnClick, closeButton]);
42
92
  return result;
43
93
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vinctus/react-maplibre",
3
- "version": "0.2.7",
3
+ "version": "0.2.9",
4
4
  "description": "Minimalist MapLibre GL JS React wrapper library",
5
5
  "type": "module",
6
6
  "types": "dist/index.d.ts",