react-bkoi-gl 1.0.6 → 2.0.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/README.md +163 -18
- package/dist/components/attribution-control.d.ts +4 -6
- package/dist/components/attribution-control.js +6 -5
- package/dist/components/attribution-control.js.map +1 -1
- package/dist/components/fullscreen-control.d.ts +4 -6
- package/dist/components/fullscreen-control.js +4 -4
- package/dist/components/fullscreen-control.js.map +1 -1
- package/dist/components/geolocate-control.d.ts +10 -26
- package/dist/components/geolocate-control.js +11 -11
- package/dist/components/geolocate-control.js.map +1 -1
- package/dist/components/layer.d.ts +7 -6
- package/dist/components/layer.js +8 -9
- package/dist/components/layer.js.map +1 -1
- package/dist/components/logo-control.d.ts +9 -0
- package/dist/components/logo-control.js +28 -0
- package/dist/components/logo-control.js.map +1 -0
- package/dist/components/map.d.ts +20 -16
- package/dist/components/map.js +38 -32
- package/dist/components/map.js.map +1 -1
- package/dist/components/marker.d.ts +10 -33
- package/dist/components/marker.js +22 -15
- package/dist/components/marker.js.map +1 -1
- package/dist/components/navigation-control.d.ts +4 -6
- package/dist/components/navigation-control.js +4 -4
- package/dist/components/navigation-control.js.map +1 -1
- package/dist/components/popup.d.ts +7 -25
- package/dist/components/popup.js +17 -28
- package/dist/components/popup.js.map +1 -1
- package/dist/components/scale-control.d.ts +4 -6
- package/dist/components/scale-control.js +4 -4
- package/dist/components/scale-control.js.map +1 -1
- package/dist/components/source.d.ts +3 -4
- package/dist/components/source.js +20 -22
- package/dist/components/source.js.map +1 -1
- package/dist/components/terrain-control.d.ts +10 -0
- package/dist/components/terrain-control.js +19 -0
- package/dist/components/terrain-control.js.map +1 -0
- package/dist/components/use-control.d.ts +6 -6
- package/dist/components/use-control.js +4 -5
- package/dist/components/use-control.js.map +1 -1
- package/dist/components/use-map.d.ts +8 -9
- package/dist/components/use-map.js +5 -5
- package/dist/components/use-map.js.map +1 -1
- package/dist/exports-maplibre-gl.d.ts +33 -0
- package/dist/exports-maplibre-gl.js +21 -0
- package/dist/exports-maplibre-gl.js.map +1 -0
- package/dist/index.cjs +590 -681
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/{mapbox → maplibre}/create-ref.d.ts +6 -6
- package/dist/maplibre/create-ref.js +30 -0
- package/dist/maplibre/create-ref.js.map +1 -0
- package/dist/maplibre/maplibre.d.ts +81 -0
- package/dist/maplibre/maplibre.js +387 -0
- package/dist/maplibre/maplibre.js.map +1 -0
- package/dist/styles/index.d.ts +4 -0
- package/dist/styles/react-bkoi-gl.css +1 -1
- package/dist/styles.d.js +2 -0
- package/dist/styles.d.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/dist/types/common.d.ts +2 -60
- package/dist/types/common.js.map +1 -1
- package/dist/types/events.d.ts +64 -23
- package/dist/types/events.js.map +1 -1
- package/dist/types/internal.d.ts +14 -0
- package/dist/types/internal.js +2 -0
- package/dist/types/internal.js.map +1 -0
- package/dist/types/lib.d.ts +16 -200
- package/dist/types/lib.js.map +1 -1
- package/dist/types/style-spec.d.ts +1 -0
- package/dist/types/style-spec.js +2 -0
- package/dist/types/style-spec.js.map +1 -0
- package/dist/utils/apply-react-style.d.ts +1 -1
- package/dist/utils/apply-react-style.js.map +1 -1
- package/dist/utils/compare-class-names.d.ts +2 -0
- package/dist/utils/compare-class-names.js +23 -0
- package/dist/utils/compare-class-names.js.map +1 -0
- package/dist/utils/deep-equal.d.ts +1 -1
- package/dist/utils/deep-equal.js +1 -1
- package/dist/utils/deep-equal.js.map +1 -1
- package/dist/utils/set-globals.d.ts +6 -8
- package/dist/utils/set-globals.js +22 -10
- package/dist/utils/set-globals.js.map +1 -1
- package/dist/utils/style-utils.d.ts +3 -2
- package/dist/utils/style-utils.js +4 -4
- package/dist/utils/style-utils.js.map +1 -1
- package/dist/utils/transform.d.ts +11 -19
- package/dist/utils/transform.js +13 -36
- package/dist/utils/transform.js.map +1 -1
- package/dist/utils/use-isomorphic-layout-effect.d.ts +1 -1
- package/dist/utils/use-isomorphic-layout-effect.js +2 -2
- package/dist/utils/use-isomorphic-layout-effect.js.map +1 -1
- package/package.json +42 -26
- package/src/components/attribution-control.ts +40 -16
- package/src/components/fullscreen-control.ts +40 -0
- package/src/components/geolocate-control.ts +45 -39
- package/src/components/layer.ts +37 -29
- package/src/components/logo-control.ts +44 -0
- package/src/components/map.tsx +86 -75
- package/src/components/marker.ts +141 -123
- package/src/components/navigation-control.ts +11 -12
- package/src/components/popup.ts +94 -97
- package/src/components/scale-control.ts +12 -14
- package/src/components/source.ts +58 -57
- package/src/components/terrain-control.ts +29 -0
- package/src/components/use-control.ts +21 -17
- package/src/components/use-map.tsx +26 -24
- package/src/exports-maplibre-gl.ts +37 -0
- package/src/index.ts +3 -2
- package/src/maplibre/create-ref.ts +70 -0
- package/src/maplibre/maplibre.ts +624 -0
- package/src/styles.d.ts +4 -0
- package/src/types/common.ts +12 -72
- package/src/types/events.ts +102 -42
- package/src/types/internal.ts +26 -0
- package/src/types/lib.ts +65 -260
- package/src/types/style-spec.ts +34 -0
- package/src/utils/apply-react-style.ts +7 -3
- package/src/utils/compare-class-names.ts +29 -0
- package/src/utils/deep-equal.ts +2 -2
- package/src/utils/set-globals.ts +22 -28
- package/src/utils/style-utils.ts +18 -9
- package/src/utils/transform.ts +32 -60
- package/src/utils/use-isomorphic-layout-effect.ts +3 -2
- package/bkoi-gl/package.json +0 -6
- package/dist/exports-bkoi-gl.cjs +0 -1512
- package/dist/exports-bkoi-gl.d.ts +0 -89
- package/dist/exports-bkoi-gl.js +0 -36
- package/dist/exports-bkoi-gl.js.map +0 -1
- package/dist/exports-mapbox.d.ts +0 -139
- package/dist/exports-mapbox.js +0 -36
- package/dist/exports-mapbox.js.map +0 -1
- package/dist/mapbox/create-ref.js +0 -64
- package/dist/mapbox/create-ref.js.map +0 -1
- package/dist/mapbox/mapbox.d.ts +0 -81
- package/dist/mapbox/mapbox.js +0 -476
- package/dist/mapbox/mapbox.js.map +0 -1
- package/dist/types/events-bkoi-gl.d.ts +0 -49
- package/dist/types/events-bkoi-gl.js +0 -2
- package/dist/types/events-bkoi-gl.js.map +0 -1
- package/dist/types/events-mapbox.d.ts +0 -49
- package/dist/types/events-mapbox.js +0 -2
- package/dist/types/events-mapbox.js.map +0 -1
- package/dist/types/index.d.ts +0 -70
- package/dist/types/index.js +0 -5
- package/dist/types/index.js.map +0 -1
- package/dist/types/public.d.ts +0 -2
- package/dist/types/public.js +0 -2
- package/dist/types/public.js.map +0 -1
- package/dist/types/style-spec-bkoi-gl.d.ts +0 -9
- package/dist/types/style-spec-bkoi-gl.js +0 -2
- package/dist/types/style-spec-bkoi-gl.js.map +0 -1
- package/dist/types/style-spec-mapbox.d.ts +0 -7
- package/dist/types/style-spec-mapbox.js +0 -2
- package/dist/types/style-spec-mapbox.js.map +0 -1
- package/src/components/fullscreen-control.tsx +0 -37
- package/src/exports-bkoi-gl.ts +0 -156
- package/src/exports-mapbox.ts +0 -159
- package/src/mapbox/create-ref.ts +0 -118
- package/src/mapbox/mapbox.ts +0 -742
- package/src/types/events-bkoi-gl.ts +0 -78
- package/src/types/events-mapbox.ts +0 -76
- package/src/types/index.ts +0 -93
- package/src/types/public.ts +0 -9
- package/src/types/style-spec-bkoi-gl.ts +0 -81
- package/src/types/style-spec-mapbox.ts +0 -80
package/src/components/popup.ts
CHANGED
|
@@ -1,116 +1,113 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-floating-promises */
|
|
1
2
|
/* global document */
|
|
2
|
-
import * as React from
|
|
3
|
-
import {createPortal} from
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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 & {
|
|
13
24
|
/** Longitude of the anchor location */
|
|
14
25
|
longitude: number;
|
|
15
26
|
/** Latitude of the anchor location */
|
|
16
27
|
latitude: number;
|
|
17
28
|
|
|
18
|
-
// These types will be further constraint by OptionsT
|
|
19
|
-
anchor?: string;
|
|
20
|
-
offset?: any;
|
|
21
|
-
className?: string;
|
|
22
|
-
maxWidth?: string;
|
|
23
|
-
|
|
24
29
|
/** CSS style override, applied to the control's container */
|
|
25
30
|
style?: React.CSSProperties;
|
|
26
31
|
|
|
27
|
-
onOpen?: (e: PopupEvent
|
|
28
|
-
onClose?: (e: PopupEvent
|
|
32
|
+
onOpen?: (e: PopupEvent) => void;
|
|
33
|
+
onClose?: (e: PopupEvent) => void;
|
|
29
34
|
children?: React.ReactNode;
|
|
30
35
|
};
|
|
31
36
|
|
|
32
|
-
// Adapted from https://github.com/mapbox/mapbox-gl-js/blob/v1.13.0/src/ui/popup.js
|
|
33
|
-
function getClassList(className: string) {
|
|
34
|
-
return new Set(className ? className.trim().split(/\s+/) : []);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
37
|
/* eslint-disable complexity,max-statements */
|
|
38
|
-
|
|
39
|
-
props: PopupProps
|
|
40
|
-
|
|
41
|
-
) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
popup.off('close', onClose);
|
|
72
|
-
if (popup.isOpen()) {
|
|
73
|
-
popup.remove();
|
|
74
|
-
}
|
|
75
|
-
};
|
|
76
|
-
}, []);
|
|
77
|
-
|
|
78
|
-
useEffect(() => {
|
|
79
|
-
applyReactStyle(popup.getElement(), props.style);
|
|
80
|
-
}, [props.style]);
|
|
81
|
-
|
|
82
|
-
useImperativeHandle(ref, () => popup, []);
|
|
83
|
-
|
|
84
|
-
if (popup.isOpen()) {
|
|
85
|
-
if (popup.getLngLat().lng !== props.longitude || popup.getLngLat().lat !== props.latitude) {
|
|
86
|
-
popup.setLngLat([props.longitude, props.latitude]);
|
|
87
|
-
}
|
|
88
|
-
if (props.offset && !deepEqual(popup.options.offset, props.offset)) {
|
|
89
|
-
popup.setOffset(props.offset);
|
|
90
|
-
}
|
|
91
|
-
if (popup.options.anchor !== props.anchor || popup.options.maxWidth !== props.maxWidth) {
|
|
92
|
-
popup.options.anchor = props.anchor;
|
|
93
|
-
popup.setMaxWidth(props.maxWidth);
|
|
94
|
-
}
|
|
95
|
-
if (popup.options.className !== props.className) {
|
|
96
|
-
const prevClassList = getClassList(popup.options.className);
|
|
97
|
-
const nextClassList = getClassList(props.className);
|
|
98
|
-
|
|
99
|
-
for (const c of prevClassList) {
|
|
100
|
-
if (!nextClassList.has(c)) {
|
|
101
|
-
popup.removeClassName(c);
|
|
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();
|
|
102
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);
|
|
103
91
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
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);
|
|
107
106
|
}
|
|
108
107
|
}
|
|
109
|
-
|
|
108
|
+
thisRef.current.props = props;
|
|
110
109
|
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
return createPortal(props.children, container);
|
|
114
|
-
}
|
|
115
110
|
|
|
116
|
-
|
|
111
|
+
return createPortal(props.children, container);
|
|
112
|
+
}),
|
|
113
|
+
);
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import * as React from
|
|
2
|
-
import {useEffect, useRef, memo} from
|
|
3
|
-
import {applyReactStyle} from
|
|
4
|
-
import useControl from
|
|
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
5
|
|
|
6
|
-
import type {ControlPosition,
|
|
6
|
+
import type { ControlPosition, ScaleControlOptions } from "../types/lib";
|
|
7
7
|
|
|
8
|
-
export type ScaleControlProps
|
|
8
|
+
export type ScaleControlProps = ScaleControlOptions & {
|
|
9
9
|
// These props will be further constraint by OptionsT
|
|
10
10
|
unit?: string;
|
|
11
11
|
maxWidth?: number;
|
|
@@ -16,18 +16,16 @@ export type ScaleControlProps<OptionsT> = OptionsT & {
|
|
|
16
16
|
style?: React.CSSProperties;
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
-
function
|
|
20
|
-
props
|
|
21
|
-
|
|
22
|
-
const ctrl = useControl<ControlT>(({mapLib}) => new mapLib.ScaleControl(props) as ControlT, {
|
|
23
|
-
position: props.position
|
|
19
|
+
function _ScaleControl(props: ScaleControlProps) {
|
|
20
|
+
const ctrl = useControl(({ mapLib }) => new mapLib.ScaleControl(props), {
|
|
21
|
+
position: props.position,
|
|
24
22
|
});
|
|
25
|
-
const propsRef = useRef<ScaleControlProps
|
|
23
|
+
const propsRef = useRef<ScaleControlProps>(props);
|
|
26
24
|
|
|
27
25
|
const prevProps = propsRef.current;
|
|
28
26
|
propsRef.current = props;
|
|
29
27
|
|
|
30
|
-
const {style} = props;
|
|
28
|
+
const { style } = props;
|
|
31
29
|
|
|
32
30
|
if (props.maxWidth !== undefined && props.maxWidth !== prevProps.maxWidth) {
|
|
33
31
|
ctrl.options.maxWidth = props.maxWidth;
|
|
@@ -43,4 +41,4 @@ function ScaleControl<ScaleControlOptions, ControlT extends ScaleControlInstance
|
|
|
43
41
|
return null;
|
|
44
42
|
}
|
|
45
43
|
|
|
46
|
-
export
|
|
44
|
+
export const ScaleControl: React.FC<ScaleControlProps> = memo(_ScaleControl);
|
package/src/components/source.ts
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
import * as React from
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import {
|
|
3
|
+
useContext,
|
|
4
|
+
useEffect,
|
|
5
|
+
useMemo,
|
|
6
|
+
useState,
|
|
7
|
+
useRef,
|
|
8
|
+
cloneElement,
|
|
9
|
+
} from "react";
|
|
10
|
+
import { MapContext } from "./map";
|
|
11
|
+
import assert from "../utils/assert";
|
|
12
|
+
import { deepEqual } from "../utils/deep-equal";
|
|
7
13
|
|
|
8
14
|
import type {
|
|
9
|
-
MapInstance,
|
|
10
|
-
ISource,
|
|
11
|
-
CustomSource,
|
|
12
15
|
GeoJSONSourceImplementation,
|
|
13
|
-
|
|
14
|
-
AnySourceImplementation
|
|
15
|
-
} from
|
|
16
|
-
import type {
|
|
16
|
+
ImageSourceImplementation,
|
|
17
|
+
AnySourceImplementation,
|
|
18
|
+
} from "../types/internal";
|
|
19
|
+
import type { SourceSpecification } from "../types/style-spec";
|
|
20
|
+
import type { Map as MapInstance } from "../types/lib";
|
|
17
21
|
|
|
18
|
-
export type SourceProps
|
|
22
|
+
export type SourceProps = SourceSpecification & {
|
|
19
23
|
id?: string;
|
|
20
24
|
children?: any;
|
|
21
25
|
};
|
|
22
26
|
|
|
23
27
|
let sourceCounter = 0;
|
|
24
28
|
|
|
25
|
-
function createSource
|
|
26
|
-
map: MapInstance,
|
|
27
|
-
id: string,
|
|
28
|
-
props: SourceProps<SourceT>
|
|
29
|
-
) {
|
|
29
|
+
function createSource(map: MapInstance, id: string, props: SourceProps) {
|
|
30
30
|
// @ts-ignore
|
|
31
31
|
if (map.style && map.style._loaded) {
|
|
32
|
-
const options = {...props};
|
|
32
|
+
const options = { ...props };
|
|
33
33
|
delete options.id;
|
|
34
34
|
delete options.children;
|
|
35
35
|
// @ts-ignore
|
|
@@ -40,19 +40,23 @@ function createSource<SourceT extends ISource>(
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
/* eslint-disable complexity */
|
|
43
|
-
function updateSource
|
|
43
|
+
function updateSource(
|
|
44
44
|
source: AnySourceImplementation,
|
|
45
|
-
props: SourceProps
|
|
46
|
-
prevProps: SourceProps
|
|
45
|
+
props: SourceProps,
|
|
46
|
+
prevProps: SourceProps,
|
|
47
47
|
) {
|
|
48
|
-
assert(props.id === prevProps.id,
|
|
49
|
-
assert(props.type === prevProps.type,
|
|
48
|
+
assert(props.id === prevProps.id, "source id changed");
|
|
49
|
+
assert(props.type === prevProps.type, "source type changed");
|
|
50
50
|
|
|
51
|
-
let changedKey =
|
|
51
|
+
let changedKey = "";
|
|
52
52
|
let changedKeyCount = 0;
|
|
53
53
|
|
|
54
54
|
for (const key in props) {
|
|
55
|
-
if (
|
|
55
|
+
if (
|
|
56
|
+
key !== "children" &&
|
|
57
|
+
key !== "id" &&
|
|
58
|
+
!deepEqual(prevProps[key], props[key])
|
|
59
|
+
) {
|
|
56
60
|
changedKey = key;
|
|
57
61
|
changedKeyCount++;
|
|
58
62
|
}
|
|
@@ -64,38 +68,36 @@ function updateSource<SourceT extends ISource>(
|
|
|
64
68
|
|
|
65
69
|
const type = props.type;
|
|
66
70
|
|
|
67
|
-
if (type ===
|
|
68
|
-
(source as GeoJSONSourceImplementation).setData(
|
|
69
|
-
|
|
70
|
-
)
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
url: (props as unknown as ImageSourceRaw).url,
|
|
74
|
-
coordinates: (props as unknown as ImageSourceRaw).coordinates
|
|
71
|
+
if (type === "geojson") {
|
|
72
|
+
(source as GeoJSONSourceImplementation).setData(props.data);
|
|
73
|
+
} else if (type === "image") {
|
|
74
|
+
(source as ImageSourceImplementation).updateImage({
|
|
75
|
+
url: props.url,
|
|
76
|
+
coordinates: props.coordinates,
|
|
75
77
|
});
|
|
76
|
-
} else
|
|
77
|
-
source.setCoordinates((props as ImageSourceRaw).coordinates);
|
|
78
|
-
} else if ('setUrl' in source) {
|
|
79
|
-
// Added in 1.12.0:
|
|
80
|
-
// vectorTileSource.setTiles
|
|
81
|
-
// vectorTileSource.setUrl
|
|
78
|
+
} else {
|
|
82
79
|
switch (changedKey) {
|
|
83
|
-
case
|
|
84
|
-
|
|
80
|
+
case "coordinates":
|
|
81
|
+
// @ts-ignore
|
|
82
|
+
source.setCoordinates?.(props.coordinates);
|
|
83
|
+
break;
|
|
84
|
+
case "url":
|
|
85
|
+
// @ts-ignore
|
|
86
|
+
source.setUrl?.(props.url);
|
|
85
87
|
break;
|
|
86
|
-
case
|
|
87
|
-
|
|
88
|
+
case "tiles":
|
|
89
|
+
// @ts-ignore
|
|
90
|
+
source.setTiles?.(props.tiles);
|
|
88
91
|
break;
|
|
89
92
|
default:
|
|
93
|
+
// eslint-disable-next-line
|
|
94
|
+
console.warn(`Unable to update <Source> prop: ${changedKey}`);
|
|
90
95
|
}
|
|
91
|
-
} else {
|
|
92
|
-
// eslint-disable-next-line
|
|
93
|
-
console.warn(`Unable to update <Source> prop: ${changedKey}`);
|
|
94
96
|
}
|
|
95
97
|
}
|
|
96
98
|
/* eslint-enable complexity */
|
|
97
99
|
|
|
98
|
-
function Source
|
|
100
|
+
export function Source(props: SourceProps) {
|
|
99
101
|
const map = useContext(MapContext).map.getMap();
|
|
100
102
|
const propsRef = useRef(props);
|
|
101
103
|
const [, setStyleLoaded] = useState(0);
|
|
@@ -105,12 +107,13 @@ function Source<SourceT extends ISource>(props: SourceProps<SourceT>) {
|
|
|
105
107
|
useEffect(() => {
|
|
106
108
|
if (map) {
|
|
107
109
|
/* global setTimeout */
|
|
108
|
-
const forceUpdate = () =>
|
|
109
|
-
|
|
110
|
+
const forceUpdate = () =>
|
|
111
|
+
setTimeout(() => setStyleLoaded((version) => version + 1), 0);
|
|
112
|
+
map.on("styledata", forceUpdate);
|
|
110
113
|
forceUpdate();
|
|
111
114
|
|
|
112
115
|
return () => {
|
|
113
|
-
map.off(
|
|
116
|
+
map.off("styledata", forceUpdate);
|
|
114
117
|
// @ts-ignore
|
|
115
118
|
if (map.style && map.style._loaded && map.getSource(id)) {
|
|
116
119
|
// Parent effects are destroyed before child ones, see
|
|
@@ -145,14 +148,12 @@ function Source<SourceT extends ISource>(props: SourceProps<SourceT>) {
|
|
|
145
148
|
(source &&
|
|
146
149
|
React.Children.map(
|
|
147
150
|
props.children,
|
|
148
|
-
child =>
|
|
151
|
+
(child) =>
|
|
149
152
|
child &&
|
|
150
153
|
cloneElement(child, {
|
|
151
|
-
source: id
|
|
152
|
-
})
|
|
154
|
+
source: id,
|
|
155
|
+
}),
|
|
153
156
|
)) ||
|
|
154
157
|
null
|
|
155
158
|
);
|
|
156
159
|
}
|
|
157
|
-
|
|
158
|
-
export default Source;
|
|
@@ -0,0 +1,29 @@
|
|
|
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 } from "../types/lib";
|
|
7
|
+
import type { TerrainSpecification } from "../types/style-spec";
|
|
8
|
+
|
|
9
|
+
export type TerrainControlProps = TerrainSpecification & {
|
|
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 _TerrainControl(props: TerrainControlProps) {
|
|
17
|
+
const ctrl = useControl(({ mapLib }) => new mapLib.TerrainControl(props), {
|
|
18
|
+
position: props.position,
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
applyReactStyle(ctrl._container, props.style);
|
|
23
|
+
}, [props.style]);
|
|
24
|
+
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const TerrainControl: React.FC<TerrainControlProps> =
|
|
29
|
+
memo(_TerrainControl);
|
|
@@ -1,45 +1,51 @@
|
|
|
1
|
-
import {useContext, useMemo, useEffect} from
|
|
2
|
-
import type {IControl, ControlPosition} from
|
|
3
|
-
import {MapContext} from
|
|
4
|
-
import type {MapContextValue} from
|
|
1
|
+
import { useContext, useMemo, useEffect } from "react";
|
|
2
|
+
import type { IControl, ControlPosition } from "../types/lib";
|
|
3
|
+
import { MapContext } from "./map";
|
|
4
|
+
import type { MapContextValue } from "./map";
|
|
5
5
|
|
|
6
6
|
type ControlOptions = {
|
|
7
7
|
position?: ControlPosition;
|
|
8
8
|
};
|
|
9
9
|
|
|
10
|
-
function useControl<T extends IControl>(
|
|
10
|
+
export function useControl<T extends IControl>(
|
|
11
11
|
onCreate: (context: MapContextValue) => T,
|
|
12
|
-
opts?: ControlOptions
|
|
12
|
+
opts?: ControlOptions,
|
|
13
13
|
): T;
|
|
14
14
|
|
|
15
|
-
function useControl<T extends IControl>(
|
|
15
|
+
export function useControl<T extends IControl>(
|
|
16
16
|
onCreate: (context: MapContextValue) => T,
|
|
17
17
|
onRemove: (context: MapContextValue) => void,
|
|
18
|
-
opts?: ControlOptions
|
|
18
|
+
opts?: ControlOptions,
|
|
19
19
|
): T;
|
|
20
20
|
|
|
21
|
-
function useControl<T extends IControl>(
|
|
21
|
+
export function useControl<T extends IControl>(
|
|
22
22
|
onCreate: (context: MapContextValue) => T,
|
|
23
23
|
onAdd: (context: MapContextValue) => void,
|
|
24
24
|
onRemove: (context: MapContextValue) => void,
|
|
25
|
-
opts?: ControlOptions
|
|
25
|
+
opts?: ControlOptions,
|
|
26
26
|
): T;
|
|
27
27
|
|
|
28
|
-
function useControl<T extends IControl>(
|
|
28
|
+
export function useControl<T extends IControl>(
|
|
29
29
|
onCreate: (context: MapContextValue) => T,
|
|
30
30
|
arg1?: ((context: MapContextValue) => void) | ControlOptions,
|
|
31
31
|
arg2?: ((context: MapContextValue) => void) | ControlOptions,
|
|
32
|
-
arg3?: ControlOptions
|
|
32
|
+
arg3?: ControlOptions,
|
|
33
33
|
): T {
|
|
34
34
|
const context = useContext(MapContext);
|
|
35
35
|
const ctrl = useMemo(() => onCreate(context), []);
|
|
36
36
|
|
|
37
37
|
useEffect(() => {
|
|
38
38
|
const opts = (arg3 || arg2 || arg1) as ControlOptions;
|
|
39
|
-
const onAdd =
|
|
40
|
-
|
|
39
|
+
const onAdd =
|
|
40
|
+
typeof arg1 === "function" && typeof arg2 === "function" ? arg1 : null;
|
|
41
|
+
const onRemove =
|
|
42
|
+
typeof arg2 === "function"
|
|
43
|
+
? arg2
|
|
44
|
+
: typeof arg1 === "function"
|
|
45
|
+
? arg1
|
|
46
|
+
: null;
|
|
41
47
|
|
|
42
|
-
const {map} = context;
|
|
48
|
+
const { map } = context;
|
|
43
49
|
if (!map.hasControl(ctrl)) {
|
|
44
50
|
map.addControl(ctrl, opts?.position);
|
|
45
51
|
if (onAdd) {
|
|
@@ -60,5 +66,3 @@ function useControl<T extends IControl>(
|
|
|
60
66
|
|
|
61
67
|
return ctrl;
|
|
62
68
|
}
|
|
63
|
-
|
|
64
|
-
export default useControl;
|
|
@@ -1,37 +1,39 @@
|
|
|
1
|
-
import * as React from
|
|
2
|
-
import {useState, useCallback, useMemo, useContext} from
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { useState, useCallback, useMemo, useContext } from "react";
|
|
3
3
|
|
|
4
|
-
import {MapRef} from
|
|
5
|
-
import {MapContext} from
|
|
6
|
-
import {MapInstance} from '../types';
|
|
4
|
+
import { MapRef } from "../maplibre/create-ref";
|
|
5
|
+
import { MapContext } from "./map";
|
|
7
6
|
|
|
8
7
|
type MountedMapsContextValue = {
|
|
9
|
-
maps: {[id: string]: MapRef
|
|
10
|
-
onMapMount: (map: MapRef
|
|
8
|
+
maps: { [id: string]: MapRef };
|
|
9
|
+
onMapMount: (map: MapRef, id: string) => void;
|
|
11
10
|
onMapUnmount: (id: string) => void;
|
|
12
11
|
};
|
|
13
12
|
|
|
14
|
-
export const MountedMapsContext =
|
|
13
|
+
export const MountedMapsContext =
|
|
14
|
+
React.createContext<MountedMapsContextValue>(null);
|
|
15
15
|
|
|
16
|
-
export const MapProvider: React.FC<{children?: React.ReactNode}> =
|
|
17
|
-
|
|
16
|
+
export const MapProvider: React.FC<{ children?: React.ReactNode }> = (
|
|
17
|
+
props,
|
|
18
|
+
) => {
|
|
19
|
+
const [maps, setMaps] = useState<{ [id: string]: MapRef }>({});
|
|
18
20
|
|
|
19
|
-
const onMapMount = useCallback((map: MapRef
|
|
20
|
-
setMaps(currMaps => {
|
|
21
|
-
if (id ===
|
|
21
|
+
const onMapMount = useCallback((map: MapRef, id: string = "default") => {
|
|
22
|
+
setMaps((currMaps) => {
|
|
23
|
+
if (id === "current") {
|
|
22
24
|
throw new Error("'current' cannot be used as map id");
|
|
23
25
|
}
|
|
24
26
|
if (currMaps[id]) {
|
|
25
27
|
throw new Error(`Multiple maps with the same id: ${id}`);
|
|
26
28
|
}
|
|
27
|
-
return {...currMaps, [id]: map};
|
|
29
|
+
return { ...currMaps, [id]: map };
|
|
28
30
|
});
|
|
29
31
|
}, []);
|
|
30
32
|
|
|
31
|
-
const onMapUnmount = useCallback((id: string =
|
|
32
|
-
setMaps(currMaps => {
|
|
33
|
+
const onMapUnmount = useCallback((id: string = "default") => {
|
|
34
|
+
setMaps((currMaps) => {
|
|
33
35
|
if (currMaps[id]) {
|
|
34
|
-
const nextMaps = {...currMaps};
|
|
36
|
+
const nextMaps = { ...currMaps };
|
|
35
37
|
delete nextMaps[id];
|
|
36
38
|
return nextMaps;
|
|
37
39
|
}
|
|
@@ -44,7 +46,7 @@ export const MapProvider: React.FC<{children?: React.ReactNode}> = props => {
|
|
|
44
46
|
value={{
|
|
45
47
|
maps,
|
|
46
48
|
onMapMount,
|
|
47
|
-
onMapUnmount
|
|
49
|
+
onMapUnmount,
|
|
48
50
|
}}
|
|
49
51
|
>
|
|
50
52
|
{props.children}
|
|
@@ -52,18 +54,18 @@ export const MapProvider: React.FC<{children?: React.ReactNode}> = props => {
|
|
|
52
54
|
);
|
|
53
55
|
};
|
|
54
56
|
|
|
55
|
-
export type MapCollection
|
|
56
|
-
[id: string]: MapRef
|
|
57
|
-
current?: MapRef
|
|
57
|
+
export type MapCollection = {
|
|
58
|
+
[id: string]: MapRef | undefined;
|
|
59
|
+
current?: MapRef;
|
|
58
60
|
};
|
|
59
61
|
|
|
60
|
-
export function useMap
|
|
62
|
+
export function useMap(): MapCollection {
|
|
61
63
|
const maps = useContext(MountedMapsContext)?.maps;
|
|
62
64
|
const currentMap = useContext(MapContext);
|
|
63
65
|
|
|
64
66
|
const mapsWithCurrent = useMemo(() => {
|
|
65
|
-
return {...maps, current: currentMap?.map};
|
|
67
|
+
return { ...maps, current: currentMap?.map };
|
|
66
68
|
}, [maps, currentMap]);
|
|
67
69
|
|
|
68
|
-
return mapsWithCurrent as MapCollection
|
|
70
|
+
return mapsWithCurrent as MapCollection;
|
|
69
71
|
}
|