This commit is contained in:
Andras Schmelczer 2026-03-15 17:38:26 +00:00
parent 80c093b7ba
commit f72c43a9fa
101 changed files with 2168 additions and 1177 deletions

View file

@ -1,10 +1,4 @@
import {
useState,
useRef,
useEffect,
useCallback,
useMemo,
} from 'react';
import { useState, useRef, useEffect, useCallback, useMemo } from 'react';
import { createPortal } from 'react-dom';
import type { Destination } from '../../hooks/useTravelDestinations';
import { useDropdownPosition } from '../../hooks/useDropdownPosition';
@ -42,9 +36,7 @@ export function DestinationDropdown({
if (!filter) return destinations;
const lower = filter.toLowerCase();
return destinations.filter(
(d) =>
d.name.toLowerCase().includes(lower) ||
d.city?.toLowerCase().includes(lower),
(d) => d.name.toLowerCase().includes(lower) || d.city?.toLowerCase().includes(lower)
);
}, [destinations, filter]);
@ -79,16 +71,14 @@ export function DestinationDropdown({
setFilter('');
setActiveIndex(-1);
},
[onSelect],
[onSelect]
);
const handleKeyDown = useCallback(
(e: React.KeyboardEvent) => {
if (e.key === 'ArrowDown') {
e.preventDefault();
setActiveIndex((prev) =>
prev < filtered.length - 1 ? prev + 1 : prev,
);
setActiveIndex((prev) => (prev < filtered.length - 1 ? prev + 1 : prev));
} else if (e.key === 'ArrowUp') {
e.preventDefault();
setActiveIndex((prev) => (prev > 0 ? prev - 1 : -1));
@ -102,7 +92,7 @@ export function DestinationDropdown({
setFilter('');
}
},
[filtered, activeIndex, handleSelect],
[filtered, activeIndex, handleSelect]
);
const handleOpen = useCallback(() => {
@ -170,10 +160,7 @@ export function DestinationDropdown({
<span className="text-warm-700 dark:text-warm-200 truncate">
{dest.name}
{dest.city && (
<span className="text-warm-400 dark:text-warm-500">
{' '}
({dest.city})
</span>
<span className="text-warm-400 dark:text-warm-500"> ({dest.city})</span>
)}
</span>
</button>
@ -185,7 +172,9 @@ export function DestinationDropdown({
return (
<div ref={containerRef} className="relative">
<div className={`w-full flex items-center gap-1.5 px-2 py-1 text-xs rounded border ${value ? 'border-warm-200 dark:border-warm-700 bg-warm-50 dark:bg-warm-800' : 'border-warm-200 dark:border-warm-600 bg-white dark:bg-warm-800 hover:border-warm-300 dark:hover:border-warm-500'}`}>
<div
className={`w-full flex items-center gap-1.5 px-2 py-1 text-xs rounded border ${value ? 'border-warm-200 dark:border-warm-700 bg-warm-50 dark:bg-warm-800' : 'border-warm-200 dark:border-warm-600 bg-white dark:bg-warm-800 hover:border-warm-300 dark:hover:border-warm-500'}`}
>
<button
type="button"
onClick={handleOpen}
@ -194,9 +183,13 @@ export function DestinationDropdown({
{loading ? (
<div className="w-3 h-3 border-2 border-warm-300 dark:border-warm-600 border-t-teal-500 rounded-full animate-spin shrink-0" />
) : (
<MapPinIcon className={`w-3 h-3 shrink-0 ${value ? 'text-red-500' : 'text-warm-400 dark:text-warm-500'}`} />
<MapPinIcon
className={`w-3 h-3 shrink-0 ${value ? 'text-red-500' : 'text-warm-400 dark:text-warm-500'}`}
/>
)}
<span className={`flex-1 text-left truncate ${value ? 'text-navy-950 dark:text-warm-200' : 'text-warm-400 dark:text-warm-500'}`}>
<span
className={`flex-1 text-left truncate ${value ? 'text-navy-950 dark:text-warm-200' : 'text-warm-400 dark:text-warm-500'}`}
>
{value || placeholder}
</span>
</button>