import { ChevronDown, Search, X } from 'lucide-react-native'; import React, { useState, useEffect, useMemo } from 'react'; import { Modal, FlatList, Text, TextInput, TouchableOpacity, View, Keyboard, KeyboardEvent, Platform } from 'react-native'; interface DropdownOption { id: any; label: string; } interface GenericDropdownProps { options: DropdownOption[]; selectedId: any; onSelect: (id: any) => void; placeholder?: string; searchPlaceholder?: string; showSearch?: boolean; } export default function GenericDropdown({ options, selectedId, onSelect, placeholder = 'Seleziona un\'opzione...', searchPlaceholder = 'Cerca...', showSearch = true }: GenericDropdownProps) { const [showPicker, setShowPicker] = useState(false); const [searchQuery, setSearchQuery] = useState(''); const [keyboardHeight, setKeyboardHeight] = useState(0); // Keyboard height listener useEffect(() => { const showSubscription = Keyboard.addListener( Platform.OS === 'ios' ? 'keyboardWillShow' : 'keyboardDidShow', (e: KeyboardEvent) => setKeyboardHeight(e.endCoordinates.height) ); const hideSubscription = Keyboard.addListener( Platform.OS === 'ios' ? 'keyboardWillHide' : 'keyboardDidHide', () => setKeyboardHeight(0) ); return () => { showSubscription.remove(); hideSubscription.remove(); }; }, []); // Reset search query every time modal is opened useEffect(() => { if (showPicker) { setSearchQuery(''); } }, [showPicker]); const filteredOptions = useMemo(() => { if (!showPicker) return []; if (!searchQuery.trim()) return options; const lowerQuery = searchQuery.toLowerCase(); return options.filter(o => o.label.toLowerCase().includes(lowerQuery)); }, [options, searchQuery, showPicker]); const selectedLabel = selectedId !== null && selectedId !== undefined ? options.find(o => o.id === selectedId)?.label || placeholder : placeholder; return ( setShowPicker(true)} className="flex-1 flex-row items-center justify-between bg-white px-5 py-4 rounded-2xl border border-gray-200 shadow-sm" > {selectedLabel} {selectedId !== null && selectedId !== undefined && ( onSelect(null)} className="bg-gray-50 p-4 rounded-2xl border border-gray-200 shadow-sm justify-center items-center" > )} setShowPicker(false)}> setShowPicker(false)} className="flex-1 bg-black/50 justify-end" style={{ paddingBottom: keyboardHeight }} > true}> Seleziona setShowPicker(false)} className="p-2 bg-gray-100 rounded-full active:bg-gray-200"> {/* Search Bar */} {showSearch && ( {searchQuery.length > 0 && ( setSearchQuery('')} className="p-1"> )} )} String(item.id)} ListHeaderComponent={() => ( searchQuery.trim() === '' ? ( { onSelect(null); setShowPicker(false); }} > Nessuna selezione ) : null )} ListEmptyComponent={() => ( Nessun risultato trovato )} initialNumToRender={15} maxToRenderPerBatch={20} windowSize={5} removeClippedSubviews={true} renderItem={({ item }) => ( { onSelect(item.id); setShowPicker(false); }} > {item.label} )} /> ); }