diff --git a/.gitignore b/.gitignore index c1cfea340..aee31b2ea 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,7 @@ lib es yarn.lock package-lock.json +pnpm-lock.yaml coverage/ .doc .history diff --git a/docs/examples/time.tsx b/docs/examples/time.tsx index 51a4fe9ff..c42fd05d5 100644 --- a/docs/examples/time.tsx +++ b/docs/examples/time.tsx @@ -16,7 +16,7 @@ export default () => { picker="date" showTime disabledTime={() => ({ - disabledHours: () => [1, 2, 3, 4, 5, 6], + disabledHours: () => [0, 1, 2, 3, 4, 5, 6, 20, 21], })} locale={zhCN} generateConfig={momentGenerateConfig} diff --git a/src/panels/DatetimePanel/index.tsx b/src/panels/DatetimePanel/index.tsx index cc3d388c5..f2a2a060b 100644 --- a/src/panels/DatetimePanel/index.tsx +++ b/src/panels/DatetimePanel/index.tsx @@ -18,6 +18,17 @@ export type DatetimePanelProps = { const ACTIVE_PANEL = tuple('date', 'time'); type ActivePanelType = (typeof ACTIVE_PANEL)[number]; +const findValidTime = (disabledRange: number[], maxValidTime: number) => { + const rangeSet = new Set(disabledRange); + for (let i = 0; i <= maxValidTime; i++) { + if (!rangeSet.has(i)) { + return i; + } + } + + return 0 +} + function DatetimePanel(props: DatetimePanelProps) { const { prefixCls, @@ -111,6 +122,15 @@ function DatetimePanel(props: DatetimePanelProps) { selectedDate = generateConfig.setYear(selectedDate, generateConfig.getYear(defaultValue)); selectedDate = generateConfig.setMonth(selectedDate, generateConfig.getMonth(defaultValue)); selectedDate = generateConfig.setDate(selectedDate, generateConfig.getDate(defaultValue)); + } else if (source === 'date' && value && disabledTime) { + const disabledTimes = disabledTime(value) + + const validHour = findValidTime(disabledTimes.disabledHours?.() || [-1], 23) + const validMinute = findValidTime(disabledTimes.disabledMinutes?.(validHour) || [-1], 59) + const validSeconds = findValidTime(disabledTimes.disabledSeconds?.(validHour, validMinute) || [-1], 59) + selectedDate = generateConfig.setHour(selectedDate, validHour) + selectedDate = generateConfig.setMinute(selectedDate, validMinute) + selectedDate = generateConfig.setSecond(selectedDate, validSeconds) } if (onSelect) { diff --git a/tests/disabledTime.spec.tsx b/tests/disabledTime.spec.tsx index 60b6a6e4c..2e73e9f0b 100644 --- a/tests/disabledTime.spec.tsx +++ b/tests/disabledTime.spec.tsx @@ -138,6 +138,27 @@ describe('Picker.DisabledTime', () => { jest.useRealTimers(); }); + it('disabledTime should reset correctly when date changed by click', function () { + const disabledTime = jest.fn((_: Moment | null, __: 'start' | 'end') => ({ + disabledHours: () => [0, 1, 2, 3, 4, 10], + })); + + render( + , + ); + + expect(document.querySelector('.rc-picker-input > input').getAttribute('value')).toEqual('1989-11-28 00:00:00'); + + fireEvent.click(document.querySelectorAll('.rc-picker-cell-inner')[2]); + + expect(document.querySelector('.rc-picker-input > input').getAttribute('value')).toEqual('1989-10-31 05:00:00'); + }); + describe('warning for legacy props', () => { it('single', () => { resetWarned();