Skip to content

Commit ce2a2e1

Browse files
Tinssondaitingyuan
andauthored
fix(date-range-quick-picker): support the time disabled of props (min, max) (#2070)
* fix: 修复DateRangeQuickPicker的min和max对时间不生效问题 Co-authored-by: daitingyuan <daitingyuan@youzan.com>
1 parent e215509 commit ce2a2e1

File tree

4 files changed

+120
-3
lines changed

4 files changed

+120
-3
lines changed

packages/zent/__tests__/date-range-quick-picker.spec.jsx

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,30 +36,47 @@ describe('DateRangeQuickPicker', () => {
3636
value={[1524106071377, 1524107071377]}
3737
onChange={onChange}
3838
valueType="number"
39+
format="YYYY-MM-DD HH:mm:ss"
40+
min="2020-04-19 10:05:12"
41+
max="2025-01-01 12:05:12"
3942
/>
4043
);
4144

4245
wrapper.instance().handleChosenDays(1);
4346
expect(onChange.mock.calls.length).toBe(1);
47+
wrapper.find('.zent-datepicker-trigger').at(1).simulate('click');
4448
});
4549

4650
it('suppports default preset', () => {
4751
const onChange = jest.fn();
48-
mount(
52+
const wrapper = mount(
4953
<DateRangeQuickPicker
5054
value={[1524106071377, 1524107071377]}
5155
onChange={onChange}
5256
defaultSelectedPresetIndex={0}
57+
disabledDate={{
58+
min: '2018-04-19 10:05:12',
59+
max: '2018-04-19 15:05:12',
60+
}}
5361
/>
5462
);
5563
expect(onChange.mock.calls.length).toBe(0);
64+
wrapper.find('.zent-datepicker-trigger').at(0).simulate('click');
5665

57-
mount(
66+
const wrapper2 = mount(
5867
<DateRangeQuickPicker
5968
onChange={onChange}
6069
defaultSelectedPresetIndex={0}
70+
disabledTime={() => {
71+
return {
72+
disabledHours: () => [],
73+
disabledMinutes: () => [],
74+
disabledSeconds: () => [],
75+
};
76+
}}
6177
/>
6278
);
6379
expect(onChange.mock.calls.length).toBe(1);
80+
wrapper2.find('.zent-datepicker-trigger').at(1).simulate('click');
6481
});
6582
});

packages/zent/src/date-picker/components/RangePickerBase.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import useRangeMergedProps from '../hooks/useRangeMergedProps';
66
import useRangeDisabledDate from '../hooks/useRangeDisabledDate';
77
import { useShowTimeRangeOption } from '../hooks/useShowTimeOption';
88
import useNormalizeDisabledDate from '../hooks/useNormalizeDisabledDate';
9+
import useNormalizeDisabledTime from '../hooks/useNormalizeDisabledTime';
910
import { useEventCallbackRef } from '../../utils/hooks/useEventCallbackRef';
1011

1112
import {
@@ -46,7 +47,7 @@ const RangePicker: React.FC<IRangePickerProps> = ({
4647
onChange,
4748
onClose,
4849
onOpen,
49-
disabledTime,
50+
disabledTime: disabledTimeProps,
5051
generateDate,
5152
PickerComponent,
5253
showTime,
@@ -104,6 +105,12 @@ const RangePicker: React.FC<IRangePickerProps> = ({
104105
[start, end, showTime, onChangeRef, getCallbackRangeValue, setSelected]
105106
);
106107

108+
const disabledTime = useNormalizeDisabledTime(
109+
format,
110+
disabledDateProps,
111+
disabledTimeProps
112+
);
113+
107114
const { disabledStartTimes, disabledEndTimes } = useRangeDisabledTime({
108115
selected,
109116
disabledTime,
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { useCallback } from 'react';
2+
import { IDisabledTime, IDisabledDate } from '../types';
3+
import unifiedDisabledTimeFromProps from '../utils/unifiedDisabledTimeFromProps';
4+
5+
export default function useNormalizeDisabledTime(
6+
format: string,
7+
disabledDate: IDisabledDate,
8+
disabledTime: IDisabledTime
9+
) {
10+
// eslint-disable-next-line react-hooks/exhaustive-deps
11+
const normalizedDisabledTime = useCallback(
12+
unifiedDisabledTimeFromProps(format, disabledDate, disabledTime),
13+
[disabledDate, format, disabledTime]
14+
);
15+
return normalizedDisabledTime;
16+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import { endOfDay, isAfter, isBefore, startOfDay, isSameDay } from 'date-fns';
2+
import { parseBase } from './index';
3+
import { IDisabledDate, IDisabledTime, IDisabledDateSimple } from '../types';
4+
5+
function generateNumberArray(max) {
6+
return Array.from({ length: max + 1 }, (_, i) => i);
7+
}
8+
9+
/**
10+
* props的DisabledDate参数 支持 {min, max} 格式
11+
* 内部统一转成方法-输出disabledTime
12+
* @param format
13+
* @param disabledDateProps
14+
* @param disabledTime
15+
*/
16+
export default function unifiedDisabledDateFromProps(
17+
format: string,
18+
disabledDateProps: IDisabledDate,
19+
disabledTime: IDisabledTime
20+
): IDisabledTime {
21+
if (typeof disabledTime === 'function') {
22+
return disabledTime;
23+
}
24+
if (typeof disabledDateProps === 'object') {
25+
const { min, max } = disabledDateProps as IDisabledDateSimple;
26+
const disabledDate = (date: Date) =>
27+
(!!min && isBefore(endOfDay(date), parseBase(min, format))) ||
28+
(!!max && isAfter(startOfDay(date), parseBase(max, format)));
29+
return (date: Date) => {
30+
const isDateDisabled = disabledDate(date);
31+
if (isDateDisabled) {
32+
return {
33+
disabledHours: () => generateNumberArray(23),
34+
disabledMinutes: () => generateNumberArray(59),
35+
disabledSeconds: () => generateNumberArray(59),
36+
};
37+
}
38+
if (!!min && isSameDay(endOfDay(date), parseBase(min, format))) {
39+
// 如果是min当天,那么只有min之前的时间是disabled的
40+
const minDate = parseBase(min, format);
41+
return {
42+
disabledHours: () => generateNumberArray(minDate.getHours() - 1),
43+
disabledMinutes: (hour: number) =>
44+
hour === minDate.getHours()
45+
? generateNumberArray(minDate.getMinutes() - 1)
46+
: [],
47+
disabledSeconds: (hour: number, minute: number) =>
48+
hour === minDate.getHours() && minute === minDate.getMinutes()
49+
? generateNumberArray(minDate.getSeconds() - 1)
50+
: [],
51+
};
52+
}
53+
if (!!max && isSameDay(startOfDay(date), parseBase(max, format))) {
54+
// 如果是max当天,那么只有max之后的时间是disabled的
55+
const maxDate = parseBase(max, format);
56+
return {
57+
disabledHours: () =>
58+
generateNumberArray(23).slice(maxDate.getHours() + 1),
59+
disabledMinutes: (hour: number) =>
60+
hour === maxDate.getHours()
61+
? generateNumberArray(59).slice(maxDate.getMinutes() + 1)
62+
: [],
63+
disabledSeconds: (hour: number, minute: number) =>
64+
hour === maxDate.getHours() && minute === maxDate.getMinutes()
65+
? generateNumberArray(59).slice(maxDate.getSeconds() + 1)
66+
: [],
67+
};
68+
}
69+
return {
70+
disabledHours: () => [],
71+
disabledMinutes: () => [],
72+
disabledSeconds: () => [],
73+
};
74+
};
75+
}
76+
return disabledTime;
77+
}

0 commit comments

Comments
 (0)