import React, { useEffect, useState } from 'react'; import { Animated, Easing, KeyboardAvoidingView, Modal, StyleSheet, Text, TouchableWithoutFeedback, View, TextStyle } from 'react-native'; import { BLOCK_CONTEXT } from '@rocket.chat/ui-kit'; import Button from '../../Button'; import TextInput from '../../TextInput'; import { textParser } from '../utils'; import { themes } from '../../../constants/colors'; import I18n from '../../../i18n'; import { isIOS } from '../../../utils/deviceInfo'; import { useTheme } from '../../../theme'; import { BlockContext, IText } from '../interfaces'; import Chips from './Chips'; import Items from './Items'; import Input from './Input'; import styles from './styles'; export interface IItemData { value: string; text: { text: string }; imageUrl?: string; } interface IMultiSelect { options?: IItemData[]; onChange: Function; placeholder?: IText; context?: BlockContext; loading?: boolean; multiselect?: boolean; onSearch?: () => void; onClose?: () => void; inputStyle?: TextStyle; value?: any[]; disabled?: boolean | null; innerInputStyle?: object; } const ANIMATION_DURATION = 200; const ANIMATION_PROPS = { duration: ANIMATION_DURATION, easing: Easing.inOut(Easing.quad), useNativeDriver: true }; const animatedValue = new Animated.Value(0); const behavior = isIOS ? 'padding' : null; export const MultiSelect = React.memo( ({ options = [], onChange, placeholder = { text: 'Search' }, context, loading, value: values, multiselect = false, onSearch, onClose = () => {}, disabled, inputStyle, innerInputStyle }: IMultiSelect) => { const { theme } = useTheme(); const [selected, select] = useState(Array.isArray(values) ? values : []); const [open, setOpen] = useState(false); const [search, onSearchChange] = useState(''); const [currentValue, setCurrentValue] = useState(''); const [showContent, setShowContent] = useState(false); useEffect(() => { if (Array.isArray(values)) { select(values); } }, [values]); useEffect(() => { setOpen(showContent); }, [showContent]); useEffect(() => { if (values && values.length && !multiselect) { setCurrentValue(values[0].text); } }, []); const onShow = () => { Animated.timing(animatedValue, { toValue: 1, ...ANIMATION_PROPS }).start(); setShowContent(true); }; const onHide = () => { onClose(); Animated.timing(animatedValue, { toValue: 0, ...ANIMATION_PROPS }).start(() => setShowContent(false)); }; const onSelect = (item: IItemData) => { const { value, text: { text } } = item; if (multiselect) { let newSelect = []; if (!selected.includes(value)) { newSelect = [...selected, value]; } else { newSelect = selected.filter((s: any) => s !== value); } select(newSelect); onChange({ value: newSelect }); } else { onChange({ value }); setCurrentValue(text); onHide(); } }; const renderContent = () => { const items: any = onSearch ? options : options.filter((option: any) => textParser([option.text]).toLowerCase().includes(search.toLowerCase())); return ( ); }; const translateY = animatedValue.interpolate({ inputRange: [0, 1], outputRange: [600, 0] }); let button = multiselect ? (