禁用的日期
- 结束时间需要大于开始时间
- 结束日期,大于今天的日期全部禁用
- 结束日期和开始日期,之间不能超过 7个自然日
- onCalendarChange 和 disabledDate 来限制动态的日期区间
import { useState, useEffect } from 'react';
import { number, array, func, string } from 'prop-types';
import { DatePicker } from 'antd';
import dayjs from 'dayjs';
import { noop, isArray, isString } from 'lodash-es';
import type { Dayjs } from 'dayjs';
import type { TimeRangePickerProps } from 'antd';
const { RangePicker: AntdRangePicker } = DatePicker;
type RangeValue = [Dayjs | null, Dayjs | null] | null;
// dayjs().add(-1, 'w') 一周 = 7天
const rangePresets: TimeRangePickerProps['presets'] = [
{ label: '今天', value: [dayjs().startOf('d'), dayjs()] },
{ label: '昨天', value: [dayjs().add(-1, 'd'), dayjs()] },
{ label: '最近 15 分钟', value: [dayjs().add(-15, 'm'), dayjs()] },
{ label: '最近 30 分钟', value: [dayjs().add(-30, 'm'), dayjs()] },
{ label: '最近 1 小时', value: [dayjs().add(-1, 'h'), dayjs()] },
{ label: '最近 6 小时', value: [dayjs().add(-6, 'h'), dayjs()] },
{ label: '最近 24 小时', value: [dayjs().add(-24, 'h'), dayjs()] },
{ label: '最近 5 天', value: [dayjs().add(-5, 'd'), dayjs()] },
];
RangePicker.propTypes = {
value: array,
onChange: func,
maxDays: number,
format: string,
};
RangePicker.defaultProps = {
onChange: noop,
maxDays: 7,
format: 'YYYY/MM/DD HH:mm',
}
function RangePicker(props: any) {
const {
value,
onChange,
maxDays,
...rest
} = props;
const [dates, setDates] = useState<RangeValue>(null);
useEffect(() => {
const _dates = isArray(value)
? value.map(it => isString(it) ? dayjs(it) : it)
: value ?? null;
setDates(_dates);
}, [value]);
// 动态的日期区间选择,不超过 7 天
const disabledDate = (current: Dayjs) => {
if (!dates) {
return false;
}
const tooLate = dates[0] && current.diff(dates[0], 'days') >= maxDays;
const tooEarly = dates[1] && dates[1].diff(current, 'days') >= maxDays;
return !!tooEarly || !!tooLate;
};
/**
* 先触发 onCalendarChange,然后触发 onChange
* 选完第一个时间,点击面板的确定按钮时,只触发 onCalendarChange,不触发 onChange
* 选择第二个时间,点击面板确定时,先触发 onCalendarChange,然后触发 onChange
* @param dates
* @param dateStrings
*/
// const onCalendarChange = (dates: RangeValue, dateStrings: string[]) => {
// setDates(dates);
// console.log('onCalendarChange', { dates, dateStrings})
// }
/**
* 清空时 { dates: null, dateStrings: ['', ''] }
* @param dates
* @param dateStrings
*/
const onRangeChange = (dates: RangeValue, dateStrings: string[]) => {
setDates(dates);
if (dates) {
onChange(dates, dateStrings);
console.log('onRangeChange', { dates, dateStrings });
} else {
onChange(dates, []);
console.log('Clear', { dates, dateStrings });
}
};
return (
<AntdRangePicker
presets={rangePresets}
changeOnBlur
showTime
// showTime={{ format: 'HH:mm:ss', minuteStep: 15 }}
disabledDate={disabledDate}
onCalendarChange={setDates}
{...rest}
value={dates}
onChange={onRangeChange}
/>
)
}
export default RangePicker;
// 大于今天的日期禁用
export function disabledAfterDate(current: any) {
return current > Date.now()
}
presets 预设日期
antd5x版本为 presets={[]},数组格式
antd4x版本为 ranges={{}},对象格式
presets
presets 数组格式
https://ant-design.antgroup.com/components/date-picker-cn#components-date-picker-demo-preset-ranges
import dayjs from 'dayjs';
import type { TimeRangePickerProps } from 'antd';
export const rangePresets: TimeRangePickerProps['presets'] = [
{ label: '最近 1 小时', value: [dayjs().add(-1, 'h'), dayjs()] },
{ label: '最近 6 小时', value: [dayjs().add(-6, 'h'), dayjs()] },
{ label: '最近 24 小时', value: [dayjs().add(-24, 'h'), dayjs()] },
{ label: '最近 5 天', value: [dayjs().add(-5, 'd'), dayjs()] },
]
ranges
export function rangeDates() {
const now = moment();
return {
'今天': [moment().startOf('d'), now],
'昨天':[
moment().subtract(1, 'days').startOf('day'),
moment().subtract(1, 'days').endOf('day'),
],
'最近15分钟': [moment().subtract(15, 'minutes'),now],
'最近30分钟': [moment().subtract(30, 'minutes'), now],
'最近1小时': [moment().subtract(1, 'hours'), now],
'最近1天': [moment().subtract(1, 'day'), now],
'最近1周': [moment().subtract(1, 'weeks'), now],
'最近1月': [moment().subtract(1, 'months'), now],
'本月': [moment().startOf('month'), moment().endOf('month')],
'本季': [moment().startOf('quarter'), now],
'本年': [moment().startOf('year'), now],
};
}