Files
blitzkit/src/app/tools/tankopedia/components/SearchBar.tsx
T

76 lines
2.2 KiB
TypeScript
Raw Normal View History

2024-06-21 19:04:34 -05:00
import { CaretRightIcon, MagnifyingGlassIcon } from '@radix-ui/react-icons';
2024-06-22 16:39:31 -05:00
import { Button, Flex, Spinner, TextField } from '@radix-ui/themes';
2024-06-21 19:04:34 -05:00
import { debounce } from 'lodash';
import { useRouter } from 'next/navigation';
2024-06-24 14:10:23 -05:00
import { KeyboardEventHandler, useCallback, useRef } from 'react';
2024-06-21 19:04:34 -05:00
import { Link } from '../../../../components/Link';
import { TankDefinition } from '../../../../core/blitzkit/tankDefinitions';
import { useTankopediaFilters } from '../../../../stores/tankopediaFilters';
2024-06-22 16:39:31 -05:00
import { Sort } from './Sort';
2024-06-21 19:04:34 -05:00
interface SearchBarProps {
topResult?: TankDefinition;
}
export function SearchBar({ topResult }: SearchBarProps) {
const router = useRouter();
const input = useRef<HTMLInputElement>(null);
2024-06-24 14:10:23 -05:00
const searching = useTankopediaFilters((state) => state.searching);
2024-06-21 19:04:34 -05:00
const search = useCallback(
debounce(() => {
2024-06-24 14:10:23 -05:00
useTankopediaFilters.setState({ searching: false });
2024-06-21 19:04:34 -05:00
if (!input.current) return;
const sanitized = input.current.value.trim();
useTankopediaFilters.setState({
search: sanitized.length === 0 ? undefined : sanitized,
});
}, 500),
[],
);
const handleChange = useCallback(() => {
2024-06-24 14:10:23 -05:00
useTankopediaFilters.setState({ searching: true });
2024-06-21 19:04:34 -05:00
search();
}, []);
const handleKeyDown = useCallback<KeyboardEventHandler>(
(event) => {
2024-06-24 14:14:25 -05:00
if (event.key !== 'Enter' || !topResult || searching) return;
2024-06-21 19:04:34 -05:00
event.preventDefault();
router.push(`/tools/tankopedia/${topResult.id}`);
},
[topResult],
);
return (
2024-06-24 13:54:08 -05:00
<Flex justify="center">
<Flex gap="2" flexGrow="1">
<TextField.Root
style={{ flex: 1 }}
ref={input}
placeholder="Search tanks..."
onChange={handleChange}
onKeyDown={handleKeyDown}
>
2024-06-22 16:39:31 -05:00
<TextField.Slot>
2024-06-24 13:54:08 -05:00
{searching ? <Spinner /> : <MagnifyingGlassIcon />}
2024-06-22 16:39:31 -05:00
</TextField.Slot>
2024-06-24 14:14:25 -05:00
{topResult && !searching && (
2024-06-24 13:54:08 -05:00
<TextField.Slot>
<Link href={`/tools/tankopedia/${topResult.id}`}>
<Button variant="ghost">
{topResult.name} <CaretRightIcon />
</Button>
</Link>
</TextField.Slot>
)}
</TextField.Root>
<Sort />
</Flex>
2024-06-22 16:39:31 -05:00
</Flex>
2024-06-21 19:04:34 -05:00
);
}