@reuters-graphics/graphics-components 3.8.0 → 3.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
<script lang="ts">
|
|
3
3
|
import { onDestroy } from 'svelte';
|
|
4
4
|
import { geocode, type GeocodeFeature, type GeocodeOptions } from './geocode';
|
|
5
|
+
import { normalizeMinLength, normalizeDebounceMs } from './normalize';
|
|
5
6
|
import MagnifyingGlass from '../SearchInput/components/MagnifyingGlass.svelte';
|
|
6
7
|
import X from '../SearchInput/components/X.svelte';
|
|
7
8
|
|
|
@@ -12,12 +13,25 @@
|
|
|
12
13
|
searchPlaceholder?: string;
|
|
13
14
|
/** Callback fired when a location is selected from the results. */
|
|
14
15
|
onselect?: (location: { lng: number; lat: number; name: string }) => void;
|
|
16
|
+
/**
|
|
17
|
+
* Minimum number of characters before a request is made. Raising this
|
|
18
|
+
* cuts the number of paid geocoding requests per search. Defaults to 2.
|
|
19
|
+
*/
|
|
20
|
+
minLength?: number;
|
|
21
|
+
/**
|
|
22
|
+
* Debounce window in milliseconds between the last keystroke and the
|
|
23
|
+
* request. Raising this fires fewer requests while the user is still
|
|
24
|
+
* typing (each request is billed). Defaults to 300.
|
|
25
|
+
*/
|
|
26
|
+
debounceMs?: number;
|
|
15
27
|
}
|
|
16
28
|
|
|
17
29
|
let {
|
|
18
30
|
accessToken,
|
|
19
31
|
searchPlaceholder = 'Search for a location',
|
|
20
32
|
onselect,
|
|
33
|
+
minLength = 2,
|
|
34
|
+
debounceMs = 300,
|
|
21
35
|
autocomplete = true,
|
|
22
36
|
bbox,
|
|
23
37
|
country,
|
|
@@ -44,12 +58,22 @@
|
|
|
44
58
|
let debounceTimer: ReturnType<typeof setTimeout>;
|
|
45
59
|
let abortController: AbortController | null = null;
|
|
46
60
|
|
|
61
|
+
// Normalize the throttling props so a non-numeric value passed via markup
|
|
62
|
+
// (e.g. `minLength="two"`) can't coerce to NaN and disable the gate — which
|
|
63
|
+
// would bill a request on every keystroke. Fall back to the documented
|
|
64
|
+
// defaults, clamped to sane floors.
|
|
65
|
+
let effectiveMinLength = $derived(normalizeMinLength(minLength));
|
|
66
|
+
let effectiveDebounceMs = $derived(normalizeDebounceMs(debounceMs));
|
|
67
|
+
|
|
47
68
|
function handleInput() {
|
|
48
69
|
selectedIndex = -1;
|
|
49
70
|
clearTimeout(debounceTimer);
|
|
50
71
|
abortController?.abort();
|
|
51
72
|
|
|
52
|
-
|
|
73
|
+
// Trim first so whitespace-only input (e.g. " ") doesn't clear the gate
|
|
74
|
+
// and bill a request for an empty search.
|
|
75
|
+
const trimmed = query.trim();
|
|
76
|
+
if (trimmed.length < effectiveMinLength) {
|
|
53
77
|
suggestions = [];
|
|
54
78
|
return;
|
|
55
79
|
}
|
|
@@ -58,7 +82,7 @@
|
|
|
58
82
|
abortController = new AbortController();
|
|
59
83
|
try {
|
|
60
84
|
suggestions = await geocode(
|
|
61
|
-
|
|
85
|
+
trimmed,
|
|
62
86
|
{
|
|
63
87
|
accessToken,
|
|
64
88
|
autocomplete,
|
|
@@ -78,7 +102,7 @@
|
|
|
78
102
|
if (e instanceof DOMException && e.name === 'AbortError') return;
|
|
79
103
|
console.error('Geocoder error:', e);
|
|
80
104
|
}
|
|
81
|
-
},
|
|
105
|
+
}, effectiveDebounceMs);
|
|
82
106
|
}
|
|
83
107
|
|
|
84
108
|
onDestroy(() => {
|
|
@@ -10,6 +10,17 @@ interface Props extends Omit<GeocodeOptions, 'accessToken'> {
|
|
|
10
10
|
lat: number;
|
|
11
11
|
name: string;
|
|
12
12
|
}) => void;
|
|
13
|
+
/**
|
|
14
|
+
* Minimum number of characters before a request is made. Raising this
|
|
15
|
+
* cuts the number of paid geocoding requests per search. Defaults to 2.
|
|
16
|
+
*/
|
|
17
|
+
minLength?: number;
|
|
18
|
+
/**
|
|
19
|
+
* Debounce window in milliseconds between the last keystroke and the
|
|
20
|
+
* request. Raising this fires fewer requests while the user is still
|
|
21
|
+
* typing (each request is billed). Defaults to 300.
|
|
22
|
+
*/
|
|
23
|
+
debounceMs?: number;
|
|
13
24
|
}
|
|
14
25
|
/** `Geocoder` [Read the docs.](https://reuters-graphics.github.io/graphics-components/?path=/docs/components-controls-geocoder--docs) */
|
|
15
26
|
declare const Geocoder: import("svelte").Component<Props, {}, "">;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coercion helpers for the Geocoder's request-throttling props.
|
|
3
|
+
*
|
|
4
|
+
* These props can arrive as strings when set via markup (e.g.
|
|
5
|
+
* `minLength="two"`), so a non-numeric value must not be trusted directly: a
|
|
6
|
+
* `NaN` would disable the length gate or the debounce and bill a Mapbox request
|
|
7
|
+
* on every keystroke. Both helpers fall back to the documented defaults and
|
|
8
|
+
* clamp to sane floors.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Coerce a consumer-supplied `minLength` to a safe integer of at least 1.
|
|
12
|
+
* Invalid or sub-1 values fall back to `fallback` (default 2).
|
|
13
|
+
*/
|
|
14
|
+
export declare function normalizeMinLength(value: unknown, fallback?: number): number;
|
|
15
|
+
/**
|
|
16
|
+
* Coerce a consumer-supplied `debounceMs` to a finite, non-negative number.
|
|
17
|
+
* Invalid or negative values fall back to `fallback` (default 300).
|
|
18
|
+
*/
|
|
19
|
+
export declare function normalizeDebounceMs(value: unknown, fallback?: number): number;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coercion helpers for the Geocoder's request-throttling props.
|
|
3
|
+
*
|
|
4
|
+
* These props can arrive as strings when set via markup (e.g.
|
|
5
|
+
* `minLength="two"`), so a non-numeric value must not be trusted directly: a
|
|
6
|
+
* `NaN` would disable the length gate or the debounce and bill a Mapbox request
|
|
7
|
+
* on every keystroke. Both helpers fall back to the documented defaults and
|
|
8
|
+
* clamp to sane floors.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Coerce a consumer-supplied `minLength` to a safe integer of at least 1.
|
|
12
|
+
* Invalid or sub-1 values fall back to `fallback` (default 2).
|
|
13
|
+
*/
|
|
14
|
+
export function normalizeMinLength(value, fallback = 2) {
|
|
15
|
+
const n = Number(value);
|
|
16
|
+
return Number.isFinite(n) && n >= 1 ? Math.floor(n) : fallback;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Coerce a consumer-supplied `debounceMs` to a finite, non-negative number.
|
|
20
|
+
* Invalid or negative values fall back to `fallback` (default 300).
|
|
21
|
+
*/
|
|
22
|
+
export function normalizeDebounceMs(value, fallback = 300) {
|
|
23
|
+
const n = Number(value);
|
|
24
|
+
return Number.isFinite(n) && n >= 0 ? n : fallback;
|
|
25
|
+
}
|