solid-map-gl 1.8.0 → 1.8.1

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
1
  import { createEffect, onCleanup } from 'solid-js';
2
- import { useMap } from '../MapProvider';
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
@@ -16,16 +16,16 @@ const easeQuad = {
16
16
  inOut: (x) => x < 0.5 ? 2 * x * x : 1 - Math.pow(-2 * x + 2, 2) / 2,
17
17
  };
18
18
  export const Camera = props => {
19
- const [map, userInteraction] = useMap();
20
- if (!map())
19
+ const [ctx] = useMapContext();
20
+ if (!ctx.map)
21
21
  return null;
22
22
  let animationTime = 0.1;
23
23
  let isReverse = false;
24
24
  const updateCameraPosition = async ([lng, lat, alt], target) => {
25
- const camera = map().getFreeCameraOptions();
26
- camera.position = map().mapLib.MercatorCoordinate.fromLngLat([lng, lat], alt);
25
+ const camera = ctx.map.getFreeCameraOptions();
26
+ camera.position = ctx.map.mapLib.MercatorCoordinate.fromLngLat([lng, lat], alt);
27
27
  camera.lookAtPoint(target);
28
- map().setFreeCameraOptions(camera);
28
+ ctx.map.setFreeCameraOptions(camera);
29
29
  };
30
30
  const frame = () => {
31
31
  props.translate && window.requestAnimationFrame(frame);
@@ -47,47 +47,47 @@ export const Camera = props => {
47
47
  });
48
48
  const options = { duration: 1000, easing: n => n };
49
49
  const rotateGlobe = () => {
50
- if (userInteraction)
50
+ if (ctx.userInteraction)
51
51
  return;
52
52
  const { secPerRev = 120, maxSpinZoom = 5, slowSpinZoom = 3, } = props.rotateGlobe;
53
- const zoom = map().getZoom();
53
+ const zoom = ctx.map.getZoom();
54
54
  if (zoom > maxSpinZoom)
55
55
  return;
56
56
  let distancePerSecond = 360 / secPerRev;
57
57
  if (zoom > slowSpinZoom)
58
58
  distancePerSecond *= (maxSpinZoom - zoom) / (maxSpinZoom - slowSpinZoom);
59
- const center = map().getCenter();
59
+ const center = ctx.map.getCenter();
60
60
  center.lng = props.reverse
61
61
  ? center.lng + distancePerSecond
62
62
  : center.lng - distancePerSecond;
63
- map().easeTo({ center, ...options }, { rotate: true });
63
+ ctx.map.easeTo({ center, ...options }, { rotate: true });
64
64
  };
65
65
  const rotateViewport = () => {
66
- if (!props.rotateViewport || userInteraction)
66
+ if (!props.rotateViewport || ctx.userInteraction)
67
67
  return;
68
68
  const rotateViewport = props.rotateViewport;
69
69
  const secPerRev = rotateViewport?.secPerRev || 60;
70
70
  const bearing = props.reverse
71
- ? map().getBearing() + 360 / secPerRev
72
- : map().getBearing() - 360 / secPerRev;
71
+ ? ctx.map.getBearing() + 360 / secPerRev
72
+ : ctx.map.getBearing() - 360 / secPerRev;
73
73
  const pitch = rotateViewport?.pitch || 60;
74
74
  const around = rotateViewport?.around;
75
- map().easeTo({ bearing, pitch, around, ...options }, { rotate: true });
75
+ ctx.map.easeTo({ bearing, pitch, around, ...options }, { rotate: true });
76
76
  };
77
77
  const onEnd = () => (props.rotateGlobe ? rotateGlobe() : rotateViewport());
78
- map().on('moveend', onEnd).on('dragend', onEnd);
78
+ ctx.map.on('moveend', onEnd).on('dragend', onEnd);
79
79
  let originalCenter;
80
80
  createEffect(() => {
81
81
  if (props.rotateGlobe == undefined)
82
82
  return;
83
83
  if (props.rotateGlobe) {
84
- originalCenter = map().getCenter();
84
+ originalCenter = ctx.map.getCenter();
85
85
  rotateGlobe();
86
86
  }
87
87
  else {
88
88
  props.resetWhenStopped
89
- ? map().stop().easeTo({ center: originalCenter })
90
- : map().stop();
89
+ ? ctx.map.stop().easeTo({ center: originalCenter })
90
+ : ctx.map.stop();
91
91
  }
92
92
  });
93
93
  createEffect(() => {
@@ -96,9 +96,9 @@ export const Camera = props => {
96
96
  props.rotateViewport
97
97
  ? rotateViewport()
98
98
  : props.resetWhenStopped
99
- ? map().stop().resetNorthPitch()
100
- : map().stop();
99
+ ? ctx.map.stop().resetNorthPitch()
100
+ : ctx.map.stop();
101
101
  });
102
- onCleanup(() => map().off('moveend', onEnd).off('dragend', onEnd));
102
+ onCleanup(() => ctx.map.off('moveend', onEnd).off('dragend', onEnd));
103
103
  return props.children;
104
104
  };
@@ -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
  };
@@ -37,7 +37,7 @@ export const MapGL = props => {
37
37
  let mapLib = props.mapLib || (await import('mapbox-gl'));
38
38
  if (!mapLib.Map)
39
39
  mapLib = window['maplibregl'] || window['mapboxgl'];
40
- if (!mapLib.supported())
40
+ if (!mapLib.supported?.())
41
41
  throw new Error('Mapbox GL not supported');
42
42
  debug(`Map (v${mapLib.version}) loading...`);
43
43
  map = new mapLib.Map({
@@ -1,12 +1,15 @@
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);
1
+ import { createContext, useContext } from "solid-js";
2
+ import { createStore } from "solid-js/store";
3
+ const [state, setState] = createStore({
4
+ map: null,
5
+ userInteraction: false
6
+ });
7
+ export const MapContext = createContext([state]);
8
+ export const useMapContext = () => useContext(MapContext);
6
9
  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.map && setState('map', props.map);
11
+ props.userInteraction && setState('userInteraction', props.userInteraction);
12
+ return (<MapContext.Provider value={[state]}>
10
13
  {props.children}
11
14
  </MapContext.Provider>);
12
15
  };
@@ -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
@@ -1,13 +1,13 @@
1
1
  import { onCleanup, createEffect, createContext, useContext, createUniqueId, } from 'solid-js';
2
- import { useMap } from '../MapProvider';
2
+ import { useMapContext } from '../MapProvider';
3
3
  import { rasterStyleList } from '../../mapStyles';
4
4
  const SourceContext = createContext();
5
5
  export const useSourceId = () => useContext(SourceContext);
6
6
  export const Source = props => {
7
- const [map] = useMap();
7
+ const [ctx] = useMapContext();
8
8
  props.id ??= createUniqueId();
9
9
  const debug = (text, value) => {
10
- map().debug &&
10
+ ctx.map.debug &&
11
11
  console.debug('%c[MapGL]', 'color: #ec4899', text, value || '');
12
12
  };
13
13
  const lookup = url => {
@@ -30,16 +30,16 @@ export const Source = props => {
30
30
  return source;
31
31
  };
32
32
  // Add Source
33
- map().addSource(props.id, lookup(props.source.url));
34
- map().sourceIdList.push(props.id);
33
+ ctx.map.addSource(props.id, lookup(props.source.url));
34
+ ctx.map.sourceIdList.push(props.id);
35
35
  debug('Add Source:', props.id);
36
36
  // Update Data
37
- const source = map().getSource(props.id);
37
+ const source = ctx.map.getSource(props.id);
38
38
  switch (props.source.type) {
39
39
  case 'geojson':
40
40
  createEffect(() => {
41
41
  const data = props.source.data;
42
- if (!map().isSourceLoaded(props.id))
42
+ if (!ctx.map.isSourceLoaded(props.id))
43
43
  return;
44
44
  source.setData(data || {});
45
45
  debug('Update GeoJSON Data:', props.id);
@@ -49,7 +49,7 @@ export const Source = props => {
49
49
  createEffect(() => {
50
50
  const url = props.source.url;
51
51
  const coords = props.source.coordinates;
52
- if (!map().isSourceLoaded(props.id))
52
+ if (!ctx.map.isSourceLoaded(props.id))
53
53
  return;
54
54
  source.updateImage(url, coords);
55
55
  debug('Update Image Data:', props.id);
@@ -59,7 +59,7 @@ export const Source = props => {
59
59
  createEffect(() => {
60
60
  const url = props.source.url;
61
61
  const tiles = props.source.tiles;
62
- if (!map().isSourceLoaded(props.id))
62
+ if (!ctx.map.isSourceLoaded(props.id))
63
63
  return;
64
64
  url ? source.setUrl(url) : source.setTiles(tiles);
65
65
  debug('Update Vector Data:', props.id);
@@ -68,7 +68,7 @@ export const Source = props => {
68
68
  case 'raster':
69
69
  createEffect(() => {
70
70
  const src = lookup(props.source.url);
71
- if (!map().isSourceLoaded(props.id))
71
+ if (!ctx.map.isSourceLoaded(props.id))
72
72
  return;
73
73
  src.url ? source.setUrl(src.url) : source.setTiles(src.tiles);
74
74
  debug('Update Raster Data:', props.id);
@@ -77,10 +77,10 @@ export const Source = props => {
77
77
  }
78
78
  // Remove Source
79
79
  onCleanup(() => {
80
- map()
80
+ ctx.map
81
81
  ?.getStyle()
82
- .layers.forEach(layer => layer.source === props.id && map().removeLayer(layer.id));
83
- map()?.getSource(props.id) && map()?.removeSource(props.id);
82
+ .layers.forEach(layer => layer.source === props.id && ctx.map.removeLayer(layer.id));
83
+ ctx.map?.getSource(props.id) && ctx.map?.removeSource(props.id);
84
84
  debug('Remove Source:', props.id);
85
85
  });
86
86
  return (<SourceContext.Provider value={props.id}>
@@ -1,25 +1,25 @@
1
1
  import { createEffect, createUniqueId } from 'solid-js';
2
- import { useMap } from '../MapProvider';
2
+ import { useMapContext } from '../MapProvider';
3
3
  import { useSourceId } from '../Source';
4
4
  export const Terrain = (props) => {
5
- const [map] = useMap();
5
+ const [ctx] = useMapContext();
6
6
  let sourceId = useSourceId();
7
7
  // Add Terrain Source if not already defined
8
8
  if (!sourceId && !props.source) {
9
9
  sourceId = createUniqueId();
10
- map().addSource(sourceId, {
10
+ ctx.map.addSource(sourceId, {
11
11
  type: 'raster-dem',
12
- url: map().isMapLibre
12
+ url: ctx.map.isMapLibre
13
13
  ? 'https://demotiles.maplibre.org/terrain-tiles/tiles.json'
14
14
  : 'mapbox://mapbox.terrain-rgb',
15
- tileSize: map().isMapLibre ? 256 : 512,
16
- maxzoom: map().isMapLibre ? undefined : 14
15
+ tileSize: ctx.map.isMapLibre ? 256 : 512,
16
+ maxzoom: ctx.map.isMapLibre ? undefined : 14
17
17
  });
18
- map().sourceIdList.push(sourceId);
18
+ ctx.map.sourceIdList.push(sourceId);
19
19
  }
20
20
  // Add or Update Terrain Layer
21
21
  createEffect(() => {
22
- map().setTerrain({
22
+ ctx.map.setTerrain({
23
23
  exaggeration: props.exaggeration || 1,
24
24
  source: props.source || sourceId,
25
25
  });
@@ -1,5 +1,5 @@
1
1
  export { MapGL as default } from './components/MapGL';
2
- export { MapProvider, useMap } from './components/MapProvider';
2
+ export { MapProvider, useMapContext } from './components/MapProvider';
3
3
  export { Source, useSourceId } from './components/Source';
4
4
  export { Layer } from './components/Layer';
5
5
  export { Atmosphere } from './components/Atmosphere';
@@ -4,8 +4,9 @@ import type { Options as FullscreenOptions } from 'mapbox-gl/src/ui/control/full
4
4
  import type { Options as GeolocateOptions } from 'mapbox-gl/src/ui/control/geolocate_control';
5
5
  import type { Options as NavigationOptions } from 'mapbox-gl/src/ui/control/navigation_control';
6
6
  import type { Options as ScaleOptions } from 'mapbox-gl/src/ui/control/scale_control';
7
+ type ControlType = 'navigation' | 'scale' | 'attribution' | 'fullscreen' | 'geolocate';
7
8
  type Props = {
8
- type?: 'navigation' | 'scale' | 'attribution' | 'fullscreen' | 'geolocate';
9
+ type?: ControlType;
9
10
  /** a string that specifies the type of control to be displayed. It can be one of 'navigation', 'scale', 'attribution', 'fullscreen', or 'geolocate' */
10
11
  options?: NavigationOptions | ScaleOptions | AttributionOptions | FullscreenOptions | GeolocateOptions | object;
11
12
  /** an optional object that contains options specific to the control type */
@@ -1,7 +1,13 @@
1
1
  import { ParentComponent } from "solid-js";
2
2
  import type { Map } from '../MapGL';
3
- export declare const MapContext: import("solid-js").Context<import("solid-js").Accessor<any>[]>;
4
- export declare const useMap: () => import("solid-js").Accessor<any>[];
3
+ export declare const MapContext: import("solid-js").Context<{
4
+ map: any;
5
+ userInteraction: boolean;
6
+ }[]>;
7
+ export declare const useMapContext: () => {
8
+ map: any;
9
+ userInteraction: boolean;
10
+ }[];
5
11
  export declare const MapProvider: ParentComponent<{
6
12
  map?: Map;
7
13
  userInteraction?: boolean;
@@ -1,5 +1,5 @@
1
1
  export { MapGL as default } from './components/MapGL';
2
- export { MapProvider, useMap } from './components/MapProvider';
2
+ export { MapProvider, useMapContext } from './components/MapProvider';
3
3
  export { Source, useSourceId } from './components/Source';
4
4
  export { Layer } from './components/Layer';
5
5
  export { Atmosphere } from './components/Atmosphere';
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.8.0",
2
+ "version": "1.8.1",
3
3
  "name": "solid-map-gl",
4
4
  "description": "Solid Component Library for Mapbox GL JS",
5
5
  "info": "Solid Component Library for Mapbox GL JS. Mapbox GL JS is a JavaScript library that renders interactive maps from vector tiles and Mapbox styles using WebGL. This project is intended to be as close as possible to the Mapbox GL JS API.",
@@ -56,7 +56,7 @@
56
56
  "canvas": "^2.11.2",
57
57
  "jsdom": "^22.1.0",
58
58
  "mapbox-gl": "^2.15.0",
59
- "rollup": "^3.24.0",
59
+ "rollup": "^3.25.1",
60
60
  "rollup-plugin-import-css": "^3.2.1",
61
61
  "rollup-preset-solid": "^2.0.1",
62
62
  "solid-js": "^1.7.6",