@versatiles/svelte 2.1.8 → 2.2.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.
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
function onFocus() {
|
|
49
|
-
inputElement.setSelectionRange(0,
|
|
49
|
+
inputElement.setSelectionRange(0, inputElement.value.length);
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
// Filter results based on search query
|
|
@@ -105,7 +105,7 @@
|
|
|
105
105
|
});
|
|
106
106
|
</script>
|
|
107
107
|
|
|
108
|
-
<svelte:window
|
|
108
|
+
<svelte:window onclick={() => close()} />
|
|
109
109
|
|
|
110
110
|
<div class="autocomplete" bind:this={autocompleteElement}>
|
|
111
111
|
<input
|
|
@@ -122,7 +122,7 @@
|
|
|
122
122
|
aria-autocomplete="list"
|
|
123
123
|
aria-controls="autocomplete-results"
|
|
124
124
|
/>
|
|
125
|
-
<div class="autocomplete-results" class:hide-results={!isOpen}>
|
|
125
|
+
<div class="autocomplete-results" class:hide-results={!isOpen} id="autocomplete-results" role="listbox">
|
|
126
126
|
{#each results as result, i (result.key)}
|
|
127
127
|
<button
|
|
128
128
|
onclick={() => close(i)}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { getCountryName } from '../../utils/location.js';
|
|
5
5
|
import BasicMap from '../BasicMap/BasicMap.svelte';
|
|
6
6
|
import { isDarkMode } from '../../utils/map_style.js';
|
|
7
|
+
import { onDestroy } from 'svelte';
|
|
7
8
|
import { loadBBoxes } from './BBoxMap.js';
|
|
8
9
|
import { BBoxDrawer, isSameBBox, type BBox } from './lib/bbox_drawer.js';
|
|
9
10
|
|
|
@@ -15,6 +16,7 @@
|
|
|
15
16
|
onMapLoad?: (map: MaplibreMapType, maplibre: typeof import('maplibre-gl')) => void;
|
|
16
17
|
} = $props();
|
|
17
18
|
|
|
19
|
+
const bboxPadding = 20;
|
|
18
20
|
const startTime = Date.now();
|
|
19
21
|
let bboxDrawer: BBoxDrawer | undefined;
|
|
20
22
|
let map: MaplibreMapType | undefined = $state();
|
|
@@ -56,9 +58,8 @@
|
|
|
56
58
|
if (!bboxDrawer || !map || !selectedBBox) return;
|
|
57
59
|
if (disableZoomTimeout) return;
|
|
58
60
|
|
|
59
|
-
const transform = map.cameraForBounds(selectedBBox) as CameraOptions;
|
|
61
|
+
const transform = map.cameraForBounds(selectedBBox, { padding: bboxPadding }) as CameraOptions;
|
|
60
62
|
if (transform == null) return;
|
|
61
|
-
transform.zoom = transform.zoom ?? 0 - 0.5;
|
|
62
63
|
transform.bearing = 0;
|
|
63
64
|
transform.pitch = 0;
|
|
64
65
|
|
|
@@ -88,17 +89,41 @@
|
|
|
88
89
|
if (disableZoomTimeout) clearTimeout(disableZoomTimeout);
|
|
89
90
|
disableZoomTimeout = setTimeout(() => (disableZoomTimeout = undefined), 100);
|
|
90
91
|
}
|
|
92
|
+
|
|
93
|
+
function selectVisibleArea() {
|
|
94
|
+
if (!map) return;
|
|
95
|
+
const pad = map.getPadding();
|
|
96
|
+
const { clientWidth: w, clientHeight: h } = map.getContainer();
|
|
97
|
+
const nw = map.unproject([(pad.left ?? 0) + bboxPadding, (pad.top ?? 0) + bboxPadding]);
|
|
98
|
+
const se = map.unproject([w - (pad.right ?? 0) - bboxPadding, h - (pad.bottom ?? 0) - bboxPadding]);
|
|
99
|
+
const round = (v: number) => Math.round(v * 1e3) / 1e3;
|
|
100
|
+
selectedBBox = [round(nw.lng), round(se.lat), round(se.lng), round(nw.lat)];
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
onDestroy(() => {
|
|
104
|
+
bboxDrawer?.destroy();
|
|
105
|
+
});
|
|
91
106
|
</script>
|
|
92
107
|
|
|
93
108
|
<div class="container">
|
|
94
109
|
{#if bboxes}
|
|
95
|
-
<div class="
|
|
96
|
-
<
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
110
|
+
<div class="toolbar">
|
|
111
|
+
<div class="input">
|
|
112
|
+
<AutoComplete
|
|
113
|
+
items={bboxes}
|
|
114
|
+
placeholder="Find country, region or city …"
|
|
115
|
+
change={(bbox) => (selectedBBox = bbox)}
|
|
116
|
+
initialInputText={getInitialInputText()}
|
|
117
|
+
/>
|
|
118
|
+
</div>
|
|
119
|
+
<button class="select-visible" onclick={selectVisibleArea} title="Use visible area as bounding box">
|
|
120
|
+
<svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor" stroke-width="2">
|
|
121
|
+
<path d="M3 8V5a2 2 0 0 1 2-2h3" />
|
|
122
|
+
<path d="M21 8V5a2 2 0 0 0-2-2h-3" />
|
|
123
|
+
<path d="M3 16v3a2 2 0 0 0 2 2h3" />
|
|
124
|
+
<path d="M21 16v3a2 2 0 0 1-2 2h-3" />
|
|
125
|
+
</svg>
|
|
126
|
+
</button>
|
|
102
127
|
</div>
|
|
103
128
|
{/if}
|
|
104
129
|
<BasicMap {onMapInit} {onMapLoad}></BasicMap>
|
|
@@ -113,11 +138,34 @@
|
|
|
113
138
|
top: 0;
|
|
114
139
|
min-height: 6em;
|
|
115
140
|
}
|
|
116
|
-
.
|
|
141
|
+
.toolbar {
|
|
117
142
|
position: absolute;
|
|
118
143
|
top: 0.5em;
|
|
119
144
|
left: 0.5em;
|
|
120
145
|
right: 0.5em;
|
|
121
146
|
z-index: 10;
|
|
147
|
+
display: flex;
|
|
148
|
+
gap: 0.3em;
|
|
149
|
+
align-items: flex-start;
|
|
150
|
+
}
|
|
151
|
+
.input {
|
|
152
|
+
flex: 1;
|
|
153
|
+
min-width: 0;
|
|
154
|
+
}
|
|
155
|
+
.select-visible {
|
|
156
|
+
flex-shrink: 0;
|
|
157
|
+
padding: 0.25em;
|
|
158
|
+
border: none;
|
|
159
|
+
border-radius: 0.5em;
|
|
160
|
+
background: color-mix(in srgb, var(--bg-color) 80%, transparent);
|
|
161
|
+
color: var(--fg-color);
|
|
162
|
+
cursor: pointer;
|
|
163
|
+
display: flex;
|
|
164
|
+
align-items: center;
|
|
165
|
+
justify-content: center;
|
|
166
|
+
line-height: 0;
|
|
167
|
+
}
|
|
168
|
+
.select-visible:hover {
|
|
169
|
+
background: color-mix(in srgb, var(--bg-color) 95%, transparent);
|
|
122
170
|
}
|
|
123
171
|
</style>
|
|
@@ -14,10 +14,15 @@ export declare class BBoxDrawer extends EventHandler<{
|
|
|
14
14
|
}> {
|
|
15
15
|
#private;
|
|
16
16
|
private sourceId;
|
|
17
|
+
private lineLayerId;
|
|
18
|
+
private fillLayerId;
|
|
17
19
|
private dragPoint;
|
|
18
20
|
private isDragging;
|
|
19
21
|
private map;
|
|
20
22
|
private canvas;
|
|
23
|
+
private handleMouseMove;
|
|
24
|
+
private handleMouseDown;
|
|
25
|
+
private handleMouseUp;
|
|
21
26
|
private insideOut;
|
|
22
27
|
constructor(map: maplibregl.Map, initialBBox: BBox, color: string, insideOut?: boolean);
|
|
23
28
|
private updateDragPoint;
|
|
@@ -28,6 +33,7 @@ export declare class BBoxDrawer extends EventHandler<{
|
|
|
28
33
|
private getAsPixel;
|
|
29
34
|
private checkDragPointAt;
|
|
30
35
|
private getCursor;
|
|
36
|
+
destroy(): void;
|
|
31
37
|
private doDrag;
|
|
32
38
|
}
|
|
33
39
|
export declare function isSameBBox(a: geojson.BBox, b: geojson.BBox): boolean;
|
|
@@ -2,7 +2,7 @@ import { EventHandler } from '../../../utils/event_handler.js';
|
|
|
2
2
|
// prettier-ignore
|
|
3
3
|
export const DragPointMap = new Map([
|
|
4
4
|
['n', { cursor: 'ns-resize', flipH: 'n', flipV: 's' }],
|
|
5
|
-
['ne', { cursor: 'nesw-resize', flipH: '
|
|
5
|
+
['ne', { cursor: 'nesw-resize', flipH: 'nw', flipV: 'se' }],
|
|
6
6
|
['e', { cursor: 'ew-resize', flipH: 'w', flipV: 'e' }],
|
|
7
7
|
['se', { cursor: 'nwse-resize', flipH: 'sw', flipV: 'ne' }],
|
|
8
8
|
['s', { cursor: 'ns-resize', flipH: 's', flipV: 'n' }],
|
|
@@ -14,10 +14,15 @@ export const DragPointMap = new Map([
|
|
|
14
14
|
const worldBBox = [-180, -85, 180, 85];
|
|
15
15
|
export class BBoxDrawer extends EventHandler {
|
|
16
16
|
sourceId;
|
|
17
|
+
lineLayerId;
|
|
18
|
+
fillLayerId;
|
|
17
19
|
dragPoint = false;
|
|
18
20
|
isDragging = false;
|
|
19
21
|
map;
|
|
20
22
|
canvas;
|
|
23
|
+
handleMouseMove;
|
|
24
|
+
handleMouseDown;
|
|
25
|
+
handleMouseUp;
|
|
21
26
|
insideOut;
|
|
22
27
|
#bbox;
|
|
23
28
|
constructor(map, initialBBox, color, insideOut) {
|
|
@@ -25,10 +30,13 @@ export class BBoxDrawer extends EventHandler {
|
|
|
25
30
|
this.#bbox = [...initialBBox];
|
|
26
31
|
this.insideOut = insideOut ?? true;
|
|
27
32
|
this.map = map;
|
|
28
|
-
|
|
33
|
+
const uid = Math.random().toString(36).slice(2);
|
|
34
|
+
this.sourceId = 'bbox_' + uid;
|
|
35
|
+
this.lineLayerId = 'bbox-line_' + uid;
|
|
36
|
+
this.fillLayerId = 'bbox-fill_' + uid;
|
|
29
37
|
map.addSource(this.sourceId, { type: 'geojson', data: this.getAsFeatureCollection() });
|
|
30
38
|
map.addLayer({
|
|
31
|
-
id:
|
|
39
|
+
id: this.lineLayerId,
|
|
32
40
|
type: 'line',
|
|
33
41
|
source: this.sourceId,
|
|
34
42
|
filter: ['==', '$type', 'LineString'],
|
|
@@ -36,7 +44,7 @@ export class BBoxDrawer extends EventHandler {
|
|
|
36
44
|
paint: { 'line-color': color }
|
|
37
45
|
});
|
|
38
46
|
map.addLayer({
|
|
39
|
-
id:
|
|
47
|
+
id: this.fillLayerId,
|
|
40
48
|
type: 'fill',
|
|
41
49
|
source: this.sourceId,
|
|
42
50
|
filter: ['==', '$type', 'Polygon'],
|
|
@@ -44,7 +52,7 @@ export class BBoxDrawer extends EventHandler {
|
|
|
44
52
|
paint: { 'fill-color': color, 'fill-opacity': 0.2 }
|
|
45
53
|
});
|
|
46
54
|
this.canvas = map.getCanvasContainer();
|
|
47
|
-
|
|
55
|
+
this.handleMouseMove = (e) => {
|
|
48
56
|
if (e.originalEvent.buttons % 2 === 0)
|
|
49
57
|
return this.checkDragPointAt(e.point);
|
|
50
58
|
if (!this.isDragging)
|
|
@@ -55,8 +63,8 @@ export class BBoxDrawer extends EventHandler {
|
|
|
55
63
|
this.redraw();
|
|
56
64
|
e.preventDefault();
|
|
57
65
|
this.emit('drag', [...this.#bbox]);
|
|
58
|
-
}
|
|
59
|
-
|
|
66
|
+
};
|
|
67
|
+
this.handleMouseDown = (e) => {
|
|
60
68
|
if (this.isDragging)
|
|
61
69
|
return;
|
|
62
70
|
if (e.originalEvent.buttons % 2) {
|
|
@@ -66,12 +74,17 @@ export class BBoxDrawer extends EventHandler {
|
|
|
66
74
|
if (this.isDragging)
|
|
67
75
|
e.preventDefault();
|
|
68
76
|
}
|
|
69
|
-
}
|
|
70
|
-
|
|
77
|
+
};
|
|
78
|
+
this.handleMouseUp = () => {
|
|
79
|
+
if (!this.isDragging)
|
|
80
|
+
return;
|
|
71
81
|
this.isDragging = false;
|
|
72
82
|
this.updateDragPoint(false);
|
|
73
83
|
this.emit('dragEnd', [...this.#bbox]);
|
|
74
|
-
}
|
|
84
|
+
};
|
|
85
|
+
map.on('mousemove', this.handleMouseMove);
|
|
86
|
+
map.on('mousedown', this.handleMouseDown);
|
|
87
|
+
map.on('mouseup', this.handleMouseUp);
|
|
75
88
|
}
|
|
76
89
|
updateDragPoint(dragPoint) {
|
|
77
90
|
if (this.dragPoint === dragPoint)
|
|
@@ -146,6 +159,19 @@ export class BBoxDrawer extends EventHandler {
|
|
|
146
159
|
getCursor(drag) {
|
|
147
160
|
return DragPointMap.get(drag)?.cursor ?? 'default';
|
|
148
161
|
}
|
|
162
|
+
destroy() {
|
|
163
|
+
this.map.off('mousemove', this.handleMouseMove);
|
|
164
|
+
this.map.off('mousedown', this.handleMouseDown);
|
|
165
|
+
this.map.off('mouseup', this.handleMouseUp);
|
|
166
|
+
if (this.map.getLayer(this.lineLayerId))
|
|
167
|
+
this.map.removeLayer(this.lineLayerId);
|
|
168
|
+
if (this.map.getLayer(this.fillLayerId))
|
|
169
|
+
this.map.removeLayer(this.fillLayerId);
|
|
170
|
+
if (this.map.getSource(this.sourceId))
|
|
171
|
+
this.map.removeSource(this.sourceId);
|
|
172
|
+
this.canvas.style.cursor = '';
|
|
173
|
+
this.clear();
|
|
174
|
+
}
|
|
149
175
|
doDrag(lngLat) {
|
|
150
176
|
this.#bbox = ((bbox) => {
|
|
151
177
|
const x = Math.round(lngLat.lng * 1e3) / 1e3;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@versatiles/svelte",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json && vite build && npm run package",
|
|
@@ -42,42 +42,42 @@
|
|
|
42
42
|
"svelte": "^5.45.8"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"@playwright/test": "^1.
|
|
45
|
+
"@playwright/test": "^1.58.1",
|
|
46
46
|
"@sveltejs/adapter-static": "^3.0.10",
|
|
47
|
-
"@sveltejs/kit": "^2.50.
|
|
47
|
+
"@sveltejs/kit": "^2.50.2",
|
|
48
48
|
"@sveltejs/package": "^2.5.7",
|
|
49
49
|
"@sveltejs/vite-plugin-svelte": "^6.2.4",
|
|
50
|
-
"@turf/turf": "^7.3.
|
|
50
|
+
"@turf/turf": "^7.3.3",
|
|
51
51
|
"@types/eslint": "^9.6.1",
|
|
52
|
-
"@types/node": "^25.
|
|
53
|
-
"@versatiles/release-tool": "^2.
|
|
54
|
-
"@vitest/coverage-v8": "^4.0.
|
|
52
|
+
"@types/node": "^25.2.1",
|
|
53
|
+
"@versatiles/release-tool": "^2.7.0",
|
|
54
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
55
55
|
"cookie": "^1.1.1",
|
|
56
56
|
"eslint": "^9.39.2",
|
|
57
57
|
"eslint-config-prettier": "^10.1.8",
|
|
58
58
|
"eslint-plugin-svelte": "^3.14.0",
|
|
59
59
|
"geojson": "^0.5.0",
|
|
60
|
-
"globals": "^17.
|
|
61
|
-
"happy-dom": "^20.
|
|
60
|
+
"globals": "^17.3.0",
|
|
61
|
+
"happy-dom": "^20.5.0",
|
|
62
62
|
"husky": "^9.1.7",
|
|
63
|
-
"prettier": "^3.8.
|
|
63
|
+
"prettier": "^3.8.1",
|
|
64
64
|
"prettier-plugin-svelte": "^3.4.1",
|
|
65
|
-
"publint": "^0.3.
|
|
66
|
-
"sass-embedded": "^1.97.
|
|
67
|
-
"svelte": "^5.
|
|
68
|
-
"svelte-check": "^4.3.
|
|
65
|
+
"publint": "^0.3.17",
|
|
66
|
+
"sass-embedded": "^1.97.3",
|
|
67
|
+
"svelte": "^5.49.2",
|
|
68
|
+
"svelte-check": "^4.3.6",
|
|
69
69
|
"svelte-preprocess": "^6.0.3",
|
|
70
70
|
"tsx": "^4.21.0",
|
|
71
71
|
"typescript": "^5.9.3",
|
|
72
|
-
"typescript-eslint": "^8.
|
|
72
|
+
"typescript-eslint": "^8.54.0",
|
|
73
73
|
"vite": "^7.3.1",
|
|
74
|
-
"vitest": "^4.0.
|
|
74
|
+
"vitest": "^4.0.18"
|
|
75
75
|
},
|
|
76
76
|
"svelte": "./dist/index.js",
|
|
77
77
|
"types": "./dist/index.d.ts",
|
|
78
78
|
"type": "module",
|
|
79
79
|
"dependencies": {
|
|
80
80
|
"@versatiles/style": "^5.8.4",
|
|
81
|
-
"maplibre-gl": "^5.
|
|
81
|
+
"maplibre-gl": "^5.17.0"
|
|
82
82
|
}
|
|
83
83
|
}
|