禁用的日期

  1. 结束时间需要大于开始时间
  2. 结束日期,大于今天的日期全部禁用
  3. 结束日期和开始日期,之间不能超过 7个自然日
    1. onCalendarChange 和 disabledDate 来限制动态的日期区间

image.png

  1. import { useState, useEffect } from 'react';
  2. import { number, array, func, string } from 'prop-types';
  3. import { DatePicker } from 'antd';
  4. import dayjs from 'dayjs';
  5. import { noop, isArray, isString } from 'lodash-es';
  6. import type { Dayjs } from 'dayjs';
  7. import type { TimeRangePickerProps } from 'antd';
  8. const { RangePicker: AntdRangePicker } = DatePicker;
  9. type RangeValue = [Dayjs | null, Dayjs | null] | null;
  10. // dayjs().add(-1, 'w') 一周 = 7天
  11. const rangePresets: TimeRangePickerProps['presets'] = [
  12. { label: '今天', value: [dayjs().startOf('d'), dayjs()] },
  13. { label: '昨天', value: [dayjs().add(-1, 'd'), dayjs()] },
  14. { label: '最近 15 分钟', value: [dayjs().add(-15, 'm'), dayjs()] },
  15. { label: '最近 30 分钟', value: [dayjs().add(-30, 'm'), dayjs()] },
  16. { label: '最近 1 小时', value: [dayjs().add(-1, 'h'), dayjs()] },
  17. { label: '最近 6 小时', value: [dayjs().add(-6, 'h'), dayjs()] },
  18. { label: '最近 24 小时', value: [dayjs().add(-24, 'h'), dayjs()] },
  19. { label: '最近 5 天', value: [dayjs().add(-5, 'd'), dayjs()] },
  20. ];
  21. RangePicker.propTypes = {
  22. value: array,
  23. onChange: func,
  24. maxDays: number,
  25. format: string,
  26. };
  27. RangePicker.defaultProps = {
  28. onChange: noop,
  29. maxDays: 7,
  30. format: 'YYYY/MM/DD HH:mm',
  31. }
  32. function RangePicker(props: any) {
  33. const {
  34. value,
  35. onChange,
  36. maxDays,
  37. ...rest
  38. } = props;
  39. const [dates, setDates] = useState<RangeValue>(null);
  40. useEffect(() => {
  41. const _dates = isArray(value)
  42. ? value.map(it => isString(it) ? dayjs(it) : it)
  43. : value ?? null;
  44. setDates(_dates);
  45. }, [value]);
  46. // 动态的日期区间选择,不超过 7 天
  47. const disabledDate = (current: Dayjs) => {
  48. if (!dates) {
  49. return false;
  50. }
  51. const tooLate = dates[0] && current.diff(dates[0], 'days') >= maxDays;
  52. const tooEarly = dates[1] && dates[1].diff(current, 'days') >= maxDays;
  53. return !!tooEarly || !!tooLate;
  54. };
  55. /**
  56. * 先触发 onCalendarChange,然后触发 onChange
  57. * 选完第一个时间,点击面板的确定按钮时,只触发 onCalendarChange,不触发 onChange
  58. * 选择第二个时间,点击面板确定时,先触发 onCalendarChange,然后触发 onChange
  59. * @param dates
  60. * @param dateStrings
  61. */
  62. // const onCalendarChange = (dates: RangeValue, dateStrings: string[]) => {
  63. // setDates(dates);
  64. // console.log('onCalendarChange', { dates, dateStrings})
  65. // }
  66. /**
  67. * 清空时 { dates: null, dateStrings: ['', ''] }
  68. * @param dates
  69. * @param dateStrings
  70. */
  71. const onRangeChange = (dates: RangeValue, dateStrings: string[]) => {
  72. setDates(dates);
  73. if (dates) {
  74. onChange(dates, dateStrings);
  75. console.log('onRangeChange', { dates, dateStrings });
  76. } else {
  77. onChange(dates, []);
  78. console.log('Clear', { dates, dateStrings });
  79. }
  80. };
  81. return (
  82. <AntdRangePicker
  83. presets={rangePresets}
  84. changeOnBlur
  85. showTime
  86. // showTime={{ format: 'HH:mm:ss', minuteStep: 15 }}
  87. disabledDate={disabledDate}
  88. onCalendarChange={setDates}
  89. {...rest}
  90. value={dates}
  91. onChange={onRangeChange}
  92. />
  93. )
  94. }
  95. export default RangePicker;
  96. // 大于今天的日期禁用
  97. export function disabledAfterDate(current: any) {
  98. return current > Date.now()
  99. }

presets 预设日期

antd5x版本为 presets={[]},数组格式
antd4x版本为 ranges={{}},对象格式
image.png

presets

presets 数组格式
https://ant-design.antgroup.com/components/date-picker-cn#components-date-picker-demo-preset-ranges

  1. import dayjs from 'dayjs';
  2. import type { TimeRangePickerProps } from 'antd';
  3. export const rangePresets: TimeRangePickerProps['presets'] = [
  4. { label: '最近 1 小时', value: [dayjs().add(-1, 'h'), dayjs()] },
  5. { label: '最近 6 小时', value: [dayjs().add(-6, 'h'), dayjs()] },
  6. { label: '最近 24 小时', value: [dayjs().add(-24, 'h'), dayjs()] },
  7. { label: '最近 5 天', value: [dayjs().add(-5, 'd'), dayjs()] },
  8. ]

ranges

ranges 对象格式
https://4x-ant-design.antgroup.com/components/date-picker-cn/#components-date-picker-demo-presetted-ranges

  1. export function rangeDates() {
  2. const now = moment();
  3. return {
  4. '今天': [moment().startOf('d'), now],
  5. '昨天':[
  6. moment().subtract(1, 'days').startOf('day'),
  7. moment().subtract(1, 'days').endOf('day'),
  8. ],
  9. '最近15分钟': [moment().subtract(15, 'minutes'),now],
  10. '最近30分钟': [moment().subtract(30, 'minutes'), now],
  11. '最近1小时': [moment().subtract(1, 'hours'), now],
  12. '最近1天': [moment().subtract(1, 'day'), now],
  13. '最近1周': [moment().subtract(1, 'weeks'), now],
  14. '最近1月': [moment().subtract(1, 'months'), now],
  15. '本月': [moment().startOf('month'), moment().endOf('month')],
  16. '本季': [moment().startOf('quarter'), now],
  17. '本年': [moment().startOf('year'), now],
  18. };
  19. }