This commit is contained in:
oneao committed 2026-01-13 22:18:01 +08:00
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%',
},
})