@uiw/react-native
Version:
UIW for React Native
156 lines • 5.17 kB
JavaScript
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;