@vinctus/react-maplibre 0.1.1 → 0.1.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.
package/dist/Map.d.ts CHANGED
@@ -19,7 +19,7 @@ export declare const viewStateFromMap: (map: maplibre.Map) => {
19
19
  };
20
20
  export declare const useMap: () => {
21
21
  map: maplibre.Map | null;
22
- setMap: React.Dispatch<React.SetStateAction<maplibre.Map | null>>;
22
+ mapRef: React.MutableRefObject<maplibre.Map | null>;
23
23
  mapLoaded: boolean;
24
24
  setMapLoaded: React.Dispatch<React.SetStateAction<boolean>>;
25
25
  };
@@ -27,6 +27,7 @@ export declare const MapProvider: FC<{
27
27
  children?: ReactNode;
28
28
  }>;
29
29
  export type MapProps = {
30
+ reuseMaps?: boolean;
30
31
  accessToken?: string;
31
32
  antialias?: boolean;
32
33
  children?: ReactNode | ReactNode[];
package/dist/Map.js CHANGED
@@ -16,10 +16,7 @@ import { ErrorBoundary } from './ErrorBoundary'; // eslint-disable-line import/n
16
16
  const DEFAULT_STYLE = 'https://demotiles.maplibre.org/style.json';
17
17
  const DISABLE_PITCH = 0;
18
18
  const MapContext = React.createContext({
19
- map: null,
20
- setMap: () => {
21
- throw new Error('Use <MapProvider>');
22
- },
19
+ mapRef: { current: null },
23
20
  mapLoaded: false,
24
21
  setMapLoaded: () => {
25
22
  throw new Error('Use <MapProvider>');
@@ -30,51 +27,92 @@ export const viewStateFromMap = (map) => ({
30
27
  latitude: map.getCenter().lat,
31
28
  zoom: map.getZoom(),
32
29
  });
33
- export const useMap = () => useContext(MapContext);
30
+ export const useMap = () => {
31
+ const context = useContext(MapContext);
32
+ if (!context) {
33
+ throw new Error('useMap must be used within a MapProvider');
34
+ }
35
+ const { mapRef, mapLoaded, setMapLoaded } = context;
36
+ return {
37
+ map: mapRef.current,
38
+ mapRef,
39
+ mapLoaded,
40
+ setMapLoaded,
41
+ };
42
+ };
34
43
  export const MapProvider = ({ children }) => {
35
- const [map, setMap] = useState(null);
44
+ const mapRef = useRef(null);
36
45
  const [mapLoaded, setMapLoaded] = useState(false);
37
- return (_jsx(MapContext.Provider, Object.assign({ value: { map, setMap, mapLoaded, setMapLoaded } }, { children: children })));
46
+ return (_jsx(MapContext.Provider, Object.assign({ value: { mapRef, mapLoaded, setMapLoaded } }, { children: children })));
38
47
  };
39
48
  function addEventHandler(map, type, handler) {
40
49
  map.on(type, (ev) => handler(Object.assign({ viewState: viewStateFromMap(map) }, ev)));
41
50
  }
42
51
  export const Map = React.forwardRef((_a, ref) => {
43
- var { children, style, id, longitude, latitude, maxPitch = DISABLE_PITCH, mapStyle = DEFAULT_STYLE, zoom, onDragEnd, onLoad, onMoveEnd, onZoomEnd, fallback } = _a, options = __rest(_a, ["children", "style", "id", "longitude", "latitude", "maxPitch", "mapStyle", "zoom", "onDragEnd", "onLoad", "onMoveEnd", "onZoomEnd", "fallback"]);
52
+ var { reuseMaps = true, children, style, id, longitude, latitude, maxPitch = DISABLE_PITCH, mapStyle = DEFAULT_STYLE, zoom, onDragEnd, onLoad, onMoveEnd, onZoomEnd, fallback } = _a, options = __rest(_a, ["reuseMaps", "children", "style", "id", "longitude", "latitude", "maxPitch", "mapStyle", "zoom", "onDragEnd", "onLoad", "onMoveEnd", "onZoomEnd", "fallback"]);
44
53
  const mapContainer = useRef(null);
45
- const { map, setMap, setMapLoaded } = useMap();
46
- useImperativeHandle(ref, () => map, [map]);
54
+ const { mapRef, mapLoaded, setMapLoaded } = useMap();
55
+ useImperativeHandle(ref, () => mapRef.current, [
56
+ mapRef,
57
+ ]);
47
58
  useEffect(() => {
48
- if (map)
49
- return; // initialize map only once
50
- if (mapContainer.current) {
59
+ if (reuseMaps && mapRef.current) {
60
+ // Reattach the existing map instance to the new container
61
+ if (mapContainer.current && mapRef.current.getContainer() !== mapContainer.current) {
62
+ mapContainer.current.appendChild(mapRef.current.getContainer());
63
+ mapRef.current.resize(); // resize map in case container dimensions have changed
64
+ }
65
+ return;
66
+ }
67
+ if (mapContainer.current && !mapRef.current) {
51
68
  const m = new maplibre.Map(Object.assign({ container: mapContainer.current, style: mapStyle, center: [longitude, latitude], zoom }, options));
52
69
  if (onDragEnd)
53
70
  addEventHandler(m, 'dragend', onDragEnd);
54
71
  if (onLoad)
55
72
  addEventHandler(m, 'load', (ev) => {
56
73
  onLoad(ev);
57
- setMapLoaded(true);
74
+ if (!mapLoaded)
75
+ setMapLoaded(true);
58
76
  });
59
77
  if (onMoveEnd)
60
78
  addEventHandler(m, 'moveend', onMoveEnd);
61
79
  if (onZoomEnd)
62
80
  addEventHandler(m, 'zoomend', onZoomEnd);
63
- setMap(m);
81
+ mapRef.current = m;
64
82
  }
83
+ // further investigation: calling .remove() causes the following error:
84
+ //
85
+ // Cannot read properties of undefined (reading 'off')
86
+ // TypeError: Cannot read properties of undefined (reading 'off')
87
+ // at t.GeolocateControl.onRemove (http://localhost:3002/static/js/bundle.js:107201:393)
88
+ // at t.Map.removeControl (http://localhost:3002/static/js/bundle.js:107351:57)
89
+ // at http://localhost:3002/static/js/bundle.js:853:53
90
+ // at safelyCallDestroy (http://localhost:3002/static/js/bundle.js:39324:9)
91
+ // at commitHookEffectListUnmount (http://localhost:3002/static/js/bundle.js:39462:15)
92
+ // at commitPassiveUnmountInsideDeletedTreeOnFiber (http://localhost:3002/static/js/bundle.js:41143:15)
93
+ // at commitPassiveUnmountEffectsInsideOfDeletedTree_begin (http://localhost:3002/static/js/bundle.js:41099:9)
94
+ // at commitPassiveUnmountEffects_begin (http://localhost:3002/static/js/bundle.js:41021:15)
95
+ // at commitPassiveUnmountEffects (http://localhost:3002/static/js/bundle.js:41009:7)
96
+ // at flushPassiveEffectsImpl (http://localhost:3002/static/js/bundle.js:42830:7)
97
+ //
98
+ // return () => {
99
+ // if (!reuseMaps && mapRef.current) {
100
+ // mapRef.current.remove()
101
+ // mapRef.current = null
102
+ // }
103
+ // }
65
104
  }, [
66
- map,
105
+ reuseMaps,
67
106
  onDragEnd,
68
107
  onLoad,
69
108
  onMoveEnd,
70
109
  onZoomEnd,
71
- setMap,
72
110
  setMapLoaded,
73
111
  mapStyle,
74
112
  longitude,
75
113
  latitude,
76
114
  zoom,
77
- options,
115
+ // options, // investigate using a useRef for this (other Map options)
78
116
  ]);
79
117
  const memoizedStyle = useMemo(() => (Object.assign({ position: 'relative', width: '100%', height: '100%' }, style)), [style]);
80
118
  return (_jsx(ErrorBoundary, Object.assign({ fallback: fallback }, { children: _jsx("div", Object.assign({ id: id, ref: mapContainer, style: memoizedStyle }, { children: children })) })));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vinctus/react-maplibre",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Minimalist MapLibre GL JS React wrapper library",
5
5
  "types": "dist/index.d.ts",
6
6
  "publishConfig": {