UNPKG

@uiw/react-native

Version:
144 lines (142 loc) 3.99 kB
import React, { useState, useEffect, memo } from 'react'; import { View, Text, SafeAreaView, StyleSheet, TouchableWithoutFeedback, ActivityIndicator, Pressable } from 'react-native'; import MaskLayer from '../MaskLayer'; import SearchInputBar from '../SearchInputBar'; import List from '../List'; import Icon from '../Icon'; // 搜索组件 function SearchBar({ onChangeText, options = [], onChange, labelInValue, disabled, value, onFocus, onBlur, loading, placeholder, extra, showClear = true, contentStyle = {}, placeholderColor, ...searchInputBarProps }) { const [curValue, setCurValue] = useState(value); const [visible, setVisivble] = useState(false); let textValue; if (labelInValue) { textValue = curValue?.label; } else { const { label } = options.find(item => item.value === curValue); textValue = label; } useEffect(() => { setCurValue(value); }, [value]); // 搜索 const onHandleChangeText = val => { onChangeText && onChangeText(val); }; // 点击打开遮罩层 const showSearchBar = () => { if (disabled) { return; } setVisivble(true); }; return !visible ? <Pressable onPress={showSearchBar}> <View style={[disabled ? styles.disabled : styles.content, contentStyle]}> <Text style={[styles.contentTitle, { color: placeholderColor }]}>{textValue ? textValue : placeholder}</Text> {React.isValidElement(extra) ? extra : curValue && showClear ? <Pressable onPress={() => { onChange && onChange(null); setCurValue(null); }} style={{ paddingRight: 3 }}> <Icon name="circle-close-o" size={18} color="#ccc" /> </Pressable> : <Icon name="right" size={18} color="#A19EA0" />} </View> </Pressable> : <MaskLayer visible={visible}> <SafeAreaView style={styles.container}> <SearchInputBar loading={loading} containerStyle={{ backgroundColor: '#fff', marginHorizontal: 10 }} autoFocus showActionButton placeholder="输入搜索..." onChangeText={onHandleChangeText} onFocus={onFocus && onFocus} onBlur={onBlur && onBlur} searchRender={<TouchableWithoutFeedback onPress={() => { setVisivble(false); }}> <View style={styles.cancel}> <Text>取消</Text> </View> </TouchableWithoutFeedback>} {...searchInputBarProps} /> {loading ? <ActivityIndicator color="#0A0258" size="large" style={styles.loading} /> : <List style={styles.list}> {options.map(itm => <List.Item key={itm.value} onPress={() => { const selectValue = labelInValue ? { key: itm.value, label: itm.label } : itm.value; onChange && onChange(selectValue); setCurValue(selectValue); setVisivble(false); }}> <Text style={{ fontSize: 16 }}>{itm.label}</Text> </List.Item>)} </List>} </SafeAreaView> </MaskLayer>; } export default memo(SearchBar); const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#F5F5F5' }, contentTitle: { fontSize: 16, color: 'black' }, icon: { backgroundColor: '#fff', paddingLeft: 10, justifyContent: 'center' }, cancel: { color: '#7C7D7E', paddingRight: 10, justifyContent: 'center' }, list: { marginLeft: 10, marginTop: 10, marginRight: 10 }, loading: { position: 'absolute', top: '20%', left: '45%' }, content: { flexDirection: 'row', height: 35, alignItems: 'center', justifyContent: 'space-between', paddingRight: 5, backgroundColor: '#fff', paddingHorizontal: 16 }, disabled: { flexDirection: 'row', height: 35, alignItems: 'center', justifyContent: 'space-between', paddingRight: 5, backgroundColor: '#f5f5f5', paddingHorizontal: 16 } });