@versatiles/svelte 0.3.0 → 1.0.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.
Files changed (47) hide show
  1. package/README.md +11 -6
  2. package/dist/components/BBoxMap/AutoComplete.svelte +176 -0
  3. package/dist/components/{AutoComplete.svelte.d.ts → BBoxMap/AutoComplete.svelte.d.ts} +12 -18
  4. package/dist/components/BBoxMap/BBoxMap.svelte +43 -54
  5. package/dist/components/BBoxMap/BBoxMap.svelte.d.ts +6 -17
  6. package/dist/components/BasicMap/BasicMap.svelte +34 -37
  7. package/dist/components/BasicMap/BasicMap.svelte.d.ts +9 -24
  8. package/dist/components/LocatorMap/LocatorMap.svelte +61 -20
  9. package/dist/components/MapEditor/Editor.svelte +25 -0
  10. package/dist/components/MapEditor/Editor.svelte.d.ts +7 -0
  11. package/dist/components/MapEditor/EditorLine.svelte +27 -0
  12. package/dist/components/MapEditor/EditorLine.svelte.d.ts +7 -0
  13. package/dist/components/MapEditor/EditorMarker.svelte +42 -0
  14. package/dist/components/MapEditor/EditorMarker.svelte.d.ts +7 -0
  15. package/dist/components/MapEditor/MapEditor.svelte +99 -0
  16. package/dist/components/MapEditor/MapEditor.svelte.d.ts +4 -0
  17. package/dist/components/MapEditor/editor.scss +16 -0
  18. package/dist/components/MapEditor/lib/element_abstract.d.ts +20 -0
  19. package/dist/components/MapEditor/lib/element_abstract.js +58 -0
  20. package/dist/components/MapEditor/lib/element_line.d.ts +14 -0
  21. package/dist/components/MapEditor/lib/element_line.js +76 -0
  22. package/dist/components/MapEditor/lib/element_marker.d.ts +20 -0
  23. package/dist/components/MapEditor/lib/element_marker.js +191 -0
  24. package/dist/components/MapEditor/lib/geocoder.d.ts +1 -0
  25. package/dist/components/MapEditor/lib/geocoder.js +8 -0
  26. package/dist/components/MapEditor/lib/geometry_manager.d.ts +18 -0
  27. package/dist/components/MapEditor/lib/geometry_manager.js +117 -0
  28. package/dist/components/MapEditor/lib/map_layer.d.ts +14 -0
  29. package/dist/components/MapEditor/lib/map_layer.js +61 -0
  30. package/dist/components/MapEditor/lib/types.d.ts +112 -0
  31. package/dist/components/MapEditor/lib/types.js +1 -0
  32. package/dist/components/MapEditor/lib/utils.d.ts +2 -0
  33. package/dist/components/MapEditor/lib/utils.js +11 -0
  34. package/dist/index.d.ts +2 -1
  35. package/dist/index.js +2 -1
  36. package/dist/utils/draw/bbox.d.ts +4 -10
  37. package/dist/utils/draw/bbox.js +62 -62
  38. package/dist/utils/map_style.d.ts +5 -2
  39. package/dist/utils/map_style.js +13 -6
  40. package/package.json +10 -7
  41. package/dist/components/AutoComplete.svelte +0 -196
  42. package/dist/utils/draw/abstract.d.ts +0 -5
  43. package/dist/utils/draw/abstract.js +0 -2
  44. package/dist/utils/draw/marker.d.ts +0 -24
  45. package/dist/utils/draw/marker.js +0 -97
  46. package/dist/utils/draw/style.d.ts +0 -19
  47. package/dist/utils/draw/style.js +0 -40
@@ -0,0 +1,117 @@
1
+ import { get, writable } from 'svelte/store';
2
+ import { MarkerElement } from './element_marker.js';
3
+ import { LineElement } from './element_line.js';
4
+ export class GeometryManager {
5
+ elements;
6
+ map;
7
+ activeElement = writable(undefined);
8
+ selection_nodes;
9
+ canvas;
10
+ constructor(map) {
11
+ this.elements = writable([]);
12
+ this.map = map;
13
+ this.canvas = this.map.getCanvasContainer();
14
+ map.addSource('selection_nodes', {
15
+ type: 'geojson',
16
+ data: { type: 'FeatureCollection', features: [] }
17
+ });
18
+ this.selection_nodes = map.getSource('selection_nodes');
19
+ map.addLayer({
20
+ id: 'selection_nodes',
21
+ source: 'selection_nodes',
22
+ type: 'circle',
23
+ layout: {},
24
+ paint: {
25
+ 'circle-color': '#ffffff',
26
+ 'circle-opacity': ['get', 'opacity'],
27
+ 'circle-radius': 4,
28
+ 'circle-stroke-color': '#000000',
29
+ 'circle-stroke-opacity': ['get', 'opacity'],
30
+ 'circle-stroke-width': 1.5
31
+ }
32
+ });
33
+ map.on('mousedown', 'selection_nodes', (e) => {
34
+ const element = get(this.activeElement);
35
+ if (element == undefined)
36
+ return;
37
+ const feature = map.queryRenderedFeatures(e.point, { layers: ['selection_nodes'] })[0];
38
+ const updateSelectionNode = element.getSelectionNodeUpdater(feature.properties);
39
+ if (updateSelectionNode == undefined)
40
+ return;
41
+ e.preventDefault();
42
+ const onMove = (e) => {
43
+ e.preventDefault();
44
+ this.canvas.style.cursor = 'grabbing';
45
+ updateSelectionNode(e.lngLat.lng, e.lngLat.lat);
46
+ this.drawSelectionNodes(element.getSelectionNodes());
47
+ };
48
+ const onUp = () => {
49
+ map.off('mousemove', onMove);
50
+ this.canvas.style.cursor = 'default';
51
+ };
52
+ map.once('mouseup', onUp);
53
+ map.on('mousemove', onMove);
54
+ });
55
+ map.on('mouseover', 'selection_nodes', () => (this.canvas.style.cursor = 'move'));
56
+ map.on('mouseout', 'selection_nodes', () => (this.canvas.style.cursor = 'default'));
57
+ map.on('click', (e) => {
58
+ this.setActiveElement(undefined);
59
+ e.preventDefault();
60
+ });
61
+ }
62
+ setActiveElement(element) {
63
+ if (element) {
64
+ if (!get(this.elements).includes(element))
65
+ throw new Error('Element not in list');
66
+ this.drawSelectionNodes(element.getSelectionNodes());
67
+ }
68
+ else {
69
+ this.drawSelectionNodes([]);
70
+ }
71
+ this.activeElement.set(element);
72
+ }
73
+ drawSelectionNodes(nodes) {
74
+ this.selection_nodes.setData({
75
+ type: 'FeatureCollection',
76
+ features: nodes.map((n) => ({
77
+ type: 'Feature',
78
+ properties: { index: n.index, opacity: n.transparent ? 0.3 : 1 },
79
+ geometry: { type: 'Point', coordinates: n.coordinates }
80
+ }))
81
+ });
82
+ }
83
+ getElement(index) {
84
+ return get(this.elements)[index];
85
+ }
86
+ getNewMarker() {
87
+ const element = new MarkerElement(this, this.newName('Marker '));
88
+ this.addElement(element);
89
+ return element;
90
+ }
91
+ getNewLine() {
92
+ const element = new LineElement(this, this.newName('Line '));
93
+ this.addElement(element);
94
+ return element;
95
+ }
96
+ addElement(element) {
97
+ this.elements.update((elements) => [...elements, element]);
98
+ }
99
+ newName(prefix) {
100
+ const set = new Set();
101
+ const elements = get(this.elements);
102
+ elements.forEach((e) => {
103
+ const name = e.name;
104
+ if (!name.startsWith(prefix))
105
+ return;
106
+ const index = name.substring(prefix.length);
107
+ if (!/^[0-9]+/.test(index))
108
+ return;
109
+ set.add(parseInt(index, 10));
110
+ });
111
+ for (let i = 1; i <= elements.length + 1; i++) {
112
+ if (!set.has(i))
113
+ return prefix + i;
114
+ }
115
+ throw new Error('Unreachable');
116
+ }
117
+ }
@@ -0,0 +1,14 @@
1
+ import type { LayerFill, LayerLine, LayerSymbol } from './types.js';
2
+ type LayerSpec = LayerFill | LayerLine | LayerSymbol;
3
+ export declare class MapLayer<T extends LayerSpec> {
4
+ readonly map: maplibregl.Map;
5
+ readonly id: string;
6
+ readonly layoutProperties: T["layout"];
7
+ readonly paintProperties: T["paint"];
8
+ constructor(map: maplibregl.Map, id: string, source: string, type: 'symbol' | 'line' | 'fill');
9
+ setPaint(paint: T['paint']): void;
10
+ updatePaint<K extends keyof T['paint'], V extends T['paint'][K]>(key: K, value: V): void;
11
+ setLayout(layout: T['layout']): void;
12
+ updateLayout<K extends keyof T['layout'], V extends T['layout'][K]>(key: K, value: V): void;
13
+ }
14
+ export {};
@@ -0,0 +1,61 @@
1
+ import { Color } from '@versatiles/style';
2
+ export class MapLayer {
3
+ map;
4
+ id;
5
+ layoutProperties = {};
6
+ paintProperties = {};
7
+ constructor(map, id, source, type) {
8
+ this.map = map;
9
+ this.id = id;
10
+ let filter;
11
+ switch (type) {
12
+ case 'symbol':
13
+ filter = 'Point';
14
+ break;
15
+ case 'line':
16
+ filter = 'LineString';
17
+ break;
18
+ case 'fill':
19
+ filter = 'Polygon';
20
+ break;
21
+ default:
22
+ throw new Error('Invalid layer type');
23
+ }
24
+ this.map.addLayer({
25
+ id,
26
+ source,
27
+ type,
28
+ layout: this.layoutProperties,
29
+ paint: this.paintProperties,
30
+ filter: ['==', '$type', filter]
31
+ }, 'selection_nodes');
32
+ }
33
+ setPaint(paint) {
34
+ if (paint === undefined)
35
+ return;
36
+ const keys = new Set(Object.keys(paint).concat(Object.keys(this.paintProperties)));
37
+ for (const key of keys.values())
38
+ this.updatePaint(key, paint[key]);
39
+ }
40
+ updatePaint(key, value) {
41
+ if (value instanceof Color)
42
+ value = value.asString();
43
+ if (this.paintProperties[key] == value)
44
+ return;
45
+ this.map.setPaintProperty(this.id, key, value);
46
+ this.paintProperties[key] = value;
47
+ }
48
+ setLayout(layout) {
49
+ if (layout === undefined)
50
+ return;
51
+ const keys = new Set(Object.keys(layout).concat(Object.keys(this.layoutProperties)));
52
+ for (const key of keys.values())
53
+ this.updateLayout(key, layout[key]);
54
+ }
55
+ updateLayout(key, value) {
56
+ if (this.layoutProperties[key] == value)
57
+ return;
58
+ this.map.setLayoutProperty(this.id, key, value);
59
+ this.layoutProperties[key] = value;
60
+ }
61
+ }
@@ -0,0 +1,112 @@
1
+ import type { Color } from '@versatiles/style';
2
+ import type { ExpressionSpecification, FormattedSpecification, PaddingSpecification, ResolvedImageSpecification, VariableAnchorOffsetCollectionSpecification } from 'maplibre-gl';
3
+ export interface LayerFill {
4
+ layout: {
5
+ 'fill-sort-key'?: number;
6
+ visibility?: 'visible' | 'none';
7
+ };
8
+ paint: {
9
+ 'fill-antialias'?: boolean;
10
+ 'fill-opacity'?: number;
11
+ 'fill-color'?: string | Color;
12
+ 'fill-outline-color'?: string | Color;
13
+ 'fill-translate'?: [number, number];
14
+ 'fill-translate-anchor'?: 'map' | 'viewport';
15
+ 'fill-pattern'?: ResolvedImageSpecification;
16
+ };
17
+ }
18
+ export interface LayerLine {
19
+ layout: {
20
+ 'line-cap'?: 'butt' | 'round' | 'square';
21
+ 'line-join'?: 'bevel' | 'round' | 'miter';
22
+ 'line-miter-limit'?: number;
23
+ 'line-round-limit'?: number;
24
+ 'line-sort-key'?: number;
25
+ visibility?: 'visible' | 'none';
26
+ };
27
+ paint: {
28
+ 'line-opacity'?: number;
29
+ 'line-color'?: string | Color;
30
+ 'line-translate'?: [number, number];
31
+ 'line-translate-anchor'?: 'map' | 'viewport';
32
+ 'line-width'?: number;
33
+ 'line-gap-width'?: number;
34
+ 'line-offset'?: number;
35
+ 'line-blur'?: number;
36
+ 'line-dasharray'?: Array<number>;
37
+ 'line-pattern'?: ResolvedImageSpecification;
38
+ 'line-gradient'?: ExpressionSpecification;
39
+ };
40
+ }
41
+ export interface LayerSymbol {
42
+ layout: {
43
+ 'symbol-placement'?: 'point' | 'line' | 'line-center';
44
+ 'symbol-spacing'?: number;
45
+ 'symbol-avoid-edges'?: boolean;
46
+ 'symbol-sort-key'?: number;
47
+ 'symbol-z-order'?: 'auto' | 'viewport-y' | 'source';
48
+ 'icon-allow-overlap'?: boolean;
49
+ 'icon-overlap'?: 'never' | 'always' | 'cooperative';
50
+ 'icon-ignore-placement'?: boolean;
51
+ 'icon-optional'?: boolean;
52
+ 'icon-rotation-alignment'?: 'map' | 'viewport' | 'auto';
53
+ 'icon-size'?: number;
54
+ 'icon-text-fit'?: 'none' | 'width' | 'height' | 'both';
55
+ 'icon-text-fit-padding'?: [number, number, number, number];
56
+ 'icon-image'?: ResolvedImageSpecification;
57
+ 'icon-rotate'?: number;
58
+ 'icon-padding'?: PaddingSpecification;
59
+ 'icon-keep-upright'?: boolean;
60
+ 'icon-offset'?: [number, number];
61
+ 'icon-anchor'?: 'center' | 'left' | 'right' | 'top' | 'bottom' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
62
+ 'icon-pitch-alignment'?: 'map' | 'viewport' | 'auto';
63
+ 'text-pitch-alignment'?: 'map' | 'viewport' | 'auto';
64
+ 'text-rotation-alignment'?: 'map' | 'viewport' | 'viewport-glyph' | 'auto';
65
+ 'text-field'?: FormattedSpecification;
66
+ 'text-font'?: Array<string>;
67
+ 'text-size'?: number;
68
+ 'text-max-width'?: number;
69
+ 'text-line-height'?: number;
70
+ 'text-letter-spacing'?: number;
71
+ 'text-justify'?: 'auto' | 'left' | 'center' | 'right';
72
+ 'text-radial-offset'?: number;
73
+ 'text-variable-anchor'?: Array<'center' | 'left' | 'right' | 'top' | 'bottom' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'>;
74
+ 'text-variable-anchor-offset'?: VariableAnchorOffsetCollectionSpecification;
75
+ 'text-anchor'?: 'center' | 'left' | 'right' | 'top' | 'bottom' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
76
+ 'text-max-angle'?: number;
77
+ 'text-writing-mode'?: Array<'horizontal' | 'vertical'>;
78
+ 'text-rotate'?: number;
79
+ 'text-padding'?: number;
80
+ 'text-keep-upright'?: boolean;
81
+ 'text-transform'?: 'none' | 'uppercase' | 'lowercase';
82
+ 'text-offset'?: [number, number];
83
+ 'text-allow-overlap'?: boolean;
84
+ 'text-overlap'?: 'never' | 'always' | 'cooperative';
85
+ 'text-ignore-placement'?: boolean;
86
+ 'text-optional'?: boolean;
87
+ visibility?: 'visible' | 'none';
88
+ };
89
+ paint: {
90
+ 'icon-opacity'?: number;
91
+ 'icon-color'?: string | Color;
92
+ 'icon-halo-color'?: string | Color;
93
+ 'icon-halo-width'?: number;
94
+ 'icon-halo-blur'?: number;
95
+ 'icon-translate'?: [number, number];
96
+ 'icon-translate-anchor'?: 'map' | 'viewport';
97
+ 'text-opacity'?: number;
98
+ 'text-color'?: string | Color;
99
+ 'text-halo-color'?: string | Color;
100
+ 'text-halo-width'?: number;
101
+ 'text-halo-blur'?: number;
102
+ 'text-translate'?: [number, number];
103
+ 'text-translate-anchor'?: 'map' | 'viewport';
104
+ };
105
+ }
106
+ export type ElementPoint = [number, number];
107
+ export type ElementLine = ElementPoint[];
108
+ export interface SelectionNode {
109
+ coordinates: ElementPoint;
110
+ index: number;
111
+ transparent?: boolean;
112
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ import type { ElementPoint } from './types.js';
2
+ export declare function getMiddlePoint(p0: ElementPoint, p1: ElementPoint): ElementPoint;
@@ -0,0 +1,11 @@
1
+ export function getMiddlePoint(p0, p1) {
2
+ const y0 = lat2mercator(p0[1]);
3
+ const y1 = lat2mercator(p1[1]);
4
+ return [(p0[0] + p1[0]) / 2, mercator2lat((y0 + y1) / 2)];
5
+ }
6
+ function lat2mercator(lat) {
7
+ return Math.log(Math.tan(Math.PI / 4 + (lat * Math.PI) / 360));
8
+ }
9
+ function mercator2lat(y) {
10
+ return ((2 * Math.atan(Math.exp(y)) - Math.PI / 2) * 180) / Math.PI;
11
+ }
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import BasicMap from './components/BasicMap/BasicMap.svelte';
2
2
  import BBoxMap from './components/BBoxMap/BBoxMap.svelte';
3
3
  import LocatorMap from './components/LocatorMap/LocatorMap.svelte';
4
- export { BasicMap, BBoxMap, LocatorMap };
4
+ import MapEditor from './components/MapEditor/MapEditor.svelte';
5
+ export { BasicMap, BBoxMap, LocatorMap, MapEditor };
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import BasicMap from './components/BasicMap/BasicMap.svelte';
2
2
  import BBoxMap from './components/BBoxMap/BBoxMap.svelte';
3
3
  import LocatorMap from './components/LocatorMap/LocatorMap.svelte';
4
- export { BasicMap, BBoxMap, LocatorMap };
4
+ import MapEditor from './components/MapEditor/MapEditor.svelte';
5
+ export { BasicMap, BBoxMap, LocatorMap, MapEditor };
@@ -1,6 +1,5 @@
1
1
  import type geojson from 'geojson';
2
- import type { FillStyle, LineStyle } from './style.js';
3
- import { AbstractDrawer } from './abstract.js';
2
+ import { type Writable } from 'svelte/store';
4
3
  type DragPoint = 'n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w' | 'nw' | false;
5
4
  export declare const DragPointMap: Map<DragPoint, {
6
5
  cursor: string;
@@ -8,20 +7,15 @@ export declare const DragPointMap: Map<DragPoint, {
8
7
  flipV: DragPoint;
9
8
  }>;
10
9
  export type BBox = [number, number, number, number];
11
- export declare class BBoxDrawer extends AbstractDrawer<geojson.BBox> {
10
+ export declare class BBoxDrawer {
12
11
  private source?;
13
12
  private dragPoint;
14
13
  private isDragging;
15
14
  private map;
16
15
  private canvas;
17
- private fillStyle;
18
- private lineStyle;
19
16
  private inverted;
20
- private bbox;
21
- constructor(map: maplibregl.Map, options?: {
22
- bbox?: BBox;
23
- inverted?: boolean;
24
- } & LineStyle & FillStyle);
17
+ readonly bbox: Writable<BBox>;
18
+ constructor(map: maplibregl.Map, bbox: BBox, color: string, inverted?: boolean);
25
19
  private updateDragPoint;
26
20
  private getAsFeatureCollection;
27
21
  setGeometry(bbox: geojson.BBox): void;
@@ -1,5 +1,4 @@
1
- import { AbstractDrawer } from './abstract.js';
2
- import { getFillStyle, getLineStyle } from './style.js';
1
+ import { get, writable } from 'svelte/store';
3
2
  const maplibregl = await import('maplibre-gl');
4
3
  const { LngLatBounds } = maplibregl;
5
4
  // prettier-ignore
@@ -15,22 +14,17 @@ export const DragPointMap = new Map([
15
14
  [false, { cursor: 'default', flipH: false, flipV: false }],
16
15
  ]);
17
16
  const worldBBox = [-180, -85, 180, 85];
18
- export class BBoxDrawer extends AbstractDrawer {
17
+ export class BBoxDrawer {
19
18
  source;
20
19
  dragPoint = false;
21
20
  isDragging = false;
22
21
  map;
23
22
  canvas;
24
- fillStyle;
25
- lineStyle;
26
23
  inverted;
27
24
  bbox;
28
- constructor(map, options) {
29
- super();
30
- this.bbox = options?.bbox ?? worldBBox;
31
- this.fillStyle = getFillStyle(options);
32
- this.lineStyle = getLineStyle(options);
33
- this.inverted = options?.inverted ?? true;
25
+ constructor(map, bbox, color, inverted) {
26
+ this.bbox = writable(bbox);
27
+ this.inverted = inverted ?? true;
34
28
  this.map = map;
35
29
  const sourceId = 'bbox_' + Math.random().toString(36).slice(2);
36
30
  if (this.source)
@@ -41,14 +35,16 @@ export class BBoxDrawer extends AbstractDrawer {
41
35
  type: 'line',
42
36
  source: sourceId,
43
37
  filter: ['==', '$type', 'LineString'],
44
- ...this.lineStyle
38
+ layout: { 'line-cap': 'round', 'line-join': 'round' },
39
+ paint: { 'line-color': color }
45
40
  });
46
41
  map.addLayer({
47
42
  id: 'bbox-fill_' + Math.random().toString(36).slice(2),
48
43
  type: 'fill',
49
44
  source: sourceId,
50
45
  filter: ['==', '$type', 'Polygon'],
51
- ...this.fillStyle
46
+ layout: {},
47
+ paint: { 'fill-color': color, 'fill-opacity': 0.2 }
52
48
  });
53
49
  this.source = map.getSource(sourceId);
54
50
  this.canvas = map.getCanvasContainer();
@@ -86,7 +82,7 @@ export class BBoxDrawer extends AbstractDrawer {
86
82
  this.canvas.style.cursor = this.getCursor(dragPoint);
87
83
  }
88
84
  getAsFeatureCollection() {
89
- const ring = getRing(this.bbox);
85
+ const ring = getRing(get(this.bbox));
90
86
  return {
91
87
  type: 'FeatureCollection',
92
88
  features: [
@@ -110,18 +106,19 @@ export class BBoxDrawer extends AbstractDrawer {
110
106
  }
111
107
  }
112
108
  setGeometry(bbox) {
113
- this.bbox = bbox.slice(0, 4);
109
+ this.bbox.set(bbox.slice(0, 4));
114
110
  this.redraw();
115
111
  }
116
112
  getBounds() {
117
- return new LngLatBounds(this.bbox);
113
+ return new LngLatBounds(get(this.bbox));
118
114
  }
119
115
  redraw() {
120
116
  this.source?.setData(this.getAsFeatureCollection());
121
117
  }
122
118
  getAsPixel() {
123
- const p0 = this.map.project([this.bbox[0], this.bbox[1]]);
124
- const p1 = this.map.project([this.bbox[2], this.bbox[3]]);
119
+ const bbox = get(this.bbox);
120
+ const p0 = this.map.project([bbox[0], bbox[1]]);
121
+ const p1 = this.map.project([bbox[2], bbox[3]]);
125
122
  return [Math.min(p0.x, p1.x), Math.min(p0.y, p1.y), Math.max(p0.x, p1.x), Math.max(p0.y, p1.y)];
126
123
  }
127
124
  checkDragPointAt(point) {
@@ -150,49 +147,52 @@ export class BBoxDrawer extends AbstractDrawer {
150
147
  return DragPointMap.get(drag)?.cursor ?? 'default';
151
148
  }
152
149
  doDrag(lngLat) {
153
- const x = Math.round(lngLat.lng * 1e3) / 1e3;
154
- const y = Math.round(lngLat.lat * 1e3) / 1e3;
155
- // prettier-ignore
156
- switch (this.dragPoint) {
157
- case 'n':
158
- this.bbox[3] = y;
159
- break;
160
- case 'ne':
161
- this.bbox[2] = x;
162
- this.bbox[3] = y;
163
- break;
164
- case 'e':
165
- this.bbox[2] = x;
166
- break;
167
- case 'se':
168
- this.bbox[2] = x;
169
- this.bbox[1] = y;
170
- break;
171
- case 's':
172
- this.bbox[1] = y;
173
- break;
174
- case 'sw':
175
- this.bbox[0] = x;
176
- this.bbox[1] = y;
177
- break;
178
- case 'w':
179
- this.bbox[0] = x;
180
- break;
181
- case 'nw':
182
- this.bbox[0] = x;
183
- this.bbox[3] = y;
184
- break;
185
- default: return;
186
- }
187
- if (this.bbox[2] < this.bbox[0]) {
188
- // flip horizontal
189
- this.bbox = [this.bbox[2], this.bbox[1], this.bbox[0], this.bbox[3]];
190
- this.updateDragPoint(DragPointMap.get(this.dragPoint)?.flipH ?? false);
191
- }
192
- if (this.bbox[3] < this.bbox[1]) {
193
- // flip vertical
194
- this.bbox = [this.bbox[0], this.bbox[3], this.bbox[2], this.bbox[1]];
195
- this.updateDragPoint(DragPointMap.get(this.dragPoint)?.flipV ?? false);
196
- }
150
+ this.bbox.update((bbox) => {
151
+ const x = Math.round(lngLat.lng * 1e3) / 1e3;
152
+ const y = Math.round(lngLat.lat * 1e3) / 1e3;
153
+ // prettier-ignore
154
+ switch (this.dragPoint) {
155
+ case 'n':
156
+ bbox[3] = y;
157
+ break;
158
+ case 'ne':
159
+ bbox[2] = x;
160
+ bbox[3] = y;
161
+ break;
162
+ case 'e':
163
+ bbox[2] = x;
164
+ break;
165
+ case 'se':
166
+ bbox[2] = x;
167
+ bbox[1] = y;
168
+ break;
169
+ case 's':
170
+ bbox[1] = y;
171
+ break;
172
+ case 'sw':
173
+ bbox[0] = x;
174
+ bbox[1] = y;
175
+ break;
176
+ case 'w':
177
+ bbox[0] = x;
178
+ break;
179
+ case 'nw':
180
+ bbox[0] = x;
181
+ bbox[3] = y;
182
+ break;
183
+ default: return bbox;
184
+ }
185
+ if (bbox[2] < bbox[0]) {
186
+ // flip horizontal
187
+ bbox = [bbox[2], bbox[1], bbox[0], bbox[3]];
188
+ this.updateDragPoint(DragPointMap.get(this.dragPoint)?.flipH ?? false);
189
+ }
190
+ if (bbox[3] < bbox[1]) {
191
+ // flip vertical
192
+ bbox = [bbox[0], bbox[3], bbox[2], bbox[1]];
193
+ this.updateDragPoint(DragPointMap.get(this.dragPoint)?.flipV ?? false);
194
+ }
195
+ return bbox;
196
+ });
197
197
  }
198
198
  }
@@ -1,3 +1,6 @@
1
1
  import { type StyleBuilderOptions } from '@versatiles/style';
2
- export declare function getMapStyle(darkMode: boolean, styleOptions?: StyleBuilderOptions): import("maplibre-gl").StyleSpecification;
3
- export declare function isDarkMode(element: HTMLElement): boolean;
2
+ export declare function getMapStyle(darkMode: boolean, styleOptions?: StyleBuilderOptions & {
3
+ transitionDuration?: number;
4
+ disableDarkMode?: boolean;
5
+ }): import("maplibre-gl").StyleSpecification;
6
+ export declare function isDarkMode(element?: HTMLElement): boolean;
@@ -1,7 +1,8 @@
1
1
  import { styles } from '@versatiles/style';
2
2
  import { getLanguage } from './location.js';
3
3
  export function getMapStyle(darkMode, styleOptions = {}) {
4
- return styles.colorful({
4
+ darkMode = darkMode && !styleOptions.disableDarkMode;
5
+ const style = styles.colorful({
5
6
  baseUrl: 'https://tiles.versatiles.org',
6
7
  language: getLanguage(),
7
8
  recolor: {
@@ -10,12 +11,18 @@ export function getMapStyle(darkMode, styleOptions = {}) {
10
11
  },
11
12
  ...styleOptions
12
13
  });
14
+ if (styleOptions.transitionDuration != null) {
15
+ style.transition = { duration: styleOptions.transitionDuration, delay: 0 };
16
+ }
17
+ return style;
13
18
  }
14
19
  export function isDarkMode(element) {
15
- const colorScheme = getComputedStyle(element).getPropertyValue('color-scheme');
16
- if (colorScheme.includes('dark'))
17
- return true;
18
- if (colorScheme.includes('light'))
19
- return false;
20
+ if (element != null) {
21
+ const colorScheme = getComputedStyle(element).getPropertyValue('color-scheme');
22
+ if (colorScheme.includes('dark'))
23
+ return true;
24
+ if (colorScheme.includes('light'))
25
+ return false;
26
+ }
20
27
  return window.matchMedia('(prefers-color-scheme: dark)').matches;
21
28
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@versatiles/svelte",
3
- "version": "0.3.0",
3
+ "version": "1.0.1",
4
4
  "license": "MIT",
5
5
  "scripts": {
6
6
  "build": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json && vite build && npm run package",
@@ -13,7 +13,7 @@
13
13
  "prepack": "npm run package",
14
14
  "prepublishOnly": "npm run package",
15
15
  "preview": "vite preview",
16
- "screenshots": "npm run build && npx tsx ./scripts/screenshots.ts",
16
+ "screenshots": "npm run build && npx tsx ./scripts/screenshots.ts && pngquant --nofs --force --ext .png screenshots/*.png && optipng -quiet screenshots/*.png",
17
17
  "release": "npm run build && npx vrt release-npm",
18
18
  "test:integration": "playwright test",
19
19
  "test:unit": "vitest run",
@@ -35,7 +35,8 @@
35
35
  "!dist/BBoxMap/helpers/*"
36
36
  ],
37
37
  "peerDependencies": {
38
- "svelte": "^5.0.3"
38
+ "svelte": "^5.0.3",
39
+ "sass-embedded": "^1.83.4"
39
40
  },
40
41
  "devDependencies": {
41
42
  "@playwright/test": "^1.50.0",
@@ -45,7 +46,7 @@
45
46
  "@sveltejs/vite-plugin-svelte": "^5.0.3",
46
47
  "@turf/turf": "^7.2.0",
47
48
  "@types/eslint": "^9.6.1",
48
- "@types/node": "^22.10.10",
49
+ "@types/node": "^22.12.0",
49
50
  "@versatiles/release-tool": "^1.2.6",
50
51
  "@vitest/coverage-v8": "^3.0.4",
51
52
  "cookie": "^1.0.2",
@@ -59,11 +60,13 @@
59
60
  "prettier": "^3.4.2",
60
61
  "prettier-plugin-svelte": "^3.3.3",
61
62
  "publint": "^0.3.2",
62
- "svelte": "^5.19.3",
63
+ "sass": "^1.83.4",
64
+ "svelte": "^5.19.6",
63
65
  "svelte-check": "^4.1.4",
66
+ "svelte-preprocess": "^6.0.3",
64
67
  "tsx": "^4.19.2",
65
68
  "typescript": "^5.7.3",
66
- "typescript-eslint": "^8.21.0",
69
+ "typescript-eslint": "^8.22.0",
67
70
  "vite": "^6.0.11",
68
71
  "vitest": "^3.0.4"
69
72
  },
@@ -72,6 +75,6 @@
72
75
  "type": "module",
73
76
  "dependencies": {
74
77
  "@versatiles/style": "^5.2.9",
75
- "maplibre-gl": "^5.0.1"
78
+ "maplibre-gl": "^5.1.0"
76
79
  }
77
80
  }