u
This commit is contained in:
1 parent
33113f279c
commit
c2c5cc92af
16 files changed
+864
-352
No files matched your search
@@ -0,0 +1,81 @@
|
||||
import type { DateTimePickerProps } from 'react-native-modal-datetime-picker'
|
||||
import dayjs from 'dayjs'
|
||||
import customParseFormat from 'dayjs/plugin/customParseFormat'
|
||||
import React, { useMemo } from 'react'
|
||||
import DateTimePickerModal from 'react-native-modal-datetime-picker'
|
||||
|
||||
dayjs.extend(customParseFormat)
|
||||
|
||||
interface ADatePickerProps extends Omit<DateTimePickerProps, 'onConfirm' | 'onCancel' | 'date'> {
|
||||
format?: string
|
||||
onConfirm?: (value: string) => void
|
||||
date?: Date | string
|
||||
is24Hour?: boolean
|
||||
onCancel?: () => void
|
||||
}
|
||||
|
||||
export default function DatePicker({
|
||||
mode = 'date',
|
||||
format,
|
||||
date,
|
||||
onConfirm,
|
||||
is24Hour = true,
|
||||
onCancel,
|
||||
...restProps
|
||||
}: ADatePickerProps) {
|
||||
const parsedDate = useMemo(() => {
|
||||
if (!date)
|
||||
return new Date()
|
||||
|
||||
if (typeof date === 'string') {
|
||||
// 支持多种常见日期格式
|
||||
const formats = ['YYYY-MM-DD', 'YYYY/MM/DD', 'YYYY-MM-DDTHH:mm:ssZ', 'YYYY/MM/DD HH:mm:ss', 'YYYY-MM-DD HH:mm:ss']
|
||||
for (const fmt of formats) {
|
||||
const d = dayjs(date, fmt, true)
|
||||
if (d.isValid())
|
||||
return d.toDate()
|
||||
}
|
||||
// fallback: 尝试直接解析
|
||||
const d = dayjs(date)
|
||||
if (d.isValid())
|
||||
return d.toDate()
|
||||
// 仍然不合法就返回当前时间
|
||||
return new Date()
|
||||
}
|
||||
|
||||
return date
|
||||
}, [date])
|
||||
|
||||
const handleConfirm = (selectedDate: Date) => {
|
||||
const fmt = format || (() => {
|
||||
switch (mode) {
|
||||
case 'time':
|
||||
return 'HH:mm:00'
|
||||
case 'datetime':
|
||||
return 'YYYY-MM-DD HH:mm:00'
|
||||
case 'date':
|
||||
default:
|
||||
return 'YYYY-MM-DD'
|
||||
}
|
||||
})()
|
||||
|
||||
const localTimeStr = dayjs(selectedDate).format(fmt)
|
||||
onConfirm?.(localTimeStr)
|
||||
}
|
||||
|
||||
const handleCancel = () => {
|
||||
onCancel?.()
|
||||
}
|
||||
|
||||
return (
|
||||
<DateTimePickerModal
|
||||
{...restProps}
|
||||
mode={mode}
|
||||
date={parsedDate}
|
||||
locale="zh-CN"
|
||||
onConfirm={handleConfirm}
|
||||
onCancel={handleCancel}
|
||||
is24Hour={is24Hour}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
import type { DateType, OrderedDateParts } from 'react-native-dates-picker/lib/typescript/types'
|
||||
import dayjs from 'dayjs'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { View } from 'react-native'
|
||||
import DateTimePicker from 'react-native-dates-picker'
|
||||
|
||||
import { Drawer, DrawerBackdrop, DrawerContent, DrawerFooter, DrawerHeader } from '@/components/ui/drawer'
|
||||
import AButton from './Button'
|
||||
|
||||
type DateWheelMode
|
||||
= | 'year-month'
|
||||
| 'year-month-day'
|
||||
| 'hour-minute-second'
|
||||
| 'year-month-day-hour-minute-second'
|
||||
|
||||
interface DateDrawerProps {
|
||||
isOpen?: boolean
|
||||
defaultDate?: DateType
|
||||
modeType?: DateWheelMode
|
||||
onClose?: () => void
|
||||
onConfirm?: (dateStr: string) => void
|
||||
}
|
||||
|
||||
const modeColumnsMap: Record<DateWheelMode, OrderedDateParts[]> = {
|
||||
'year-month': ['year', 'month'],
|
||||
'year-month-day': ['year', 'month', 'day'],
|
||||
'hour-minute-second': ['hour', 'minute', 'second'],
|
||||
'year-month-day-hour-minute-second': ['year', 'month', 'day', 'hour', 'minute', 'second'],
|
||||
}
|
||||
|
||||
const modeFormatMap: Record<DateWheelMode, string> = {
|
||||
'year-month': 'YYYY-MM',
|
||||
'year-month-day': 'YYYY-MM-DD',
|
||||
'hour-minute-second': 'HH:mm:ss',
|
||||
'year-month-day-hour-minute-second': 'YYYY-MM-DD HH:mm:ss',
|
||||
}
|
||||
|
||||
export default function DateWheelDrawer({
|
||||
isOpen,
|
||||
defaultDate = dayjs(),
|
||||
onClose,
|
||||
onConfirm,
|
||||
modeType = 'year-month-day',
|
||||
}: DateDrawerProps) {
|
||||
const columns = modeColumnsMap[modeType]
|
||||
const format = modeFormatMap[modeType]
|
||||
|
||||
// 当前选择的值
|
||||
const [date, setDate] = useState<DateType>(defaultDate)
|
||||
// 保存上一次确认的值
|
||||
const lastConfirmedRef = useRef<DateType>(defaultDate)
|
||||
|
||||
// 每次弹窗打开时,把滚轮显示初始化为上一次确认的值
|
||||
useEffect(() => {
|
||||
if (isOpen) {
|
||||
setDate(lastConfirmedRef.current)
|
||||
}
|
||||
}, [isOpen])
|
||||
|
||||
// 点击取消
|
||||
const handleCancel = () => {
|
||||
onClose?.()
|
||||
}
|
||||
|
||||
// 点击确认
|
||||
const handleConfirm = () => {
|
||||
console.log("确实")
|
||||
onClose?.()
|
||||
lastConfirmedRef.current = date // 保存为上一次确认的值
|
||||
|
||||
if (onConfirm) {
|
||||
const formatted = dayjs(date).format(format)
|
||||
onConfirm(formatted)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Drawer
|
||||
isOpen={isOpen}
|
||||
anchor="bottom"
|
||||
closeOnOverlayClick
|
||||
onClose={onClose}
|
||||
size="md"
|
||||
>
|
||||
<DrawerBackdrop />
|
||||
<DrawerContent className="p-0 flex-1">
|
||||
<DrawerHeader className="flex items-center justify-between p-4">
|
||||
<AButton action="secondary" onPress={handleCancel}>取消</AButton>
|
||||
<AButton onPress={handleConfirm}>确认</AButton>
|
||||
</DrawerHeader>
|
||||
|
||||
<View className="flex-1 flex items-center justify-center">
|
||||
<DateTimePicker
|
||||
mode="wheel"
|
||||
date={date}
|
||||
columns={columns}
|
||||
wheelPickerSelectedIndicatorStyle={{ backgroundColor: '#eee' }}
|
||||
onChange={params => setDate(params.date)}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<DrawerFooter></DrawerFooter>
|
||||
</DrawerContent>
|
||||
</Drawer>
|
||||
)
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
import Button from './Button'
|
||||
import Checkbox from './Checkbox'
|
||||
import DatePicker from './DatePicker'
|
||||
import DateTimeDrawer from './DateTimeDrawer'
|
||||
import Form, { FormRef } from './Form'
|
||||
import FormItem from './FormItem'
|
||||
import Input from './Input'
|
||||
@@ -8,6 +10,8 @@ import LucideIcon from './LucideIcon'
|
||||
export {
|
||||
Button as AButton,
|
||||
Checkbox as ACheckbox,
|
||||
DatePicker as ADatePicker,
|
||||
DateTimeDrawer as ADateTimeDrawer,
|
||||
Form as AForm,
|
||||
FormItem as AFormItem,
|
||||
FormRef as AFormRef,
|
||||
|
||||
Reference in new issue
Block a user