Files
Kazier/mobile/components/SearchBar.tsx
T
2026-08-28 23:41:42 +02:00

118 lines
2.9 KiB
TypeScript

import React from 'react';
import { View, TextInput, TouchableOpacity, Text, StyleSheet } from 'react-native';
import { MaterialIcons } from '@expo/vector-icons';
import type { ComponentProps } from 'react';
type IconName = ComponentProps<typeof MaterialIcons>['name'];
export interface SearchFilters {
name: boolean;
ocrText: boolean;
}
export type SortKey = 'date' | 'name' | 'size';
export type SortDirection = 'asc' | 'desc';
export interface SortState {
key: SortKey;
direction: SortDirection;
}
interface SearchBarProps {
query: string;
onQueryChange: (q: string) => void;
onClear: () => void;
filters: SearchFilters;
onFiltersChange: (f: SearchFilters) => void;
onSettingsPress: () => void;
sort: SortState;
bottomPadding?: number;
}
export function SearchBar({ query, onQueryChange, onClear, filters, onSettingsPress, sort, bottomPadding = 0 }: SearchBarProps) {
const hasActiveFilter = filters.name || filters.ocrText || sort.key !== 'date';
return (
<View style={[styles.wrapper, { paddingBottom: bottomPadding }]}>
<View style={styles.inputRow}>
<View style={styles.inputContainer}>
<MaterialIcons name="search" size={20} color="#999" style={styles.searchIcon} />
<TextInput
style={styles.input}
placeholder="Rechercher..."
placeholderTextColor="#999"
value={query}
onChangeText={onQueryChange}
returnKeyType="search"
autoCorrect={false}
/>
{query.length > 0 && (
<TouchableOpacity onPress={onClear} style={styles.clearBtn}>
<MaterialIcons name="close" size={18} color="#999" />
</TouchableOpacity>
)}
</View>
<TouchableOpacity
style={[styles.iconBtn, hasActiveFilter && styles.iconBtnActive]}
onPress={onSettingsPress}
>
<MaterialIcons
name="tune"
size={22}
color={hasActiveFilter ? '#fff' : '#1976D2'}
/>
</TouchableOpacity>
</View>
</View>
);
}
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,
},
iconBtn: {
width: 40,
height: 40,
borderRadius: 10,
borderWidth: 1,
borderColor: '#1976D2',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#fff',
},
iconBtnActive: {
backgroundColor: '#1976D2',
},
});