feat(SKY-8998): hint city/state search in proxy location selector (#5640)
Some checks are pending
Run tests and pre-commit / Frontend Lint and Build (push) Waiting to run
Run tests and pre-commit / Run tests and pre-commit hooks (push) Waiting to run
Publish Fern Docs / run (push) Waiting to run

This commit is contained in:
Aaron Perez 2026-04-23 23:30:38 -05:00 committed by GitHub
parent 80308d8246
commit a06d3bbace
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -47,27 +47,48 @@ export function GeoTargetSelector({
cities: [], cities: [],
}); });
const [loading, setLoading] = React.useState(false); const [loading, setLoading] = React.useState(false);
// Monotonic id for the latest in-flight search. Stale completions whose
// id no longer matches are ignored so a slow prior request cannot clobber
// results from a newer one (e.g. reopen after a granular search).
const searchIdRef = React.useRef(0);
const handleSearch = useDebouncedCallback(async (searchQuery: string) => { const runSearch = React.useCallback(
setLoading(true); async (searchQuery: string) => {
try { const id = ++searchIdRef.current;
const data = await searchGeoData(searchQuery, { setLoading(true);
includeGranularResults: allowGranularSearch, try {
}); const data = await searchGeoData(searchQuery, {
setResults(data); includeGranularResults: allowGranularSearch,
} catch (error) { });
console.error("Failed to search geo data", error); if (searchIdRef.current === id) {
} finally { setResults(data);
setLoading(false); }
} } catch (error) {
}, 300); if (searchIdRef.current === id) {
console.error("Failed to search geo data", error);
}
} finally {
if (searchIdRef.current === id) {
setLoading(false);
}
}
},
[allowGranularSearch],
);
// Initial load of countries const handleSearch = useDebouncedCallback(runSearch, 300);
// Reset query, drop any stale granular results, and reload countries each
// time the popover opens. The search runs without debounce so the list
// matches the empty input immediately rather than after a 300ms window.
React.useEffect(() => { React.useEffect(() => {
if (open) { if (open) {
handleSearch(""); handleSearch.cancel();
setQuery("");
setResults({ countries: [], subdivisions: [], cities: [] });
runSearch("");
} }
}, [open, handleSearch]); }, [open, handleSearch, runSearch]);
const onInput = (val: string) => { const onInput = (val: string) => {
setQuery(val); setQuery(val);
@ -109,7 +130,7 @@ export function GeoTargetSelector({
<CommandInput <CommandInput
placeholder={ placeholder={
allowGranularSearch allowGranularSearch
? "Search country, state, or city..." ? "Type a country, state, or city..."
: "Search country..." : "Search country..."
} }
value={query} value={query}
@ -128,6 +149,12 @@ export function GeoTargetSelector({
<CommandEmpty>No location found.</CommandEmpty> <CommandEmpty>No location found.</CommandEmpty>
)} )}
{!loading && allowGranularSearch && query.trim().length < 2 && (
<div className="border-b px-3 py-2 text-xs text-muted-foreground">
Type to search by state or city.
</div>
)}
{!loading && ( {!loading && (
<> <>
{results.countries.length > 0 && ( {results.countries.length > 0 && (