@maptiler/geocoding-control 0.0.31
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 +165 -0
- package/dist/leaflet.js +1002 -0
- package/dist/leaflet.umd.cjs +1 -0
- package/dist/lib/LeafletGeocodingControl.d.ts +40 -0
- package/dist/lib/LeafletMapControllerImpl.d.ts +3 -0
- package/dist/lib/MaplibreMapControllerImpl.d.ts +4 -0
- package/dist/lib/MaplibreglGeocodingControl.d.ts +49 -0
- package/dist/lib/leafletMapController.d.ts +3 -0
- package/dist/lib/maplibreMapController.d.ts +4 -0
- package/dist/lib/types.d.ts +128 -0
- package/dist/main.d.ts +3 -0
- package/dist/maplibregl.js +995 -0
- package/dist/maplibregl.umd.cjs +1 -0
- package/dist/style.css +1 -0
- package/package.json +58 -0
- package/src/lib/BullseyeIcon.svelte +12 -0
- package/src/lib/ClearIcon.svelte +12 -0
- package/src/lib/GeocodingControl.svelte +687 -0
- package/src/lib/LeafletGeocodingControl.ts +123 -0
- package/src/lib/LoadingIcon.svelte +40 -0
- package/src/lib/MaplibreglGeocodingControl.ts +141 -0
- package/src/lib/MarkerIcon.svelte +63 -0
- package/src/lib/SearchIcon.svelte +12 -0
- package/src/lib/leafletMapController.ts +146 -0
- package/src/lib/maplibreMapController.ts +149 -0
- package/src/lib/types.ts +198 -0
|
@@ -0,0 +1,687 @@
|
|
|
1
|
+
<script type="ts">
|
|
2
|
+
import { createEventDispatcher } from "svelte";
|
|
3
|
+
import { onDestroy } from "svelte/internal";
|
|
4
|
+
import BullseyeIcon from "./BullseyeIcon.svelte";
|
|
5
|
+
import ClearIcon from "./ClearIcon.svelte";
|
|
6
|
+
import LoadingIcon from "./LoadingIcon.svelte";
|
|
7
|
+
import MarkerIcon from "./MarkerIcon.svelte";
|
|
8
|
+
import SearchIcon from "./SearchIcon.svelte";
|
|
9
|
+
import type {
|
|
10
|
+
Feature,
|
|
11
|
+
FeatureCollection,
|
|
12
|
+
MapController,
|
|
13
|
+
Proximity,
|
|
14
|
+
} from "./types";
|
|
15
|
+
|
|
16
|
+
let className: string | undefined = undefined;
|
|
17
|
+
|
|
18
|
+
export { className as class };
|
|
19
|
+
|
|
20
|
+
export let mapController: MapController | undefined = undefined;
|
|
21
|
+
|
|
22
|
+
export let apiKey: string;
|
|
23
|
+
|
|
24
|
+
export let debounceSearch = 200;
|
|
25
|
+
|
|
26
|
+
export let placeholder = "Search";
|
|
27
|
+
|
|
28
|
+
export let errorMessage = "Searching failed";
|
|
29
|
+
|
|
30
|
+
export let noResultsMessage = "No results found";
|
|
31
|
+
|
|
32
|
+
export let proximity: Proximity = undefined;
|
|
33
|
+
|
|
34
|
+
export let bbox: [number, number, number, number] | undefined = undefined;
|
|
35
|
+
|
|
36
|
+
export let trackProximity = true;
|
|
37
|
+
|
|
38
|
+
export let minLength = 2;
|
|
39
|
+
|
|
40
|
+
export let language: string | undefined = undefined;
|
|
41
|
+
|
|
42
|
+
export let showResultsWhileTyping = true;
|
|
43
|
+
|
|
44
|
+
export let zoom = 16;
|
|
45
|
+
|
|
46
|
+
export let flyTo = true;
|
|
47
|
+
|
|
48
|
+
export let collapsed = false;
|
|
49
|
+
|
|
50
|
+
export let clearOnBlur = false;
|
|
51
|
+
|
|
52
|
+
export let enableReverse: boolean | string = false;
|
|
53
|
+
|
|
54
|
+
export let filter: (feature: Feature) => boolean = () => true;
|
|
55
|
+
|
|
56
|
+
export let searchValue = "";
|
|
57
|
+
|
|
58
|
+
export let reverseActive = false;
|
|
59
|
+
|
|
60
|
+
export let showPlaceType = false;
|
|
61
|
+
|
|
62
|
+
// export let limit = 5;
|
|
63
|
+
|
|
64
|
+
// export let autocomplete = true;
|
|
65
|
+
|
|
66
|
+
// export let fuzzy = true;
|
|
67
|
+
|
|
68
|
+
export function focus() {
|
|
69
|
+
input.focus();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function blur() {
|
|
73
|
+
input.blur();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function setQuery(value: string, submit = true) {
|
|
77
|
+
searchValue = value;
|
|
78
|
+
|
|
79
|
+
if (submit) {
|
|
80
|
+
selectedItemIndex = -1;
|
|
81
|
+
|
|
82
|
+
handleOnSubmit();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
let focused = false;
|
|
87
|
+
|
|
88
|
+
let listFeatures: Feature[] | undefined;
|
|
89
|
+
|
|
90
|
+
let markedFeatures: Feature[] | undefined;
|
|
91
|
+
|
|
92
|
+
let picked: Feature | undefined;
|
|
93
|
+
|
|
94
|
+
let lastSearchUrl = "";
|
|
95
|
+
|
|
96
|
+
let input: HTMLInputElement;
|
|
97
|
+
|
|
98
|
+
let selectedItemIndex = -1;
|
|
99
|
+
|
|
100
|
+
let error: unknown;
|
|
101
|
+
|
|
102
|
+
let cachedFeatures: Feature[] = [];
|
|
103
|
+
|
|
104
|
+
let abortController: AbortController | undefined;
|
|
105
|
+
|
|
106
|
+
let searchTimeoutRef: number;
|
|
107
|
+
|
|
108
|
+
let focusedDelayed: boolean;
|
|
109
|
+
|
|
110
|
+
const dispatch = createEventDispatcher<{
|
|
111
|
+
select: Feature;
|
|
112
|
+
pick: Feature;
|
|
113
|
+
optionsVisibilityChange: boolean;
|
|
114
|
+
featuresListed: Feature[];
|
|
115
|
+
featuresMarked: Feature[];
|
|
116
|
+
response: { url: string; featureCollection: FeatureCollection };
|
|
117
|
+
reverseToggle: boolean;
|
|
118
|
+
queryChange: string;
|
|
119
|
+
}>();
|
|
120
|
+
|
|
121
|
+
$: if (mapController) {
|
|
122
|
+
mapController.setProximityChangeHandler(
|
|
123
|
+
trackProximity
|
|
124
|
+
? (p) => {
|
|
125
|
+
proximity = p;
|
|
126
|
+
}
|
|
127
|
+
: undefined
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
$: if (!trackProximity) {
|
|
132
|
+
proximity = undefined;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
$: if (mapController && picked && flyTo) {
|
|
136
|
+
if (
|
|
137
|
+
!picked.bbox ||
|
|
138
|
+
(picked.bbox[0] === picked.bbox[2] && picked.bbox[1] === picked.bbox[3])
|
|
139
|
+
) {
|
|
140
|
+
mapController.flyTo(picked.center, zoom);
|
|
141
|
+
} else {
|
|
142
|
+
mapController.fitBounds(picked.bbox, 0);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
listFeatures = undefined;
|
|
146
|
+
markedFeatures = undefined;
|
|
147
|
+
selectedItemIndex = -1;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
$: if (markedFeatures !== listFeatures) {
|
|
151
|
+
markedFeatures = undefined;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
$: if (mapController) {
|
|
155
|
+
mapController.setMarkers(markedFeatures, picked);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
$: if (!searchValue) {
|
|
159
|
+
picked = undefined;
|
|
160
|
+
listFeatures = undefined;
|
|
161
|
+
error = undefined;
|
|
162
|
+
markedFeatures = listFeatures;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// highlight selected marker
|
|
166
|
+
$: mapController?.setSelectedMarker(selectedItemIndex);
|
|
167
|
+
|
|
168
|
+
// close dropdown in the next cycle so that the selected item event has the chance to fire
|
|
169
|
+
$: setTimeout(() => {
|
|
170
|
+
focusedDelayed = focused;
|
|
171
|
+
|
|
172
|
+
if (clearOnBlur && !focused) {
|
|
173
|
+
searchValue = "";
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
// clear selection on edit
|
|
178
|
+
$: {
|
|
179
|
+
searchValue;
|
|
180
|
+
|
|
181
|
+
selectedItemIndex = -1;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
$: selected = listFeatures?.[selectedItemIndex];
|
|
185
|
+
|
|
186
|
+
$: dispatch("select", selected);
|
|
187
|
+
|
|
188
|
+
$: dispatch("pick", picked);
|
|
189
|
+
|
|
190
|
+
$: dispatch("optionsVisibilityChange", focusedDelayed && !!listFeatures);
|
|
191
|
+
|
|
192
|
+
$: dispatch("featuresListed", listFeatures);
|
|
193
|
+
|
|
194
|
+
$: dispatch("featuresMarked", markedFeatures);
|
|
195
|
+
|
|
196
|
+
$: dispatch("reverseToggle", reverseActive);
|
|
197
|
+
|
|
198
|
+
$: dispatch("queryChange", searchValue);
|
|
199
|
+
|
|
200
|
+
$: if (mapController) {
|
|
201
|
+
mapController.indicateReverse(reverseActive);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
$: if (mapController) {
|
|
205
|
+
mapController.setMapClickHandler(reverseActive ? handleReverse : undefined);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
onDestroy(() => {
|
|
209
|
+
if (mapController) {
|
|
210
|
+
mapController.setProximityChangeHandler(undefined);
|
|
211
|
+
mapController.setMapClickHandler(undefined);
|
|
212
|
+
mapController.indicateReverse(false);
|
|
213
|
+
mapController.setSelectedMarker(-1);
|
|
214
|
+
mapController.setMarkers(undefined, undefined);
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
function handleOnSubmit() {
|
|
219
|
+
if (selectedItemIndex > -1 && listFeatures) {
|
|
220
|
+
picked = listFeatures[selectedItemIndex];
|
|
221
|
+
searchValue = picked.place_name.replace(/,.*/, "");
|
|
222
|
+
error = undefined;
|
|
223
|
+
markedFeatures = undefined;
|
|
224
|
+
selectedItemIndex = -1;
|
|
225
|
+
} else if (searchValue) {
|
|
226
|
+
search(searchValue)
|
|
227
|
+
.then(() => {
|
|
228
|
+
markedFeatures = listFeatures;
|
|
229
|
+
|
|
230
|
+
picked = undefined;
|
|
231
|
+
|
|
232
|
+
zoomToResults();
|
|
233
|
+
})
|
|
234
|
+
.catch((err) => (error = err));
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
async function search(searchValue: string) {
|
|
239
|
+
error = undefined;
|
|
240
|
+
|
|
241
|
+
const isReverse = /^-?\d+(\.\d+)?,-?\d+(\.\d+)?$/.test(searchValue);
|
|
242
|
+
|
|
243
|
+
const sp = new URLSearchParams();
|
|
244
|
+
|
|
245
|
+
sp.set("key", apiKey);
|
|
246
|
+
|
|
247
|
+
if (language) {
|
|
248
|
+
sp.set("language", String(language));
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
if (!isReverse) {
|
|
252
|
+
if (bbox) {
|
|
253
|
+
sp.set("bbox", bbox.join(","));
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
if (proximity) {
|
|
257
|
+
sp.set("proximity", proximity.join(","));
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// sp.set("autocomplete", String(autocomplete));
|
|
261
|
+
|
|
262
|
+
// sp.set("fuzzyMatch", String(fuzzy));
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// sp.set("limit", String(limit));
|
|
266
|
+
|
|
267
|
+
const url =
|
|
268
|
+
import.meta.env.VITE_API_URL +
|
|
269
|
+
"/" +
|
|
270
|
+
encodeURIComponent(searchValue) +
|
|
271
|
+
".json?" +
|
|
272
|
+
sp.toString();
|
|
273
|
+
|
|
274
|
+
if (url === lastSearchUrl) {
|
|
275
|
+
listFeatures = cachedFeatures;
|
|
276
|
+
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
lastSearchUrl = url;
|
|
281
|
+
|
|
282
|
+
abortController?.abort();
|
|
283
|
+
|
|
284
|
+
abortController = new AbortController();
|
|
285
|
+
|
|
286
|
+
let res: Response;
|
|
287
|
+
|
|
288
|
+
try {
|
|
289
|
+
res = await fetch(url, { signal: abortController.signal }).finally(() => {
|
|
290
|
+
abortController = undefined;
|
|
291
|
+
});
|
|
292
|
+
} catch (e) {
|
|
293
|
+
if (e && typeof e === "object" && (e as any).name === "AbortError") {
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
throw new Error();
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
if (!res.ok) {
|
|
301
|
+
throw new Error();
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
const featureCollection: FeatureCollection = await res.json();
|
|
305
|
+
|
|
306
|
+
dispatch("response", { url, featureCollection });
|
|
307
|
+
|
|
308
|
+
listFeatures = featureCollection.features.filter(filter);
|
|
309
|
+
|
|
310
|
+
cachedFeatures = listFeatures;
|
|
311
|
+
|
|
312
|
+
if (isReverse) {
|
|
313
|
+
input.focus();
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
function zoomToResults() {
|
|
318
|
+
if (!markedFeatures?.length || !flyTo) {
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
const bbox: [number, number, number, number] = [180, 90, -180, -90];
|
|
323
|
+
|
|
324
|
+
for (const feature of markedFeatures) {
|
|
325
|
+
bbox[0] = Math.min(bbox[0], feature.bbox?.[0] ?? feature.center[0]);
|
|
326
|
+
bbox[1] = Math.min(bbox[1], feature.bbox?.[1] ?? feature.center[1]);
|
|
327
|
+
bbox[2] = Math.max(bbox[2], feature.bbox?.[2] ?? feature.center[0]);
|
|
328
|
+
bbox[3] = Math.max(bbox[3], feature.bbox?.[3] ?? feature.center[1]);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
if (mapController && markedFeatures.length > 0) {
|
|
332
|
+
if (picked && bbox[0] === bbox[2] && bbox[1] === bbox[3]) {
|
|
333
|
+
mapController.flyTo(picked.center, zoom);
|
|
334
|
+
} else {
|
|
335
|
+
mapController.fitBounds(bbox, 50);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
function handleReverse(coordinates: [lng: number, lat: number]) {
|
|
341
|
+
reverseActive = false;
|
|
342
|
+
|
|
343
|
+
setQuery(coordinates[0].toFixed(6) + "," + coordinates[1].toFixed(6));
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
function handleKeyDown(e: KeyboardEvent) {
|
|
347
|
+
if (!listFeatures) {
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
let dir = e.key === "ArrowDown" ? 1 : e.key === "ArrowUp" ? -1 : 0;
|
|
352
|
+
|
|
353
|
+
if (dir) {
|
|
354
|
+
if (selectedItemIndex === -1 && dir === -1) {
|
|
355
|
+
selectedItemIndex = listFeatures.length;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
selectedItemIndex += dir;
|
|
359
|
+
|
|
360
|
+
if (selectedItemIndex >= listFeatures.length) {
|
|
361
|
+
selectedItemIndex = -1;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
e.preventDefault();
|
|
365
|
+
} else if (["ArrowLeft", "ArrowRight", "Home", "End"].includes(e.key)) {
|
|
366
|
+
selectedItemIndex = -1;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
function handleInput(debounce = true) {
|
|
371
|
+
if (showResultsWhileTyping && searchValue.length > minLength) {
|
|
372
|
+
if (searchTimeoutRef) {
|
|
373
|
+
clearTimeout(searchTimeoutRef);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
const sv = searchValue;
|
|
377
|
+
|
|
378
|
+
searchTimeoutRef = window.setTimeout(
|
|
379
|
+
() => {
|
|
380
|
+
search(sv).catch((err) => (error = err));
|
|
381
|
+
},
|
|
382
|
+
debounce ? debounceSearch : 0
|
|
383
|
+
);
|
|
384
|
+
} else {
|
|
385
|
+
listFeatures = undefined;
|
|
386
|
+
error = undefined;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
</script>
|
|
390
|
+
|
|
391
|
+
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
|
|
392
|
+
<form
|
|
393
|
+
tabindex="0"
|
|
394
|
+
on:submit|preventDefault={handleOnSubmit}
|
|
395
|
+
class:can-collapse={collapsed && searchValue === ""}
|
|
396
|
+
class={className}
|
|
397
|
+
>
|
|
398
|
+
<div class="input-group">
|
|
399
|
+
<button type="button" on:click={() => input.focus()}>
|
|
400
|
+
<SearchIcon />
|
|
401
|
+
</button>
|
|
402
|
+
|
|
403
|
+
<input
|
|
404
|
+
bind:this={input}
|
|
405
|
+
bind:value={searchValue}
|
|
406
|
+
on:focus={() => (focused = true)}
|
|
407
|
+
on:blur={() => (focused = false)}
|
|
408
|
+
on:keydown={handleKeyDown}
|
|
409
|
+
on:input={() => handleInput()}
|
|
410
|
+
{placeholder}
|
|
411
|
+
aria-label={placeholder}
|
|
412
|
+
/>
|
|
413
|
+
|
|
414
|
+
<div class="clear-button-container">
|
|
415
|
+
<button
|
|
416
|
+
type="button"
|
|
417
|
+
on:click={() => {
|
|
418
|
+
searchValue = "";
|
|
419
|
+
input.focus();
|
|
420
|
+
}}
|
|
421
|
+
class:displayable={searchValue !== ""}
|
|
422
|
+
>
|
|
423
|
+
<ClearIcon />
|
|
424
|
+
</button>
|
|
425
|
+
|
|
426
|
+
{#if abortController}
|
|
427
|
+
<LoadingIcon />
|
|
428
|
+
{/if}
|
|
429
|
+
</div>
|
|
430
|
+
|
|
431
|
+
{#if enableReverse}
|
|
432
|
+
<button
|
|
433
|
+
type="button"
|
|
434
|
+
class:active={reverseActive}
|
|
435
|
+
title={enableReverse === true
|
|
436
|
+
? "toggle reverse geocoding"
|
|
437
|
+
: enableReverse}
|
|
438
|
+
on:click={() => (reverseActive = !reverseActive)}
|
|
439
|
+
>
|
|
440
|
+
<BullseyeIcon />
|
|
441
|
+
</button>
|
|
442
|
+
{/if}
|
|
443
|
+
|
|
444
|
+
<slot />
|
|
445
|
+
</div>
|
|
446
|
+
|
|
447
|
+
{#if !focusedDelayed}
|
|
448
|
+
{""}
|
|
449
|
+
{:else if error}
|
|
450
|
+
<div class="error">{errorMessage}</div>
|
|
451
|
+
{:else if listFeatures?.length === 0}
|
|
452
|
+
<div class="no-results">{noResultsMessage}</div>
|
|
453
|
+
{:else if focusedDelayed && listFeatures?.length}
|
|
454
|
+
<ul on:mouseout={() => (selectedItemIndex = -1)} on:blur={() => undefined}>
|
|
455
|
+
{#each listFeatures as feature, i}
|
|
456
|
+
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
|
|
457
|
+
<li
|
|
458
|
+
tabindex="0"
|
|
459
|
+
data-selected={selectedItemIndex === i}
|
|
460
|
+
class:selected={selectedItemIndex === i}
|
|
461
|
+
on:mouseover={() => (selectedItemIndex = i)}
|
|
462
|
+
on:focus={() => {
|
|
463
|
+
picked = feature;
|
|
464
|
+
searchValue = feature.place_name.replace(/,.*/, "");
|
|
465
|
+
selectedItemIndex = -1;
|
|
466
|
+
}}
|
|
467
|
+
>
|
|
468
|
+
<MarkerIcon displayIn="list" />
|
|
469
|
+
<span>
|
|
470
|
+
<span>
|
|
471
|
+
<span>{feature.place_name.replace(/,.*/, "")}</span>
|
|
472
|
+
{#if showPlaceType}
|
|
473
|
+
<span>{feature.place_type}</span>
|
|
474
|
+
{/if}
|
|
475
|
+
</span>
|
|
476
|
+
</span>
|
|
477
|
+
<span>
|
|
478
|
+
<span>{feature.place_name.replace(/[^,]*,?\s*/, "")}</span>
|
|
479
|
+
</span>
|
|
480
|
+
</li>
|
|
481
|
+
{/each}
|
|
482
|
+
</ul>
|
|
483
|
+
{/if}
|
|
484
|
+
</form>
|
|
485
|
+
|
|
486
|
+
<style>
|
|
487
|
+
form,
|
|
488
|
+
form *,
|
|
489
|
+
form *:after,
|
|
490
|
+
form *:before {
|
|
491
|
+
box-sizing: border-box;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
form {
|
|
495
|
+
font-family: "Ubuntu", "Open Sans", "Helvetica Neue", Arial, Helvetica,
|
|
496
|
+
sans-serif;
|
|
497
|
+
position: relative;
|
|
498
|
+
background-color: #fff;
|
|
499
|
+
width: 100%;
|
|
500
|
+
max-width: 240px;
|
|
501
|
+
z-index: 10;
|
|
502
|
+
border-radius: 4px;
|
|
503
|
+
transition: max-width 0.25s;
|
|
504
|
+
box-shadow: 0px 2px 8px rgba(51, 51, 89, 0.15);
|
|
505
|
+
--color-text: #333359;
|
|
506
|
+
--color-icon-button: #333359;
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
form.can-collapse {
|
|
510
|
+
max-width: 35px;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
form:focus-within,
|
|
514
|
+
form:hover {
|
|
515
|
+
max-width: 240px;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
input {
|
|
519
|
+
font: inherit;
|
|
520
|
+
font-size: 14px;
|
|
521
|
+
width: 100%;
|
|
522
|
+
border: 0;
|
|
523
|
+
background-color: transparent;
|
|
524
|
+
margin: 0;
|
|
525
|
+
height: 36px;
|
|
526
|
+
color: rgba(0, 0, 0, 0.75);
|
|
527
|
+
white-space: nowrap;
|
|
528
|
+
overflow: hidden;
|
|
529
|
+
padding: 0;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
input:focus {
|
|
533
|
+
color: rgba(0, 0, 0, 0.75);
|
|
534
|
+
outline: 0;
|
|
535
|
+
outline: none;
|
|
536
|
+
box-shadow: none;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
ul,
|
|
540
|
+
div.error,
|
|
541
|
+
div.no-results {
|
|
542
|
+
background-color: #fff;
|
|
543
|
+
border-radius: 4px;
|
|
544
|
+
left: 0;
|
|
545
|
+
list-style: none;
|
|
546
|
+
margin: 0;
|
|
547
|
+
padding: 0;
|
|
548
|
+
position: absolute;
|
|
549
|
+
width: 100%;
|
|
550
|
+
top: calc(100% + 6px);
|
|
551
|
+
font-size: 14px;
|
|
552
|
+
box-shadow: 0px 2px 8px rgba(51, 51, 89, 0.15);
|
|
553
|
+
line-height: 16px;
|
|
554
|
+
overflow: hidden;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
:global(.maplibregl-ctrl-bottom-left) ul,
|
|
558
|
+
:global(.maplibregl-ctrl-bottom-right) ul {
|
|
559
|
+
top: auto;
|
|
560
|
+
bottom: 100%;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
li {
|
|
564
|
+
cursor: default;
|
|
565
|
+
display: grid;
|
|
566
|
+
grid-template-columns: auto 1fr;
|
|
567
|
+
color: var(--color-text);
|
|
568
|
+
padding: 4px 0px;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
li:first-child {
|
|
572
|
+
padding-top: 8px;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
li:last-child {
|
|
576
|
+
padding-bottom: 8px;
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
li > span {
|
|
580
|
+
/* text-overflow: ellipsis; */
|
|
581
|
+
overflow: hidden;
|
|
582
|
+
padding-right: 8px;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
li > span > span {
|
|
586
|
+
white-space: nowrap;
|
|
587
|
+
display: block;
|
|
588
|
+
min-width: fit-content;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
li.selected > span > span {
|
|
592
|
+
animation: backAndForth 5s linear infinite;
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
li > span:nth-of-type(1) > span > span:nth-of-type(1) {
|
|
596
|
+
font-weight: bold;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
li > span:nth-of-type(1) > span > span:nth-of-type(2) {
|
|
600
|
+
color: #aeb6c7;
|
|
601
|
+
font-size: 12px;
|
|
602
|
+
padding-left: 4px;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
li.selected {
|
|
606
|
+
background-color: #f3f3f3;
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
button:hover {
|
|
610
|
+
background-color: transparent;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
button:hover :global(svg),
|
|
614
|
+
button.active :global(svg) {
|
|
615
|
+
fill: #6b7c92;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
button {
|
|
619
|
+
padding: 0;
|
|
620
|
+
margin: 0;
|
|
621
|
+
border: 0;
|
|
622
|
+
background-color: transparent;
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
.input-group {
|
|
626
|
+
display: flex;
|
|
627
|
+
align-items: stretch;
|
|
628
|
+
gap: 7px;
|
|
629
|
+
padding-inline: 8px;
|
|
630
|
+
outline: #c1cfe4 solid 2px;
|
|
631
|
+
border-radius: 4px;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
.input-group:hover .displayable {
|
|
635
|
+
visibility: visible;
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
.input-group:focus-within {
|
|
639
|
+
outline: #3170fe solid 2px;
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
div.error,
|
|
643
|
+
div.no-results {
|
|
644
|
+
font: inherit;
|
|
645
|
+
font-size: 14px;
|
|
646
|
+
padding: 6px 10px;
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
div.error {
|
|
650
|
+
color: #e25041;
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
div.no-results {
|
|
654
|
+
color: var(--color-text);
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
.clear-button-container {
|
|
658
|
+
position: relative;
|
|
659
|
+
display: flex;
|
|
660
|
+
align-items: stretch;
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
.clear-button-container button {
|
|
664
|
+
visibility: hidden;
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
@keyframes backAndForth {
|
|
668
|
+
0% {
|
|
669
|
+
transform: translateX(0);
|
|
670
|
+
}
|
|
671
|
+
10% {
|
|
672
|
+
transform: translateX(0);
|
|
673
|
+
}
|
|
674
|
+
45% {
|
|
675
|
+
transform: translateX(calc(-100% + 196px));
|
|
676
|
+
}
|
|
677
|
+
55% {
|
|
678
|
+
transform: translateX(calc(-100% + 196px));
|
|
679
|
+
}
|
|
680
|
+
90% {
|
|
681
|
+
transform: translateX(0);
|
|
682
|
+
}
|
|
683
|
+
100% {
|
|
684
|
+
transform: translateX(0);
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
</style>
|