react-bkoi-gl 1.0.7 → 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.
Files changed (167) hide show
  1. package/README.md +163 -18
  2. package/dist/components/attribution-control.d.ts +4 -6
  3. package/dist/components/attribution-control.js +6 -5
  4. package/dist/components/attribution-control.js.map +1 -1
  5. package/dist/components/fullscreen-control.d.ts +4 -6
  6. package/dist/components/fullscreen-control.js +4 -4
  7. package/dist/components/fullscreen-control.js.map +1 -1
  8. package/dist/components/geolocate-control.d.ts +10 -26
  9. package/dist/components/geolocate-control.js +11 -11
  10. package/dist/components/geolocate-control.js.map +1 -1
  11. package/dist/components/layer.d.ts +7 -6
  12. package/dist/components/layer.js +8 -9
  13. package/dist/components/layer.js.map +1 -1
  14. package/dist/components/logo-control.d.ts +9 -0
  15. package/dist/components/logo-control.js +28 -0
  16. package/dist/components/logo-control.js.map +1 -0
  17. package/dist/components/map.d.ts +20 -16
  18. package/dist/components/map.js +38 -32
  19. package/dist/components/map.js.map +1 -1
  20. package/dist/components/marker.d.ts +10 -33
  21. package/dist/components/marker.js +22 -15
  22. package/dist/components/marker.js.map +1 -1
  23. package/dist/components/navigation-control.d.ts +4 -6
  24. package/dist/components/navigation-control.js +4 -4
  25. package/dist/components/navigation-control.js.map +1 -1
  26. package/dist/components/popup.d.ts +7 -25
  27. package/dist/components/popup.js +17 -28
  28. package/dist/components/popup.js.map +1 -1
  29. package/dist/components/scale-control.d.ts +4 -6
  30. package/dist/components/scale-control.js +4 -4
  31. package/dist/components/scale-control.js.map +1 -1
  32. package/dist/components/source.d.ts +3 -4
  33. package/dist/components/source.js +20 -22
  34. package/dist/components/source.js.map +1 -1
  35. package/dist/components/terrain-control.d.ts +10 -0
  36. package/dist/components/terrain-control.js +19 -0
  37. package/dist/components/terrain-control.js.map +1 -0
  38. package/dist/components/use-control.d.ts +6 -6
  39. package/dist/components/use-control.js +4 -5
  40. package/dist/components/use-control.js.map +1 -1
  41. package/dist/components/use-map.d.ts +8 -9
  42. package/dist/components/use-map.js +5 -5
  43. package/dist/components/use-map.js.map +1 -1
  44. package/dist/exports-maplibre-gl.d.ts +33 -0
  45. package/dist/exports-maplibre-gl.js +21 -0
  46. package/dist/exports-maplibre-gl.js.map +1 -0
  47. package/dist/index.cjs +590 -681
  48. package/dist/index.d.ts +2 -2
  49. package/dist/index.js +2 -2
  50. package/dist/index.js.map +1 -1
  51. package/dist/{mapbox → maplibre}/create-ref.d.ts +6 -6
  52. package/dist/maplibre/create-ref.js +30 -0
  53. package/dist/maplibre/create-ref.js.map +1 -0
  54. package/dist/maplibre/maplibre.d.ts +81 -0
  55. package/dist/maplibre/maplibre.js +387 -0
  56. package/dist/maplibre/maplibre.js.map +1 -0
  57. package/dist/styles/index.d.ts +4 -0
  58. package/dist/styles/react-bkoi-gl.css +1 -1
  59. package/dist/styles.d.js +2 -0
  60. package/dist/styles.d.js.map +1 -0
  61. package/dist/tsconfig.build.tsbuildinfo +1 -0
  62. package/dist/types/common.d.ts +2 -60
  63. package/dist/types/common.js.map +1 -1
  64. package/dist/types/events.d.ts +64 -23
  65. package/dist/types/events.js.map +1 -1
  66. package/dist/types/internal.d.ts +14 -0
  67. package/dist/types/internal.js +2 -0
  68. package/dist/types/internal.js.map +1 -0
  69. package/dist/types/lib.d.ts +16 -200
  70. package/dist/types/lib.js.map +1 -1
  71. package/dist/types/style-spec.d.ts +1 -0
  72. package/dist/types/style-spec.js +2 -0
  73. package/dist/types/style-spec.js.map +1 -0
  74. package/dist/utils/apply-react-style.d.ts +1 -1
  75. package/dist/utils/apply-react-style.js.map +1 -1
  76. package/dist/utils/compare-class-names.d.ts +2 -0
  77. package/dist/utils/compare-class-names.js +23 -0
  78. package/dist/utils/compare-class-names.js.map +1 -0
  79. package/dist/utils/deep-equal.d.ts +1 -1
  80. package/dist/utils/deep-equal.js +1 -1
  81. package/dist/utils/deep-equal.js.map +1 -1
  82. package/dist/utils/set-globals.d.ts +6 -8
  83. package/dist/utils/set-globals.js +22 -10
  84. package/dist/utils/set-globals.js.map +1 -1
  85. package/dist/utils/style-utils.d.ts +3 -2
  86. package/dist/utils/style-utils.js +4 -4
  87. package/dist/utils/style-utils.js.map +1 -1
  88. package/dist/utils/transform.d.ts +11 -19
  89. package/dist/utils/transform.js +13 -36
  90. package/dist/utils/transform.js.map +1 -1
  91. package/dist/utils/use-isomorphic-layout-effect.d.ts +1 -1
  92. package/dist/utils/use-isomorphic-layout-effect.js +2 -2
  93. package/dist/utils/use-isomorphic-layout-effect.js.map +1 -1
  94. package/package.json +42 -26
  95. package/src/components/attribution-control.ts +40 -16
  96. package/src/components/fullscreen-control.ts +40 -0
  97. package/src/components/geolocate-control.ts +45 -39
  98. package/src/components/layer.ts +37 -29
  99. package/src/components/logo-control.ts +44 -0
  100. package/src/components/map.tsx +86 -75
  101. package/src/components/marker.ts +141 -123
  102. package/src/components/navigation-control.ts +11 -12
  103. package/src/components/popup.ts +94 -97
  104. package/src/components/scale-control.ts +12 -14
  105. package/src/components/source.ts +58 -57
  106. package/src/components/terrain-control.ts +29 -0
  107. package/src/components/use-control.ts +21 -17
  108. package/src/components/use-map.tsx +26 -24
  109. package/src/exports-maplibre-gl.ts +37 -0
  110. package/src/index.ts +3 -2
  111. package/src/maplibre/create-ref.ts +70 -0
  112. package/src/maplibre/maplibre.ts +624 -0
  113. package/src/styles.d.ts +4 -0
  114. package/src/types/common.ts +12 -72
  115. package/src/types/events.ts +102 -42
  116. package/src/types/internal.ts +26 -0
  117. package/src/types/lib.ts +65 -260
  118. package/src/types/style-spec.ts +34 -0
  119. package/src/utils/apply-react-style.ts +7 -3
  120. package/src/utils/compare-class-names.ts +29 -0
  121. package/src/utils/deep-equal.ts +2 -2
  122. package/src/utils/set-globals.ts +22 -28
  123. package/src/utils/style-utils.ts +18 -9
  124. package/src/utils/transform.ts +32 -60
  125. package/src/utils/use-isomorphic-layout-effect.ts +3 -2
  126. package/bkoi-gl/package.json +0 -6
  127. package/dist/exports-bkoi-gl.cjs +0 -1512
  128. package/dist/exports-bkoi-gl.d.ts +0 -89
  129. package/dist/exports-bkoi-gl.js +0 -36
  130. package/dist/exports-bkoi-gl.js.map +0 -1
  131. package/dist/exports-mapbox.d.ts +0 -139
  132. package/dist/exports-mapbox.js +0 -36
  133. package/dist/exports-mapbox.js.map +0 -1
  134. package/dist/mapbox/create-ref.js +0 -64
  135. package/dist/mapbox/create-ref.js.map +0 -1
  136. package/dist/mapbox/mapbox.d.ts +0 -81
  137. package/dist/mapbox/mapbox.js +0 -476
  138. package/dist/mapbox/mapbox.js.map +0 -1
  139. package/dist/types/events-bkoi-gl.d.ts +0 -49
  140. package/dist/types/events-bkoi-gl.js +0 -2
  141. package/dist/types/events-bkoi-gl.js.map +0 -1
  142. package/dist/types/events-mapbox.d.ts +0 -49
  143. package/dist/types/events-mapbox.js +0 -2
  144. package/dist/types/events-mapbox.js.map +0 -1
  145. package/dist/types/index.d.ts +0 -70
  146. package/dist/types/index.js +0 -5
  147. package/dist/types/index.js.map +0 -1
  148. package/dist/types/public.d.ts +0 -2
  149. package/dist/types/public.js +0 -2
  150. package/dist/types/public.js.map +0 -1
  151. package/dist/types/style-spec-bkoi-gl.d.ts +0 -9
  152. package/dist/types/style-spec-bkoi-gl.js +0 -2
  153. package/dist/types/style-spec-bkoi-gl.js.map +0 -1
  154. package/dist/types/style-spec-mapbox.d.ts +0 -7
  155. package/dist/types/style-spec-mapbox.js +0 -2
  156. package/dist/types/style-spec-mapbox.js.map +0 -1
  157. package/src/components/fullscreen-control.tsx +0 -37
  158. package/src/exports-bkoi-gl.ts +0 -156
  159. package/src/exports-mapbox.ts +0 -159
  160. package/src/mapbox/create-ref.ts +0 -118
  161. package/src/mapbox/mapbox.ts +0 -742
  162. package/src/types/events-bkoi-gl.ts +0 -78
  163. package/src/types/events-mapbox.ts +0 -76
  164. package/src/types/index.ts +0 -93
  165. package/src/types/public.ts +0 -9
  166. package/src/types/style-spec-bkoi-gl.ts +0 -81
  167. package/src/types/style-spec-mapbox.ts +0 -80
@@ -1,116 +1,113 @@
1
+ /* eslint-disable @typescript-eslint/no-floating-promises */
1
2
  /* global document */
2
- import * as React from 'react';
3
- import {createPortal} from 'react-dom';
4
- import {useImperativeHandle, useEffect, useMemo, useRef, useContext, forwardRef, memo} from 'react';
5
- import {applyReactStyle} from '../utils/apply-react-style';
6
-
7
- import type {PopupEvent, PopupInstance} from '../types';
8
-
9
- import {MapContext} from './map';
10
- import {deepEqual} from '../utils/deep-equal';
11
-
12
- export type PopupProps<OptionsT, PopupT extends PopupInstance> = OptionsT & {
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<PopupT>) => void;
28
- onClose?: (e: PopupEvent<PopupT>) => void;
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
- function Popup<PopupOptions, PopupT extends PopupInstance>(
39
- props: PopupProps<PopupOptions, PopupT>,
40
- ref: React.Ref<PopupT>
41
- ) {
42
- const {map, mapLib} = useContext(MapContext);
43
- const container = useMemo(() => {
44
- return document.createElement('div');
45
- }, []);
46
- const thisRef = useRef({props});
47
- thisRef.current.props = props;
48
-
49
- const popup: PopupT = useMemo(() => {
50
- const options = {...props};
51
- const pp = new mapLib.Popup(options) as PopupT;
52
- pp.setLngLat([props.longitude, props.latitude]);
53
- pp.once('open', e => {
54
- thisRef.current.props.onOpen?.(e as PopupEvent<PopupT>);
55
- });
56
- return pp;
57
- }, []);
58
-
59
- useEffect(() => {
60
- const onClose = e => {
61
- thisRef.current.props.onClose?.(e as PopupEvent<PopupT>);
62
- };
63
- popup.on('close', onClose);
64
- popup.setDOMContent(container).addTo(map.getMap());
65
-
66
- return () => {
67
- // https://github.com/visgl/react-map-gl/issues/1825
68
- // onClose should not be fired if the popup is removed by unmounting
69
- // When using React strict mode, the component is mounted twice.
70
- // Firing the onClose callback here would be a false signal to remove the component.
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
- for (const c of nextClassList) {
105
- if (!prevClassList.has(c)) {
106
- popup.addClassName(c);
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
- popup.options.className = props.className;
108
+ thisRef.current.props = props;
110
109
  }
111
- }
112
-
113
- return createPortal(props.children, container);
114
- }
115
110
 
116
- export default memo(forwardRef(Popup));
111
+ return createPortal(props.children, container);
112
+ }),
113
+ );
@@ -1,11 +1,11 @@
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';
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, ScaleControlInstance} from '../types';
6
+ import type { ControlPosition, ScaleControlOptions } from "../types/lib";
7
7
 
8
- export type ScaleControlProps<OptionsT> = OptionsT & {
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 ScaleControl<ScaleControlOptions, ControlT extends ScaleControlInstance>(
20
- props: ScaleControlProps<ScaleControlOptions>
21
- ): null {
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<ScaleControlOptions>>(props);
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 default memo(ScaleControl);
44
+ export const ScaleControl: React.FC<ScaleControlProps> = memo(_ScaleControl);
@@ -1,35 +1,35 @@
1
- import * as React from 'react';
2
- import {useContext, useEffect, useMemo, useState, useRef} from 'react';
3
- import {cloneElement} from 'react';
4
- import {MapContext} from './map';
5
- import assert from '../utils/assert';
6
- import {deepEqual} from '../utils/deep-equal';
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
- ImageSourceImplemtation,
14
- AnySourceImplementation
15
- } from '../types';
16
- import type {GeoJSONSourceRaw, ImageSourceRaw, VectorSourceRaw} from '../types/style-spec-bkoi-gl';
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<SourceT> = (SourceT | CustomSource) & {
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<SourceT extends ISource>(
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<SourceT extends ISource>(
43
+ function updateSource(
44
44
  source: AnySourceImplementation,
45
- props: SourceProps<SourceT>,
46
- prevProps: SourceProps<SourceT>
45
+ props: SourceProps,
46
+ prevProps: SourceProps,
47
47
  ) {
48
- assert(props.id === prevProps.id, 'source id changed');
49
- assert(props.type === prevProps.type, 'source type changed');
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 (key !== 'children' && key !== 'id' && !deepEqual(prevProps[key], props[key])) {
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 === 'geojson') {
68
- (source as GeoJSONSourceImplementation).setData(
69
- (props as unknown as GeoJSONSourceRaw).data as any
70
- );
71
- } else if (type === 'image') {
72
- (source as ImageSourceImplemtation).updateImage({
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 if ('setCoordinates' in source && changedKeyCount === 1 && changedKey === 'coordinates') {
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 'url':
84
- source.setUrl((props as VectorSourceRaw).url);
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 'tiles':
87
- source.setTiles((props as VectorSourceRaw).tiles);
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<SourceT extends ISource>(props: SourceProps<SourceT>) {
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 = () => setTimeout(() => setStyleLoaded(version => version + 1), 0);
109
- map.on('styledata', forceUpdate);
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('styledata', forceUpdate);
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 'react';
2
- import type {IControl, ControlPosition} from '../types';
3
- import {MapContext} from './map';
4
- import type {MapContextValue} from './map';
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 = typeof arg1 === 'function' && typeof arg2 === 'function' ? arg1 : null;
40
- const onRemove = typeof arg2 === 'function' ? arg2 : typeof arg1 === 'function' ? arg1 : null;
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 'react';
2
- import {useState, useCallback, useMemo, useContext} from 'react';
1
+ import * as React from "react";
2
+ import { useState, useCallback, useMemo, useContext } from "react";
3
3
 
4
- import {MapRef} from '../mapbox/create-ref';
5
- import {MapContext} from './map';
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<MapInstance>};
10
- onMapMount: (map: MapRef<MapInstance>, id: string) => void;
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 = React.createContext<MountedMapsContextValue>(null);
13
+ export const MountedMapsContext =
14
+ React.createContext<MountedMapsContextValue>(null);
15
15
 
16
- export const MapProvider: React.FC<{children?: React.ReactNode}> = props => {
17
- const [maps, setMaps] = useState<{[id: string]: MapRef<MapInstance>}>({});
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<MapInstance>, id: string = 'default') => {
20
- setMaps(currMaps => {
21
- if (id === 'current') {
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 = 'default') => {
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<MapT extends MapInstance> = {
56
- [id: string]: MapRef<MapT> | undefined;
57
- current?: MapRef<MapT>;
57
+ export type MapCollection = {
58
+ [id: string]: MapRef | undefined;
59
+ current?: MapRef;
58
60
  };
59
61
 
60
- export function useMap<MapT extends MapInstance>(): MapCollection<MapT> {
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<MapT>;
70
+ return mapsWithCurrent as MapCollection;
69
71
  }