feat: select first location suggestion on enter

This commit is contained in:
zv
2026-06-14 10:26:40 +02:00
parent 89d2066077
commit de06056596

View File

@@ -1,12 +1,13 @@
"use client"; "use client";
import { useMemo, useState } from "react"; import { useMemo, useState, type KeyboardEvent } from "react";
import { LoaderCircle, MapPin, Search, X } from "lucide-react"; import { LoaderCircle, MapPin, Search, X } from "lucide-react";
import { useLocationSearch } from "@/hooks/use-location-search"; import { useLocationSearch } from "@/hooks/use-location-search";
import { useWeatherStore } from "@/lib/store"; import { useWeatherStore } from "@/lib/store";
import { findNearestSynopStation, locateSynopStations } from "@/lib/location-utils"; import { findNearestSynopStation, locateSynopStations } from "@/lib/location-utils";
import { useI18n } from "@/lib/i18n"; import { useI18n } from "@/lib/i18n";
import type { MeteoStationPosition, SynopStation } from "@/types/imgw"; import type { MeteoStationPosition, SynopStation } from "@/types/imgw";
import type { SelectedLocation } from "@/types/location";
import { CurrentLocationControl } from "@/components/weather/current-location-control"; import { CurrentLocationControl } from "@/components/weather/current-location-control";
export function LocationSearch({ stations, positions }: { stations: SynopStation[]; positions: MeteoStationPosition[] }) { export function LocationSearch({ stations, positions }: { stations: SynopStation[]; positions: MeteoStationPosition[] }) {
@@ -24,6 +25,19 @@ export function LocationSearch({ stations, positions }: { stations: SynopStation
const showSuggestions = isFocused && query.trim().length >= 2; const showSuggestions = isFocused && query.trim().length >= 2;
const isPreparingStations = positions.length === 0; const isPreparingStations = positions.length === 0;
function chooseLocation(location: SelectedLocation) {
selectLocation(location);
setQuery("");
setIsFocused(false);
}
function handleSearchKeyDown(event: KeyboardEvent<HTMLInputElement>) {
const firstSuggestion = suggestions[0]?.nearest;
if (event.key !== "Enter" || !showSuggestions || !firstSuggestion) return;
event.preventDefault();
chooseLocation(firstSuggestion);
}
return ( return (
<section className="relative z-30"> <section className="relative z-30">
<div className="glass rounded-panel p-3 sm:p-4"> <div className="glass rounded-panel p-3 sm:p-4">
@@ -38,6 +52,7 @@ export function LocationSearch({ stations, positions }: { stations: SynopStation
<input <input
value={query} value={query}
onChange={(event) => setQuery(event.target.value)} onChange={(event) => setQuery(event.target.value)}
onKeyDown={handleSearchKeyDown}
onFocus={() => setIsFocused(true)} onFocus={() => setIsFocused(true)}
onBlur={() => window.setTimeout(() => setIsFocused(false), 150)} onBlur={() => window.setTimeout(() => setIsFocused(false), 150)}
placeholder={t("location.placeholder")} placeholder={t("location.placeholder")}
@@ -55,11 +70,7 @@ export function LocationSearch({ stations, positions }: { stations: SynopStation
<button <button
type="button" type="button"
key={location.id} key={location.id}
onClick={() => { onClick={() => chooseLocation(nearest)}
selectLocation(nearest);
setQuery("");
setIsFocused(false);
}}
className="flex w-full items-start justify-between gap-3 rounded-card px-3 py-3 text-left transition hover:bg-surface-muted/70 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent" className="flex w-full items-start justify-between gap-3 rounded-card px-3 py-3 text-left transition hover:bg-surface-muted/70 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent"
> >
<span> <span>