import React, { useEffect, useRef, useState } from 'react'; import { TextInput, View, type StyleProp, type ViewStyle } from 'react-native'; import AntDesign from 'react-native-vector-icons/AntDesign'; import Feather from 'react-native-vector-icons/Feather'; import { colors } from '../colors/colors'; import { globalStyles } from '../styles/globalStyles'; import { replaceName } from '../utils/replaceName'; import Card from './Card'; import Col from './Col'; import Row from './Row'; import Space from './Space'; import Text from './Text'; import type { SelectModel } from '../models/SelectModel'; export interface SelectProps { options: SelectModel[]; multible?: boolean; selected?: string | string[]; onSelect: (val: string | string[]) => void; styles?: StyleProp; placeholder?: string; } const Select = (props: SelectProps) => { const { options, multible, selected, onSelect, styles, placeholder } = props; const [searchKey, setSearchKey] = useState(''); const [itemsSelected, setItemsSelected] = useState([]); const [buttonHeight, setButtonHeight] = useState(); const [isShow, setIsShow] = useState(false); const [results, setResults] = useState([]); const inpRef = useRef(null); useEffect(() => { setResults(options); }, [options]); useEffect(() => { !isShow && setSearchKey(''); }, [isShow]); useEffect(() => { if (!searchKey) { setResults(options); } else { const items = options.filter( (element) => typeof element.label === 'string' && replaceName(element.label).includes(replaceName(searchKey)) ); setResults(items); } }, [searchKey, options]); useEffect(() => { setItemsSelected( selected ? (typeof selected === 'string' ? [selected] : selected) : [] ); }, [selected]); const handleSelect = (val: string) => { const items = [...itemsSelected]; const index = items.findIndex((element) => element === val); if (index !== -1) { items.splice(index, 1); } else { items.push(val); } onSelect(items); setSearchKey(''); }; const renderText = (val: string, index: number) => { const item = results.find((element) => element.value === val); const text = typeof item?.label === 'string' ? ( ) : ( item?.label ); return multible ? ( { const items = [...itemsSelected]; items.splice(index, 1); setItemsSelected(items); }} key={`selected${val}`} styles={{ backgroundColor: '#f3f3f3', paddingVertical: 2, borderRadius: 100, paddingHorizontal: 12, marginRight: 6, marginBottom: 6, }} > {text} ) : ( text ); }; return ( { setButtonHeight(event.nativeEvent.layout.height); }} > {itemsSelected.length > 0 && itemsSelected.map((item, index) => renderText(item, index))} setIsShow(true)} onBlur={() => setIsShow(false)} style={[globalStyles.input, { flex: 1, minWidth: 100 }]} placeholder={ itemsSelected.length === 0 ? placeholder ? placeholder : 'Chọn' : '' } value={searchKey} onChangeText={(val) => setSearchKey(val)} ref={inpRef} /> {isShow ? ( {results.length > 0 ? ( results.map((item, index) => typeof item.label === 'string' ? ( { if (multible) { handleSelect(item.value); } else { onSelect(item.value); setIsShow(false); inpRef.current?.blur(); } }} key={item.value} justifyContent="flex-start" styles={{ marginBottom: index < options.length - 1 ? 12 : 0, }} > {itemsSelected.includes(item.value) && ( )} ) : ( item.label ) ) ) : ( )} ) : null} ); }; export default Select;