20260507213409

This commit is contained in:
oneao committed 2026-05-07 21:34:09 +08:00
1 parent 3070eac71b
commit 4c7f516a03
204 files changed
+3623

No files matched your search

+103
View File
@@ -0,0 +1,103 @@
import { DatePicker as YzDatePicker } from "@yz1311/react-native-wheel-picker";
import dayjs from "dayjs";
import { BottomSheet, Button, Spinner } from "heroui-native";
import { useState, useEffect } from "react";
import { toDate } from "@/utils/time";
import { View } from "react-native";
import { CheckIcon } from "lucide-react-native";
import { FadeIn } from "react-native-reanimated";
export type DatePickerMode = "year" | "month" | "date" | "time" | "datetime";
export type DateFormatType = "YYYY" | "YYYY-MM" | "YYYY-MM-DD" | "HH:mm:ss" | "YYYY-MM-DD HH:mm";
interface DatePickerProps {
value: Date | string;
show?: boolean;
onClose?: () => void;
onConfirm?: (value: string) => void | Promise<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",
};
export default function DateTime({
value,
show = false,
onClose,
onConfirm,
mode = "date",
format,
}: DatePickerProps) {
const finalFormat = format ?? defaultFormatMap[mode];
const [tempDate, setTempDate] = useState<Date>(toDate(value) ?? new Date());
const [loading, setLoading] = useState(false);
useEffect(() => {
if (show) {
setTempDate(toDate(value) ?? new Date());
}
}, [show, value]);
const handleClose = () => {
if (loading) return;
onClose?.();
};
const handleConfirm = async () => {
if (!tempDate || loading) return;
try {
setLoading(true);
const result = dayjs(tempDate).format(finalFormat);
await onConfirm?.(result);
handleClose();
} catch (e) {
console.log(e);
} finally {
setLoading(false);
}
};
return (
<BottomSheet isOpen={show} onOpenChange={(v) => !v && handleClose()}>
<BottomSheet.Portal>
<BottomSheet.Overlay />
<BottomSheet.Content>
<View style={{ width: "100%", alignItems: "center" }}>
<YzDatePicker
showHeader={false}
date={tempDate}
mode={mode}
isModal={false}
onDateChange={(d: Date) => setTempDate(d)}
/>
<Button className="w-full" onPress={handleConfirm} isDisabled={loading}>
{loading ? (
<Spinner entering={FadeIn.delay(50)} color="white" />
) : (
<>
<CheckIcon color="#fff" />
<Button.Label>确认</Button.Label>
</>
)}
</Button>
</View>
</BottomSheet.Content>
</BottomSheet.Portal>
</BottomSheet>
);
}