/* eslint-disable @typescript-eslint/indent */ import { useState, useRef } from 'react'; import { TextField, Stack, Typography, useMediaQuery, useTheme, Popover, Dialog, DialogTitle, DialogContent, DialogActions, Button, Box, IconButton, } from '@mui/material'; import { DateRange, Close, Clear } from '@mui/icons-material'; import { useLocaleContext } from '@arcblock/ux/lib/Locale/context'; import FormLabel from './label'; import { formatToDate } from '../libs/util'; export interface DateRangeValue { start: number | undefined; end: number | undefined; } export interface DateRangePickerProps { value: DateRangeValue; onChange: (value: DateRangeValue) => void; label?: string; size?: 'small' | 'medium'; fullWidth?: boolean; disabled?: boolean; } interface DatePickerContentProps { tempValue: { startDate: string; endDate: string }; setTempValue: ( value: | { startDate: string; endDate: string } | ((prev: { startDate: string; endDate: string }) => { startDate: string; endDate: string }) ) => void; handleCancel: () => void; handleApply: () => void; handleClear: () => void; } // 日期选择器内容组件 function DatePickerContent({ tempValue, setTempValue, handleCancel, handleApply, handleClear, }: DatePickerContentProps) { const { t } = useLocaleContext(); return ( {t('common.startDate')} setTempValue((prev) => ({ ...prev, startDate: e.target.value }))} size="small" fullWidth slotProps={{ inputLabel: { shrink: true }, }} /> {t('common.endDate')} setTempValue((prev) => ({ ...prev, endDate: e.target.value }))} size="small" fullWidth slotProps={{ inputLabel: { shrink: true }, }} /> ); } const DateFormat = 'YYYY-MM-DD'; export default function DateRangePicker({ value, onChange, label = '', size = 'small', fullWidth = false, disabled = false, }: DateRangePickerProps) { const theme = useTheme(); const isMobile = useMediaQuery(theme.breakpoints.down('sm')); const [open, setOpen] = useState(false); const { t, locale } = useLocaleContext(); // 内部使用字符串格式的临时值 const [tempValue, setTempValue] = useState<{ startDate: string; endDate: string }>({ startDate: value.start ? formatToDate(value.start * 1000, locale, DateFormat) : '', endDate: value.end ? formatToDate(value.end * 1000, locale, DateFormat) : '', }); const anchorRef = useRef(null); const formatDisplayValue = (startUnix: number | undefined, endUnix: number | undefined) => { if (!startUnix || !endUnix) return t('common.selectTimeRange'); const start = formatToDate(startUnix * 1000, locale, DateFormat); const end = formatToDate(endUnix * 1000, locale, DateFormat); return `${start} ~ ${end}`; }; const handleOpen = () => { if (disabled) return; setTempValue({ startDate: value.start ? formatToDate(value.start * 1000, locale, DateFormat) : '', endDate: value.end ? formatToDate(value.end * 1000, locale, DateFormat) : '', }); setOpen(true); }; const handleClose = () => { setOpen(false); }; const handleApply = () => { const unixValue: DateRangeValue = { start: tempValue.startDate ? Math.floor(new Date(`${tempValue.startDate}T00:00:00`).getTime() / 1000) : 0, end: tempValue.endDate ? Math.floor(new Date(`${tempValue.endDate}T23:59:59`).getTime() / 1000) : 0, }; onChange(unixValue); setOpen(false); }; const handleCancel = () => { setTempValue({ startDate: value.start ? formatToDate(value.start * 1000, locale, DateFormat) : '', endDate: value.end ? formatToDate(value.end * 1000, locale, DateFormat) : '', }); setOpen(false); }; const handleClear = () => { const emptyValue: DateRangeValue = { start: undefined, end: undefined }; onChange(emptyValue); setTempValue({ startDate: '', endDate: '' }); setOpen(false); }; const hasValue = !!value.start && !!value.end; return ( <> , endAdornment: hasValue && !disabled && ( { e.stopPropagation(); handleClear(); }} sx={{ color: 'text.secondary', '&:hover': { color: 'text.primary' }, }}> ), }, inputLabel: { shrink: true }, }} /> {/* 桌面端使用 Popover */} {!isMobile && ( )} {/* 移动端使用 Dialog */} {isMobile && ( {t('common.selectTimeRange')} {t('common.startDate')} setTempValue((prev) => ({ ...prev, startDate: e.target.value }))} size="small" fullWidth slotProps={{ inputLabel: { shrink: true }, }} /> {t('common.endDate')} setTempValue((prev) => ({ ...prev, endDate: e.target.value }))} size="small" fullWidth slotProps={{ inputLabel: { shrink: true }, }} /> )} ); }