@vinctus/react-maplibre 0.2.25 → 1.0.0-alpha

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.
@@ -1,4 +1,4 @@
1
- import React, { Component, ErrorInfo, ReactNode } from 'react';
1
+ import { Component, ErrorInfo, ReactNode } from 'react';
2
2
  interface Props {
3
3
  children?: ReactNode;
4
4
  fallback?: ReactNode;
@@ -10,6 +10,6 @@ export declare class ErrorBoundary extends Component<Props, State> {
10
10
  constructor(props: any);
11
11
  static getDerivedStateFromError(_: Error): State;
12
12
  componentDidCatch(error: Error, errorInfo: ErrorInfo): void;
13
- render(): string | number | boolean | Iterable<React.ReactNode> | import("react/jsx-runtime").JSX.Element | null | undefined;
13
+ render(): string | number | boolean | Iterable<ReactNode> | import("react/jsx-runtime").JSX.Element | null | undefined;
14
14
  }
15
15
  export {};
@@ -1,6 +1,5 @@
1
1
  import { FC } from 'react';
2
- import { GeolocateControlOptions } from 'maplibre-gl';
3
- import { ControlPosition } from './types';
2
+ import { GeolocateControlOptions, ControlPosition } from 'maplibre-gl';
4
3
  export type GeolocateControlProps = {
5
4
  position?: ControlPosition;
6
5
  options?: GeolocateControlOptions;
@@ -1,19 +1,24 @@
1
- import { useEffect } from 'react';
1
+ import { useContext, useEffect } from 'react';
2
2
  import maplibre from 'maplibre-gl';
3
- import { useMap } from './Map';
3
+ import { MapContext } from './Map';
4
4
  export const GeolocateControl = ({ position = 'bottom-right', options = { showUserLocation: false }, }) => {
5
- const { map } = useMap();
5
+ const { map, mapLoaded } = useContext(MapContext);
6
6
  const optionsString = JSON.stringify(options || {});
7
7
  useEffect(() => {
8
8
  const control = new maplibre.GeolocateControl(JSON.parse(optionsString));
9
- if (map && position) {
9
+ if (map && mapLoaded && position) {
10
10
  map.addControl(control, position);
11
11
  }
12
12
  return () => {
13
- if (map && map.hasControl(control)) {
14
- map.removeControl(control);
13
+ try {
14
+ if (map && !map._removed && map.hasControl(control)) {
15
+ map.removeControl(control);
16
+ }
17
+ }
18
+ catch (_a) {
19
+ console.warn('Error cleaning up GeolocateControl');
15
20
  }
16
21
  };
17
- }, [position, optionsString, map]);
22
+ }, [position, optionsString, map, mapLoaded]);
18
23
  return null;
19
24
  };
package/dist/Layer.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { FC } from 'react';
2
- import { LayerSpecification, GeoJSONSourceSpecification } from 'maplibre-gl';
2
+ import { GeoJSONSourceSpecification, LayerSpecification } from 'maplibre-gl';
3
3
  export type LayerProps = {
4
4
  layer: Omit<LayerSpecification, 'source'>;
5
5
  source: GeoJSONSourceSpecification;
package/dist/Layer.js CHANGED
@@ -1,29 +1,30 @@
1
- import { useEffect } from 'react';
2
- import { useMap } from './Map';
1
+ import { useContext, useEffect } from 'react';
2
+ import { MapContext } from './Map';
3
3
  export const Layer = ({ layer, source }) => {
4
- const { map, mapLoaded } = useMap();
4
+ const { map, mapLoaded } = useContext(MapContext);
5
5
  const layerString = JSON.stringify(Object.assign({ source: layer.id }, layer));
6
6
  const sourceString = JSON.stringify(source);
7
7
  useEffect(() => {
8
- let added = false;
9
8
  const parsedSource = JSON.parse(sourceString);
10
9
  const parsedLayer = JSON.parse(layerString);
11
10
  if (map && mapLoaded) {
12
- added = true;
13
11
  map.addSource(parsedLayer.id, parsedSource); // when adding, the source must be added first, and then the layer
14
12
  map.addLayer(parsedLayer);
15
13
  }
16
14
  return () => {
17
- if (map) {
18
- // Check if layer exists before removing
19
- if (map.getLayer(parsedLayer.id)) {
20
- map.removeLayer(parsedLayer.id); // when removing, the layer must be removed first, and then the source
21
- }
22
- // Check if source exists before removing
23
- if (map.getSource(parsedLayer.id)) {
24
- map.removeSource(parsedLayer.id);
15
+ try {
16
+ if (map && mapLoaded && !map._removed) {
17
+ if (map.getLayer(parsedLayer.id)) {
18
+ map.removeLayer(parsedLayer.id); // when removing, the layer must be removed first, and then the source
19
+ }
20
+ if (map.getSource(parsedLayer.id)) {
21
+ map.removeSource(parsedLayer.id);
22
+ }
25
23
  }
26
24
  }
25
+ catch (_a) {
26
+ console.warn('Error cleaning up Layer');
27
+ }
27
28
  };
28
29
  }, [layerString, sourceString, map, mapLoaded]);
29
30
  return null;
package/dist/Map.d.ts CHANGED
@@ -1,48 +1,25 @@
1
- import React, { FC, RefAttributes, ReactNode, CSSProperties } from 'react';
2
- import maplibre, { MapLibreEvent, StyleSpecification } from 'maplibre-gl';
3
- export type ViewState = {
4
- longitude: number;
5
- latitude: number;
6
- zoom: number;
7
- };
8
- export type ViewStateChangeEvent = (MapLibreEvent<MouseEvent | TouchEvent | WheelEvent | undefined> & {
9
- type: 'movestart' | 'move' | 'moveend' | 'zoomstart' | 'zoom' | 'zoomend';
10
- viewState: ViewState;
11
- }) | (MapLibreEvent<MouseEvent | TouchEvent | undefined> & {
12
- type: 'rotatestart' | 'rotate' | 'rotateend' | 'dragstart' | 'drag' | 'dragend' | 'pitchstart' | 'pitch' | 'pitchend';
13
- viewState: ViewState;
14
- });
15
- export declare const viewStateFromMap: (map: maplibre.Map) => {
16
- longitude: number;
17
- latitude: number;
18
- zoom: number;
19
- };
20
- export declare const useMap: () => {
1
+ import maplibre, { MapLibreEvent } from 'maplibre-gl';
2
+ import { ReactNode } from 'react';
3
+ export declare const MapContext: import("react").Context<{
21
4
  map: maplibre.Map | null;
22
- setMap: React.Dispatch<React.SetStateAction<maplibre.Map | null>>;
23
5
  mapLoaded: boolean;
24
- setMapLoaded: React.Dispatch<React.SetStateAction<boolean>>;
25
- };
26
- export declare const MapProvider: FC<{
27
- children?: ReactNode;
28
6
  }>;
29
- export type MapProps = {
30
- accessToken?: string;
31
- antialias?: boolean;
32
- children?: ReactNode | ReactNode[];
33
- fallback?: ReactNode;
34
- id?: string;
7
+ export type MapDragEndEvent = MapLibreEvent & {
8
+ viewState: {
9
+ longitude: number;
10
+ latitude: number;
11
+ zoom: number;
12
+ };
13
+ };
14
+ type MapProps = {
35
15
  longitude: number;
36
16
  latitude: number;
37
- logoPosition?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
38
- maxPitch?: number;
39
- mapStyle?: StyleSpecification | string;
40
- onLoad?: (e: import('maplibre-gl').MapLibreEvent) => void;
41
- onDragEnd?: (e: ViewStateChangeEvent) => void;
42
- onMoveEnd?: (e: ViewStateChangeEvent) => void;
43
- onZoomEnd?: (e: ViewStateChangeEvent) => void;
44
- ref?: RefAttributes<maplibre.Map | null>;
45
- style?: CSSProperties;
46
- zoom: number;
17
+ mapStyle: string;
18
+ fallback?: ReactNode;
19
+ children?: ReactNode | ReactNode[];
20
+ onLoad?: (e: MapLibreEvent) => void;
21
+ onZoomEnd?: (e: MapLibreEvent) => void;
22
+ onDragEnd?: (e: MapDragEndEvent) => void;
47
23
  };
48
- export declare const Map: React.ForwardRefExoticComponent<Omit<MapProps, "ref"> & React.RefAttributes<maplibre.Map | null>>;
24
+ export declare const Map: import("react").ForwardRefExoticComponent<MapProps & import("react").RefAttributes<maplibre.Map | null>>;
25
+ export {};
package/dist/Map.js CHANGED
@@ -1,101 +1,68 @@
1
- var __rest = (this && this.__rest) || function (s, e) {
2
- var t = {};
3
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
- t[p] = s[p];
5
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
- t[p[i]] = s[p[i]];
9
- }
10
- return t;
11
- };
12
1
  import { jsx as _jsx } from "react/jsx-runtime";
13
- import React, { useRef, useEffect, useState, useContext, useImperativeHandle, useMemo, useCallback, } from 'react';
14
2
  import maplibre from 'maplibre-gl';
15
- import { ErrorBoundary } from './ErrorBoundary'; // eslint-disable-line import/no-webpack-loader-syntax
16
- const DEFAULT_STYLE = 'https://demotiles.maplibre.org/style.json';
17
- const DISABLE_PITCH = 0;
18
- const MapContext = React.createContext({
3
+ import { createContext, forwardRef, useEffect, useImperativeHandle, useRef, useState, } from 'react';
4
+ import { ErrorBoundary } from './ErrorBoundary';
5
+ export const MapContext = createContext({
19
6
  map: null,
20
- setMap: () => {
21
- throw new Error('Use <MapProvider>');
22
- },
23
7
  mapLoaded: false,
24
- setMapLoaded: () => {
25
- throw new Error('Use <MapProvider>');
26
- },
27
- });
28
- export const viewStateFromMap = (map) => ({
29
- longitude: map.getCenter().lng,
30
- latitude: map.getCenter().lat,
31
- zoom: map.getZoom(),
32
8
  });
33
- export const useMap = () => useContext(MapContext);
34
- export const MapProvider = ({ children }) => {
35
- const [map, setMap] = useState(null);
36
- const [mapLoaded, setMapLoaded] = useState(false);
37
- const stableSetMap = useCallback((newMap) => {
38
- setMap(newMap);
39
- }, []);
40
- const stableSetMapLoaded = useCallback((loaded) => {
41
- setMapLoaded(loaded);
42
- }, []);
43
- return (_jsx(MapContext.Provider, { value: { map, setMap: stableSetMap, mapLoaded, setMapLoaded: stableSetMapLoaded }, children: children }));
44
- };
45
- function addEventHandler(map, type, handler) {
46
- map.on(type, (ev) => handler(Object.assign({ viewState: viewStateFromMap(map) }, ev)));
47
- }
48
- export const Map = React.forwardRef((_a, ref) => {
49
- 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"]);
9
+ export const Map = forwardRef(({ longitude, latitude, mapStyle, fallback, children, onLoad, onZoomEnd, onDragEnd }, ref) => {
50
10
  const mapContainer = useRef(null);
51
- const mapInstanceRef = useRef(null);
52
- const { map, setMap, setMapLoaded } = useMap();
53
- const optionsString = JSON.stringify(options || {});
54
- useImperativeHandle(ref, () => map, [map]);
11
+ const [mapInstance, setMapInstance] = useState(null);
12
+ const [mapLoaded, setMapLoaded] = useState(false);
13
+ useImperativeHandle(ref, () => mapInstance, [
14
+ mapInstance,
15
+ ]);
55
16
  useEffect(() => {
56
- if (map) {
57
- return;
58
- }
17
+ let newMap;
59
18
  if (mapContainer.current) {
60
- const parsedOptions = JSON.parse(optionsString);
61
- const m = new maplibre.Map(Object.assign({ container: mapContainer.current, style: mapStyle, center: [longitude, latitude], zoom }, parsedOptions));
62
- mapInstanceRef.current = m;
63
- if (onDragEnd) {
64
- addEventHandler(m, 'dragend', onDragEnd);
65
- }
66
- if (onLoad) {
67
- addEventHandler(m, 'load', (ev) => {
19
+ newMap = new maplibre.Map({
20
+ container: mapContainer.current,
21
+ style: mapStyle,
22
+ zoom: 15,
23
+ maxPitch: 0,
24
+ });
25
+ setMapInstance(newMap);
26
+ newMap.on('load', (ev) => {
27
+ if (onLoad) {
68
28
  onLoad(ev);
29
+ }
30
+ setTimeout(() => {
69
31
  setMapLoaded(true);
32
+ }, 1000);
33
+ });
34
+ if (onZoomEnd) {
35
+ newMap.on('zoomend', onZoomEnd);
36
+ }
37
+ if (onDragEnd) {
38
+ newMap.on('dragend', (ev) => {
39
+ const newEvent = Object.assign(Object.assign({}, ev), { viewState: {
40
+ longitude: newMap.getCenter().lng,
41
+ latitude: newMap.getCenter().lat,
42
+ zoom: newMap.getZoom(),
43
+ } });
44
+ onDragEnd(newEvent);
70
45
  });
71
46
  }
72
- if (onMoveEnd) {
73
- addEventHandler(m, 'moveend', onMoveEnd);
47
+ }
48
+ return () => {
49
+ try {
50
+ if (newMap) {
51
+ newMap.remove();
52
+ }
53
+ setMapInstance(null);
54
+ setMapLoaded(false);
74
55
  }
75
- if (onZoomEnd) {
76
- addEventHandler(m, 'zoomend', onZoomEnd);
56
+ catch (_a) {
57
+ console.warn('Error cleaning up Map');
77
58
  }
78
- setMap(m);
79
- // Cleanup when component unmounts
80
- return () => {
81
- m.remove(); // This destroys the map and cleans up all layers/sources
82
- mapInstanceRef.current = null;
83
- setMap(null);
84
- };
59
+ };
60
+ }, [mapStyle, onLoad, onZoomEnd, onDragEnd]);
61
+ useEffect(() => {
62
+ if (mapInstance) {
63
+ mapInstance.setCenter([longitude, latitude]);
85
64
  }
86
- }, [
87
- mapStyle,
88
- longitude,
89
- latitude,
90
- zoom,
91
- optionsString,
92
- onDragEnd,
93
- onLoad,
94
- onMoveEnd,
95
- onZoomEnd,
96
- setMap,
97
- setMapLoaded,
98
- ]);
99
- const memoizedStyle = useMemo(() => (Object.assign({ position: 'relative', width: '100%', height: '100%' }, style)), [style]);
100
- return (_jsx(ErrorBoundary, { fallback: fallback, children: _jsx("div", { id: id, ref: mapContainer, style: memoizedStyle, children: children }) }));
65
+ }, [mapInstance, latitude, longitude]);
66
+ return (_jsx(ErrorBoundary, { fallback: fallback, children: _jsx(MapContext.Provider, { value: { map: mapInstance, mapLoaded }, children: _jsx("div", { ref: mapContainer, style: { width: '100%', height: '100%' }, children: children }) }) }));
101
67
  });
68
+ Map.displayName = 'Map';
package/dist/Marker.d.ts CHANGED
@@ -1,14 +1,15 @@
1
- import { FC, ReactElement, ReactNode } from 'react';
1
+ import { FC, ReactNode, ReactElement } from 'react';
2
2
  import { PositionAnchor } from 'maplibre-gl';
3
3
  export type MarkerProps = {
4
4
  longitude: number;
5
5
  latitude: number;
6
+ className?: string;
7
+ anchor?: PositionAnchor;
8
+ color?: string;
9
+ children?: ReactNode;
6
10
  popup?: ReactElement;
7
11
  popupClassName?: string;
8
12
  closeOnClick?: boolean;
9
13
  closeButton?: boolean;
10
- anchor?: PositionAnchor;
11
- color?: string;
12
- children?: ReactNode;
13
14
  };
14
15
  export declare const Marker: FC<MarkerProps>;
package/dist/Marker.js CHANGED
@@ -1,89 +1,69 @@
1
- var __rest = (this && this.__rest) || function (s, e) {
2
- var t = {};
3
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
- t[p] = s[p];
5
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
- t[p[i]] = s[p[i]];
9
- }
10
- return t;
11
- };
12
- import { useEffect, useState, useRef } from 'react';
1
+ import { useEffect, useState, useContext } from 'react';
13
2
  import maplibre from 'maplibre-gl';
14
- import { useMap } from './Map';
15
3
  import ReactDOM from 'react-dom';
16
4
  import ReactDOMServer from 'react-dom/server';
17
- export const Marker = (_a) => {
18
- var { children, longitude, latitude, popup, popupClassName, closeOnClick = false, closeButton = true } = _a, options = __rest(_a, ["children", "longitude", "latitude", "popup", "popupClassName", "closeOnClick", "closeButton"]);
19
- const { map } = useMap();
5
+ import { MapContext } from './Map';
6
+ export const Marker = ({ children, longitude, latitude, className, anchor, color, popup, popupClassName, closeOnClick = false, closeButton = false, }) => {
7
+ const { map, mapLoaded } = useContext(MapContext);
20
8
  const [result, setResult] = useState(null);
21
- const markerRef = useRef(null);
22
- const popupRef = useRef(null);
23
- const cleanupRef = useRef(null);
24
- const optionsString = JSON.stringify(options || {});
25
9
  useEffect(() => {
26
- if (!map) {
27
- return;
10
+ let marker;
11
+ let newPopup;
12
+ let handleMarkerClick;
13
+ if (map && mapLoaded) {
14
+ // We create the DOM element that we will attach to the marker, and then
15
+ // render the `children` props into the DOM element.
16
+ const element = document.createElement('div');
17
+ setResult(ReactDOM.createPortal(children, element));
18
+ marker = new maplibre.Marker({ anchor, className, color, element })
19
+ .setLngLat([longitude, latitude])
20
+ .addTo(map);
21
+ if (popup) {
22
+ const popupHTML = ReactDOMServer.renderToStaticMarkup(popup);
23
+ handleMarkerClick = (e) => {
24
+ e.stopPropagation();
25
+ newPopup = new maplibre.Popup({
26
+ offset: [0, -15],
27
+ closeButton,
28
+ closeOnClick,
29
+ className: popupClassName,
30
+ })
31
+ .setLngLat([longitude, latitude])
32
+ .setHTML(popupHTML)
33
+ .addTo(map);
34
+ };
35
+ marker.getElement().addEventListener('click', handleMarkerClick);
36
+ }
28
37
  }
29
- const element = document.createElement('div');
30
- const parsedOptions = JSON.parse(optionsString);
31
- setResult(ReactDOM.createPortal(children, element));
32
- // Create marker
33
- const marker = new maplibre.Marker(Object.assign(Object.assign({}, parsedOptions), { element }));
34
- marker.setLngLat([longitude, latitude]).addTo(map);
35
- markerRef.current = marker;
36
- // Handle popup manually if provided
37
- if (popup) {
38
- const popupHTML = ReactDOMServer.renderToStaticMarkup(popup);
39
- const handleMarkerClick = (e) => {
40
- e.stopPropagation();
41
- // Close existing popup if any
42
- if (popupRef.current) {
43
- popupRef.current.remove();
44
- popupRef.current = null;
45
- return; // Toggle behavior - close if already open
38
+ return () => {
39
+ try {
40
+ if (marker) {
41
+ marker.remove();
46
42
  }
47
- // Create new popup directly on the map
48
- const newPopup = new maplibre.Popup({
49
- offset: [0, -15],
50
- closeOnClick,
51
- closeButton,
52
- className: popupClassName,
53
- })
54
- .setLngLat([longitude, latitude])
55
- .setHTML(popupHTML)
56
- .addTo(map);
57
- popupRef.current = newPopup;
58
- // Listen for popup close to clean up reference
59
- newPopup.on('close', () => {
60
- popupRef.current = null;
61
- });
62
- };
63
- // Add click listener to marker element
64
- const markerElement = marker.getElement();
65
- markerElement.style.cursor = 'pointer';
66
- markerElement.addEventListener('click', handleMarkerClick);
67
- // Cleanup function
68
- const cleanup = () => {
69
- markerElement.removeEventListener('click', handleMarkerClick);
70
- if (popupRef.current) {
71
- popupRef.current.remove();
72
- popupRef.current = null;
43
+ if (newPopup) {
44
+ newPopup.remove();
45
+ }
46
+ if (marker && handleMarkerClick) {
47
+ marker.getElement().removeEventListener('click', handleMarkerClick);
73
48
  }
74
- };
75
- cleanupRef.current = cleanup;
76
- }
77
- return () => {
78
- if (cleanupRef.current) {
79
- cleanupRef.current();
80
- cleanupRef.current = null;
81
49
  }
82
- if (markerRef.current) {
83
- markerRef.current.remove();
84
- markerRef.current = null;
50
+ catch (_a) {
51
+ console.warn('Error cleaning up Marker');
85
52
  }
86
53
  };
87
- }, [map, optionsString, children, longitude, latitude, popup, closeOnClick, closeButton, popupClassName]);
54
+ }, [
55
+ anchor,
56
+ className,
57
+ children,
58
+ color,
59
+ latitude,
60
+ longitude,
61
+ map,
62
+ popup,
63
+ popupClassName,
64
+ closeOnClick,
65
+ closeButton,
66
+ mapLoaded,
67
+ ]);
88
68
  return result;
89
69
  };
@@ -1,6 +1,5 @@
1
1
  import { FC } from 'react';
2
- import { NavigationControlOptions } from 'maplibre-gl';
3
- import { ControlPosition } from './types';
2
+ import { NavigationControlOptions, ControlPosition } from 'maplibre-gl';
4
3
  export type NavigationControlProps = {
5
4
  position?: ControlPosition;
6
5
  options?: NavigationControlOptions;
@@ -1,22 +1,27 @@
1
- import { useEffect } from 'react';
1
+ import { useContext, useEffect } from 'react';
2
2
  import maplibre from 'maplibre-gl';
3
- import { useMap } from './Map';
3
+ import { MapContext } from './Map';
4
4
  export const NavigationControl = ({ position = 'bottom-right', options = {
5
5
  showZoom: true,
6
6
  showCompass: false,
7
7
  }, }) => {
8
- const { map } = useMap();
8
+ const { map, mapLoaded } = useContext(MapContext);
9
9
  const optionsString = JSON.stringify(options || {});
10
10
  useEffect(() => {
11
11
  const control = new maplibre.NavigationControl(JSON.parse(optionsString));
12
- if (map && position) {
12
+ if (map && mapLoaded && position) {
13
13
  map.addControl(control, position);
14
14
  }
15
15
  return () => {
16
- if (map && map.hasControl(control)) {
17
- map.removeControl(control);
16
+ try {
17
+ if (map && !map._removed && map.hasControl(control)) {
18
+ map.removeControl(control);
19
+ }
20
+ }
21
+ catch (_a) {
22
+ console.warn('Error cleaning up NavigationControl');
18
23
  }
19
24
  };
20
- }, [position, optionsString, map]);
25
+ }, [position, optionsString, map, mapLoaded]);
21
26
  return null;
22
27
  };
package/dist/Popup.js CHANGED
@@ -1,35 +1,27 @@
1
- var __rest = (this && this.__rest) || function (s, e) {
2
- var t = {};
3
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
- t[p] = s[p];
5
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
- t[p[i]] = s[p[i]];
9
- }
10
- return t;
11
- };
12
- import { useEffect } from 'react';
1
+ import { useEffect, useContext } from 'react';
13
2
  import maplibre from 'maplibre-gl';
14
- import { useMap } from './Map';
15
- import ReactDOMServer from 'react-dom/server'; // eslint-disable-line import/no-webpack-loader-syntax
16
- export const Popup = (_a) => {
17
- var { children, longitude, latitude } = _a, options = __rest(_a, ["children", "longitude", "latitude"]);
18
- const { map } = useMap();
19
- const optionsString = JSON.stringify(options || {});
3
+ import ReactDOMServer from 'react-dom/server';
4
+ import { MapContext } from './Map';
5
+ export const Popup = ({ children, longitude, latitude, className, closeOnClick, closeButton, }) => {
6
+ const { map, mapLoaded } = useContext(MapContext);
20
7
  useEffect(() => {
21
8
  let popup = null;
22
- if (map) {
23
- popup = new maplibre.Popup(Object.assign({ offset: [0, -15] }, JSON.parse(optionsString)))
9
+ if (map && mapLoaded) {
10
+ popup = new maplibre.Popup({ offset: [0, -15], className, closeOnClick, closeButton })
24
11
  .setLngLat([longitude, latitude])
25
12
  .setHTML(ReactDOMServer.renderToStaticMarkup(children))
26
13
  .addTo(map);
27
14
  }
28
15
  return () => {
29
- if (popup) {
30
- popup.remove();
16
+ try {
17
+ if (popup) {
18
+ popup.remove();
19
+ }
20
+ }
21
+ catch (_a) {
22
+ console.warn('Error cleaning up Popup');
31
23
  }
32
24
  };
33
- }, [children, latitude, longitude, map, optionsString]);
25
+ }, [children, latitude, longitude, map, className, closeOnClick, closeButton, mapLoaded]);
34
26
  return null;
35
27
  };
@@ -1,6 +1,5 @@
1
1
  import { FC } from 'react';
2
- import { ScaleControlOptions } from 'maplibre-gl';
3
- import { ControlPosition } from './types';
2
+ import { ScaleControlOptions, ControlPosition } from 'maplibre-gl';
4
3
  export type ScaleControlProps = {
5
4
  position?: ControlPosition;
6
5
  options?: ScaleControlOptions;
@@ -1,19 +1,24 @@
1
- import { useEffect } from 'react';
1
+ import { useContext, useEffect } from 'react';
2
2
  import maplibre from 'maplibre-gl';
3
- import { useMap } from './Map';
3
+ import { MapContext } from './Map';
4
4
  export const ScaleControl = ({ position = 'bottom-right', options }) => {
5
- const { map } = useMap();
5
+ const { map, mapLoaded } = useContext(MapContext);
6
6
  const optionsString = JSON.stringify(options || {});
7
7
  useEffect(() => {
8
8
  const control = new maplibre.ScaleControl(JSON.parse(optionsString));
9
- if (map && position) {
9
+ if (map && mapLoaded && position) {
10
10
  map.addControl(control, position);
11
11
  }
12
12
  return () => {
13
- if (map && map.hasControl(control)) {
14
- map.removeControl(control);
13
+ try {
14
+ if (map && !map._removed && map.hasControl(control)) {
15
+ map.removeControl(control);
16
+ }
17
+ }
18
+ catch (_a) {
19
+ console.warn('Error cleaning up ScaleControl');
15
20
  }
16
21
  };
17
- }, [position, optionsString, map]);
22
+ }, [position, optionsString, map, mapLoaded]);
18
23
  return null;
19
24
  };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- export { Map, useMap, MapProvider, viewStateFromMap } from './Map';
2
- export type { ViewState } from './Map';
1
+ export { Map, MapContext } from './Map';
2
+ export type { MapDragEndEvent } from './Map';
3
3
  export { Marker } from './Marker';
4
4
  export { Popup } from './Popup';
5
5
  export { Layer } from './Layer';
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export { Map, useMap, MapProvider, viewStateFromMap } from './Map';
1
+ export { Map, MapContext } from './Map';
2
2
  export { Marker } from './Marker';
3
3
  export { Popup } from './Popup';
4
4
  export { Layer } from './Layer';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vinctus/react-maplibre",
3
- "version": "0.2.25",
3
+ "version": "1.0.0-alpha",
4
4
  "description": "Minimalist MapLibre GL JS React wrapper library",
5
5
  "type": "module",
6
6
  "types": "dist/index.d.ts",
@@ -1 +0,0 @@
1
- {"root":["../src/ErrorBoundary.tsx","../src/GeolocateControl.tsx","../src/Layer.tsx","../src/Map.tsx","../src/Marker.tsx","../src/NavigationControl.tsx","../src/Popup.tsx","../src/ScaleControl.tsx","../src/index.tsx","../src/types.tsx"],"version":"5.8.2"}
package/dist/types.d.ts DELETED
@@ -1 +0,0 @@
1
- export type ControlPosition = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
package/dist/types.js DELETED
@@ -1 +0,0 @@
1
- export {};