@beyonk/svelte-mapbox 11.0.0 → 12.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.
@@ -2,16 +2,8 @@ name: publish
2
2
 
3
3
  on:
4
4
  push:
5
- branches:
6
- - '*'
7
5
  tags:
8
6
  - 'v*'
9
- pull_request:
10
- branches:
11
- - '*'
12
-
13
- env:
14
- NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
15
7
 
16
8
  jobs:
17
9
  publish-npm:
@@ -24,7 +16,7 @@ jobs:
24
16
  - name: set up node and pnpm
25
17
  run: |
26
18
  corepack enable
27
- pnpm config set '//registry.npmjs.org/:_authToken' "${NODE_AUTH_TOKEN}"
19
+ pnpm config set '//registry.npmjs.org/:_authToken' "${{secrets.NPM_TOKEN}}"
28
20
  pnpm i
29
21
 
30
22
  - name: publish
File without changes
package/jsconfig.json CHANGED
@@ -1,11 +1,4 @@
1
1
  {
2
2
  "extends": "./.svelte-kit/tsconfig.json",
3
- "compilerOptions": {
4
- "baseUrl": ".",
5
- "paths": {
6
- "$lib": ["src/lib"],
7
- "$lib/*": ["src/lib/*"]
8
- }
9
- },
10
3
  "include": ["src/**/*.d.ts", "src/**/*.js", "src/**/*.svelte"]
11
4
  }
package/package.json CHANGED
@@ -1,18 +1,18 @@
1
1
  {
2
2
  "name": "@beyonk/svelte-mapbox",
3
- "version": "11.0.0",
3
+ "version": "12.0.0",
4
4
  "devDependencies": {
5
5
  "@beyonk/eslint-config": "^8.0.2",
6
6
  "@eslint/eslintrc": "^3.1.0",
7
7
  "@eslint/js": "^9.14.0",
8
- "@sveltejs/kit": "^2.8.0",
9
- "@sveltejs/vite-plugin-svelte": "^4.0.0",
8
+ "@sveltejs/kit": "^2.55.0",
9
+ "@sveltejs/vite-plugin-svelte": "^7.0.0",
10
10
  "eslint": "^9.14.0",
11
11
  "eslint-plugin-svelte": "^2.46.0",
12
- "svelte": "^5.1.14",
12
+ "svelte": "^5.55.0",
13
13
  "svelte2tsx": "^0.7.23",
14
14
  "typescript": "^5.6.3",
15
- "vite": "^5.4.11"
15
+ "vite": "^8.0.2"
16
16
  },
17
17
  "peerDependencies": {
18
18
  "svelte": ">=4.0.0"
@@ -22,7 +22,6 @@
22
22
  },
23
23
  "types": "./components.d.ts",
24
24
  "type": "module",
25
- "packageManager": "pnpm@8.15.7",
26
25
  "scripts": {
27
26
  "dev": "vite dev --port 3030",
28
27
  "build": "vite build",
@@ -1,48 +1,44 @@
1
- <div
2
- id={fieldId}
3
- use:action={optionsWithDefaults}
4
- on:ready={init}
5
- on:results
6
- on:result
7
- on:loading
8
- on:error
9
- on:clear
10
- on:load
11
- ></div>
12
-
13
1
  <script>
14
- import { createEventDispatcher } from 'svelte'
15
- import action from './geocoder-action.js'
2
+ import geocoderAttachment from './geocoder-attachment.js'
16
3
 
17
- export let accessToken
18
- export let options = {}
19
- export let version = 'v5.0.3'
20
- export let types = [ 'country', 'region', 'postcode', 'district', 'place', 'locality', 'neighborhood', 'address' ]
21
- export let placeholder = 'Search'
22
- export let value = null
23
- export let customStylesheetUrl = false
24
- export let geocoder
4
+ let {
5
+ accessToken,
6
+ options = {},
7
+ version = 'v5.1.0',
8
+ types = [ 'country', 'region', 'postcode', 'district', 'place', 'locality', 'neighborhood', 'address' ],
9
+ placeholder = 'Search',
10
+ value = null,
11
+ customStylesheetUrl = false,
12
+ geocoder = $bindable(),
13
+ ...rest
14
+ } = $props()
25
15
 
26
- const dispatch = createEventDispatcher()
27
16
  const fieldId = 'bsm-' + Math.random().toString(36).substring(6)
28
17
 
29
- const optionsWithDefaults = Object.assign({
18
+ const optionsWithDefaults = $derived.by(() => Object.assign({
30
19
  version,
31
20
  accessToken,
32
21
  types: types.join(','),
33
22
  placeholder,
34
23
  customStylesheetUrl,
35
24
  value
36
- }, options)
25
+ }, options))
37
26
 
38
- function init ({ detail }) {
39
- geocoder = detail.geocoder
40
- dispatch('ready')
27
+ function init (e) {
28
+ geocoder = e.detail.geocoder
29
+ onready?.()
41
30
  }
42
31
  </script>
43
32
 
33
+ <div
34
+ id={fieldId}
35
+ {@attach geocoderAttachment(optionsWithDefaults)}
36
+ onready={init}
37
+ {...rest}
38
+ ></div>
39
+
44
40
  <style>
45
41
  div {
46
42
  padding: 0;
47
43
  }
48
- </style>
44
+ </style>
@@ -0,0 +1,55 @@
1
+ import { load } from '../asset-loader.js'
2
+ import { bindEvents } from '../event-bindings.js'
3
+
4
+ export default function geocoderAttachment (options) {
5
+ return (element) => {
6
+ let geocoderInstance
7
+ let unbind = () => {}
8
+
9
+ const resources = [
10
+ { type: 'script', value: `//api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/${options.version}/mapbox-gl-geocoder.min.js`, id: 'byk-gc-js' }
11
+ ]
12
+
13
+ const customStylesheetUrl = options.customStylesheetUrl
14
+ if (customStylesheetUrl) {
15
+ resources.push({ type: 'link', value: customStylesheetUrl, id: 'byk-gcsu-css' })
16
+ } else {
17
+ resources.push({ type: 'link', value: `//api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/${options.version}/mapbox-gl-geocoder.css`, id: 'byk-gc-css' })
18
+ }
19
+
20
+ load(resources, () => {
21
+ geocoderInstance = new window.MapboxGeocoder(options)
22
+ geocoderInstance.addTo(`#${element.id}`)
23
+ if (options.value) {
24
+ geocoderInstance.setInput(options.value)
25
+ }
26
+ unbind = bindEvents(geocoderInstance, handlers, false, element)
27
+ })
28
+
29
+ return () => {
30
+ unbind()
31
+ geocoderInstance && geocoderInstance.remove && geocoderInstance.remove()
32
+ }
33
+ }
34
+ }
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
+ }
@@ -1,60 +1,30 @@
1
- <!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
2
- <div
3
- use:action={optionsWithDefaults}
4
- on:ready={init}
5
- on:recentre
6
- on:dragend
7
- on:click
8
- on:zoomstart
9
- on:zoom
10
- on:zoomend
11
- on:drag
12
- on:keydown
13
- on:keyup
14
- role="application"
15
- >
16
- {#if map}
17
- <slot></slot>
18
- {/if}
19
- </div>
20
-
21
- <style>
22
- div {
23
- width: 100%;
24
- height: 100%;
25
- }
26
- </style>
27
-
28
1
  <script>
29
- import { setContext, onDestroy, createEventDispatcher } from 'svelte'
2
+ import { setContext, untrack } from 'svelte'
30
3
  import { contextKey } from '../mapbox.js'
31
- import action from './map-action.js'
32
- import { EventQueue } from '../queue.js'
33
-
34
- export let map = null
35
- export let version = 'v3.7.0'
36
- export let center = [ 0, 0 ]
37
- export let zoom = 9
38
- export let zoomRate = 1
39
- export let wheelZoomRate = 1
40
- export let options = {}
41
- export let accessToken
42
- export let customStylesheetUrl = false
43
- export let style = 'mapbox://styles/mapbox/streets-v11'
44
-
45
- const dispatch = createEventDispatcher()
4
+ import mapAttachment from './map-attachment.js'
5
+ import { EventQueue } from '../queue.svelte.js'
6
+
7
+ let {
8
+ map = $bindable(null),
9
+ version = 'v3.20.0',
10
+ center = [ 0, 0 ],
11
+ zoom = $bindable(9),
12
+ zoomRate = 1,
13
+ wheelZoomRate = 1,
14
+ options = {},
15
+ accessToken,
16
+ customStylesheetUrl = false,
17
+ style = 'mapbox://styles/mapbox/streets-v11',
18
+ children,
19
+ onready,
20
+ ...rest
21
+ } = $props()
46
22
 
47
- setContext(contextKey, {
48
- getMap: () => map,
49
- getMapbox: () => mapbox
50
- })
23
+ let mapbox = $state()
51
24
 
52
- let container
53
- let mapbox
54
25
 
55
- const optionsWithDefaults = Object.assign({
26
+ const optionsWithDefaults = {
56
27
  accessToken,
57
- container,
58
28
  style,
59
29
  center,
60
30
  zoom,
@@ -62,21 +32,37 @@
62
32
  wheelZoomRate,
63
33
  version,
64
34
  customStylesheetUrl,
65
- map
66
- }, options)
35
+ map,
36
+ ...options
37
+ }
38
+
39
+ setContext(contextKey, {
40
+ getMap: () => map,
41
+ getMapbox: () => mapbox
42
+ })
67
43
 
68
44
  const queue = new EventQueue()
69
45
 
70
- function init ({ detail }) {
71
- map = detail.map
72
- mapbox = detail.mapbox
46
+ function init (e) {
47
+ map = e.detail.map
48
+ mapbox = e.detail.mapbox
73
49
  queue.start(map)
74
- dispatch('ready')
50
+ onready?.()
51
+
52
+ map.on('zoomend', (e) => {
53
+ zoom = map.getZoom()
54
+ })
75
55
  }
76
56
 
77
- onDestroy(() => {
78
- queue.stop()
79
- map = undefined
57
+ $effect(() => {
58
+ return () => {
59
+ queue.stop()
60
+ map = undefined
61
+ }
62
+ })
63
+
64
+ $effect(() => {
65
+ zoom && setZoom(zoom)
80
66
  })
81
67
 
82
68
  export function fitBounds (bbox, data = {}) {
@@ -110,6 +96,22 @@
110
96
  export function getMapbox () {
111
97
  return mapbox
112
98
  }
113
-
114
- $: zoom && setZoom(zoom)
115
99
  </script>
100
+
101
+ <div
102
+ {@attach mapAttachment(optionsWithDefaults)}
103
+ onready={init}
104
+ {...rest}
105
+ role="presentation"
106
+ >
107
+ {#if map}
108
+ {@render children?.()}
109
+ {/if}
110
+ </div>
111
+
112
+ <style>
113
+ div {
114
+ width: 100%;
115
+ height: 100%;
116
+ }
117
+ </style>
@@ -10,36 +10,40 @@
10
10
  return Math.round(Math.random() * 255)
11
11
  }
12
12
 
13
+ let {
14
+ lat,
15
+ lng,
16
+ label = 'Marker',
17
+ popupClassName = 'beyonk-mapbox-popup',
18
+ markerOffset = [ 0, 0 ],
19
+ popupOffset = 10,
20
+ color = randomColour(),
21
+ popup = true,
22
+ popupOptions = {},
23
+ markerOptions = {},
24
+ children,
25
+ popupContent
26
+ } = $props()
27
+
28
+ let marker = $state()
29
+ let element = $state()
30
+ let elementPopup = $state()
31
+
13
32
  function move (lng, lat) {
14
33
  marker.setLngLat({ lng, lat })
15
34
  }
16
35
 
17
- export let lat
18
- export let lng
19
- export let label = 'Marker'
20
- export let popupClassName = 'beyonk-mapbox-popup'
21
- export let markerOffset = [ 0, 0 ]
22
- export let popupOffset = 10
23
- export let color = randomColour()
24
- export let popup = true
25
- export let popupOptions = {}
26
- export let markerOptions = {}
27
-
28
- let marker
29
- let element
30
- let elementPopup
31
-
32
- $: marker && move(lng, lat)
36
+ $effect(() => {
37
+ if (marker) move(lng, lat)
38
+ })
33
39
 
34
40
  onMount(() => {
35
41
  const namedParams = Object.assign(
36
- {
37
- offset: markerOffset
38
- },
42
+ { offset: markerOffset },
39
43
  element.hasChildNodes() ? { element } : { color }
40
44
  )
41
45
  marker = new mapbox.Marker(Object.assign(namedParams, markerOptions))
42
-
46
+
43
47
  if (popup) {
44
48
  const namedPopupParams = { offset: popupOffset, className: popupClassName }
45
49
  const popupEl = new mapbox.Popup(Object.assign(namedPopupParams, popupOptions))
@@ -48,7 +52,6 @@
48
52
  } else {
49
53
  popupEl.setText(label)
50
54
  }
51
-
52
55
  marker.setPopup(popupEl)
53
56
  }
54
57
 
@@ -67,9 +70,9 @@
67
70
  </script>
68
71
 
69
72
  <div bind:this={element}>
70
- <slot></slot>
73
+ {@render children?.()}
71
74
  </div>
72
75
 
73
76
  <div class='popup' bind:this={elementPopup}>
74
- <slot name="popup"></slot>
77
+ {@render popupContent?.()}
75
78
  </div>
@@ -1,56 +1,38 @@
1
- <div
2
- bind:this={dispatcher}
3
- on:error
4
- on:geolocate
5
- on:outofmaxbounds
6
- on:trackuserlocationend
7
- on:trackuserlocationstart
8
- />
9
-
10
1
  <script>
11
- import { getContext, onMount } from 'svelte'
12
- import { contextKey } from '../../mapbox.js'
13
- import { bindEvents } from '../../event-bindings.js'
14
-
15
- const { getMap, getMapbox } = getContext(contextKey)
16
- const map = getMap()
17
- const mapbox = getMapbox()
18
-
19
- export let position = 'top-left'
20
- export let options = {}
21
-
22
- let dispatcher
23
-
24
- const handlers = {
25
- error: (el, ev) => {
26
- return [ 'error', ev ]
27
- },
28
- geolocate: (el, ev) => {
29
- return [ 'geolocate', ev ]
30
- },
31
- outofmaxbounds: (el, ev) => {
32
- return [ 'outofmaxbounds', ev ]
33
- },
34
- trackuserlocationend: (el, ev) => {
35
- return [ 'trackuserlocationend', ev ]
36
- },
37
- trackuserlocationstart: (el, ev) => {
38
- return [ 'trackuserlocationstart', ev ]
39
- }
40
- }
41
-
42
- const geolocate = new mapbox.GeolocateControl(options)
43
- map.addControl(geolocate, position)
44
-
45
- onMount(() => {
46
- return bindEvents(geolocate, handlers, mapbox, dispatcher)
47
- })
48
-
49
- export function trigger () {
50
- geolocate.trigger()
51
- }
2
+ import { getContext, onMount, untrack } from 'svelte'
3
+ import { contextKey } from '../../mapbox.js'
4
+ import { bindEvents } from '../../event-bindings.js'
5
+
6
+ const { getMap, getMapbox } = getContext(contextKey)
7
+ const map = getMap()
8
+ const mapbox = getMapbox()
9
+
10
+ let { position = 'top-left', options = {}, ...rest } = $props()
11
+
12
+ let dispatcher = $state()
13
+
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
+ const geolocate = new mapbox.GeolocateControl(untrack(() => options))
23
+ map.addControl(geolocate, untrack(() => position))
24
+
25
+ onMount(() => {
26
+ return bindEvents(geolocate, handlers, mapbox, dispatcher)
27
+ })
28
+
29
+ export function trigger () {
30
+ geolocate.trigger()
31
+ }
52
32
  </script>
53
33
 
34
+ <div bind:this={dispatcher} {...rest}></div>
35
+
54
36
  <style>
55
- div { display: none; }
37
+ div { display: none; }
56
38
  </style>
@@ -1,14 +1,13 @@
1
1
  <script>
2
- import { getContext } from 'svelte'
3
- import { contextKey } from '../../mapbox.js'
2
+ import { getContext, untrack } from 'svelte'
3
+ import { contextKey } from '../../mapbox.js'
4
4
 
5
- const { getMap, getMapbox } = getContext(contextKey)
6
- const map = getMap()
7
- const mapbox = getMapbox()
5
+ const { getMap, getMapbox } = getContext(contextKey)
6
+ const map = getMap()
7
+ const mapbox = getMapbox()
8
8
 
9
- export let position = 'top-right'
10
- export let options = {}
9
+ let { position = 'top-right', options = {} } = $props()
11
10
 
12
- const nav = new mapbox.NavigationControl(options)
13
- map.addControl(nav, position)
14
- </script>
11
+ const nav = new mapbox.NavigationControl(untrack(() => options))
12
+ map.addControl(nav, untrack(() => position))
13
+ </script>
@@ -1,19 +1,18 @@
1
1
  <script>
2
- import { getContext } from 'svelte'
3
- import { contextKey } from '../../mapbox.js'
2
+ import { getContext, untrack } from 'svelte'
3
+ import { contextKey } from '../../mapbox.js'
4
4
 
5
- const { getMap, getMapbox } = getContext(contextKey)
6
- const map = getMap()
7
- const mapbox = getMapbox()
5
+ const { getMap, getMapbox } = getContext(contextKey)
6
+ const map = getMap()
7
+ const mapbox = getMapbox()
8
8
 
9
- export let position = 'bottom-right'
10
- export let options = {}
9
+ let { position = 'bottom-right', options = {} } = $props()
11
10
 
12
- const optionsWithDefaults = Object.assign({
13
- maxWidth: 80,
14
- unit: 'metric'
15
- }, options)
11
+ const optionsWithDefaults = untrack(() => Object.assign({
12
+ maxWidth: 80,
13
+ unit: 'metric'
14
+ }, options))
16
15
 
17
- const scale = new mapbox.ScaleControl(optionsWithDefaults)
18
- map.addControl(scale, position)
19
- </script>
16
+ const scale = new mapbox.ScaleControl(optionsWithDefaults)
17
+ map.addControl(scale, untrack(() => position))
18
+ </script>
@@ -0,0 +1,65 @@
1
+ import { load } from '../asset-loader.js'
2
+ import { bindEvents } from '../event-bindings.js'
3
+
4
+ export default function mapAttachment (options = {}) {
5
+ return (element) => {
6
+ console.log('attach', element, options)
7
+ let map
8
+
9
+ function init (options) {
10
+ window.mapboxgl.accessToken = options.accessToken
11
+ const el = new window.mapboxgl.Map(options)
12
+
13
+ return bindEvents(el, handlers, window.mapboxgl, element)
14
+ }
15
+
16
+ const resources = [
17
+ { type: 'script', attr: 'src', value: `//api.mapbox.com/mapbox-gl-js/${options.version}/mapbox-gl.js`, id: 'byk-gl-js' },
18
+ { type: 'link', attr: 'href', value: `//api.mapbox.com/mapbox-gl-js/${options.version}/mapbox-gl.css`, id: 'byk-gl-css' }
19
+ ]
20
+
21
+ const customStylesheetUrl = options.customStylesheetUrl
22
+ if (customStylesheetUrl) {
23
+ resources.push({ type: 'link', attr: 'href', value: customStylesheetUrl, id: 'byk-mcsu-css' })
24
+ }
25
+
26
+ let unbind = () => {}
27
+ load(resources, () => {
28
+ unbind = init({ ...options, container: element })
29
+ })
30
+
31
+ return {
32
+ destroy () {
33
+ unbind()
34
+ map && map.remove && map.remove()
35
+ }
36
+ }
37
+ }
38
+ }
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
+ }
@@ -0,0 +1,31 @@
1
+ export class EventQueue {
2
+ queue = []
3
+ started = false
4
+ map = null
5
+
6
+ send (command, params = []) {
7
+ if (!command) { return }
8
+ this.queue.push([ command, params ])
9
+ this.#process()
10
+ }
11
+
12
+ start (map) {
13
+ this.started = true
14
+ this.map = map
15
+ }
16
+
17
+ #process () {
18
+ if (!this.started) { return }
19
+ while (this.queue.length) {
20
+ const [ command, params ] = this.queue.shift()
21
+ this.map[command].apply(this.map, params)
22
+ }
23
+ }
24
+
25
+ stop () {
26
+ if (!this.started) { return }
27
+ this.queue = []
28
+ this.map = null
29
+ this.started = false
30
+ }
31
+ }
@@ -1,3 +1,51 @@
1
+ <script>
2
+ import { PUBLIC_MAPBOX_TOKEN } from '$env/static/public'
3
+ import { Map, Geocoder, Marker, controls } from '$lib/components.js'
4
+ import Earthquakes from './_Earthquakes.svelte'
5
+
6
+ const { GeolocateControl, NavigationControl } = controls
7
+
8
+ let place = $state(null)
9
+ let page = $state('about')
10
+ let center = $state({ lat: 53.3358627, lng: -2.8572362 })
11
+ let marker = $derived(center)
12
+ let zoom = $state(11.15)
13
+ let mapComponent = $state()
14
+
15
+ function navigate (next) {
16
+ page = next
17
+ }
18
+
19
+ function placeChanged (e) {
20
+ const { result } = e.detail
21
+ mapComponent.setCenter(result.center, 14)
22
+ place = result
23
+ }
24
+
25
+ function randomLng () {
26
+ return 77 + (Math.random() - 0.5) * 30
27
+ }
28
+
29
+ function randomLat () {
30
+ return 13 + (Math.random() - 0.5) * 30
31
+ }
32
+
33
+ function flyToRandomPlace () {
34
+ mapComponent.flyTo({
35
+ center: [ randomLng(), randomLat() ],
36
+ essential: true
37
+ })
38
+ }
39
+
40
+ function recentre (e) {
41
+ center = e.detail.center
42
+ }
43
+
44
+ function drag (e) {
45
+ marker = e.detail.center
46
+ }
47
+ </script>
48
+
1
49
  <header>
2
50
  <div class="container">
3
51
  <div class="row">
@@ -42,39 +90,32 @@
42
90
  <div class="row">
43
91
  <aside>
44
92
  <div class="menu-box">
45
- <h4>Navigation</h4>
93
+ <h4>Navigation</h4>
46
94
  <nav>
47
95
  <ul>
48
- <li><a href="#geocoder" on:click={() => { navigate('geocoder') } } class:current={page === 'geocoder'}>Geocoder</a></li>
49
- <li><a href="#map" on:click={() => { navigate('map') }} class:current={page === 'map'}>Map</a></li>
50
- </ul>
96
+ <li><a href="#geocoder" onclick={() => navigate('geocoder')} class:current={page === 'geocoder'}>Geocoder</a></li>
97
+ <li><a href="#map" onclick={() => navigate('map')} class:current={page === 'map'}>Map</a></li>
98
+ </ul>
51
99
  </nav>
52
100
  </div>
53
101
  </aside>
54
102
  <div class="content-info">
55
103
  <div class="action-buttons">
56
- <button id="fly-to" on:click={flyToRandomPlace}
57
- >Fly to random location</button
58
- >
59
-
60
- <button
61
- id="change-zoom"
62
- on:click={() => (zoom = Math.floor(Math.random() * 10))}
63
- >Change Zoom Level</button
64
- >
65
- </div>
104
+ <button id="fly-to" onclick={flyToRandomPlace}>Fly to random location</button>
105
+ <button id="change-zoom" onclick={() => (zoom = Math.floor(Math.random() * 10))}>Change Zoom Level</button>
106
+ </div>
66
107
 
67
108
  <div class="section-txt" id="geocoder">
68
109
  <form>
69
- <Geocoder value="(Near London)" accessToken={PUBLIC_MAPBOX_TOKEN} on:result={placeChanged} on:clear={() => mapComponent.setCenter({ lng: 0, lat: 0 })} />
70
- {#if place}
71
- <dl>
72
- <dt>Name:</dt>
73
- <dd>{place.label}</dd>
74
- <dt>Geolocation:</dt>
75
- <dd>lat: {place.geometry.lat}, lng: {place.geometry.lng}</dd>
76
- </dl>
77
- {/if}
110
+ <Geocoder value="(Near London)" accessToken={PUBLIC_MAPBOX_TOKEN} onresult={placeChanged} onclear={() => mapComponent.setCenter({ lng: 0, lat: 0 })} />
111
+ {#if place}
112
+ <dl>
113
+ <dt>Name:</dt>
114
+ <dd>{place.place_name}</dd>
115
+ <dt>Geolocation:</dt>
116
+ <dd>lat: {place.geometry.coordinates[1]}, lng: {place.geometry.coordinates[0]}</dd>
117
+ </dl>
118
+ {/if}
78
119
  </form>
79
120
  </div>
80
121
  <div class="section-txt" id="map">
@@ -82,14 +123,14 @@
82
123
  <Map
83
124
  bind:this={mapComponent}
84
125
  accessToken={PUBLIC_MAPBOX_TOKEN}
85
- on:recentre={recentre}
86
- on:drag={drag}
126
+ onrecentre={recentre}
127
+ ondrag={drag}
87
128
  {center}
88
129
  bind:zoom
89
130
  >
90
131
  <Earthquakes />
91
132
  <NavigationControl />
92
- <GeolocateControl on:geolocate={e => console.log('geolocated', e.detail)} />
133
+ <GeolocateControl ongeolocate={e => console.log('geolocated', e.detail)} />
93
134
  <Marker lat={marker.lat} lng={marker.lng} />
94
135
  </Map>
95
136
  </div>
@@ -157,55 +198,4 @@
157
198
  color: #fff;
158
199
  background: #ee8a65;
159
200
  }
160
-
161
201
  </style>
162
-
163
- <script>
164
- import { PUBLIC_MAPBOX_TOKEN } from '$env/static/public'
165
- import { Map, Geocoder, Marker, controls } from '$lib/components.js'
166
- import Earthquakes from './_Earthquakes.svelte'
167
-
168
- const { GeolocateControl, NavigationControl } = controls
169
- const place = null
170
-
171
- let page = 'about'
172
- let center = { lat: 53.3358627, lng: -2.8572362 }
173
- let marker = center
174
- let zoom = 11.15
175
- let mapComponent
176
-
177
- function navigate (next) {
178
- page = next
179
- }
180
-
181
- function placeChanged (e) {
182
- const { result } = e.detail
183
- mapComponent.setCenter(result.center, 14)
184
- }
185
-
186
- function randomLng () {
187
- return 77 + (Math.random() - 0.5) * 30
188
- }
189
-
190
- function randomLat () {
191
- return 13 + (Math.random() - 0.5) * 30
192
- }
193
-
194
- function flyToRandomPlace () {
195
- mapComponent.flyTo({
196
- center: [
197
- randomLng(),
198
- randomLat()
199
- ],
200
- essential: true
201
- })
202
- }
203
-
204
- function recentre ({ detail }) {
205
- center = detail.center
206
- }
207
-
208
- function drag ({ detail }) {
209
- marker = detail.center
210
- }
211
- </script>
package/svelte.config.js CHANGED
@@ -1,5 +1,9 @@
1
1
 
2
2
  /** @type {import('@sveltejs/kit').Config} */
3
- const config = {}
3
+ const config = {
4
+ vitePlugin: {
5
+ inspector: true
6
+ }
7
+ }
4
8
 
5
9
  export default config
@@ -1,21 +0,0 @@
1
- import path from "node:path";
2
- import { fileURLToPath } from "node:url";
3
- import js from "@eslint/js";
4
- import { FlatCompat } from "@eslint/eslintrc";
5
-
6
- const __filename = fileURLToPath(import.meta.url);
7
- const __dirname = path.dirname(__filename);
8
- const compat = new FlatCompat({
9
- baseDirectory: __dirname,
10
- recommendedConfig: js.configs.recommended,
11
- allConfig: js.configs.all
12
- });
13
-
14
- export default [{
15
- ignores: ["**/package", "**/.svelte-kit"],
16
- }, ...compat.extends("@beyonk/eslint-config/svelte"), {
17
- languageOptions: {
18
- ecmaVersion: 2020,
19
- sourceType: "module",
20
- },
21
- }];
@@ -1,60 +0,0 @@
1
- import { load } from '../asset-loader.js'
2
- import { bindEvents } from '../event-bindings.js'
3
-
4
- export default function action (node, options = {}) {
5
- let map
6
-
7
- const resources = [
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' }
9
- ]
10
-
11
- const customStylesheetUrl = options.customStylesheetUrl
12
- if (customStylesheetUrl) {
13
- resources.push({ type: 'link', value: customStylesheetUrl, id: 'byk-gcsu-css' })
14
- } else {
15
- resources.push({ type: 'link', value: `//api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/${options.version}/mapbox-gl-geocoder.css`, id: 'byk-gc-css' })
16
- }
17
-
18
- let unbind = () => {}
19
- load(resources, () => {
20
- unbind = init(options, node)
21
- })
22
-
23
- return {
24
- destroy () {
25
- unbind()
26
- map && map.remove && map.remove()
27
- }
28
- }
29
- }
30
-
31
- function init (options, node) {
32
- const geocoder = new window.MapboxGeocoder(options)
33
- geocoder.addTo(`#${node.id}`)
34
- if (options.value) {
35
- geocoder.setInput(options.value)
36
- }
37
-
38
- return bindEvents(geocoder, handlers, false, node)
39
- }
40
-
41
- const handlers = {
42
- results: (el, ev) => {
43
- return [ 'results', ev ]
44
- },
45
- result: (el, ev) => {
46
- return [ 'result', ev ]
47
- },
48
- loading: (el, ev) => {
49
- return [ 'loading', ev ]
50
- },
51
- error: (el, ev) => {
52
- return [ 'error', ev ]
53
- },
54
- clear: (el, ev) => {
55
- return [ 'clear', ev ]
56
- },
57
- load: el => {
58
- return [ 'ready', { geocoder: el } ]
59
- }
60
- }
@@ -1,62 +0,0 @@
1
- import { load } from '../asset-loader.js'
2
- import { bindEvents } from '../event-bindings.js'
3
-
4
- export default function action (node, options = {}) {
5
- let map
6
-
7
- const resources = [
8
- { type: 'script', attr: 'src', value: `//api.mapbox.com/mapbox-gl-js/${options.version}/mapbox-gl.js`, id: 'byk-gl-js' },
9
- { type: 'link', attr: 'href', value: `//api.mapbox.com/mapbox-gl-js/${options.version}/mapbox-gl.css`, id: 'byk-gl-css' }
10
- ]
11
-
12
- const customStylesheetUrl = options.customStylesheetUrl
13
- if (customStylesheetUrl) {
14
- resources.push({ type: 'link', attr: 'href', value: customStylesheetUrl, id: 'byk-mcsu-css' })
15
- }
16
-
17
- let unbind = () => {}
18
- load(resources, () => {
19
- unbind = init({ ...options, container: node }, node)
20
- })
21
-
22
- return {
23
- destroy () {
24
- unbind()
25
- map && map.remove && map.remove()
26
- }
27
- }
28
- }
29
-
30
- function init (options, node) {
31
- window.mapboxgl.accessToken = options.accessToken
32
- const el = new window.mapboxgl.Map(options)
33
-
34
- return bindEvents(el, handlers, window.mapboxgl, node)
35
- }
36
-
37
- const handlers = {
38
- dragend: el => {
39
- return [ 'dragend', { center: el.getCenter() } ]
40
- },
41
- drag: el => {
42
- return [ 'drag', { center: el.getCenter() } ]
43
- },
44
- moveend: el => {
45
- return [ 'recentre', { center: el.getCenter() } ]
46
- },
47
- click: (el, { lngLat }) => {
48
- return [ 'click', { lng: lngLat.lng, lat: lngLat.lat } ]
49
- },
50
- zoomstart: el => {
51
- return [ 'zoomstart', { zoom: el.getZoom() } ]
52
- },
53
- zoom: el => {
54
- return [ 'zoom', { zoom: el.getZoom() } ]
55
- },
56
- zoomend: el => {
57
- return [ 'zoomend', { zoom: el.getZoom() } ]
58
- },
59
- load: (el, ev, mapbox) => {
60
- return [ 'ready', { map: el, mapbox } ]
61
- }
62
- }
package/src/lib/queue.js DELETED
@@ -1,31 +0,0 @@
1
- import { writable } from 'svelte/store'
2
-
3
- export class EventQueue {
4
- constructor () {
5
- this.queue = writable([])
6
- this.unsubscribe = null
7
- this.started = false
8
- }
9
-
10
- send (command, params = []) {
11
- if (!command) { return }
12
- this.queue.update(q => ([ ...q, [ command, params ] ]))
13
- }
14
-
15
- start (map) {
16
- this.unsubscribe = this.queue.subscribe(queue => {
17
- while (queue.length) {
18
- const [ command, params ] = queue.shift()
19
- map[command].apply(map, params)
20
- }
21
- })
22
- this.started = true
23
- }
24
-
25
- stop () {
26
- if (!this.started) { return }
27
- this.unsubscribe()
28
- this.queue = writable([])
29
- this.started = false
30
- }
31
- }