54 lines
1.4 KiB
TypeScript
54 lines
1.4 KiB
TypeScript
import React, { useState, useEffect } from 'react';
|
|
import { View, TextInput, TouchableOpacity, Image } from 'react-native';
|
|
import icons from '@/constants/icons';
|
|
|
|
interface Props {
|
|
onSearch: (query: string) => void;
|
|
}
|
|
|
|
export function useDebounce<T>(value: T, delay: number = 500): T {
|
|
const [debouncedValue, setDebouncedValue] = useState<T>(value);
|
|
|
|
useEffect(() => {
|
|
const timer = setTimeout(() => {
|
|
setDebouncedValue(value);
|
|
}, delay);
|
|
|
|
return () => {
|
|
clearTimeout(timer);
|
|
};
|
|
}, [value, delay]);
|
|
|
|
return debouncedValue;
|
|
}
|
|
|
|
const Search = ({ onSearch }: Props) => {
|
|
const [searchQuery, setSearchQuery] = useState('');
|
|
const debouncedQuery = useDebounce(searchQuery);
|
|
|
|
React.useEffect(() => {
|
|
onSearch(debouncedQuery);
|
|
}, [debouncedQuery]);
|
|
|
|
return (
|
|
<View className="flex-row items-center bg-gray-100 rounded-full px-4 py-2">
|
|
<Image source={icons.search} className="w-5 h-5 mr-2" />
|
|
<TextInput
|
|
placeholder="Search cars..."
|
|
className="flex-1"
|
|
placeholderTextColor="#666"
|
|
value={searchQuery}
|
|
onChangeText={setSearchQuery}
|
|
/>
|
|
{searchQuery ? (
|
|
<TouchableOpacity onPress={() => setSearchQuery('')}>
|
|
<Image source={icons.backArrow} className="w-5 h-5" />
|
|
</TouchableOpacity>
|
|
) : null}
|
|
</View>
|
|
);
|
|
};
|
|
|
|
|
|
export default Search;
|