react-bkoi-gl 2.0.0 → 2.1.0
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/LICENSE +21 -0
- package/README.md +1429 -176
- package/dist/index.cjs +1299 -266
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +870 -0
- package/dist/index.d.ts +870 -2
- package/dist/index.js +2420 -2
- package/dist/index.js.map +1 -1
- package/dist/styles/react-bkoi-gl.css +95 -1
- package/package.json +83 -31
- package/dist/components/attribution-control.d.ts +0 -9
- package/dist/components/attribution-control.js +0 -20
- package/dist/components/attribution-control.js.map +0 -1
- package/dist/components/fullscreen-control.d.ts +0 -12
- package/dist/components/fullscreen-control.js +0 -21
- package/dist/components/fullscreen-control.js.map +0 -1
- package/dist/components/geolocate-control.d.ts +0 -21
- package/dist/components/geolocate-control.js +0 -46
- package/dist/components/geolocate-control.js.map +0 -1
- package/dist/components/layer.d.ts +0 -18
- package/dist/components/layer.js +0 -98
- package/dist/components/layer.js.map +0 -1
- package/dist/components/logo-control.d.ts +0 -9
- package/dist/components/logo-control.js +0 -28
- package/dist/components/logo-control.js.map +0 -1
- package/dist/components/map.d.ts +0 -27
- package/dist/components/map.js +0 -108
- package/dist/components/map.js.map +0 -1
- package/dist/components/marker.d.ts +0 -18
- package/dist/components/marker.js +0 -105
- package/dist/components/marker.js.map +0 -1
- package/dist/components/navigation-control.d.ts +0 -9
- package/dist/components/navigation-control.js +0 -19
- package/dist/components/navigation-control.js.map +0 -1
- package/dist/components/popup.d.ts +0 -15
- package/dist/components/popup.js +0 -68
- package/dist/components/popup.js.map +0 -1
- package/dist/components/scale-control.d.ts +0 -11
- package/dist/components/scale-control.js +0 -31
- package/dist/components/scale-control.js.map +0 -1
- package/dist/components/source.d.ts +0 -6
- package/dist/components/source.js +0 -95
- package/dist/components/source.js.map +0 -1
- package/dist/components/terrain-control.d.ts +0 -10
- package/dist/components/terrain-control.js +0 -19
- package/dist/components/terrain-control.js.map +0 -1
- package/dist/components/use-control.d.ts +0 -9
- package/dist/components/use-control.js +0 -30
- package/dist/components/use-control.js.map +0 -1
- package/dist/components/use-map.d.ts +0 -19
- package/dist/components/use-map.js +0 -54
- package/dist/components/use-map.js.map +0 -1
- package/dist/exports-maplibre-gl.d.ts +0 -33
- package/dist/exports-maplibre-gl.js +0 -21
- package/dist/exports-maplibre-gl.js.map +0 -1
- package/dist/maplibre/create-ref.d.ts +0 -9
- package/dist/maplibre/create-ref.js +0 -30
- package/dist/maplibre/create-ref.js.map +0 -1
- package/dist/maplibre/maplibre.d.ts +0 -81
- package/dist/maplibre/maplibre.js +0 -387
- package/dist/maplibre/maplibre.js.map +0 -1
- package/dist/styles.d.js +0 -2
- package/dist/styles.d.js.map +0 -1
- package/dist/tsconfig.build.tsbuildinfo +0 -1
- package/dist/types/common.d.ts +0 -20
- package/dist/types/common.js +0 -2
- package/dist/types/common.js.map +0 -1
- package/dist/types/events.d.ts +0 -80
- package/dist/types/events.js +0 -2
- package/dist/types/events.js.map +0 -1
- package/dist/types/internal.d.ts +0 -14
- package/dist/types/internal.js +0 -2
- package/dist/types/internal.js.map +0 -1
- package/dist/types/lib.d.ts +0 -40
- package/dist/types/lib.js +0 -2
- package/dist/types/lib.js.map +0 -1
- package/dist/types/style-spec.d.ts +0 -1
- package/dist/types/style-spec.js +0 -2
- package/dist/types/style-spec.js.map +0 -1
- package/dist/utils/apply-react-style.d.ts +0 -2
- package/dist/utils/apply-react-style.js +0 -16
- package/dist/utils/apply-react-style.js.map +0 -1
- package/dist/utils/assert.d.ts +0 -1
- package/dist/utils/assert.js +0 -6
- package/dist/utils/assert.js.map +0 -1
- package/dist/utils/compare-class-names.d.ts +0 -2
- package/dist/utils/compare-class-names.js +0 -23
- package/dist/utils/compare-class-names.js.map +0 -1
- package/dist/utils/deep-equal.d.ts +0 -15
- package/dist/utils/deep-equal.js +0 -46
- package/dist/utils/deep-equal.js.map +0 -1
- package/dist/utils/set-globals.d.ts +0 -20
- package/dist/utils/set-globals.js +0 -31
- package/dist/utils/set-globals.js.map +0 -1
- package/dist/utils/style-utils.d.ts +0 -3
- package/dist/utils/style-utils.js +0 -42
- package/dist/utils/style-utils.js.map +0 -1
- package/dist/utils/transform.d.ts +0 -18
- package/dist/utils/transform.js +0 -33
- package/dist/utils/transform.js.map +0 -1
- package/dist/utils/use-isomorphic-layout-effect.d.ts +0 -3
- package/dist/utils/use-isomorphic-layout-effect.js +0 -4
- package/dist/utils/use-isomorphic-layout-effect.js.map +0 -1
- package/src/components/attribution-control.ts +0 -56
- package/src/components/fullscreen-control.ts +0 -40
- package/src/components/geolocate-control.ts +0 -96
- package/src/components/layer.ts +0 -141
- package/src/components/logo-control.ts +0 -44
- package/src/components/map.tsx +0 -166
- package/src/components/marker.ts +0 -155
- package/src/components/navigation-control.ts +0 -28
- package/src/components/popup.ts +0 -113
- package/src/components/scale-control.ts +0 -44
- package/src/components/source.ts +0 -159
- package/src/components/terrain-control.ts +0 -29
- package/src/components/use-control.ts +0 -68
- package/src/components/use-map.tsx +0 -71
- package/src/exports-maplibre-gl.ts +0 -37
- package/src/index.ts +0 -3
- package/src/maplibre/create-ref.ts +0 -70
- package/src/maplibre/maplibre.ts +0 -624
- package/src/styles.d.ts +0 -4
- package/src/types/common.ts +0 -34
- package/src/types/events.ts +0 -133
- package/src/types/internal.ts +0 -26
- package/src/types/lib.ts +0 -84
- package/src/types/style-spec.ts +0 -34
- package/src/utils/apply-react-style.ts +0 -24
- package/src/utils/assert.ts +0 -5
- package/src/utils/compare-class-names.ts +0 -29
- package/src/utils/deep-equal.ts +0 -61
- package/src/utils/set-globals.ts +0 -51
- package/src/utils/style-utils.ts +0 -68
- package/src/utils/transform.ts +0 -58
- package/src/utils/use-isomorphic-layout-effect.ts +0 -8
package/src/components/layer.ts
DELETED
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
import { useContext, useEffect, useMemo, useState, useRef } from "react";
|
|
2
|
-
import { MapContext } from "./map";
|
|
3
|
-
import assert from "../utils/assert";
|
|
4
|
-
import { deepEqual } from "../utils/deep-equal";
|
|
5
|
-
|
|
6
|
-
import type { Map as MapInstance, CustomLayerInterface } from "../types/lib";
|
|
7
|
-
import type { LayerSpecification } from "../types/style-spec";
|
|
8
|
-
|
|
9
|
-
// Omiting property from a union type, see
|
|
10
|
-
// https://github.com/microsoft/TypeScript/issues/39556#issuecomment-656925230
|
|
11
|
-
type OptionalId<T> = T extends { id: string }
|
|
12
|
-
? Omit<T, "id"> & { id?: string }
|
|
13
|
-
: T;
|
|
14
|
-
type OptionalSource<T> = T extends { source: string }
|
|
15
|
-
? Omit<T, "source"> & { source?: string }
|
|
16
|
-
: T;
|
|
17
|
-
|
|
18
|
-
export type LayerProps = (
|
|
19
|
-
| OptionalSource<OptionalId<LayerSpecification>>
|
|
20
|
-
| CustomLayerInterface
|
|
21
|
-
) & {
|
|
22
|
-
/** If set, the layer will be inserted before the specified layer */
|
|
23
|
-
beforeId?: string;
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
/* eslint-disable complexity, max-statements */
|
|
27
|
-
function updateLayer(
|
|
28
|
-
map: MapInstance,
|
|
29
|
-
id: string,
|
|
30
|
-
props: LayerProps,
|
|
31
|
-
prevProps: LayerProps,
|
|
32
|
-
) {
|
|
33
|
-
assert(props.id === prevProps.id, "layer id changed");
|
|
34
|
-
assert(props.type === prevProps.type, "layer type changed");
|
|
35
|
-
|
|
36
|
-
if (props.type === "custom" || prevProps.type === "custom") {
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// @ts-ignore filter does not exist in some Layer types
|
|
41
|
-
const { layout = {}, paint = {}, filter, minzoom, maxzoom, beforeId } = props;
|
|
42
|
-
|
|
43
|
-
if (beforeId !== prevProps.beforeId) {
|
|
44
|
-
map.moveLayer(id, beforeId);
|
|
45
|
-
}
|
|
46
|
-
if (layout !== prevProps.layout) {
|
|
47
|
-
const prevLayout = prevProps.layout || {};
|
|
48
|
-
for (const key in layout) {
|
|
49
|
-
if (!deepEqual(layout[key], prevLayout[key])) {
|
|
50
|
-
map.setLayoutProperty(id, key, layout[key]);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
for (const key in prevLayout) {
|
|
54
|
-
if (!layout.hasOwnProperty(key)) {
|
|
55
|
-
map.setLayoutProperty(id, key, undefined);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
if (paint !== prevProps.paint) {
|
|
60
|
-
const prevPaint = prevProps.paint || {};
|
|
61
|
-
for (const key in paint) {
|
|
62
|
-
if (!deepEqual(paint[key], prevPaint[key])) {
|
|
63
|
-
map.setPaintProperty(id, key, paint[key]);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
for (const key in prevPaint) {
|
|
67
|
-
if (!paint.hasOwnProperty(key)) {
|
|
68
|
-
map.setPaintProperty(id, key, undefined);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// @ts-ignore filter does not exist in some Layer types
|
|
74
|
-
if (!deepEqual(filter, prevProps.filter)) {
|
|
75
|
-
map.setFilter(id, filter);
|
|
76
|
-
}
|
|
77
|
-
if (minzoom !== prevProps.minzoom || maxzoom !== prevProps.maxzoom) {
|
|
78
|
-
map.setLayerZoomRange(id, minzoom, maxzoom);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function createLayer(map: MapInstance, id: string, props: LayerProps) {
|
|
83
|
-
// @ts-ignore
|
|
84
|
-
if (
|
|
85
|
-
map.style &&
|
|
86
|
-
map.style._loaded &&
|
|
87
|
-
(!("source" in props) || map.getSource(props.source))
|
|
88
|
-
) {
|
|
89
|
-
const options: LayerProps = { ...props, id };
|
|
90
|
-
delete options.beforeId;
|
|
91
|
-
|
|
92
|
-
// @ts-ignore
|
|
93
|
-
map.addLayer(options, props.beforeId);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/* eslint-enable complexity, max-statements */
|
|
98
|
-
|
|
99
|
-
let layerCounter = 0;
|
|
100
|
-
|
|
101
|
-
export function Layer(props: LayerProps) {
|
|
102
|
-
const map = useContext(MapContext).map.getMap();
|
|
103
|
-
const propsRef = useRef(props);
|
|
104
|
-
const [, setStyleLoaded] = useState(0);
|
|
105
|
-
|
|
106
|
-
const id = useMemo(() => props.id || `jsx-layer-${layerCounter++}`, []);
|
|
107
|
-
|
|
108
|
-
useEffect(() => {
|
|
109
|
-
if (map) {
|
|
110
|
-
const forceUpdate = () => setStyleLoaded((version) => version + 1);
|
|
111
|
-
map.on("styledata", forceUpdate);
|
|
112
|
-
forceUpdate();
|
|
113
|
-
|
|
114
|
-
return () => {
|
|
115
|
-
map.off("styledata", forceUpdate);
|
|
116
|
-
// @ts-ignore
|
|
117
|
-
if (map.style && map.style._loaded && map.getLayer(id)) {
|
|
118
|
-
map.removeLayer(id);
|
|
119
|
-
}
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
return undefined;
|
|
123
|
-
}, [map]);
|
|
124
|
-
|
|
125
|
-
// @ts-ignore
|
|
126
|
-
const layer = map && map.style && map.getLayer(id);
|
|
127
|
-
if (layer) {
|
|
128
|
-
try {
|
|
129
|
-
updateLayer(map, id, props, propsRef.current);
|
|
130
|
-
} catch (error) {
|
|
131
|
-
console.warn(error); // eslint-disable-line
|
|
132
|
-
}
|
|
133
|
-
} else {
|
|
134
|
-
createLayer(map, id, props);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// Store last rendered props
|
|
138
|
-
propsRef.current = props;
|
|
139
|
-
|
|
140
|
-
return null;
|
|
141
|
-
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-unnecessary-type-assertion */
|
|
2
|
-
import * as React from "react";
|
|
3
|
-
import { useEffect, memo } from "react";
|
|
4
|
-
import { applyReactStyle } from "../utils/apply-react-style";
|
|
5
|
-
import { useControl } from "./use-control";
|
|
6
|
-
|
|
7
|
-
import type { ControlPosition, LogoControlOptions } from "../types/lib";
|
|
8
|
-
|
|
9
|
-
export type LogoControlProps = LogoControlOptions & {
|
|
10
|
-
/** Placement of the control relative to the map. */
|
|
11
|
-
position?: ControlPosition;
|
|
12
|
-
/** CSS style override, applied to the control's container */
|
|
13
|
-
style?: React.CSSProperties;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
function _LogoControl(props: LogoControlProps) {
|
|
17
|
-
const ctrl = useControl(({ mapLib }) => new mapLib.LogoControl(props), {
|
|
18
|
-
position: props.position,
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
useEffect(() => {
|
|
22
|
-
applyReactStyle(ctrl._container, props.style);
|
|
23
|
-
|
|
24
|
-
// Update the DOM structure and attributes directly
|
|
25
|
-
const logoElement = ctrl._container?.querySelector(
|
|
26
|
-
".maplibregl-ctrl-logo",
|
|
27
|
-
) as HTMLAnchorElement | null;
|
|
28
|
-
if (logoElement) {
|
|
29
|
-
// Update the link attributes
|
|
30
|
-
logoElement.href = "https://barikoi.com/";
|
|
31
|
-
logoElement.setAttribute("aria-label", "Barikoi logo");
|
|
32
|
-
logoElement.target = "_blank";
|
|
33
|
-
logoElement.rel = "noopener nofollow";
|
|
34
|
-
logoElement.style.cursor = "pointer";
|
|
35
|
-
|
|
36
|
-
// Remove any existing click handlers
|
|
37
|
-
logoElement.replaceWith(logoElement.cloneNode(true));
|
|
38
|
-
}
|
|
39
|
-
}, [props.style, ctrl._container]);
|
|
40
|
-
|
|
41
|
-
return null;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export const LogoControl: React.FC<LogoControlProps> = memo(_LogoControl);
|
package/src/components/map.tsx
DELETED
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
/* eslint-disable react/display-name */
|
|
2
|
-
/* eslint-disable react/no-unknown-property */
|
|
3
|
-
import * as React from "react";
|
|
4
|
-
import {
|
|
5
|
-
useState,
|
|
6
|
-
useRef,
|
|
7
|
-
useEffect,
|
|
8
|
-
useContext,
|
|
9
|
-
useMemo,
|
|
10
|
-
useImperativeHandle,
|
|
11
|
-
} from "react";
|
|
12
|
-
|
|
13
|
-
import { MountedMapsContext } from "./use-map";
|
|
14
|
-
import Maplibre, { MaplibreProps } from "../maplibre/maplibre";
|
|
15
|
-
import createRef, { MapRef } from "../maplibre/create-ref";
|
|
16
|
-
|
|
17
|
-
import type { CSSProperties } from "react";
|
|
18
|
-
import useIsomorphicLayoutEffect from "../utils/use-isomorphic-layout-effect";
|
|
19
|
-
import setGlobals, { GlobalSettings } from "../utils/set-globals";
|
|
20
|
-
import type { MapLib, MapOptions } from "../types/lib";
|
|
21
|
-
import { LogoControl } from "./logo-control";
|
|
22
|
-
import { AttributionControl } from "./attribution-control";
|
|
23
|
-
|
|
24
|
-
export type MapContextValue = {
|
|
25
|
-
mapLib: MapLib;
|
|
26
|
-
map: MapRef;
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
export const MapContext = React.createContext<MapContextValue>(null);
|
|
30
|
-
|
|
31
|
-
type MapInitOptions = Omit<
|
|
32
|
-
MapOptions,
|
|
33
|
-
"style" | "container" | "bounds" | "fitBoundsOptions" | "center"
|
|
34
|
-
>;
|
|
35
|
-
|
|
36
|
-
export type MapProps = MapInitOptions &
|
|
37
|
-
MaplibreProps &
|
|
38
|
-
GlobalSettings & {
|
|
39
|
-
mapLib?: MapLib | Promise<MapLib>;
|
|
40
|
-
reuseMaps?: boolean;
|
|
41
|
-
/** Map container id */
|
|
42
|
-
id?: string;
|
|
43
|
-
/** Map container CSS style */
|
|
44
|
-
style?: CSSProperties;
|
|
45
|
-
children?: React.ReactNode;
|
|
46
|
-
/** Show Barikoi logo (default: true) */
|
|
47
|
-
showBarikoiLogo?: boolean;
|
|
48
|
-
/** Show Attribution (default: true) */
|
|
49
|
-
showAttribution?: boolean;
|
|
50
|
-
} & React.RefAttributes<MapRef>;
|
|
51
|
-
|
|
52
|
-
function _Map(props: MapProps, ref: React.Ref<MapRef>) {
|
|
53
|
-
const mountedMapsContext = useContext(MountedMapsContext);
|
|
54
|
-
const [mapInstance, setMapInstance] = useState<Maplibre>(null);
|
|
55
|
-
const containerRef = useRef();
|
|
56
|
-
|
|
57
|
-
const { current: contextValue } = useRef<MapContextValue>({
|
|
58
|
-
mapLib: null,
|
|
59
|
-
map: null,
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
useEffect(() => {
|
|
63
|
-
const mapLib = props.mapLib;
|
|
64
|
-
let isMounted = true;
|
|
65
|
-
let maplibre: Maplibre;
|
|
66
|
-
|
|
67
|
-
Promise.resolve(mapLib || import("maplibre-gl"))
|
|
68
|
-
.then((module: MapLib | { default: MapLib }) => {
|
|
69
|
-
if (!isMounted) {
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
72
|
-
if (!module) {
|
|
73
|
-
throw new Error("Invalid mapLib");
|
|
74
|
-
}
|
|
75
|
-
const mapboxgl = "Map" in module ? module : module.default;
|
|
76
|
-
if (!mapboxgl.Map) {
|
|
77
|
-
throw new Error("Invalid mapLib");
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
setGlobals(mapboxgl, props);
|
|
81
|
-
if (props.reuseMaps) {
|
|
82
|
-
maplibre = Maplibre.reuse(props, containerRef.current);
|
|
83
|
-
}
|
|
84
|
-
if (!maplibre) {
|
|
85
|
-
maplibre = new Maplibre(
|
|
86
|
-
mapboxgl.Map,
|
|
87
|
-
{
|
|
88
|
-
...props,
|
|
89
|
-
// @ts-ignore
|
|
90
|
-
attributionControl: false,
|
|
91
|
-
},
|
|
92
|
-
containerRef.current,
|
|
93
|
-
);
|
|
94
|
-
}
|
|
95
|
-
contextValue.map = createRef(maplibre);
|
|
96
|
-
contextValue.mapLib = mapboxgl;
|
|
97
|
-
|
|
98
|
-
setMapInstance(maplibre);
|
|
99
|
-
mountedMapsContext?.onMapMount(contextValue.map, props.id);
|
|
100
|
-
})
|
|
101
|
-
.catch((error) => {
|
|
102
|
-
const { onError } = props;
|
|
103
|
-
if (onError) {
|
|
104
|
-
onError({
|
|
105
|
-
type: "error",
|
|
106
|
-
target: null,
|
|
107
|
-
originalEvent: null,
|
|
108
|
-
error,
|
|
109
|
-
});
|
|
110
|
-
} else {
|
|
111
|
-
console.error(error); // eslint-disable-line
|
|
112
|
-
}
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
return () => {
|
|
116
|
-
isMounted = false;
|
|
117
|
-
if (maplibre) {
|
|
118
|
-
mountedMapsContext?.onMapUnmount(props.id);
|
|
119
|
-
if (props.reuseMaps) {
|
|
120
|
-
maplibre.recycle();
|
|
121
|
-
} else {
|
|
122
|
-
maplibre.destroy();
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
};
|
|
126
|
-
}, []);
|
|
127
|
-
|
|
128
|
-
useIsomorphicLayoutEffect(() => {
|
|
129
|
-
if (mapInstance) {
|
|
130
|
-
mapInstance.setProps(props);
|
|
131
|
-
}
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
useImperativeHandle(ref, () => contextValue.map, [mapInstance]);
|
|
135
|
-
|
|
136
|
-
const style: CSSProperties = useMemo(
|
|
137
|
-
() => ({
|
|
138
|
-
position: "relative",
|
|
139
|
-
width: "100%",
|
|
140
|
-
height: "100%",
|
|
141
|
-
...props.style,
|
|
142
|
-
}),
|
|
143
|
-
[props.style],
|
|
144
|
-
);
|
|
145
|
-
|
|
146
|
-
const CHILD_CONTAINER_STYLE = {
|
|
147
|
-
height: "100%",
|
|
148
|
-
};
|
|
149
|
-
|
|
150
|
-
return (
|
|
151
|
-
<div id={props.id} ref={containerRef} style={style}>
|
|
152
|
-
{mapInstance && (
|
|
153
|
-
<MapContext.Provider value={contextValue}>
|
|
154
|
-
<div mapboxgl-children="" style={CHILD_CONTAINER_STYLE}>
|
|
155
|
-
{/* Automatically include Barikoi Logo and Attribution controls */}
|
|
156
|
-
<LogoControl position="bottom-left" />
|
|
157
|
-
<AttributionControl position="bottom-right" />
|
|
158
|
-
{props.children}
|
|
159
|
-
</div>
|
|
160
|
-
</MapContext.Provider>
|
|
161
|
-
)}
|
|
162
|
-
</div>
|
|
163
|
-
);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
export const Map: React.FC<MapProps> = React.forwardRef(_Map);
|
package/src/components/marker.ts
DELETED
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
/* global document */
|
|
2
|
-
import * as React from "react";
|
|
3
|
-
import { createPortal } from "react-dom";
|
|
4
|
-
import {
|
|
5
|
-
useImperativeHandle,
|
|
6
|
-
useEffect,
|
|
7
|
-
useMemo,
|
|
8
|
-
useRef,
|
|
9
|
-
useContext,
|
|
10
|
-
forwardRef,
|
|
11
|
-
memo,
|
|
12
|
-
} from "react";
|
|
13
|
-
import { applyReactStyle } from "../utils/apply-react-style";
|
|
14
|
-
|
|
15
|
-
import type {
|
|
16
|
-
Popup as PopupInstance,
|
|
17
|
-
Marker as MarkerInstance,
|
|
18
|
-
MarkerOptions,
|
|
19
|
-
} from "../types/lib";
|
|
20
|
-
import type { MarkerEvent, MarkerDragEvent } from "../types/events";
|
|
21
|
-
|
|
22
|
-
import { MapContext } from "./map";
|
|
23
|
-
import { arePointsEqual } from "../utils/deep-equal";
|
|
24
|
-
import { compareClassNames } from "../utils/compare-class-names";
|
|
25
|
-
|
|
26
|
-
export type MarkerProps = MarkerOptions & {
|
|
27
|
-
/** Longitude of the anchor location */
|
|
28
|
-
longitude: number;
|
|
29
|
-
/** Latitude of the anchor location */
|
|
30
|
-
latitude: number;
|
|
31
|
-
|
|
32
|
-
popup?: PopupInstance;
|
|
33
|
-
|
|
34
|
-
/** CSS style override, applied to the control's container */
|
|
35
|
-
style?: React.CSSProperties;
|
|
36
|
-
onClick?: (e: MarkerEvent<MouseEvent>) => void;
|
|
37
|
-
onDragStart?: (e: MarkerDragEvent) => void;
|
|
38
|
-
onDrag?: (e: MarkerDragEvent) => void;
|
|
39
|
-
onDragEnd?: (e: MarkerDragEvent) => void;
|
|
40
|
-
children?: React.ReactNode;
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
/* eslint-disable complexity,max-statements */
|
|
44
|
-
export const Marker: React.FC<MarkerProps> = memo(
|
|
45
|
-
forwardRef((props: MarkerProps, ref: React.Ref<MarkerInstance>) => {
|
|
46
|
-
const { map, mapLib } = useContext(MapContext);
|
|
47
|
-
const thisRef = useRef({ props });
|
|
48
|
-
|
|
49
|
-
const marker: MarkerInstance = useMemo(() => {
|
|
50
|
-
let hasChildren = false;
|
|
51
|
-
React.Children.forEach(props.children, (el) => {
|
|
52
|
-
if (el) {
|
|
53
|
-
hasChildren = true;
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
|
-
const options = {
|
|
57
|
-
...props,
|
|
58
|
-
element: hasChildren ? document.createElement("div") : undefined,
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
const mk = new mapLib.Marker(options);
|
|
62
|
-
mk.setLngLat([props.longitude, props.latitude]);
|
|
63
|
-
|
|
64
|
-
mk.getElement().addEventListener("click", (e: MouseEvent) => {
|
|
65
|
-
thisRef.current.props.onClick?.({
|
|
66
|
-
type: "click",
|
|
67
|
-
target: mk,
|
|
68
|
-
originalEvent: e,
|
|
69
|
-
});
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
mk.on("dragstart", (e) => {
|
|
73
|
-
const evt = e as MarkerDragEvent;
|
|
74
|
-
evt.lngLat = marker.getLngLat();
|
|
75
|
-
thisRef.current.props.onDragStart?.(evt);
|
|
76
|
-
});
|
|
77
|
-
mk.on("drag", (e) => {
|
|
78
|
-
const evt = e as MarkerDragEvent;
|
|
79
|
-
evt.lngLat = marker.getLngLat();
|
|
80
|
-
thisRef.current.props.onDrag?.(evt);
|
|
81
|
-
});
|
|
82
|
-
mk.on("dragend", (e) => {
|
|
83
|
-
const evt = e as MarkerDragEvent;
|
|
84
|
-
evt.lngLat = marker.getLngLat();
|
|
85
|
-
thisRef.current.props.onDragEnd?.(evt);
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
return mk;
|
|
89
|
-
}, []);
|
|
90
|
-
|
|
91
|
-
useEffect(() => {
|
|
92
|
-
marker.addTo(map.getMap());
|
|
93
|
-
|
|
94
|
-
return () => {
|
|
95
|
-
marker.remove();
|
|
96
|
-
};
|
|
97
|
-
}, []);
|
|
98
|
-
|
|
99
|
-
const {
|
|
100
|
-
longitude,
|
|
101
|
-
latitude,
|
|
102
|
-
offset,
|
|
103
|
-
style,
|
|
104
|
-
draggable = false,
|
|
105
|
-
popup = null,
|
|
106
|
-
rotation = 0,
|
|
107
|
-
rotationAlignment = "auto",
|
|
108
|
-
pitchAlignment = "auto",
|
|
109
|
-
} = props;
|
|
110
|
-
|
|
111
|
-
useEffect(() => {
|
|
112
|
-
applyReactStyle(marker.getElement(), style);
|
|
113
|
-
}, [style]);
|
|
114
|
-
|
|
115
|
-
useImperativeHandle(ref, () => marker, []);
|
|
116
|
-
|
|
117
|
-
const oldProps = thisRef.current.props;
|
|
118
|
-
if (
|
|
119
|
-
marker.getLngLat().lng !== longitude ||
|
|
120
|
-
marker.getLngLat().lat !== latitude
|
|
121
|
-
) {
|
|
122
|
-
marker.setLngLat([longitude, latitude]);
|
|
123
|
-
}
|
|
124
|
-
if (offset && !arePointsEqual(marker.getOffset(), offset)) {
|
|
125
|
-
marker.setOffset(offset);
|
|
126
|
-
}
|
|
127
|
-
if (marker.isDraggable() !== draggable) {
|
|
128
|
-
marker.setDraggable(draggable);
|
|
129
|
-
}
|
|
130
|
-
if (marker.getRotation() !== rotation) {
|
|
131
|
-
marker.setRotation(rotation);
|
|
132
|
-
}
|
|
133
|
-
if (marker.getRotationAlignment() !== rotationAlignment) {
|
|
134
|
-
marker.setRotationAlignment(rotationAlignment);
|
|
135
|
-
}
|
|
136
|
-
if (marker.getPitchAlignment() !== pitchAlignment) {
|
|
137
|
-
marker.setPitchAlignment(pitchAlignment);
|
|
138
|
-
}
|
|
139
|
-
if (marker.getPopup() !== popup) {
|
|
140
|
-
marker.setPopup(popup);
|
|
141
|
-
}
|
|
142
|
-
const classNameDiff = compareClassNames(
|
|
143
|
-
oldProps.className,
|
|
144
|
-
props.className,
|
|
145
|
-
);
|
|
146
|
-
if (classNameDiff) {
|
|
147
|
-
for (const c of classNameDiff) {
|
|
148
|
-
marker.toggleClassName(c);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
thisRef.current.props = props;
|
|
153
|
-
return createPortal(props.children, marker.getElement());
|
|
154
|
-
}),
|
|
155
|
-
);
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import { useEffect, memo } from "react";
|
|
3
|
-
import { applyReactStyle } from "../utils/apply-react-style";
|
|
4
|
-
import { useControl } from "./use-control";
|
|
5
|
-
|
|
6
|
-
import type { ControlPosition, NavigationControlOptions } from "../types/lib";
|
|
7
|
-
|
|
8
|
-
export type NavigationControlProps = NavigationControlOptions & {
|
|
9
|
-
/** Placement of the control relative to the map. */
|
|
10
|
-
position?: ControlPosition;
|
|
11
|
-
/** CSS style override, applied to the control's container */
|
|
12
|
-
style?: React.CSSProperties;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
function _NavigationControl(props: NavigationControlProps) {
|
|
16
|
-
const ctrl = useControl(({ mapLib }) => new mapLib.NavigationControl(props), {
|
|
17
|
-
position: props.position,
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
useEffect(() => {
|
|
21
|
-
applyReactStyle(ctrl._container, props.style);
|
|
22
|
-
}, [props.style]);
|
|
23
|
-
|
|
24
|
-
return null;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export const NavigationControl: React.FC<NavigationControlProps> =
|
|
28
|
-
memo(_NavigationControl);
|
package/src/components/popup.ts
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-floating-promises */
|
|
2
|
-
/* global document */
|
|
3
|
-
import * as React from "react";
|
|
4
|
-
import { createPortal } from "react-dom";
|
|
5
|
-
import {
|
|
6
|
-
useImperativeHandle,
|
|
7
|
-
useEffect,
|
|
8
|
-
useMemo,
|
|
9
|
-
useRef,
|
|
10
|
-
useContext,
|
|
11
|
-
forwardRef,
|
|
12
|
-
memo,
|
|
13
|
-
} from "react";
|
|
14
|
-
import { applyReactStyle } from "../utils/apply-react-style";
|
|
15
|
-
|
|
16
|
-
import type { Popup as PopupInstance, PopupOptions } from "../types/lib";
|
|
17
|
-
import type { PopupEvent } from "../types/events";
|
|
18
|
-
|
|
19
|
-
import { MapContext } from "./map";
|
|
20
|
-
import { deepEqual } from "../utils/deep-equal";
|
|
21
|
-
import { compareClassNames } from "../utils/compare-class-names";
|
|
22
|
-
|
|
23
|
-
export type PopupProps = PopupOptions & {
|
|
24
|
-
/** Longitude of the anchor location */
|
|
25
|
-
longitude: number;
|
|
26
|
-
/** Latitude of the anchor location */
|
|
27
|
-
latitude: number;
|
|
28
|
-
|
|
29
|
-
/** CSS style override, applied to the control's container */
|
|
30
|
-
style?: React.CSSProperties;
|
|
31
|
-
|
|
32
|
-
onOpen?: (e: PopupEvent) => void;
|
|
33
|
-
onClose?: (e: PopupEvent) => void;
|
|
34
|
-
children?: React.ReactNode;
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
/* eslint-disable complexity,max-statements */
|
|
38
|
-
export const Popup: React.FC<PopupProps> = memo(
|
|
39
|
-
forwardRef((props: PopupProps, ref: React.Ref<PopupInstance>) => {
|
|
40
|
-
const { map, mapLib } = useContext(MapContext);
|
|
41
|
-
const container = useMemo(() => {
|
|
42
|
-
return document.createElement("div");
|
|
43
|
-
}, []);
|
|
44
|
-
const thisRef = useRef({ props });
|
|
45
|
-
|
|
46
|
-
const popup: PopupInstance = useMemo(() => {
|
|
47
|
-
const options = { ...props };
|
|
48
|
-
const pp = new mapLib.Popup(options);
|
|
49
|
-
pp.setLngLat([props.longitude, props.latitude]);
|
|
50
|
-
pp.once("open", (e) => {
|
|
51
|
-
thisRef.current.props.onOpen?.(e as PopupEvent);
|
|
52
|
-
});
|
|
53
|
-
return pp;
|
|
54
|
-
}, []);
|
|
55
|
-
|
|
56
|
-
useEffect(() => {
|
|
57
|
-
const onClose = (e) => {
|
|
58
|
-
thisRef.current.props.onClose?.(e as PopupEvent);
|
|
59
|
-
};
|
|
60
|
-
popup.on("close", onClose);
|
|
61
|
-
popup.setDOMContent(container).addTo(map.getMap());
|
|
62
|
-
|
|
63
|
-
return () => {
|
|
64
|
-
// https://github.com/visgl/react-map-gl/issues/1825
|
|
65
|
-
// onClose should not be fired if the popup is removed by unmounting
|
|
66
|
-
// When using React strict mode, the component is mounted twice.
|
|
67
|
-
// Firing the onClose callback here would be a false signal to remove the component.
|
|
68
|
-
popup.off("close", onClose);
|
|
69
|
-
if (popup.isOpen()) {
|
|
70
|
-
popup.remove();
|
|
71
|
-
}
|
|
72
|
-
};
|
|
73
|
-
}, []);
|
|
74
|
-
|
|
75
|
-
useEffect(() => {
|
|
76
|
-
applyReactStyle(popup.getElement(), props.style);
|
|
77
|
-
}, [props.style]);
|
|
78
|
-
|
|
79
|
-
useImperativeHandle(ref, () => popup, []);
|
|
80
|
-
|
|
81
|
-
if (popup.isOpen()) {
|
|
82
|
-
const oldProps = thisRef.current.props;
|
|
83
|
-
if (
|
|
84
|
-
popup.getLngLat().lng !== props.longitude ||
|
|
85
|
-
popup.getLngLat().lat !== props.latitude
|
|
86
|
-
) {
|
|
87
|
-
popup.setLngLat([props.longitude, props.latitude]);
|
|
88
|
-
}
|
|
89
|
-
if (props.offset && !deepEqual(oldProps.offset, props.offset)) {
|
|
90
|
-
popup.setOffset(props.offset);
|
|
91
|
-
}
|
|
92
|
-
if (
|
|
93
|
-
oldProps.anchor !== props.anchor ||
|
|
94
|
-
oldProps.maxWidth !== props.maxWidth
|
|
95
|
-
) {
|
|
96
|
-
popup.options.anchor = props.anchor;
|
|
97
|
-
popup.setMaxWidth(props.maxWidth);
|
|
98
|
-
}
|
|
99
|
-
const classNameDiff = compareClassNames(
|
|
100
|
-
oldProps.className,
|
|
101
|
-
props.className,
|
|
102
|
-
);
|
|
103
|
-
if (classNameDiff) {
|
|
104
|
-
for (const c of classNameDiff) {
|
|
105
|
-
popup.toggleClassName(c);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
thisRef.current.props = props;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
return createPortal(props.children, container);
|
|
112
|
-
}),
|
|
113
|
-
);
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import { useEffect, useRef, memo } from "react";
|
|
3
|
-
import { applyReactStyle } from "../utils/apply-react-style";
|
|
4
|
-
import { useControl } from "./use-control";
|
|
5
|
-
|
|
6
|
-
import type { ControlPosition, ScaleControlOptions } from "../types/lib";
|
|
7
|
-
|
|
8
|
-
export type ScaleControlProps = ScaleControlOptions & {
|
|
9
|
-
// These props will be further constraint by OptionsT
|
|
10
|
-
unit?: string;
|
|
11
|
-
maxWidth?: number;
|
|
12
|
-
|
|
13
|
-
/** Placement of the control relative to the map. */
|
|
14
|
-
position?: ControlPosition;
|
|
15
|
-
/** CSS style override, applied to the control's container */
|
|
16
|
-
style?: React.CSSProperties;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
function _ScaleControl(props: ScaleControlProps) {
|
|
20
|
-
const ctrl = useControl(({ mapLib }) => new mapLib.ScaleControl(props), {
|
|
21
|
-
position: props.position,
|
|
22
|
-
});
|
|
23
|
-
const propsRef = useRef<ScaleControlProps>(props);
|
|
24
|
-
|
|
25
|
-
const prevProps = propsRef.current;
|
|
26
|
-
propsRef.current = props;
|
|
27
|
-
|
|
28
|
-
const { style } = props;
|
|
29
|
-
|
|
30
|
-
if (props.maxWidth !== undefined && props.maxWidth !== prevProps.maxWidth) {
|
|
31
|
-
ctrl.options.maxWidth = props.maxWidth;
|
|
32
|
-
}
|
|
33
|
-
if (props.unit !== undefined && props.unit !== prevProps.unit) {
|
|
34
|
-
ctrl.setUnit(props.unit);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
useEffect(() => {
|
|
38
|
-
applyReactStyle(ctrl._container, style);
|
|
39
|
-
}, [style]);
|
|
40
|
-
|
|
41
|
-
return null;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export const ScaleControl: React.FC<ScaleControlProps> = memo(_ScaleControl);
|