@beyonk/svelte-mapbox 12.0.0 → 12.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -30,17 +30,17 @@ npm install --save-dev @beyonk/svelte-mapbox
30
30
 
31
31
  The container component is the map, and there are a variety of components which go on the map.
32
32
 
33
- ```jsx
33
+ ```svelte
34
34
  <Map
35
35
  accessToken="<your api key>" // add your api key here
36
36
  bind:this={mapComponent} // Get reference to your map component to use methods
37
- on:recentre={e => console.log(e.detail.center.lat, e.detail.center.lng) } // recentre events
37
+ onrecentre={e => console.log(e.detail.center.lat, e.detail.center.lng) } // recentre events
38
38
  options={{ scrollZoom: false }} // // add arbitrary options to the map from the mapbox api
39
39
  >
40
40
  <Earthquakes /> // Any custom component you create or want here - see marker example
41
41
  <Marker lat={someLat} lng={someLng} color="rgb(255,255,255)" label="some marker label" popupClassName="class-name" /> // built in Marker component
42
42
  <NavigationControl />
43
- <GeolocateControl options={{ some: 'control-option' }} on:eventname={eventHandler} />
43
+ <GeolocateControl options={{ some: 'control-option' }} oneventname={eventHandler} />
44
44
  <ScaleControl />
45
45
  </Map>
46
46
 
@@ -73,13 +73,13 @@ The container component is the map, and there are a variety of components which
73
73
 
74
74
  By default, markers are typical map pins to which you can pass a color property.
75
75
 
76
- ```jsx
76
+ ```svelte
77
77
  <Marker color={brandColour} />
78
78
  ```
79
79
 
80
80
  You may also create a custom pin with the default slot.
81
81
 
82
- ```jsx
82
+ ```svelte
83
83
  <Marker
84
84
  lat={waypoint.geo.lat}
85
85
  lng={waypoint.geo.lng}
@@ -98,13 +98,13 @@ lng={waypoint.geo.lng}
98
98
  ### Marker Popups
99
99
  By default a popup is revealed when you click a pin. It is populated with text provided in the label property.
100
100
 
101
- ```jsx
101
+ ```svelte
102
102
  <Marker label={markerText} />
103
103
  ```
104
104
 
105
105
  To indicate interactivity, you may target the marker with some custom CSS:
106
106
 
107
- ```jsx
107
+ ```svelte
108
108
  <style>
109
109
  :global(.mapboxgl-marker){
110
110
  cursor: pointer;
@@ -114,13 +114,13 @@ To indicate interactivity, you may target the marker with some custom CSS:
114
114
 
115
115
  Optionally, disable the popup with the `popup={false}` property:
116
116
 
117
- ```jsx
117
+ ```svelte
118
118
  <Marker popup={false} />
119
119
  ```
120
120
 
121
121
  You may alternatively pass a custom DOM element to the marker to use as a popup.
122
122
 
123
- ```jsx
123
+ ```svelte
124
124
  <Marker lat={pin.coordinates.latitude} lng={pin.coordinates.longitude}>
125
125
  <div class="content" slot="popup">
126
126
  <h3>{pin.name}</h3>
@@ -139,7 +139,7 @@ This also means that if you bind these properties to a variable, that variable w
139
139
 
140
140
  This is often easier than waiting for events such as `recentre` or `zoom` to be fired, to update markers and similar:
141
141
 
142
- ```jsx
142
+ ```svelte
143
143
  <Map accessToken="<your api key>" bind:center bind:zoom>
144
144
  <Marker bind:lat bind:lng />
145
145
  </Map>
@@ -165,19 +165,19 @@ map is ready in your browser when you call it this way.
165
165
 
166
166
  The Geocoder is an autocompleting place lookup, which returns a lat and lng for a place.
167
167
 
168
- ```jsx
169
- <Geocoder accessToken="<your api key>" on:result={somePlaceChangeFunction} />
168
+ ```svelte
169
+ <Geocoder accessToken="<your api key>" onresult={somePlaceChangeFunction} />
170
170
 
171
171
  <script>
172
172
  import { Geocoder } from '@beyonk/svelte-mapbox'
173
173
  </script>
174
174
  ```
175
175
 
176
- The geocoder has five events you can subscribe to: `on:loading`, `on:result`, `on:results`, `on:clear`, and `on:error` which are [documented here](https://github.com/mapbox/mapbox-gl-geocoder/blob/master/API.md#on)
176
+ The geocoder has five events you can subscribe to: `onloading`, `onresult`, `onresults`, `onclear`, and `onerror` which are [documented here](https://github.com/mapbox/mapbox-gl-geocoder/blob/master/API.md#on)
177
177
 
178
- The most important event is `on:result` which is fired when a user selects an autocomplete result.
178
+ The most important event is `onresult` which is fired when a user selects an autocomplete result.
179
179
 
180
- There is a sixth event specific to this library, which is `on:ready`, which is fired when the component is ready for use. You can likely ignore it.
180
+ There is a sixth event specific to this library, which is `onready`, which is fired when the component is ready for use. You can likely ignore it.
181
181
 
182
182
  ## Custom CSS
183
183
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@beyonk/svelte-mapbox",
3
- "version": "12.0.0",
3
+ "version": "12.1.0",
4
4
  "devDependencies": {
5
5
  "@beyonk/eslint-config": "^8.0.2",
6
6
  "@eslint/eslintrc": "^3.1.0",
@@ -10,6 +10,12 @@
10
10
  value = null,
11
11
  customStylesheetUrl = false,
12
12
  geocoder = $bindable(),
13
+ onresults,
14
+ onresult,
15
+ onloading,
16
+ onerror,
17
+ onclear,
18
+ onload,
13
19
  ...rest
14
20
  } = $props()
15
21
 
@@ -24,15 +30,14 @@
24
30
  value
25
31
  }, options))
26
32
 
27
- function init (e) {
28
- geocoder = e.detail.geocoder
29
- onready?.()
33
+ function init (detail) {
34
+ geocoder = detail.geocoder
30
35
  }
31
36
  </script>
32
37
 
33
38
  <div
34
39
  id={fieldId}
35
- {@attach geocoderAttachment(optionsWithDefaults)}
40
+ {@attach geocoderAttachment(optionsWithDefaults, { onresults, onresult, onloading, onerror, onclear, onload })}
36
41
  onready={init}
37
42
  {...rest}
38
43
  ></div>
@@ -1,10 +1,8 @@
1
1
  import { load } from '../asset-loader.js'
2
- import { bindEvents } from '../event-bindings.js'
3
2
 
4
- export default function geocoderAttachment (options) {
3
+ export default function geocoderAttachment (options, { onresults, onresult, onloading, onerror, onclear, onready }) {
5
4
  return (element) => {
6
5
  let geocoderInstance
7
- let unbind = () => {}
8
6
 
9
7
  const resources = [
10
8
  { type: 'script', value: `//api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/${options.version}/mapbox-gl-geocoder.min.js`, id: 'byk-gc-js' }
@@ -23,33 +21,30 @@ export default function geocoderAttachment (options) {
23
21
  if (options.value) {
24
22
  geocoderInstance.setInput(options.value)
25
23
  }
26
- unbind = bindEvents(geocoderInstance, handlers, false, element)
24
+
25
+ geocoderInstance.on('results', (ev) => {
26
+ onresults?.(ev)
27
+ })
28
+ geocoderInstance.on('result', (ev) => {
29
+ console.log('result', onresult, ev)
30
+ onresult?.(ev)
31
+ })
32
+ geocoderInstance.on('loading', (ev) => {
33
+ onloading?.(ev)
34
+ })
35
+ geocoderInstance.on('error', (ev) => {
36
+ onerror?.(ev)
37
+ })
38
+ geocoderInstance.on('clear', (ev) => {
39
+ onclear?.(ev)
40
+ })
41
+ geocoderInstance.on('load', (ev) => {
42
+ onready?.({ ...ev, geocoder: geocoderInstance })
43
+ })
27
44
  })
28
45
 
29
46
  return () => {
30
- unbind()
31
47
  geocoderInstance && geocoderInstance.remove && geocoderInstance.remove()
32
48
  }
33
49
  }
34
50
  }
35
-
36
- const handlers = {
37
- results: (el, ev) => {
38
- return [ 'results', ev ]
39
- },
40
- result: (el, ev) => {
41
- return [ 'result', ev ]
42
- },
43
- loading: (el, ev) => {
44
- return [ 'loading', ev ]
45
- },
46
- error: (el, ev) => {
47
- return [ 'error', ev ]
48
- },
49
- clear: (el, ev) => {
50
- return [ 'clear', ev ]
51
- },
52
- load: el => {
53
- return [ 'ready', { geocoder: el } ]
54
- }
55
- }
@@ -5,7 +5,6 @@
5
5
  import { EventQueue } from '../queue.svelte.js'
6
6
 
7
7
  let {
8
- map = $bindable(null),
9
8
  version = 'v3.20.0',
10
9
  center = [ 0, 0 ],
11
10
  zoom = $bindable(9),
@@ -17,13 +16,24 @@
17
16
  style = 'mapbox://styles/mapbox/streets-v11',
18
17
  children,
19
18
  onready,
19
+ ondragend,
20
+ ondrag,
21
+ onmoveend,
22
+ onzoomstart,
23
+ onzoom,
24
+ onzoomend,
20
25
  ...rest
21
26
  } = $props()
22
27
 
28
+ let map = $state()
23
29
  let mapbox = $state()
24
30
 
31
+ setContext(contextKey, {
32
+ getMap: () => map,
33
+ getMapbox: () => mapbox
34
+ })
25
35
 
26
- const optionsWithDefaults = {
36
+ const optionsWithDefaults = $derived.by(() => Object.assign({
27
37
  accessToken,
28
38
  style,
29
39
  center,
@@ -32,26 +42,21 @@
32
42
  wheelZoomRate,
33
43
  version,
34
44
  customStylesheetUrl,
35
- map,
36
45
  ...options
37
- }
38
-
39
- setContext(contextKey, {
40
- getMap: () => map,
41
- getMapbox: () => mapbox
42
- })
46
+ }))
43
47
 
44
48
  const queue = new EventQueue()
45
49
 
46
- function init (e) {
47
- map = e.detail.map
48
- mapbox = e.detail.mapbox
50
+ function init (detail) {
51
+ map = detail.map
52
+ mapbox = detail.mapbox
49
53
  queue.start(map)
50
- onready?.()
51
54
 
52
55
  map.on('zoomend', (e) => {
53
56
  zoom = map.getZoom()
54
57
  })
58
+
59
+ onready?.({ map, mapbox })
55
60
  }
56
61
 
57
62
  $effect(() => {
@@ -99,8 +104,10 @@
99
104
  </script>
100
105
 
101
106
  <div
102
- {@attach mapAttachment(optionsWithDefaults)}
103
- onready={init}
107
+ {@attach mapAttachment(
108
+ optionsWithDefaults,
109
+ { onready: init, ondragend, ondrag, onmoveend, onzoomstart, onzoom, onzoomend }
110
+ )}
104
111
  {...rest}
105
112
  role="presentation"
106
113
  >
@@ -1,29 +1,24 @@
1
1
  <script>
2
2
  import { getContext, onMount, untrack } from 'svelte'
3
3
  import { contextKey } from '../../mapbox.js'
4
- import { bindEvents } from '../../event-bindings.js'
5
4
 
6
5
  const { getMap, getMapbox } = getContext(contextKey)
7
6
  const map = getMap()
8
7
  const mapbox = getMapbox()
9
8
 
10
- let { position = 'top-left', options = {}, ...rest } = $props()
9
+ let { position = 'top-left', options = {}, onerror, ongeolocate, onoutofmaxbounds, ontrackuserlocationend, ontrackuserlocationstart, ...rest } = $props()
11
10
 
12
11
  let dispatcher = $state()
13
12
 
14
- const handlers = {
15
- error: (el, ev) => [ 'error', ev ],
16
- geolocate: (el, ev) => [ 'geolocate', ev ],
17
- outofmaxbounds: (el, ev) => [ 'outofmaxbounds', ev ],
18
- trackuserlocationend: (el, ev) => [ 'trackuserlocationend', ev ],
19
- trackuserlocationstart: (el, ev) => [ 'trackuserlocationstart', ev ]
20
- }
21
-
22
13
  const geolocate = new mapbox.GeolocateControl(untrack(() => options))
23
14
  map.addControl(geolocate, untrack(() => position))
24
15
 
25
16
  onMount(() => {
26
- return bindEvents(geolocate, handlers, mapbox, dispatcher)
17
+ geolocate.on('error', onerror)
18
+ geolocate.on('geolocate', ongeolocate)
19
+ geolocate.on('outofmaxbounds', onoutofmaxbounds)
20
+ geolocate.on('trackuserlocationend', ontrackuserlocationend)
21
+ geolocate.on('trackuserlocationstart', ontrackuserlocationstart)
27
22
  })
28
23
 
29
24
  export function trigger () {
@@ -1,16 +1,34 @@
1
1
  import { load } from '../asset-loader.js'
2
- import { bindEvents } from '../event-bindings.js'
3
2
 
4
- export default function mapAttachment (options = {}) {
3
+ export default function mapAttachment (options = {}, { ondragend, ondrag, onmoveend, onzoomstart, onzoom, onzoomend, onready }) {
5
4
  return (element) => {
6
- console.log('attach', element, options)
7
5
  let map
8
6
 
9
7
  function init (options) {
10
8
  window.mapboxgl.accessToken = options.accessToken
11
9
  const el = new window.mapboxgl.Map(options)
12
10
 
13
- return bindEvents(el, handlers, window.mapboxgl, element)
11
+ el.on('dragend', () => {
12
+ ondragend?.({ center: el.getCenter() })
13
+ })
14
+ el.on('drag', () => {
15
+ ondrag?.({ center: el.getCenter() })
16
+ })
17
+ el.on('moveend', () => {
18
+ onmoveend?.({ center: el.getCenter() })
19
+ })
20
+ el.on('zoomstart', () => {
21
+ onzoomstart?.({ zoom: el.getZoom() })
22
+ })
23
+ el.on('zoom', () => {
24
+ onzoom?.({ zoom: el.getZoom() })
25
+ })
26
+ el.on('zoomend', () => {
27
+ onzoomend?.({ zoom: el.getZoom() })
28
+ })
29
+ el.on('load', () => {
30
+ onready?.({ map: el, mapbox: window.mapboxgl })
31
+ })
14
32
  }
15
33
 
16
34
  const resources = [
@@ -36,30 +54,3 @@ export default function mapAttachment (options = {}) {
36
54
  }
37
55
  }
38
56
  }
39
-
40
- const handlers = {
41
- dragend: el => {
42
- return [ 'dragend', { center: el.getCenter() } ]
43
- },
44
- drag: el => {
45
- return [ 'drag', { center: el.getCenter() } ]
46
- },
47
- moveend: el => {
48
- return [ 'recentre', { center: el.getCenter() } ]
49
- },
50
- click: (el, { lngLat }) => {
51
- return [ 'click', { lng: lngLat.lng, lat: lngLat.lat } ]
52
- },
53
- zoomstart: el => {
54
- return [ 'zoomstart', { zoom: el.getZoom() } ]
55
- },
56
- zoom: el => {
57
- return [ 'zoom', { zoom: el.getZoom() } ]
58
- },
59
- zoomend: el => {
60
- return [ 'zoomend', { zoom: el.getZoom() } ]
61
- },
62
- load: (el, ev, mapbox) => {
63
- return [ 'ready', { map: el, mapbox } ]
64
- }
65
- }
@@ -2,10 +2,12 @@
2
2
  import { PUBLIC_MAPBOX_TOKEN } from '$env/static/public'
3
3
  import { Map, Geocoder, Marker, controls } from '$lib/components.js'
4
4
  import Earthquakes from './_Earthquakes.svelte'
5
+ import { untrack } from 'svelte'
5
6
 
6
7
  const { GeolocateControl, NavigationControl } = controls
7
8
 
8
- let place = $state(null)
9
+ let place = $state()
10
+ let placeName = $derived(untrack(() => place?.place_name || '(Near London)'))
9
11
  let page = $state('about')
10
12
  let center = $state({ lat: 53.3358627, lng: -2.8572362 })
11
13
  let marker = $derived(center)
@@ -16,12 +18,6 @@
16
18
  page = next
17
19
  }
18
20
 
19
- function placeChanged (e) {
20
- const { result } = e.detail
21
- mapComponent.setCenter(result.center, 14)
22
- place = result
23
- }
24
-
25
21
  function randomLng () {
26
22
  return 77 + (Math.random() - 0.5) * 30
27
23
  }
@@ -37,12 +33,12 @@
37
33
  })
38
34
  }
39
35
 
40
- function recentre (e) {
41
- center = e.detail.center
36
+ function recentre (result) {
37
+ center = result.center
42
38
  }
43
39
 
44
- function drag (e) {
45
- marker = e.detail.center
40
+ function drag (result) {
41
+ marker = result.center
46
42
  }
47
43
  </script>
48
44
 
@@ -79,7 +75,7 @@
79
75
  </div>
80
76
  </div>
81
77
  <div class="col-lg-2 col-md-3 col-xs-12 right">
82
- <a class="btn" href="http://www.github.com/beyonk-adventures/svelte-mapbox">Github</a>
78
+ <a class="btn" href="http://www.github.com/beyonk/svelte-mapbox">Github</a>
83
79
  </div>
84
80
  </div>
85
81
  </div>
@@ -107,7 +103,18 @@
107
103
 
108
104
  <div class="section-txt" id="geocoder">
109
105
  <form>
110
- <Geocoder value="(Near London)" accessToken={PUBLIC_MAPBOX_TOKEN} onresult={placeChanged} onclear={() => mapComponent.setCenter({ lng: 0, lat: 0 })} />
106
+ <Geocoder
107
+ bind:value={placeName}
108
+ accessToken={PUBLIC_MAPBOX_TOKEN}
109
+ onresult={({ result }) => {
110
+ console.log('sets center', result.center)
111
+ mapComponent.setCenter(result.center, 14)
112
+ place = result
113
+ }}
114
+ onclear={() => {
115
+ mapComponent.setCenter({ lng: 0, lat: 0 })
116
+ }}
117
+ />
111
118
  {#if place}
112
119
  <dl>
113
120
  <dt>Name:</dt>
@@ -130,7 +137,7 @@
130
137
  >
131
138
  <Earthquakes />
132
139
  <NavigationControl />
133
- <GeolocateControl ongeolocate={e => console.log('geolocated', e.detail)} />
140
+ <GeolocateControl ongeolocate={({ result }) => console.log('geolocated', result)} />
134
141
  <Marker lat={marker.lat} lng={marker.lng} />
135
142
  </Map>
136
143
  </div>
@@ -158,7 +165,7 @@
158
165
  <div class="container">
159
166
  <div class="row">
160
167
  <div class="col-lg-12 center">
161
- © 2019 Beyonk. All rights reserved.
168
+ © 2026 Beyonk. All rights reserved.
162
169
  </div>
163
170
  </div>
164
171
  </div>
@@ -1,24 +0,0 @@
1
- function bindEvents (el, handlers, mapbox, node) {
2
- const unbindings = []
3
-
4
- for (const [ handler, fn ] of Object.entries(handlers)) {
5
- const cmd = ev => {
6
- const [ eventName, detail ] = fn(el, ev, mapbox)
7
- node.dispatchEvent(
8
- new CustomEvent(eventName, { detail })
9
- )
10
- }
11
- el.on(handler, cmd)
12
- unbindings.push([ handler, cmd ])
13
- }
14
-
15
- return () => {
16
- for (const [ handler, cmd ] of unbindings) {
17
- el.off(handler, cmd)
18
- }
19
- }
20
- }
21
-
22
- export {
23
- bindEvents
24
- }