UNPKG

@uiw/react-native

Version:
156 lines 5.17 kB
import React, { useState, useEffect, useRef } from 'react'; import { View, StyleSheet, SafeAreaView } from 'react-native'; import Modal from '../Modal'; import PickerView from './component/PickerView'; import Control from './component/Control'; import { precisionValue, setTimer, setTimerDiff, getPickerData, minData, maxData, changeData } from './pure-function'; export const typeTimer = ['year', 'month', 'day', 'hour', 'minute', 'second']; const DatePicker = props => { const { precision, min, max, visible, onClosed, modalProps, value = '', onOk, onChange, okText = '确定', cancelText = '取消', underlayColor = '#E6E6E6', showTitle = false, titleStyle = {}, renderTitle, pickerProps } = props; /** 最终精度 */ const result = useRef('day'); /** 最小时间 */ const MINTIMER = useRef({}); /** 最大时间 */ const MAXTIMER = useRef({}); /** 下一次的 label */ const nextLabel = useRef({}); /** 上一次的 label */ const prevLabel = useRef({}); /** 下标 */ const [dateIndex, setDateIndex] = useState({}); /** 数据 */ const [datePicker, setDatePicker] = useState({}); /** 结果值 2020-10-10 10:59:59 */ const [date, setDate] = useState(''); useEffect(() => { result.current = precisionValue(precision || 'day'); const star = setTimer(result.current, min); const end = setTimer(result.current, max); const prev = setTimer(result.current, value); const timerDiff = setTimerDiff(star, end, result.current); const getPickerDate = getPickerData(timerDiff, result.current); star.forEach((it, i) => { MINTIMER.current[typeTimer[i]] = getPickerDate[typeTimer[i]]?.find(item => item.value === it)?.label; }); end.forEach((it, i) => { MAXTIMER.current[typeTimer[i]] = getPickerDate[typeTimer[i]]?.find(item => item.value === it)?.label; }); prev.forEach((it, i) => { prevLabel.current[typeTimer[i]] = getPickerDate[typeTimer[i]]?.find(item => item.value === it)?.label; }); setDatePicker(getPickerDate); }, [precision, min, max]); // useEffect(() => { // if(!datePicker.year) return // const index = handleIndex(value) // if(JSON.stringify(index) === JSON.stringify(dateIndex)) return // setDateIndex(index) // }, [value, datePicker]) useEffect(() => { onChange?.(date); }, [date]); const handleIndex = (params = '', d = datePicker) => { const val = setTimer(result.current, params); const obj = {}; for (let i = 0; i < val.length; i++) { const item = typeTimer[i]; obj[item] = d[item]?.findIndex(it => it.value === val[i]); } return obj; }; const onConfirm = () => { onOk?.(date); }; const datePickerUpdate = (key, index, str) => { let newObj = {}; let i = 0; const changeParams = { MAXTIMER: MAXTIMER.current, MINTIMER: MINTIMER.current, nextLabel: nextLabel.current, prevLabel: prevLabel.current }; if (prevLabel.current.year === MINTIMER.current.year) { newObj = minData(key, changeParams, result.current); i++; } if (i === 0 && prevLabel.current.year === MAXTIMER.current.year) { newObj = maxData(key, changeParams, result.current); i++; } if (i === 0) { newObj = changeData(key, changeParams, result.current); } if (JSON.stringify(newObj) !== '{}') { setDatePicker({ ...datePicker, ...newObj }); } setDateIndex(handleIndex(str, { ...datePicker, ...newObj })); }; const getTypeDate = (index, val, key) => { nextLabel.current = { ...nextLabel.current, [key]: val }; const TIMER = ['hour', 'minute', 'second']; const DATETIMER = ['day', 'second']; let str = ''; Object.keys(nextLabel.current).forEach(it => { const val = nextLabel.current[it]; let char = TIMER.includes(it) ? ':' : '-'; char = DATETIMER.includes(it) ? '' : char; const space = it === 'hour' ? ' ' : ''; if (val) { str = str + space + val + char; } }); setDate(str); if (nextLabel.current[precision] && JSON.stringify(nextLabel.current) !== JSON.stringify(prevLabel.current)) { datePickerUpdate(key, index, str); return; } }; return <Modal placement="bottom" visible={visible} onClosed={onClosed} {...modalProps}> <SafeAreaView> <Control onConfirm={onConfirm} onClosed={onClosed} okText={okText} cancelText={cancelText} underlayColor={underlayColor} /> <View style={styles.container}> {Object.keys(datePicker).map(item => <PickerView {...pickerProps} getTypeDate={getTypeDate} showTitle={showTitle} titleStyle={titleStyle} renderTitle={renderTitle} key={item} title={item} data={datePicker[item]} value={dateIndex[item]} />)} </View> </SafeAreaView> </Modal>; }; const styles = StyleSheet.create({ container: { flexDirection: 'row', justifyContent: 'space-around', alignItems: 'center', flex: 1, paddingVertical: 0, paddingHorizontal: 0, paddingBottom: 20 } }); export default DatePicker;