import React, { useRef, useEffect } from 'react'; import { View, TextInput, TouchableOpacity, Text, StyleSheet, Animated } from 'react-native'; import { MaterialIcons } from '@expo/vector-icons'; import type { ComponentProps } from 'react'; type IconName = ComponentProps['name']; export interface SearchFilters { name: boolean; ocrText: boolean; tags: boolean; } interface SearchBarProps { query: string; onQueryChange: (q: string) => void; onClear: () => void; filters: SearchFilters; onFiltersChange: (f: SearchFilters) => void; } const FILTER_OPTIONS: { key: keyof SearchFilters; label: string; icon: IconName }[] = [ { key: 'name', label: 'Nom', icon: 'drive-file-rename-outline' }, { key: 'ocrText', label: 'Texte OCR', icon: 'document-scanner' }, { key: 'tags', label: 'Tags', icon: 'label-outline' }, ]; export function SearchBar({ query, onQueryChange, onClear, filters, onFiltersChange }: SearchBarProps) { const animatedHeight = useRef(new Animated.Value(0)).current; const [panelOpen, setPanelOpen] = React.useState(false); useEffect(() => { Animated.spring(animatedHeight, { toValue: panelOpen ? 1 : 0, useNativeDriver: false, tension: 60, friction: 8, }).start(); }, [panelOpen]); const panelMaxHeight = animatedHeight.interpolate({ inputRange: [0, 1], outputRange: [0, 100], }); const toggleFilter = (key: keyof SearchFilters) => { onFiltersChange({ ...filters, [key]: !filters[key] }); }; const hasActiveFilter = filters.name || filters.ocrText || filters.tags; return ( {query.length > 0 && ( )} setPanelOpen(!panelOpen)} > {FILTER_OPTIONS.map((opt) => ( toggleFilter(opt.key)} > {opt.label} ))} ); } const styles = StyleSheet.create({ wrapper: { backgroundColor: '#fff', borderTopWidth: 1, borderTopColor: '#e0e0e0', }, inputRow: { flexDirection: 'row', alignItems: 'center', paddingHorizontal: 12, paddingVertical: 10, gap: 8, }, inputContainer: { flex: 1, flexDirection: 'row', alignItems: 'center', backgroundColor: '#f5f5f5', borderRadius: 10, paddingHorizontal: 10, }, searchIcon: { marginRight: 6, }, input: { flex: 1, paddingVertical: 8, fontSize: 14, color: '#333', }, clearBtn: { padding: 4, }, filterBtn: { width: 40, height: 40, borderRadius: 10, borderWidth: 1, borderColor: '#1976D2', justifyContent: 'center', alignItems: 'center', backgroundColor: '#fff', }, filterBtnActive: { backgroundColor: '#1976D2', }, filterPanel: { flexDirection: 'row', paddingHorizontal: 12, paddingBottom: 10, gap: 8, overflow: 'hidden', }, filterChip: { flexDirection: 'row', alignItems: 'center', paddingHorizontal: 12, paddingVertical: 6, borderRadius: 16, borderWidth: 1, borderColor: '#1976D2', gap: 4, }, filterChipActive: { backgroundColor: '#1976D2', }, filterChipText: { fontSize: 12, color: '#1976D2', }, filterChipTextActive: { color: '#fff', }, });