| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- import React, { useEffect, useRef, useState } from 'react';
- import { FlatList, Keyboard, Pressable, StyleSheet, Text, View } from 'react-native';
- import Modal from 'react-native-modal';
- import Button from './Button';
- import Dialog, { getDialogWidth } from './Dialog';
- //const DialogMaxWidth = $vw(85) > 500 ? 500 : $vw(85);
- //const DialogIOSWidth = $vw(75) > 450 ? 450 : $vw(75);
- export default Dropdown = ({
- list = [],
- title = '',
- value,
- onChange,
- nameKey,
- valueKey,
- prefixText='',//前缀
- suffixText='',//后缀
- itemHeight=50,
- prefixList='',//列表前缀
- suffixList='',//列表后缀
- rippleStyle,
- style = styles.valueView,
- textStyle = styles.valueText,
- placeholderStyle=styles.placeText,
- placeholder='',
- showText = true,
- showIcon = true,
- iconColor = '#888',
- iconStyle = styles.iconStyle,
- autoSelect = true,
- customerItemView
- }) => {
-
- const refFlat = useRef();
- const [visible, showDialog] = useState(false);
- const [selected, changeValue] = useState('');
- const [currentIndex, setCurrent] = useState(0);
- useEffect(() => {
- if (value !== selected) {
- if (nameKey && valueKey) {
- for (var i = 0; i < list.length; i++) {
- let item = list[i];
- if (item[valueKey] == value) {
- changeValue(prefixText+item[nameKey]+suffixText);
- if (list.length > 20) {
- setCurrent(i > 5 ? i - 4 : 0);
- }
- break;
- }
- }
- } else {
- changeValue(prefixText+value+suffixText);
- }
- }
- }, [value, []]);
- useEffect(() => {
- if (autoSelect && list.length > 0) {
- if (!value) {
- const item = list[0];
- /*if (nameKey) {
- changeValue(item[nameKey]);
- } else {
- changeValue(item);
- }*/
- if (onChange) {
- onChange(valueKey ? item[valueKey] : item, 0)
- }
- }
- }
- }, [list]);
- const showList = () => {
- Keyboard.dismiss();
- showDialog(true);
- /*if (currentIndex > 0) {
- console.log(refFlat.current);
- setTimeout(() => {
- if (refFlat.current) {
- refFlat.current.scrollToIndex({
- animated: false,
- index: currentIndex,
- viewPosition: 0.5
- })
- }
- }, 100)
- }*/
- }
- const renderItem = ({ item, index, separators }) => {
- if (customerItemView) {
- return customerItemView(item, index, () => {
- showDialog(false);
- if (onChange) {
- onChange(valueKey ? item[valueKey] : item, index)
- }
- })
- } else {
- return (
- <Button
- text={prefixList + (nameKey ? item[nameKey] : item) + suffixList}
- style={styles.itemView}
- textStyle={styles.itemText}
- onClick={() => {
- showDialog(false);
- if (onChange) {
- onChange(valueKey ? item[valueKey] : item, index)
- }
- }
- }/>
- )
- }
- }
- return (
- <>
- <Pressable
- style={style}
- android_ripple={rippleStyle}
- onPress={() => showList()}>
- { showText &&
- ( selected
- ? <Text style={[ui.flex1, textStyle]} numberOfLines={1}>{selected}</Text>
- : <Text style={[textStyle, placeholderStyle]} numberOfLines={1}>{placeholder}</Text>
- )
- }
- { showIcon &&
- <Entypo
- name={'chevron-thin-down'}
- size={14}
- color={iconColor}
- style={iconStyle}
- />
- }
- </Pressable>
- <Modal
- isVisible={visible}
- onTouchOutside={() => showDialog(false)}
- onBackdropPress={() => showDialog(false)}
- onBackButtonPress={() => showDialog(false)}
- {...Dialog.modalProps}
- >
- <View style={styles.dialog}>
- { title !== '' && <Text style={styles.title}>{title}</Text> }
- <FlatList
- data={list}
- ref={refFlat}
- renderItem={renderItem}
- initialScrollIndex={currentIndex}
- keyExtractor={(item, index) => index}
- style={{maxHeight: $vh(55)}}
- getItemLayout={(data, index) => (
- {length: itemHeight, offset: itemHeight * index, index}
- )}
- />
- </View>
- </Modal>
- </>
- );
- }
- const styles = StyleSheet.create({
- dialog: {
- width: getDialogWidth(),
- marginLeft: 'auto',
- marginRight: 'auto',
- paddingTop: isIOS ? 12 : 8,
- paddingBottom: isIOS ? 12 : 8,
- backgroundColor: colorLight,
- borderRadius: isIOS ? 10 : 3
- },
- title: {
- color: '#000',
- paddingTop: 8,
- paddingLeft: 16,
- paddingBottom: 16,
- fontSize: 17,
- fontWeight: 'bold'
- },
- valueView: {
- paddingLeft: 16,
- paddingRight: 32,
- alignItems: 'center',
- flexDirection: 'row'
- },
- valueText: {
- color: '#000',
- fontSize: 16
- },
- itemView: {
- borderRadius: 0,
- backgroundColor: colorLight
- },
- itemText: {
- flex: 1,
- color: textPrimary,
- fontSize: 14,
- textAlign: 'left',
- fontWeight: 'normal'
- },
- placeText: {
- flex: 1,
- color: '#aaa'
- },
- iconStyle: {
- top: '50%',
- right: 16,
- marginTop: -7,
- position: 'absolute',
- }
- });
|