u
This commit is contained in:
1 parent
6277fb2f9e
commit
8ecac0d7dd
270 files changed
+40438
-529
No files matched your search
@@ -0,0 +1,108 @@
|
||||
import type { IDatePickerProps } from '@yz1311/react-native-wheel-picker'
|
||||
import { DatePicker } from '@yz1311/react-native-wheel-picker'
|
||||
import dayjs from 'dayjs'
|
||||
import React, { useEffect, useRef, useState } from 'react'
|
||||
import { Animated, Modal, StyleSheet, TouchableOpacity } from 'react-native'
|
||||
import { toDate } from '@/utils/time'
|
||||
// 定义 mode 类型
|
||||
export type DatePickerMode = 'year' | 'month' | 'date' | 'time' | 'datetime'
|
||||
|
||||
// 定义 format 类型
|
||||
export type DateFormatType = 'YYYY' | 'YYYY-MM' | 'YYYY-MM-DD' | 'HH:mm:ss' | 'YYYY-MM-DD HH:mm:ss'
|
||||
|
||||
interface ADatePickerProps extends Omit<IDatePickerProps, 'date'> {
|
||||
date?: Date | string
|
||||
show?: boolean
|
||||
onClose?: () => void
|
||||
onConfirm?: (value: string) => void
|
||||
mode?: DatePickerMode
|
||||
format?: DateFormatType
|
||||
}
|
||||
|
||||
const defaultFormatMap: Record<DatePickerMode, DateFormatType> = {
|
||||
year: 'YYYY',
|
||||
month: 'YYYY-MM',
|
||||
date: 'YYYY-MM-DD',
|
||||
time: 'HH:mm:ss',
|
||||
datetime: 'YYYY-MM-DD HH:mm:ss',
|
||||
}
|
||||
|
||||
export default function ADatePicker({
|
||||
date,
|
||||
show = false,
|
||||
onClose,
|
||||
onConfirm,
|
||||
mode = 'date',
|
||||
format,
|
||||
...restProps
|
||||
}: ADatePickerProps) {
|
||||
const fadeAnim = useRef(new Animated.Value(0)).current
|
||||
const slideAnim = useRef(new Animated.Value(300)).current
|
||||
const [visible, setVisible] = useState(show)
|
||||
|
||||
// 使用传入 format 或默认 format
|
||||
const finalFormat = format || defaultFormatMap[mode]
|
||||
|
||||
useEffect(() => {
|
||||
if (show) {
|
||||
setVisible(true)
|
||||
fadeAnim.setValue(0)
|
||||
slideAnim.setValue(300)
|
||||
Animated.parallel([
|
||||
Animated.timing(fadeAnim, { toValue: 1, duration: 250, useNativeDriver: true }),
|
||||
Animated.timing(slideAnim, { toValue: 0, duration: 250, useNativeDriver: true }),
|
||||
]).start()
|
||||
}
|
||||
else {
|
||||
Animated.parallel([
|
||||
Animated.timing(fadeAnim, { toValue: 0, duration: 250, useNativeDriver: true }),
|
||||
Animated.timing(slideAnim, { toValue: 280, duration: 250, useNativeDriver: true }),
|
||||
]).start(() => setVisible(false))
|
||||
}
|
||||
}, [show])
|
||||
|
||||
const handleCancel = () => onClose?.()
|
||||
|
||||
const handleConfirm = (date: Date) => {
|
||||
const value = dayjs(date).format(finalFormat)
|
||||
onConfirm?.(value)
|
||||
}
|
||||
|
||||
if (!visible)
|
||||
return null
|
||||
|
||||
return (
|
||||
<Modal transparent visible={visible} animationType="none">
|
||||
<Animated.View style={[styles.overlay, { opacity: fadeAnim }]}>
|
||||
<TouchableOpacity style={{ flex: 1 }} activeOpacity={1} onPress={handleCancel} />
|
||||
</Animated.View>
|
||||
|
||||
<Animated.View
|
||||
style={[styles.pickerContainer, { transform: [{ translateY: slideAnim }] }]}
|
||||
>
|
||||
<DatePicker
|
||||
{...restProps}
|
||||
date={toDate(date)}
|
||||
mode={mode}
|
||||
isModal={false}
|
||||
onPickerCancel={handleCancel}
|
||||
onPickerConfirm={handleConfirm}
|
||||
/>
|
||||
</Animated.View>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
overlay: {
|
||||
...StyleSheet.absoluteFillObject,
|
||||
backgroundColor: 'rgba(0,0,0,0.5)',
|
||||
},
|
||||
pickerContainer: {
|
||||
backgroundColor: '#fff',
|
||||
overflow: 'hidden',
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
width: '100%',
|
||||
},
|
||||
})
|
||||
Reference in new issue
Block a user