feat : Différents inputs

This commit is contained in:
Yaël Perret
2026-09-08 21:44:07 +02:00
parent 8ed48a6cd3
commit 845a9509b7
10 changed files with 665 additions and 199 deletions

View 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;