solid-map-gl 1.8.0 → 1.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
- import { createEffect, onCleanup } from 'solid-js';
2
- import { useMap } from '../MapProvider';
1
+ import { createEffect, onCleanup, createSignal } from 'solid-js';
2
+ import { useMapContext } from '../MapProvider';
3
3
  // linearly interpolate between two positions [x,y,z] based on time
4
4
  const lerp = (a, b, t) => a.map((_, idx) => (1.0 - t) * a[idx] + t * b[idx]);
5
5
  // sphericaly interpolate between two positions [x,y,z] based on time
@@ -15,17 +15,19 @@ const easeQuad = {
15
15
  out: (x) => 1 - (1 - x) * (1 - x),
16
16
  inOut: (x) => x < 0.5 ? 2 * x * x : 1 - Math.pow(-2 * x + 2, 2) / 2,
17
17
  };
18
- export const Camera = props => {
19
- const [map, userInteraction] = useMap();
20
- if (!map())
21
- return null;
18
+ export const Camera = (props) => {
19
+ const [ctx] = useMapContext();
22
20
  let animationTime = 0.1;
23
21
  let isReverse = false;
22
+ // Handle User Interaction
23
+ const [userInteraction, setUserInteraction] = createSignal(false);
24
+ ['mousedown', 'touchstart', 'wheel'].forEach((event) => ctx.map.on(event, (evt) => !evt.rotate && setUserInteraction(true)));
25
+ ['moveend', 'mouseup', 'touchend'].forEach((event) => ctx.map.on(event, (evt) => !evt.rotate && setUserInteraction(false)));
24
26
  const updateCameraPosition = async ([lng, lat, alt], target) => {
25
- const camera = map().getFreeCameraOptions();
26
- camera.position = map().mapLib.MercatorCoordinate.fromLngLat([lng, lat], alt);
27
+ const camera = ctx.map.getFreeCameraOptions();
28
+ camera.position = ctx.map.mapLib.MercatorCoordinate.fromLngLat([lng, lat], alt);
27
29
  camera.lookAtPoint(target);
28
- map().setFreeCameraOptions(camera);
30
+ ctx.map.setFreeCameraOptions(camera);
29
31
  };
30
32
  const frame = () => {
31
33
  props.translate && window.requestAnimationFrame(frame);
@@ -45,49 +47,49 @@ export const Camera = props => {
45
47
  createEffect(() => {
46
48
  props.translate && window.requestAnimationFrame(frame);
47
49
  });
48
- const options = { duration: 1000, easing: n => n };
50
+ const options = { duration: 1000, easing: (n) => n };
49
51
  const rotateGlobe = () => {
50
- if (userInteraction)
52
+ if (userInteraction())
51
53
  return;
52
54
  const { secPerRev = 120, maxSpinZoom = 5, slowSpinZoom = 3, } = props.rotateGlobe;
53
- const zoom = map().getZoom();
55
+ const zoom = ctx.map.getZoom();
54
56
  if (zoom > maxSpinZoom)
55
57
  return;
56
58
  let distancePerSecond = 360 / secPerRev;
57
59
  if (zoom > slowSpinZoom)
58
60
  distancePerSecond *= (maxSpinZoom - zoom) / (maxSpinZoom - slowSpinZoom);
59
- const center = map().getCenter();
61
+ const center = ctx.map.getCenter();
60
62
  center.lng = props.reverse
61
63
  ? center.lng + distancePerSecond
62
64
  : center.lng - distancePerSecond;
63
- map().easeTo({ center, ...options }, { rotate: true });
65
+ ctx.map.easeTo({ center, ...options }, { rotate: true });
64
66
  };
65
67
  const rotateViewport = () => {
66
- if (!props.rotateViewport || userInteraction)
68
+ if (!props.rotateViewport || userInteraction())
67
69
  return;
68
70
  const rotateViewport = props.rotateViewport;
69
71
  const secPerRev = rotateViewport?.secPerRev || 60;
70
72
  const bearing = props.reverse
71
- ? map().getBearing() + 360 / secPerRev
72
- : map().getBearing() - 360 / secPerRev;
73
+ ? ctx.map.getBearing() + 360 / secPerRev
74
+ : ctx.map.getBearing() - 360 / secPerRev;
73
75
  const pitch = rotateViewport?.pitch || 60;
74
76
  const around = rotateViewport?.around;
75
- map().easeTo({ bearing, pitch, around, ...options }, { rotate: true });
77
+ ctx.map.easeTo({ bearing, pitch, around, ...options }, { rotate: true });
76
78
  };
77
79
  const onEnd = () => (props.rotateGlobe ? rotateGlobe() : rotateViewport());
78
- map().on('moveend', onEnd).on('dragend', onEnd);
80
+ ctx.map.on('moveend', onEnd).on('dragend', onEnd);
79
81
  let originalCenter;
80
82
  createEffect(() => {
81
83
  if (props.rotateGlobe == undefined)
82
84
  return;
83
85
  if (props.rotateGlobe) {
84
- originalCenter = map().getCenter();
86
+ originalCenter = ctx.map.getCenter();
85
87
  rotateGlobe();
86
88
  }
87
89
  else {
88
90
  props.resetWhenStopped
89
- ? map().stop().easeTo({ center: originalCenter })
90
- : map().stop();
91
+ ? ctx.map.stop().easeTo({ center: originalCenter })
92
+ : ctx.map.stop();
91
93
  }
92
94
  });
93
95
  createEffect(() => {
@@ -96,9 +98,9 @@ export const Camera = props => {
96
98
  props.rotateViewport
97
99
  ? rotateViewport()
98
100
  : props.resetWhenStopped
99
- ? map().stop().resetNorthPitch()
100
- : map().stop();
101
+ ? ctx.map.stop().resetNorthPitch()
102
+ : ctx.map.stop();
101
103
  });
102
- onCleanup(() => map().off('moveend', onEnd).off('dragend', onEnd));
104
+ onCleanup(() => ctx.map.off('moveend', onEnd).off('dragend', onEnd));
103
105
  return props.children;
104
106
  };
@@ -1,34 +1,22 @@
1
- import { createEffect, onCleanup } from 'solid-js';
2
- import { useMap } from '../MapProvider';
3
- const getControl = (lib, type, options, custom) => {
4
- if (custom)
5
- return new custom(options);
6
- switch (type) {
7
- case 'navigation':
8
- return new lib.NavigationControl(options);
9
- case 'scale':
10
- return new lib.ScaleControl(options);
11
- case 'attribution':
12
- return new lib.AttributionControl(options);
13
- case 'geolocate':
14
- return new lib.GeolocateControl(options);
15
- case 'fullscreen':
16
- return new lib.FullscreenControl();
17
- // options || { container: map().container }
18
- default:
19
- throw new Error(`Unknown control type: ${type}`);
20
- }
21
- };
1
+ import { createEffect } from 'solid-js';
2
+ import { useMapContext } from '../MapProvider';
22
3
  export const Control = props => {
23
- const [map] = useMap();
24
- let control = null;
4
+ const [ctx] = useMapContext();
5
+ const controlClasses = new Map([
6
+ ['navigation', ctx.map.mapLib.NavigationControl],
7
+ ['scale', ctx.map.mapLib.ScaleControl],
8
+ ['attribution', ctx.map.mapLib.AttributionControl],
9
+ ['geolocate', ctx.map.mapLib.GeolocateControl],
10
+ ['fullscreen', ctx.map.mapLib.FullscreenControl],
11
+ ]);
12
+ const ControlClass = props.custom || controlClasses.get(props.type || 'navigation');
13
+ if (!ControlClass)
14
+ throw new Error(`Unknown control type: ${props.type}`);
25
15
  // Add or Update Control
26
16
  createEffect(() => {
27
- control && map().hasControl(control) && map().removeControl(control);
28
- control = getControl(map().mapLib, props.type, props.options, props.custom);
29
- map().addControl(control, props.position);
17
+ const control = new ControlClass(props.options);
18
+ control && ctx.map.hasControl(control) && ctx.map.removeControl(control);
19
+ ctx.map.addControl(control, props.position);
30
20
  });
31
- // Remove Control
32
- onCleanup(() => map()?.removeControl(control));
33
21
  return null;
34
22
  };
@@ -1,11 +1,11 @@
1
1
  import { onCleanup } from 'solid-js';
2
- import { useMap } from '../MapProvider';
2
+ import { useMapContext } from '../MapProvider';
3
3
  import { drawEvents } from '../../events';
4
4
  export const Draw = (props) => {
5
- const [map] = useMap();
5
+ const [ctx] = useMapContext();
6
6
  // Add Draw Control
7
7
  const draw = new props.lib(props.options);
8
- map().addControl(draw, props.position || 'top-right');
8
+ ctx.map.addControl(draw, props.position || 'top-right');
9
9
  props.getInstance && props.getInstance(draw);
10
10
  // Hook up events
11
11
  const eventList = {};
@@ -14,15 +14,15 @@ export const Draw = (props) => {
14
14
  const event = `draw.${item.slice(2).toLowerCase()}`;
15
15
  const fn = evt => props[item](evt);
16
16
  eventList[event] = fn;
17
- map().on(event, fn);
17
+ ctx.map.on(event, fn);
18
18
  }
19
19
  });
20
20
  // Remove Draw Control
21
21
  onCleanup(() => {
22
22
  // Remove Events
23
- Object.keys(eventList).forEach(event => map().off(event, eventList[event]));
23
+ Object.keys(eventList).forEach(event => ctx.map.off(event, eventList[event]));
24
24
  // Remove Control
25
- map()?.removeControl(draw);
25
+ ctx.map?.removeControl(draw);
26
26
  });
27
27
  return null;
28
28
  };
@@ -1,5 +1,5 @@
1
1
  import { onCleanup, createSignal, createEffect, untrack, } from 'solid-js';
2
- import { useMap } from '../MapProvider';
2
+ import { useMapContext } from '../MapProvider';
3
3
  const PATTERN = {
4
4
  diagonal_l: { size: 20, path: 'M20 0 0 20M-10 10 10-10M10 30 30 10' },
5
5
  diagonal_r: { size: 20, path: 'M0 0 20 20M30 10 10-10M10 30-10 10' },
@@ -19,15 +19,15 @@ const PATTERN = {
19
19
  };
20
20
  export const patternList = Object.keys(PATTERN);
21
21
  export const MGL_Image = props => {
22
- const [map] = useMap();
22
+ const [ctx] = useMapContext();
23
23
  const [size, setSize] = createSignal({ width: 0, height: 0 });
24
24
  const debug = (text, value) => {
25
- map().debug &&
25
+ ctx.map.debug &&
26
26
  console.debug('%c[MapGL]', 'color: #10b981', text, value || '');
27
27
  };
28
28
  // Remove Image
29
29
  onCleanup(() => {
30
- map()?.hasImage(props.id) && map()?.removeImage(props.id);
30
+ ctx.map?.hasImage(props.id) && ctx.map?.removeImage(props.id);
31
31
  debug('Remove Image:', props.id);
32
32
  });
33
33
  // Add or Update Image
@@ -41,23 +41,23 @@ export const MGL_Image = props => {
41
41
  : props.options;
42
42
  _loadImage(props.source || _createPattern(props.pattern), data => {
43
43
  const { width, height } = data;
44
- if (map() && !map().hasImage(props.id))
45
- map().addImage(props.id, data, ops);
44
+ if (ctx.map && !ctx.map.hasImage(props.id))
45
+ ctx.map.addImage(props.id, data, ops);
46
46
  if (!props.pattern &&
47
47
  untrack(() => width === size().width && height === size().height)) {
48
- map().updateImage(props.id, data);
49
- map().triggerRepaint();
48
+ ctx.map.updateImage(props.id, data);
49
+ ctx.map.triggerRepaint();
50
50
  }
51
51
  else {
52
- map().removeImage(props.id);
53
- map().addImage(props.id, data, ops);
52
+ ctx.map.removeImage(props.id);
53
+ ctx.map.addImage(props.id, data, ops);
54
54
  }
55
55
  setSize({ width, height });
56
56
  debug('Add Image:', props.id);
57
- map().on('style.load', () => {
58
- if (map().hasImage(props.id))
57
+ ctx.map.on('style.load', () => {
58
+ if (ctx.map.hasImage(props.id))
59
59
  return;
60
- map().addImage(props.id, data, ops);
60
+ ctx.map.addImage(props.id, data, ops);
61
61
  debug('Re-Add Image:', props.id);
62
62
  });
63
63
  });
@@ -76,7 +76,7 @@ export const MGL_Image = props => {
76
76
  }
77
77
  if (typeof image !== 'string')
78
78
  return callback(image);
79
- map().loadImage(image, async (error, imageData) => {
79
+ ctx.map.loadImage(image, async (error, imageData) => {
80
80
  if (error) {
81
81
  if (typeof image == 'string' && image?.trimEnd().endsWith('.svg')) {
82
82
  image = await (await fetch(image)).text();
@@ -1,5 +1,5 @@
1
1
  import { onCleanup, createEffect, createUniqueId } from 'solid-js';
2
- import { useMap } from '../MapProvider';
2
+ import { useMapContext } from '../MapProvider';
3
3
  import { useSourceId } from '../Source';
4
4
  import { layerEvents } from '../../events';
5
5
  const diff = (newProps = {}, prevProps = {}) => {
@@ -13,15 +13,15 @@ const diff = (newProps = {}, prevProps = {}) => {
13
13
  }, []);
14
14
  };
15
15
  export const Layer = props => {
16
- const [map] = useMap();
16
+ const [ctx] = useMapContext();
17
17
  const sourceId = props.style?.source || useSourceId();
18
18
  props.id ??= createUniqueId();
19
19
  const debug = (text, value) => {
20
- map().debug &&
20
+ ctx.map.debug &&
21
21
  console.debug('%c[MapGL]', 'color: #10b981', text, value || '');
22
22
  };
23
23
  // Add Layer
24
- map().addLayer(props.customLayer || {
24
+ ctx.map.addLayer(props.customLayer || {
25
25
  ...props.style,
26
26
  id: props.id,
27
27
  source: sourceId,
@@ -29,17 +29,17 @@ export const Layer = props => {
29
29
  smg: { beforeType: props.beforeType, beforeId: props.beforeId },
30
30
  },
31
31
  }, props.beforeType
32
- ? map()
32
+ ? ctx.map
33
33
  .getStyle()
34
34
  .layers.find(l => l.type === props.beforeType)?.id
35
35
  : props.beforeId);
36
- map().layerIdList.push(props.id);
36
+ ctx.map.layerIdList.push(props.id);
37
37
  debug('Add Layer:', props.id);
38
38
  // Hook up events
39
39
  layerEvents.forEach(item => {
40
40
  if (props[item]) {
41
41
  const event = item.slice(2).toLowerCase();
42
- map().on(event, props.id, evt => {
42
+ ctx.map.on(event, props.id, evt => {
43
43
  props[item](evt);
44
44
  debug(`Layer '${event}' event on '${props.id}':`, evt);
45
45
  });
@@ -51,13 +51,13 @@ export const Layer = props => {
51
51
  if (style === prev)
52
52
  return;
53
53
  if (style.layout !== prev?.layout)
54
- diff(style.layout, prev?.layout).forEach(([key, value]) => map().setLayoutProperty(props.id, key, value, { validate: false }));
54
+ diff(style.layout, prev?.layout).forEach(([key, value]) => ctx.map.setLayoutProperty(props.id, key, value, { validate: false }));
55
55
  if (style.paint !== prev?.paint)
56
- diff(style.paint, prev?.paint).forEach(([key, value]) => map().setPaintProperty(props.id, key, value, { validate: false }));
56
+ diff(style.paint, prev?.paint).forEach(([key, value]) => ctx.map.setPaintProperty(props.id, key, value, { validate: false }));
57
57
  if (style.minzoom !== prev?.minzoom || style.maxzoom !== prev?.maxzoom)
58
- map().setLayerZoomRange(props.id, style.minzoom, style.maxzoom);
58
+ ctx.map.setLayerZoomRange(props.id, style.minzoom, style.maxzoom);
59
59
  if (style.filter !== prev?.filter)
60
- map().setFilter(props.id, style.filter, { validate: false });
60
+ ctx.map.setFilter(props.id, style.filter, { validate: false });
61
61
  debug('Update Layer Style:', props.id);
62
62
  return style;
63
63
  }, props.style);
@@ -65,7 +65,7 @@ export const Layer = props => {
65
65
  createEffect((prev) => {
66
66
  if (props.visible === prev)
67
67
  return;
68
- map().setLayoutProperty(props.id, 'visibility', props.visible ? 'visible' : 'none', { validate: false });
68
+ ctx.map.setLayoutProperty(props.id, 'visibility', props.visible ? 'visible' : 'none', { validate: false });
69
69
  debug(`Update Visibility (${props.id}):`, props.visible);
70
70
  return props.visible;
71
71
  }, props.visible);
@@ -73,26 +73,26 @@ export const Layer = props => {
73
73
  createEffect(async () => {
74
74
  if (!props.filter)
75
75
  return;
76
- !map().isStyleLoaded() && (await map().once('styledata'));
77
- map().setFilter(props.id, props.filter);
76
+ !ctx.map.isStyleLoaded() && (await ctx.map.once('styledata'));
77
+ ctx.map.setFilter(props.id, props.filter);
78
78
  debug(`Update Filter (${props.id}):`, props.filter);
79
79
  });
80
80
  // Update Feature State
81
81
  createEffect(async () => {
82
- if (!props.featureState || !props.featureState.id)
82
+ if (!props.featureState || props.featureState.id === null)
83
83
  return;
84
- !map().isStyleLoaded() && (await map().once('styledata'));
85
- map().removeFeatureState({
84
+ !ctx.map.isStyleLoaded() && (await ctx.map.once('styledata'));
85
+ ctx.map.removeFeatureState({
86
86
  source: sourceId,
87
87
  sourceLayer: props.style['source-layer'],
88
88
  });
89
- map().setFeatureState({
89
+ ctx.map.setFeatureState({
90
90
  source: sourceId,
91
91
  sourceLayer: props.style['source-layer'],
92
92
  id: props.featureState.id,
93
93
  }, props.featureState.state);
94
94
  });
95
95
  //Remove Layer
96
- onCleanup(() => map()?.getLayer(props.id) && map()?.removeLayer(props.id));
96
+ onCleanup(() => ctx.map?.getLayer(props.id) && ctx.map?.removeLayer(props.id));
97
97
  return props.children;
98
98
  };
@@ -1,10 +1,10 @@
1
1
  import { onCleanup, createEffect } from 'solid-js';
2
- import { useMap } from '../MapProvider';
2
+ import { useMapContext } from '../MapProvider';
3
3
  export const Light = (props) => {
4
- const [map] = useMap();
4
+ const [ctx] = useMapContext();
5
5
  // Add or Update Light Layer
6
- createEffect(() => map().setLight(props.style || {}));
6
+ createEffect(() => ctx.map.setLight(props.style || {}));
7
7
  // Remove Light Layer
8
- onCleanup(() => map()?.setLight(null));
8
+ onCleanup(() => ctx.map?.setLight(null));
9
9
  return null;
10
10
  };
@@ -3,7 +3,7 @@ import { MapProvider } from '../MapProvider';
3
3
  import { mapEvents } from '../../events';
4
4
  import { vectorStyleList } from '../../mapStyles';
5
5
  /** Creates a new Map Container */
6
- export const MapGL = props => {
6
+ export const MapGL = (props) => {
7
7
  props.id ??= createUniqueId();
8
8
  let map;
9
9
  let mapRef;
@@ -14,10 +14,7 @@ export const MapGL = props => {
14
14
  window.matchMedia('(prefers-color-scheme: dark)').matches) ||
15
15
  (typeof document !== 'undefined' &&
16
16
  document.body.classList.contains('dark')));
17
- const [userInteraction, setUserInteraction] = createSignal(false);
18
17
  const [internal, setInternal] = createSignal(false);
19
- // debounce user interactions
20
- createEffect(() => props.onUserInteraction?.(userInteraction()));
21
18
  const debug = (text, value) => {
22
19
  props.debug &&
23
20
  console.debug('%c[MapGL]', 'color: #0ea5e9', text, value || '');
@@ -37,7 +34,7 @@ export const MapGL = props => {
37
34
  let mapLib = props.mapLib || (await import('mapbox-gl'));
38
35
  if (!mapLib.Map)
39
36
  mapLib = window['maplibregl'] || window['mapboxgl'];
40
- if (!mapLib.supported())
37
+ if (!mapLib.supported?.())
41
38
  throw new Error('Mapbox GL not supported');
42
39
  debug(`Map (v${mapLib.version}) loading...`);
43
40
  map = new mapLib.Map({
@@ -59,8 +56,8 @@ export const MapGL = props => {
59
56
  map.once('load', () => {
60
57
  setMapLoaded(map);
61
58
  debug('Map loaded');
62
- ['mousedown', 'touchstart', 'wheel'].forEach(event => map.on(event, evt => !evt.rotate && setUserInteraction(true)));
63
- ['moveend', 'mouseup', 'touchend'].forEach(event => map.on(event, evt => !evt.rotate && setUserInteraction(false)));
59
+ ['mousedown', 'touchstart', 'wheel'].forEach((event) => map.on(event, (evt) => !evt.rotate && props.onUserInteraction(true)));
60
+ ['moveend', 'mouseup', 'touchend'].forEach((event) => map.on(event, (evt) => !evt.rotate && props.onUserInteraction(false)));
64
61
  // Listen to dark theme changes
65
62
  const darkTheme = typeof window !== 'undefined' &&
66
63
  window?.matchMedia('(prefers-color-scheme: dark)');
@@ -83,21 +80,21 @@ export const MapGL = props => {
83
80
  // resizeObserver.observe(mapRef as Element)
84
81
  // }
85
82
  // Hook up events
86
- mapEvents.forEach(item => {
83
+ mapEvents.forEach((item) => {
87
84
  const prop = props[item];
88
85
  let isFirstMessage = true;
89
86
  if (prop) {
90
87
  const event = item.slice(2).toLowerCase();
91
88
  if (typeof prop === 'function') {
92
- map.on(event, e => {
89
+ map.on(event, (e) => {
93
90
  prop(e);
94
91
  isFirstMessage && debug(`Map '${event}' event:`, e);
95
92
  isFirstMessage = false;
96
93
  });
97
94
  }
98
95
  else {
99
- Object.keys(prop).forEach(layerId => {
100
- map.on(event, layerId, e => {
96
+ Object.keys(prop).forEach((layerId) => {
97
+ map.on(event, layerId, (e) => {
101
98
  prop[layerId](e);
102
99
  isFirstMessage &&
103
100
  debug(`Map '${event}' event on '${layerId}':`, e);
@@ -108,7 +105,7 @@ export const MapGL = props => {
108
105
  }
109
106
  });
110
107
  // Update Viewport
111
- map.on('move', event => {
108
+ map.on('move', (event) => {
112
109
  const viewport = {
113
110
  ...props.viewport,
114
111
  id: props.id,
@@ -124,7 +121,7 @@ export const MapGL = props => {
124
121
  setInternal(true);
125
122
  !event.viewport && props.onViewportChange?.(viewport);
126
123
  });
127
- map.on('moveend', event => {
124
+ map.on('moveend', (event) => {
128
125
  !event.rotate &&
129
126
  props.onViewportChange?.({ ...props.viewport, inTransit: false });
130
127
  setInternal(false);
@@ -132,7 +129,7 @@ export const MapGL = props => {
132
129
  });
133
130
  });
134
131
  // Hook up viewport event
135
- createEffect(on(() => props.viewport, vp => {
132
+ createEffect(on(() => props.viewport, (vp) => {
136
133
  if (props.id !== vp?.id || internal())
137
134
  return;
138
135
  const viewport = {
@@ -163,8 +160,8 @@ export const MapGL = props => {
163
160
  debug('Set Cursor to:', cur);
164
161
  });
165
162
  const insertLayers = (list, layers) => {
166
- layers.forEach(layer => {
167
- const index = list.findIndex(i => layer.metadata.smg.beforeType
163
+ layers.forEach((layer) => {
164
+ const index = list.findIndex((i) => layer.metadata.smg.beforeType
168
165
  ? i.type === layer.metadata.smg.beforeType
169
166
  : i.id === layer.metadata.smg.beforeId);
170
167
  list =
@@ -175,13 +172,13 @@ export const MapGL = props => {
175
172
  return list;
176
173
  };
177
174
  // Update map style
178
- createEffect(prev => {
175
+ createEffect((prev) => {
179
176
  const style = getStyle(props.options?.style, props.darkStyle);
180
177
  if (map?.isStyleLoaded() && prev !== style) {
181
178
  const oldStyle = map.getStyle();
182
- const oldLayers = oldStyle.layers.filter(l => map.layerIdList.includes(l.id));
179
+ const oldLayers = oldStyle.layers.filter((l) => map.layerIdList.includes(l.id));
183
180
  const oldSources = Object.keys(oldStyle.sources)
184
- .filter(s => map.sourceIdList.includes(s))
181
+ .filter((s) => map.sourceIdList.includes(s))
185
182
  .reduce((obj, key) => ({ ...obj, [key]: oldStyle.sources[key] }), {});
186
183
  map.setStyle(style);
187
184
  map.once('styledata', () => {
@@ -206,7 +203,7 @@ export const MapGL = props => {
206
203
  'showCollisionBoxes',
207
204
  'showPadding',
208
205
  'showOverdrawInspector',
209
- ].forEach(item => {
206
+ ].forEach((item) => {
210
207
  createEffect(() => {
211
208
  const prop = props[item];
212
209
  if (!map || !prop)
@@ -229,9 +226,6 @@ export const MapGL = props => {
229
226
  inset: 0,
230
227
  'z-index': -1,
231
228
  }}/>
232
- {mapLoaded() &&
233
- <MapProvider map={mapLoaded()}>
234
- {props.children}
235
- </MapProvider>}
229
+ {mapLoaded() && (<MapProvider map={mapLoaded()}>{props.children}</MapProvider>)}
236
230
  </>);
237
231
  };
@@ -1,12 +1,9 @@
1
- import { createContext, useContext, createSignal } from "solid-js";
2
- const [map, setMap] = createSignal(null);
3
- const [userInteraction, setUserInteraction] = createSignal(null);
4
- export const MapContext = createContext([map, userInteraction]);
5
- export const useMap = () => useContext(MapContext);
6
- export const MapProvider = props => {
7
- props.map && setMap(props.map);
8
- props.userInteraction && setUserInteraction(props.userInteraction);
9
- return (<MapContext.Provider value={[map, userInteraction]}>
10
- {props.children}
11
- </MapContext.Provider>);
1
+ import { createContext, useContext } from 'solid-js';
2
+ import { createStore } from 'solid-js/store';
3
+ const [state, setState] = createStore({ map: null });
4
+ export const MapContext = createContext([state]);
5
+ export const useMapContext = () => useContext(MapContext);
6
+ export const MapProvider = (props) => {
7
+ props.map && setState('map', props.map);
8
+ return (<MapContext.Provider value={[state]}>{props.children}</MapContext.Provider>);
12
9
  };
@@ -1,7 +1,7 @@
1
1
  import { onCleanup, createEffect, untrack } from 'solid-js';
2
- import { useMap } from '../MapProvider';
2
+ import { useMapContext } from '../MapProvider';
3
3
  export const Marker = (props) => {
4
- const [map] = useMap();
4
+ const [ctx] = useMapContext();
5
5
  let marker = null;
6
6
  let popup = null;
7
7
  if (!props.lngLat)
@@ -10,9 +10,9 @@ export const Marker = (props) => {
10
10
  createEffect(() => {
11
11
  const ops = { ...props.options };
12
12
  const pops = { ...props.options?.popup };
13
- if (!map())
13
+ if (!ctx.map)
14
14
  return;
15
- const mapboxgl = map().mapLib;
15
+ const mapboxgl = ctx.map.mapLib;
16
16
  untrack(() => {
17
17
  popup?.remove();
18
18
  popup = props.children
@@ -28,7 +28,7 @@ export const Marker = (props) => {
28
28
  .on('drag', () => props.onLngLatChange?.(marker.getLngLat().toArray()))
29
29
  .setDraggable(props.draggable || props.options?.draggable)
30
30
  .setLngLat(props.lngLat)
31
- .addTo(map());
31
+ .addTo(ctx.map);
32
32
  props.openPopup !== popup?.isOpen() && marker.togglePopup();
33
33
  });
34
34
  });
@@ -1,16 +1,16 @@
1
1
  import { onCleanup, createEffect, untrack } from 'solid-js';
2
- import { useMap } from '../MapProvider';
2
+ import { useMapContext } from '../MapProvider';
3
3
  export const Popup = (props) => {
4
- const [map] = useMap();
4
+ const [ctx] = useMapContext();
5
5
  let popup = null;
6
6
  if (!props.trackPointer && !props.lngLat)
7
7
  throw new Error('Popup - lngLat or trackPointer is required');
8
8
  // Add or Update Popup
9
9
  createEffect(() => {
10
10
  const ops = { ...props.options };
11
- if (!map())
11
+ if (!ctx.map)
12
12
  return;
13
- const mapboxgl = map().mapLib;
13
+ const mapboxgl = ctx.map.mapLib;
14
14
  untrack(() => {
15
15
  popup?.remove();
16
16
  popup = new mapboxgl.Popup(props.trackPointer
@@ -19,7 +19,7 @@ export const Popup = (props) => {
19
19
  .setHTML(props.children || '')
20
20
  .setLngLat(props.lngLat)
21
21
  .on('close', () => props.onClose?.())
22
- .addTo(map());
22
+ .addTo(ctx.map);
23
23
  });
24
24
  });
25
25
  // Update Position