@radiofrance/svelte-leaflet 0.1.0-alpha.0 → 0.1.0-alpha.11

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
@@ -10,16 +10,15 @@ A library that wraps leaflet classes in domless/renderless svelte components.
10
10
 
11
11
  ### Map
12
12
 
13
- Renders a map with the given center and zoom level.
13
+ Renders a map Leaflet Map. The Map will take up 100% of its container's height and width.
14
14
 
15
15
  #### Attributes
16
16
 
17
- | Attribute | Type | Default | Notes |
18
- | ------------- | ----------------------------------------------------- | -------------------------------------------------- | ---------------------------------------------------------------------------------- |
19
- | `center` | [LatLng](https://leafletjs.com/reference.html#latlng) | _required_ | initial center of the map. |
20
- | `zoom` | number | _required_ | initial zoom level |
21
- | `tilesUrl` | string | `'https://tile.openstreetmap.org/{z}/{x}/{y}.png'` | more free tile services can be found at https://alexurquhart.github.io/free-tiles/ |
22
- | `attribution` | string | `'©OpenStreetMap'` _(link to openstreetmap)_ | |
17
+ | Attribute | Type | Default | Notes |
18
+ | ------------- | ------------------------------------------------------------- | -------------------------------------------------- | ---------------------------------------------------------------------------------- |
19
+ | `options` | [MapOptions](https://leafletjs.com/reference.html#map-option) | `{}` | Map options |
20
+ | `tilesUrl` | string | `'https://tile.openstreetmap.org/{z}/{x}/{y}.png'` | more free tile services can be found at https://alexurquhart.github.io/free-tiles/ |
21
+ | `attribution` | string | `'©OpenStreetMap'` _(link to openstreetmap)_ | |
23
22
 
24
23
  #### Events
25
24
 
@@ -30,7 +29,7 @@ All events are forwarded from the Map class, see the leaflet documentation for m
30
29
  Example:
31
30
 
32
31
  ```svelte
33
- <Map {center} {zoom} on:click={(e) => console.log(e.detail.latlng)} />
32
+ <Map {options} on:click={(e) => console.log(e.detail.latlng)} />
34
33
  ```
35
34
 
36
35
  ### Marker
@@ -81,7 +80,7 @@ Enables clustering of child markers
81
80
 
82
81
  ### Polyline
83
82
 
84
- - Allows to draw lines on the map
83
+ Allows to draw lines on the map
85
84
 
86
85
  #### Attributes
87
86
 
@@ -0,0 +1,41 @@
1
+ <script>import { createEventDispatcher, getContext, onDestroy, onMount } from "svelte";
2
+ import {
3
+ bindEvents,
4
+ interactiveLayerEvents,
5
+ layerEvents,
6
+ popupEvents,
7
+ tooltipEvents
8
+ } from "./index.js";
9
+ export let center;
10
+ export let options = { radius: 100 };
11
+ export let instance = void 0;
12
+ const events = [
13
+ "move",
14
+ ...interactiveLayerEvents,
15
+ ...layerEvents,
16
+ ...popupEvents,
17
+ ...tooltipEvents
18
+ ];
19
+ let map = getContext("map")();
20
+ const dispatch = createEventDispatcher();
21
+ $:
22
+ updateCircle(center, options);
23
+ function updateCircle(center2, options2) {
24
+ if (instance) {
25
+ instance.setLatLng(center2);
26
+ instance.setStyle(options2);
27
+ instance.setRadius(options2.radius);
28
+ }
29
+ }
30
+ onMount(async () => {
31
+ const L = window.L;
32
+ instance = new L.Circle(center, options);
33
+ bindEvents(instance, dispatch, events);
34
+ instance.addTo(map);
35
+ });
36
+ onDestroy(() => {
37
+ instance?.remove();
38
+ });
39
+ </script>
40
+
41
+ <slot />
@@ -0,0 +1,36 @@
1
+ import { SvelteComponent } from "svelte";
2
+ import type { Circle as LeafletCircle, LatLngExpression } from 'leaflet';
3
+ declare const __propDef: {
4
+ props: {
5
+ center: LatLngExpression;
6
+ options?: import("leaflet").CircleMarkerOptions | undefined;
7
+ instance?: LeafletCircle | undefined;
8
+ };
9
+ events: {
10
+ click: CustomEvent<import("leaflet").LeafletMouseEvent>;
11
+ dblclick: CustomEvent<import("leaflet").LeafletMouseEvent>;
12
+ mousedown: CustomEvent<import("leaflet").LeafletMouseEvent>;
13
+ mouseup: CustomEvent<import("leaflet").LeafletMouseEvent>;
14
+ mouseover: CustomEvent<import("leaflet").LeafletMouseEvent>;
15
+ mouseout: CustomEvent<import("leaflet").LeafletMouseEvent>;
16
+ contextmenu: CustomEvent<import("leaflet").LeafletMouseEvent>;
17
+ move: CustomEvent<import("leaflet").LeafletEvent>;
18
+ popupopen: CustomEvent<import("leaflet").PopupEvent>;
19
+ popupclose: CustomEvent<import("leaflet").PopupEvent>;
20
+ tooltipopen: CustomEvent<import("leaflet").TooltipEvent>;
21
+ tooltipclose: CustomEvent<import("leaflet").TooltipEvent>;
22
+ add: CustomEvent<import("leaflet").LeafletEvent>;
23
+ remove: CustomEvent<import("leaflet").LeafletEvent>;
24
+ } & {
25
+ [evt: string]: CustomEvent<any>;
26
+ };
27
+ slots: {
28
+ default: {};
29
+ };
30
+ };
31
+ export type CircleProps = typeof __propDef.props;
32
+ export type CircleEvents = typeof __propDef.events;
33
+ export type CircleSlots = typeof __propDef.slots;
34
+ export default class Circle extends SvelteComponent<CircleProps, CircleEvents, CircleSlots> {
35
+ }
36
+ export {};
package/dist/Map.svelte CHANGED
@@ -1,50 +1,119 @@
1
1
  <script>import "leaflet/dist/leaflet.css";
2
2
  import "leaflet.markercluster/dist/MarkerCluster.css";
3
3
  import "leaflet.markercluster/dist/MarkerCluster.Default.css";
4
- import { createEventDispatcher, setContext } from "svelte";
4
+ import markerIcon2x from "leaflet/dist/images/marker-icon-2x.png";
5
+ import markerIcon from "leaflet/dist/images/marker-icon.png";
6
+ import markerShadow from "leaflet/dist/images/marker-shadow.png";
7
+ import { createEventDispatcher, setContext, tick } from "svelte";
8
+ import {
9
+ bindEvents,
10
+ keyboardEvents,
11
+ layerGroupEvents,
12
+ layersControlEvents,
13
+ leafletMouseEvents,
14
+ locationEvents,
15
+ mapStateChangeEvents,
16
+ popupEvents,
17
+ tooltipEvents
18
+ } from "./index.js";
19
+ import GeolocationButton from "./private/GeolocationButton.svelte";
5
20
  let L;
6
- export let center;
7
- export let zoom;
21
+ let locateButtonContainer;
22
+ export let options = {};
8
23
  export let tilesUrl = "https://tile.openstreetmap.org/{z}/{x}/{y}.png";
9
24
  export let attribution = `&copy;<a href="https://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a>`;
25
+ export let instance = null;
26
+ export let locateControl = void 0;
10
27
  const dispatch = createEventDispatcher();
11
- let thisMap;
12
28
  export const getMarkers = () => {
13
29
  const markers = [];
14
- thisMap?.eachLayer((layer) => {
30
+ instance?.eachLayer((layer) => {
15
31
  if (layer instanceof L.Marker) {
16
32
  markers.push(layer);
17
33
  }
18
34
  });
19
35
  return markers;
20
36
  };
21
- export const map = () => thisMap;
22
- setContext("map", () => thisMap);
37
+ setContext("map", () => instance);
23
38
  let container;
24
39
  $:
25
- thisMap?.setView(center, zoom);
40
+ if (instance)
41
+ instance.options = Object.assign(instance.options, options);
26
42
  function resizeMap() {
27
- thisMap?.invalidateSize();
43
+ instance?.invalidateSize();
28
44
  }
45
+ const events = [
46
+ ...keyboardEvents,
47
+ ...layerGroupEvents,
48
+ ...layersControlEvents,
49
+ ...leafletMouseEvents,
50
+ ...locationEvents,
51
+ ...mapStateChangeEvents,
52
+ ...popupEvents,
53
+ ...tooltipEvents,
54
+ "autopanstart",
55
+ "zoomanim"
56
+ ];
29
57
  function onLoad() {
30
58
  L = window.L;
31
- thisMap = L.map(container).on("baselayerchange", (e) => dispatch("baselayerchange", e)).on("overlayadd", (e) => dispatch("overlayadd", e)).on("overlayremove", (e) => dispatch("overlayremove", e)).on("layeradd", (e) => dispatch("layeradd", e)).on("layerremove", (e) => dispatch("layerremove", e)).on("zoomlevelschange", (e) => dispatch("zoomlevelschange", e)).on("resize", (e) => dispatch("resize", e)).on("unload", (e) => dispatch("unload", e)).on("load", (e) => dispatch("load", e)).on("move", (e) => dispatch("move", e)).on("moveend", (e) => dispatch("moveend", e)).on("movestart", (e) => dispatch("movestart", e)).on("viewreset", (e) => dispatch("viewreset", e)).on("zoom", (e) => dispatch("zoom", e)).on("zoomend", (e) => dispatch("zoomend", e)).on("zoomstart", (e) => dispatch("zoomstart", e)).on("autopanstart", (e) => dispatch("autopanstart", e)).on("popupclose", (e) => dispatch("popupclose", e)).on("popupopen", (e) => dispatch("popupopen", e)).on("tooltipclose", (e) => dispatch("tooltipclose", e)).on("tooltipopen", (e) => dispatch("tooltipopen", e)).on("locationerror", (e) => dispatch("locationerror", e)).on("locationfound", (e) => dispatch("locationfound", e)).on("click", (e) => dispatch("click", e)).on("contextmenu", (e) => dispatch("contextmenu", e)).on("dblclick", (e) => dispatch("dblclick", e)).on("keydown", (e) => dispatch("keydown", e)).on("keypress", (e) => dispatch("keypress", e)).on("keyup", (e) => dispatch("keyup", e)).on("mousedown", (e) => dispatch("mousedown", e)).on("mousemove", (e) => dispatch("mousemove", e)).on("mouseout", (e) => dispatch("mouseout", e)).on("mouseover", (e) => dispatch("mouseover", e)).on("mouseup", (e) => dispatch("mouseup", e)).on("preclick", (e) => dispatch("preclick", e)).on("zoomanim", (e) => dispatch("zoomanim", e)).setView(center, zoom).setMinZoom(5).setMaxZoom(20);
59
+ delete L.Icon.Default.prototype._getIconUrl;
60
+ L.Icon.Default.mergeOptions({
61
+ iconRetinaUrl: markerIcon2x,
62
+ iconUrl: markerIcon,
63
+ shadowUrl: markerShadow
64
+ });
65
+ instance = L.map(container, { maxZoom: 18, ...options });
66
+ bindEvents(instance, dispatch, events);
32
67
  L.tileLayer(tilesUrl, {
33
- attribution,
34
- maxZoom: 20
35
- }).addTo(thisMap);
68
+ attribution
69
+ }).addTo(instance);
70
+ instance.whenReady(async () => {
71
+ instance.fireEvent("load");
72
+ await tick();
73
+ if (locateControl) {
74
+ const control = L.Control.extend({
75
+ position: "topleft",
76
+ onAdd() {
77
+ const button = locateButtonContainer.firstChild;
78
+ button.onclick = (e) => {
79
+ e.stopPropagation();
80
+ instance.locate(locateControl?.options);
81
+ };
82
+ return button;
83
+ }
84
+ });
85
+ instance.addControl(new control(locateControl));
86
+ }
87
+ });
36
88
  }
37
89
  function leafletLoader(_node) {
38
- import("leaflet").then(() => {
39
- import("leaflet.markercluster").then(onLoad);
40
- });
90
+ (async function() {
91
+ await import("leaflet");
92
+ await import("leaflet.markercluster");
93
+ onLoad();
94
+ })();
41
95
  }
42
96
  </script>
43
97
 
44
98
  <svelte:window on:resize={resizeMap} use:leafletLoader />
45
99
 
46
100
  <div class="Map" bind:this={container} style="height: 100%; width: 100%">
47
- {#if thisMap}
48
- <slot map={thisMap} />
101
+ {#if instance}
102
+ <slot map={instance} />
49
103
  {/if}
50
104
  </div>
105
+ <div class="locate-button-container" bind:this={locateButtonContainer}>
106
+ <slot name="locate-button">
107
+ <GeolocationButton />
108
+ </slot>
109
+ </div>
110
+
111
+ <style>
112
+ .Map {
113
+ z-index: 0;
114
+ }
115
+
116
+ .locate-button-container {
117
+ display: none;
118
+ }
119
+ </style>
@@ -1,55 +1,56 @@
1
1
  import { SvelteComponent } from "svelte";
2
- import type { LatLngExpression, Map, Marker } from 'leaflet';
2
+ import type { MapOptions, Marker, Map } from 'leaflet';
3
3
  import type Leaflet from 'leaflet';
4
4
  import 'leaflet/dist/leaflet.css';
5
5
  import 'leaflet.markercluster/dist/MarkerCluster.css';
6
6
  import 'leaflet.markercluster/dist/MarkerCluster.Default.css';
7
+ import { type LocateControlOptions } from './index.js';
7
8
  declare const __propDef: {
8
9
  props: {
9
- center: LatLngExpression;
10
- zoom: number;
10
+ options?: MapOptions | undefined;
11
11
  tilesUrl?: string | undefined;
12
12
  attribution?: string | undefined;
13
- getMarkers?: (() => Leaflet.Marker[]) | undefined;
14
- map?: (() => Map) | undefined;
13
+ instance?: Map | undefined;
14
+ locateControl?: LocateControlOptions | undefined;
15
+ getMarkers?: (() => Marker[]) | undefined;
15
16
  };
16
17
  events: {
17
- baselayerchange: CustomEvent<any>;
18
- overlayadd: CustomEvent<any>;
19
- overlayremove: CustomEvent<any>;
20
- layeradd: CustomEvent<any>;
21
- layerremove: CustomEvent<any>;
22
- zoomlevelschange: CustomEvent<any>;
23
- resize: CustomEvent<any>;
24
- unload: CustomEvent<any>;
25
- load: CustomEvent<any>;
26
- move: CustomEvent<any>;
27
- moveend: CustomEvent<any>;
28
- movestart: CustomEvent<any>;
29
- viewreset: CustomEvent<any>;
30
- zoom: CustomEvent<any>;
31
- zoomend: CustomEvent<any>;
32
- zoomstart: CustomEvent<any>;
33
- autopanstart: CustomEvent<any>;
34
- popupclose: CustomEvent<any>;
35
- popupopen: CustomEvent<any>;
36
- tooltipclose: CustomEvent<any>;
37
- tooltipopen: CustomEvent<any>;
38
- locationerror: CustomEvent<any>;
39
- locationfound: CustomEvent<any>;
40
- click: CustomEvent<any>;
41
- contextmenu: CustomEvent<any>;
42
- dblclick: CustomEvent<any>;
43
- keydown: CustomEvent<any>;
44
- keypress: CustomEvent<any>;
45
- keyup: CustomEvent<any>;
46
- mousedown: CustomEvent<any>;
47
- mousemove: CustomEvent<any>;
48
- mouseout: CustomEvent<any>;
49
- mouseover: CustomEvent<any>;
50
- mouseup: CustomEvent<any>;
51
- preclick: CustomEvent<any>;
52
- zoomanim: CustomEvent<any>;
18
+ keypress: CustomEvent<Leaflet.LeafletKeyboardEvent>;
19
+ keydown: CustomEvent<Leaflet.LeafletKeyboardEvent>;
20
+ keyup: CustomEvent<Leaflet.LeafletKeyboardEvent>;
21
+ layeradd: CustomEvent<Leaflet.LayerEvent>;
22
+ layerremove: CustomEvent<Leaflet.LayerEvent>;
23
+ baselayerchange: CustomEvent<Leaflet.LayersControlEvent>;
24
+ overlayadd: CustomEvent<Leaflet.LayersControlEvent>;
25
+ overlayremove: CustomEvent<Leaflet.LayersControlEvent>;
26
+ click: CustomEvent<Leaflet.LeafletMouseEvent>;
27
+ dblclick: CustomEvent<Leaflet.LeafletMouseEvent>;
28
+ mousedown: CustomEvent<Leaflet.LeafletMouseEvent>;
29
+ mouseup: CustomEvent<Leaflet.LeafletMouseEvent>;
30
+ mouseover: CustomEvent<Leaflet.LeafletMouseEvent>;
31
+ mouseout: CustomEvent<Leaflet.LeafletMouseEvent>;
32
+ contextmenu: CustomEvent<Leaflet.LeafletMouseEvent>;
33
+ mousemove: CustomEvent<Leaflet.LeafletMouseEvent>;
34
+ preclick: CustomEvent<Leaflet.LeafletMouseEvent>;
35
+ locationfound: CustomEvent<Leaflet.LocationEvent>;
36
+ locationerror: CustomEvent<Leaflet.ErrorEvent>;
37
+ load: CustomEvent<Leaflet.LeafletEvent>;
38
+ move: CustomEvent<Leaflet.LeafletEvent>;
39
+ moveend: CustomEvent<Leaflet.LeafletEvent>;
40
+ movestart: CustomEvent<Leaflet.LeafletEvent>;
41
+ unload: CustomEvent<Leaflet.LeafletEvent>;
42
+ viewreset: CustomEvent<Leaflet.LeafletEvent>;
43
+ zoom: CustomEvent<Leaflet.LeafletEvent>;
44
+ zoomend: CustomEvent<Leaflet.LeafletEvent>;
45
+ zoomlevelschange: CustomEvent<Leaflet.LeafletEvent>;
46
+ zoomstart: CustomEvent<Leaflet.LeafletEvent>;
47
+ resize: CustomEvent<Leaflet.ResizeEvent>;
48
+ popupopen: CustomEvent<Leaflet.PopupEvent>;
49
+ popupclose: CustomEvent<Leaflet.PopupEvent>;
50
+ tooltipopen: CustomEvent<Leaflet.TooltipEvent>;
51
+ tooltipclose: CustomEvent<Leaflet.TooltipEvent>;
52
+ autopanstart: CustomEvent<Leaflet.LeafletEvent>;
53
+ zoomanim: CustomEvent<Leaflet.LeafletEvent>;
53
54
  } & {
54
55
  [evt: string]: CustomEvent<any>;
55
56
  };
@@ -57,6 +58,7 @@ declare const __propDef: {
57
58
  default: {
58
59
  map: Map;
59
60
  };
61
+ 'locate-button': {};
60
62
  };
61
63
  };
62
64
  export type MapProps = typeof __propDef.props;
@@ -64,6 +66,5 @@ export type MapEvents = typeof __propDef.events;
64
66
  export type MapSlots = typeof __propDef.slots;
65
67
  export default class Map extends SvelteComponent<MapProps, MapEvents, MapSlots> {
66
68
  get getMarkers(): () => Marker<any>[];
67
- get map(): () => Map;
68
69
  }
69
70
  export {};
@@ -6,29 +6,28 @@ const L = globalThis.window.L;
6
6
  export let size = 25;
7
7
  export let latlng;
8
8
  export let id = "";
9
+ export let options = {};
9
10
  let markerElement;
10
11
  let marker;
11
12
  const getMap = getContext("map");
12
13
  const getLayerGroup = getContext("layerGroup");
13
14
  setContext("layer", () => marker);
14
15
  $:
15
- recreateMarker(size, latlng, id);
16
- async function recreateMarker(size2, latlng2, id2) {
16
+ recreateMarker(size, latlng, id, options);
17
+ async function recreateMarker(size2, latlng2, id2, options2) {
17
18
  removeMarker();
18
19
  await tick();
19
- createMarker(size2, latlng2, id2);
20
+ createMarker(size2, latlng2, id2, options2);
20
21
  }
21
- async function createMarker(size2, latlng2, id2) {
22
+ async function createMarker(size2, latlng2, id2, options2) {
22
23
  await tick();
23
24
  const layerGroup = getLayerGroup?.();
24
25
  const map = getMap();
25
26
  const mapOrLayerGroup = layerGroup || map;
26
- const markerOptions = {};
27
- marker = L.marker(latlng2, markerOptions);
27
+ marker = L.marker(latlng2, options2);
28
28
  marker.id = id2;
29
- marker.on("click", (e) => dispatch("click", e)).on("dblclick", (e) => dispatch("dblclick", e)).on("contextmenu", (e) => dispatch("contextmenu", e));
29
+ marker.on("click", (e) => dispatch("click", e)).on("dblclick", (e) => dispatch("dblclick", e)).on("contextmenu", (e) => dispatch("contextmenu", e)).on("dragstart", (e) => dispatch("dragstart", e)).on("drag", (e) => dispatch("drag", e)).on("dragend", (e) => dispatch("dragend", e));
30
30
  mapOrLayerGroup.addLayer(marker);
31
- const icon = marker.getIcon();
32
31
  await tick();
33
32
  if (markerElement.childElementCount > 0) {
34
33
  marker.setIcon(
@@ -3,17 +3,21 @@ type MarkerContext = {
3
3
  id?: string;
4
4
  };
5
5
  export type Marker = LeafletMarker & MarkerContext;
6
- import type { LatLngExpression, Marker as LeafletMarker } from 'leaflet';
6
+ import type { LatLngExpression, Marker as LeafletMarker, MarkerOptions } from 'leaflet';
7
7
  declare const __propDef: {
8
8
  props: {
9
9
  size?: number | undefined;
10
10
  latlng: LatLngExpression;
11
11
  id?: string | undefined;
12
+ options?: MarkerOptions | undefined;
12
13
  };
13
14
  events: {
14
15
  click: CustomEvent<any>;
15
16
  dblclick: CustomEvent<any>;
16
17
  contextmenu: CustomEvent<any>;
18
+ dragstart: CustomEvent<any>;
19
+ drag: CustomEvent<any>;
20
+ dragend: CustomEvent<any>;
17
21
  } & {
18
22
  [evt: string]: CustomEvent<any>;
19
23
  };
@@ -1,14 +1,44 @@
1
- <script>import { getContext, onMount, setContext } from "svelte";
1
+ <script>import { getContext, onMount, setContext, tick } from "svelte";
2
2
  export let options = {};
3
+ export let icon = null;
4
+ let markerElement;
3
5
  const L = globalThis.window.L;
4
6
  const getMap = getContext("map");
5
- let markers;
6
- setContext("layerGroup", () => markers);
7
+ let clusterGroup;
8
+ setContext("layerGroup", () => clusterGroup);
7
9
  onMount(async () => {
8
10
  const map = getMap();
9
- markers = L.markerClusterGroup(options);
10
- map.addLayer(markers);
11
+ if (icon) {
12
+ options.iconCreateFunction = function(cluster) {
13
+ const html = document.createElement("div");
14
+ new icon({ target: html, props: { count: cluster.getChildCount() } });
15
+ return L.divIcon({ html });
16
+ };
17
+ }
18
+ if (markerElement.childElementCount > 0) {
19
+ options.iconCreateFunction = function(cluster) {
20
+ const html = markerElement.innerHTML.replace("%count%", cluster.getChildCount().toString());
21
+ return L.divIcon({ html });
22
+ };
23
+ }
24
+ clusterGroup = L.markerClusterGroup(options);
25
+ map.addLayer(clusterGroup);
11
26
  });
12
27
  </script>
13
28
 
14
29
  <slot />
30
+ <template>
31
+ <div bind:this={markerElement} class="leaflet-markercluster">
32
+ <slot name="icon" />
33
+ </div>
34
+ </template>
35
+
36
+ <style>
37
+ /* .leaflet-markercluster {
38
+ display: none;
39
+ }
40
+
41
+ :global(.map-marker .leaflet-markercluster) {
42
+ display: inherit;
43
+ } */
44
+ </style>
@@ -3,12 +3,14 @@ import type { MarkerClusterGroupOptions } from 'leaflet';
3
3
  declare const __propDef: {
4
4
  props: {
5
5
  options?: MarkerClusterGroupOptions | undefined;
6
+ icon?: any;
6
7
  };
7
8
  events: {
8
9
  [evt: string]: CustomEvent<any>;
9
10
  };
10
11
  slots: {
11
12
  default: {};
13
+ icon: {};
12
14
  };
13
15
  };
14
16
  export type MarkerClusterGroupProps = typeof __propDef.props;
@@ -14,7 +14,7 @@ function updateLine(latLngs, lineStyle) {
14
14
  }
15
15
  onMount(async () => {
16
16
  const L = window.L;
17
- line = new L.Polyline(latlngs);
17
+ line = new L.Polyline(latlngs, options);
18
18
  line.on("click", (e) => dispatch("click", e));
19
19
  line.addTo(map);
20
20
  });
package/dist/Popup.svelte CHANGED
@@ -20,17 +20,19 @@ async function createPopup() {
20
20
  layer = getLayer();
21
21
  popup = L.popup().setContent(popupElement);
22
22
  layer.bindPopup(popup, options);
23
- layer.on("popupopen", () => {
23
+ layer.on("popupopen", async () => {
24
24
  popupOpen = true;
25
25
  showContents = true;
26
+ await tick();
27
+ popup?.update();
26
28
  });
27
- layer.on("popupclose", () => {
29
+ layer.on("popupclose", async () => {
28
30
  popupOpen = false;
29
31
  setTimeout(() => {
30
32
  if (!popupOpen) {
31
33
  showContents = false;
32
34
  }
33
- }, 500);
35
+ }, 200);
34
36
  });
35
37
  }
36
38
  onMount(createPopup);
package/dist/index.d.ts CHANGED
@@ -1,6 +1,58 @@
1
+ import type { ControlPosition, DragEndEvent, ErrorEvent, Evented, LayerEvent, LayersControlEvent, LeafletEvent, LeafletKeyboardEvent, LeafletMouseEvent, LocateOptions, LocationEvent, PopupEvent, ResizeEvent, TooltipEvent } from 'leaflet';
2
+ import type { EventDispatcher } from 'svelte';
1
3
  export { default as Map } from './Map.svelte';
2
4
  export { default as Marker } from './Marker.svelte';
3
5
  export { default as MarkerClusterGroup } from './MarkerClusterGroup.svelte';
4
6
  export { default as Polyline } from './Polyline.svelte';
5
7
  export { default as Popup } from './Popup.svelte';
6
- export type { LatLngTuple, LatLng, LatLngExpression } from 'leaflet';
8
+ export { default as Circle } from './Circle.svelte';
9
+ export type { Marker as LeafletMarker } from './Marker.svelte';
10
+ export type { Circle as LeafletCircle, CircleOptions, DragEndEvent, ErrorEvent, LatLngExpression, LatLngLiteral, LatLngTuple, LayerEvent, LayersControlEvent, LeafletEvent, LeafletKeyboardEvent, LeafletMouseEvent, LocationEvent, Map as LeafletMap, MapOptions, MarkerOptions, PathOptions, PopupEvent, PopupOptions, ResizeEvent, TooltipEvent } from 'leaflet';
11
+ export declare function bindEvents(instance: Evented, dispatch: EventDispatcher<Record<string, unknown>>, events: readonly string[]): void;
12
+ export declare const interactiveLayerEvents: readonly ["click", "dblclick", "mousedown", "mouseup", "mouseover", "mouseout", "contextmenu"];
13
+ export declare const keyboardEvents: readonly ["keypress", "keydown", "keyup"];
14
+ export declare const locationEvents: readonly ["locationfound", "locationerror"];
15
+ export declare const leafletMouseEvents: readonly ["click", "dblclick", "mousedown", "mouseup", "mouseover", "mouseout", "contextmenu", "mousemove", "preclick"];
16
+ export declare const layerEvents: readonly ["add", "remove"];
17
+ export declare const popupEvents: readonly ["popupopen", "popupclose"];
18
+ export declare const tooltipEvents: readonly ["tooltipopen", "tooltipclose"];
19
+ export declare const layerGroupEvents: readonly ["layeradd", "layerremove"];
20
+ export declare const layersControlEvents: readonly ["baselayerchange", "overlayadd", "overlayremove"];
21
+ declare const leafletEvents: readonly ["load", "move", "moveend", "movestart", "unload", "viewreset", "zoom", "zoomend", "zoomlevelschange", "zoomstart"];
22
+ export declare const mapStateChangeEvents: readonly ["load", "move", "moveend", "movestart", "unload", "viewreset", "zoom", "zoomend", "zoomlevelschange", "zoomstart", "resize"];
23
+ type LeafletEventTypes = {
24
+ resize: ResizeEvent;
25
+ locationerror: ErrorEvent;
26
+ locationfound: LocationEvent;
27
+ add: LeafletEvent;
28
+ remove: LeafletEvent;
29
+ dragend: DragEndEvent;
30
+ } & LeafletEvents & LayersControlEvents & MouseEvents & PopupEvents & TooltipEvents & LayerGroupEvents & KeyboardEvents;
31
+ type LeafletEvents = {
32
+ [K in (typeof leafletEvents)[number]]: LeafletEvent;
33
+ };
34
+ type LayersControlEvents = {
35
+ [K in (typeof layersControlEvents)[number]]: LayersControlEvent;
36
+ };
37
+ type MouseEvents = {
38
+ [K in (typeof leafletMouseEvents)[number]]: LeafletMouseEvent;
39
+ };
40
+ type PopupEvents = {
41
+ [K in (typeof popupEvents)[number]]: PopupEvent;
42
+ };
43
+ type TooltipEvents = {
44
+ [K in (typeof tooltipEvents)[number]]: TooltipEvent;
45
+ };
46
+ type LayerGroupEvents = {
47
+ [K in (typeof layerGroupEvents)[number]]: LayerEvent;
48
+ };
49
+ type KeyboardEvents = {
50
+ [K in (typeof keyboardEvents)[number]]: LeafletKeyboardEvent;
51
+ };
52
+ export type LeafletEventsRecord<T extends readonly string[]> = {
53
+ [K in T[number]]: K extends keyof LeafletEventTypes ? LeafletEventTypes[K] : LeafletEvent;
54
+ };
55
+ export type LocateControlOptions = {
56
+ position?: ControlPosition;
57
+ options?: LocateOptions;
58
+ };
package/dist/index.js CHANGED
@@ -4,3 +4,54 @@ export { default as Marker } from './Marker.svelte';
4
4
  export { default as MarkerClusterGroup } from './MarkerClusterGroup.svelte';
5
5
  export { default as Polyline } from './Polyline.svelte';
6
6
  export { default as Popup } from './Popup.svelte';
7
+ export { default as Circle } from './Circle.svelte';
8
+ export function bindEvents(instance, dispatch, events) {
9
+ events.forEach((event) => {
10
+ instance.on(event, (e) => dispatch(event, e));
11
+ });
12
+ }
13
+ // export const leafletEvents = [
14
+ // 'dragstart',
15
+ // 'drag',
16
+ // 'add',
17
+ // 'remove',
18
+ // 'loading',
19
+ // 'error',
20
+ // 'update',
21
+ // 'down',
22
+ // 'predrag'
23
+ // ] as const;
24
+ // export const resizeEvents = ['resize'] as const;
25
+ // export const zoomAnimEvents = ['zoomanim'] as const;
26
+ // export const tileEvents = ['tileunload', 'tileloadstart', 'tileload', 'tileabort'] as const;
27
+ // export const tileErrorEvents = ['tileerror'] as const;
28
+ export const interactiveLayerEvents = [
29
+ 'click',
30
+ 'dblclick',
31
+ 'mousedown',
32
+ 'mouseup',
33
+ 'mouseover',
34
+ 'mouseout',
35
+ 'contextmenu'
36
+ ];
37
+ export const keyboardEvents = ['keypress', 'keydown', 'keyup'];
38
+ export const locationEvents = ['locationfound', 'locationerror'];
39
+ export const leafletMouseEvents = [...interactiveLayerEvents, 'mousemove', 'preclick'];
40
+ export const layerEvents = ['add', 'remove'];
41
+ export const popupEvents = ['popupopen', 'popupclose'];
42
+ export const tooltipEvents = ['tooltipopen', 'tooltipclose'];
43
+ export const layerGroupEvents = ['layeradd', 'layerremove'];
44
+ export const layersControlEvents = ['baselayerchange', 'overlayadd', 'overlayremove'];
45
+ const leafletEvents = [
46
+ 'load',
47
+ 'move',
48
+ 'moveend',
49
+ 'movestart',
50
+ 'unload',
51
+ 'viewreset',
52
+ 'zoom',
53
+ 'zoomend',
54
+ 'zoomlevelschange',
55
+ 'zoomstart'
56
+ ];
57
+ export const mapStateChangeEvents = [...leafletEvents, 'resize'];
@@ -0,0 +1,32 @@
1
+ <script>
2
+ import GeolocationIcon from './GeolocationIcon.svelte';
3
+ </script>
4
+
5
+ <div>
6
+ <button>
7
+ <GeolocationIcon width="1rem" />
8
+ </button>
9
+ </div>
10
+
11
+ <style>
12
+ button {
13
+ display: flex;
14
+ align-items: center;
15
+ justify-content: center;
16
+ width: 30px;
17
+ height: 30px;
18
+ background-color: white;
19
+ cursor: pointer;
20
+ border: none;
21
+ border-radius: 2px;
22
+ }
23
+
24
+ button:hover {
25
+ background-color: #f4f4f4;
26
+ }
27
+
28
+ div {
29
+ border-radius: 4px;
30
+ border: 2px solid rgba(0, 0, 0, 0.2);
31
+ }
32
+ </style>
@@ -0,0 +1,23 @@
1
+ /** @typedef {typeof __propDef.props} GeolocationButtonProps */
2
+ /** @typedef {typeof __propDef.events} GeolocationButtonEvents */
3
+ /** @typedef {typeof __propDef.slots} GeolocationButtonSlots */
4
+ export default class GeolocationButton extends SvelteComponent<{
5
+ [x: string]: never;
6
+ }, {
7
+ [evt: string]: CustomEvent<any>;
8
+ }, {}> {
9
+ }
10
+ export type GeolocationButtonProps = typeof __propDef.props;
11
+ export type GeolocationButtonEvents = typeof __propDef.events;
12
+ export type GeolocationButtonSlots = typeof __propDef.slots;
13
+ import { SvelteComponent } from "svelte";
14
+ declare const __propDef: {
15
+ props: {
16
+ [x: string]: never;
17
+ };
18
+ events: {
19
+ [evt: string]: CustomEvent<any>;
20
+ };
21
+ slots: {};
22
+ };
23
+ export {};
@@ -0,0 +1,20 @@
1
+ <script>export let width = "32";
2
+ </script>
3
+
4
+ <svg
5
+ {width}
6
+ viewBox="0 0 16 16"
7
+ version="1.1"
8
+ xmlns="http://www.w3.org/2000/svg"
9
+ xmlns:xlink="http://www.w3.org/1999/xlink"
10
+ fill="#000000"
11
+ >
12
+ <g id="SVGRepo_bgCarrier" stroke-width="0"></g>
13
+ <g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g>
14
+ <g id="SVGRepo_iconCarrier">
15
+ <rect width="16" height="16" id="icon-bound" fill="none"></rect>
16
+ <path
17
+ d="M13.916,7C13.494,4.488,11.512,2.506,9,2.084V0H7v2.084C4.488,2.506,2.506,4.488,2.084,7H0v2h2.084 C2.506,11.512,4.488,13.494,7,13.916V16h2v-2.084c2.512-0.422,4.494-2.403,4.916-4.916H16V7H13.916z M10.828,10.828 C10.072,11.584,9.069,12,8,12s-2.072-0.416-2.828-1.172S4,9.069,4,8s0.416-2.072,1.172-2.828S6.931,4,8,4s2.072,0.416,2.828,1.172 S12,6.931,12,8S11.584,10.072,10.828,10.828z M8,6C6.897,6,6,6.897,6,8s0.897,2,2,2s2-0.897,2-2S9.103,6,8,6z"
18
+ ></path>
19
+ </g>
20
+ </svg>
@@ -0,0 +1,16 @@
1
+ import { SvelteComponent } from "svelte";
2
+ declare const __propDef: {
3
+ props: {
4
+ width?: string | undefined;
5
+ };
6
+ events: {
7
+ [evt: string]: CustomEvent<any>;
8
+ };
9
+ slots: {};
10
+ };
11
+ export type GeolocationIconProps = typeof __propDef.props;
12
+ export type GeolocationIconEvents = typeof __propDef.events;
13
+ export type GeolocationIconSlots = typeof __propDef.slots;
14
+ export default class GeolocationIcon extends SvelteComponent<GeolocationIconProps, GeolocationIconEvents, GeolocationIconSlots> {
15
+ }
16
+ export {};
package/package.json CHANGED
@@ -1,7 +1,14 @@
1
1
  {
2
2
  "name": "@radiofrance/svelte-leaflet",
3
- "version": "0.1.0-alpha.0",
3
+ "version": "0.1.0-alpha.11",
4
4
  "description": "A library that wraps leaflet classes in domless/renderless svelte components.",
5
+ "keywords": [
6
+ "svelte",
7
+ "leaflet",
8
+ "map",
9
+ "cartography",
10
+ "sveltekit"
11
+ ],
5
12
  "author": {
6
13
  "email": "romain.durand@radiofrance.com",
7
14
  "name": "Romain Durand"
@@ -47,8 +54,6 @@
47
54
  "@types/d3-scale": "^4.0.8",
48
55
  "@types/d3-scale-chromatic": "^3.0.3",
49
56
  "@types/eslint": "8.56.0",
50
- "@types/leaflet": "^1.9.8",
51
- "@types/leaflet.markercluster": "^1.5.4",
52
57
  "@typescript-eslint/eslint-plugin": "^6.0.0",
53
58
  "@typescript-eslint/parser": "^6.0.0",
54
59
  "d3-scale": "^4.0.2",
@@ -56,8 +61,6 @@
56
61
  "eslint": "^8.56.0",
57
62
  "eslint-config-prettier": "^9.1.0",
58
63
  "eslint-plugin-svelte": "^2.35.1",
59
- "leaflet": "^1.9.4",
60
- "leaflet.markercluster": "^1.5.3",
61
64
  "prettier": "^3.1.1",
62
65
  "prettier-plugin-svelte": "^3.1.2",
63
66
  "publint": "^0.1.9",
@@ -66,9 +69,20 @@
66
69
  "tslib": "^2.4.1",
67
70
  "typescript": "^5.0.0",
68
71
  "vite": "^5.0.11",
69
- "vitest": "^1.2.0"
72
+ "vitest": "^1.6.0"
70
73
  },
71
74
  "svelte": "./dist/index.js",
72
75
  "types": "./dist/index.d.ts",
73
- "type": "module"
76
+ "type": "module",
77
+ "private": false,
78
+ "publishConfig": {
79
+ "access": "public",
80
+ "registry": "https://registry.npmjs.org/"
81
+ },
82
+ "dependencies": {
83
+ "@types/leaflet": "^1.9.12",
84
+ "@types/leaflet.markercluster": "^1.5.4",
85
+ "leaflet": "^1.9.4",
86
+ "leaflet.markercluster": "^1.5.3"
87
+ }
74
88
  }