feat : Différents inputs
This commit is contained in:
84
src/components/form/SearchInput.tsx
Normal file
84
src/components/form/SearchInput.tsx
Normal file
@@ -0,0 +1,84 @@
|
||||
import { Search, X } from 'lucide-react-native';
|
||||
import {
|
||||
forwardRef,
|
||||
useEffect,
|
||||
useImperativeHandle,
|
||||
useRef,
|
||||
type ReactNode,
|
||||
} from 'react';
|
||||
import { Pressable, StyleSheet, TextInput } from 'react-native';
|
||||
|
||||
import { colors } from '@/theme/colors';
|
||||
|
||||
import Input, { type InputProps } from './Input';
|
||||
|
||||
export type SearchInputProps = Omit<InputProps, 'left' | 'right'> & {
|
||||
onDebouncedChange?: (value: string) => void;
|
||||
debounceMs?: number;
|
||||
};
|
||||
|
||||
const SearchInput = forwardRef<TextInput, SearchInputProps>(function SearchInput(
|
||||
{ onDebouncedChange, debounceMs = 300, value, onChangeText, ...props },
|
||||
ref,
|
||||
) {
|
||||
const inputRef = useRef<TextInput>(null);
|
||||
const valueAsString = typeof value === 'string' ? value : '';
|
||||
|
||||
useImperativeHandle(ref, () => inputRef.current as TextInput);
|
||||
|
||||
useEffect(() => {
|
||||
if (!onDebouncedChange) {
|
||||
return;
|
||||
}
|
||||
|
||||
const timer = setTimeout(() => {
|
||||
onDebouncedChange(valueAsString);
|
||||
}, debounceMs);
|
||||
|
||||
return () => {
|
||||
clearTimeout(timer);
|
||||
};
|
||||
}, [debounceMs, onDebouncedChange, valueAsString]);
|
||||
|
||||
const clearButton: ReactNode =
|
||||
valueAsString.length > 0 ? (
|
||||
<Pressable
|
||||
onPress={() => {
|
||||
onChangeText?.('');
|
||||
inputRef.current?.clear();
|
||||
inputRef.current?.focus();
|
||||
}}
|
||||
style={styles.clearButton}
|
||||
hitSlop={8}
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel="Vider la recherche"
|
||||
>
|
||||
<X color={colors.textSecondary} size={20} />
|
||||
</Pressable>
|
||||
) : null;
|
||||
|
||||
return (
|
||||
<Input
|
||||
ref={inputRef}
|
||||
value={value}
|
||||
onChangeText={onChangeText}
|
||||
left={<Search color={colors.textSecondary} size={20} />}
|
||||
right={clearButton}
|
||||
returnKeyType="search"
|
||||
autoCorrect={false}
|
||||
clearButtonMode="never"
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
clearButton: {
|
||||
width: 44,
|
||||
height: 44,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
});
|
||||
|
||||
export default SearchInput;
|
||||
Reference in New Issue
Block a user