From 6dcf4b98f781aa623154c1cbc7560bc3de7445bd Mon Sep 17 00:00:00 2001 From: snowingfox <1503401882@qq.com> Date: Wed, 27 Sep 2023 14:20:35 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20DatePicker=20=E4=B8=ADdisabledTime=20?= =?UTF-8?q?=E7=A6=81=E7=94=A8=E9=97=AE=E9=A2=98=20(#666)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: fix-bug * chore: remove whitespace * feat: change logic * feat: change logic * feat: change logic * test: add test case * test: add test case * test: add test case * fix: fix incorrect time --- .gitignore | 1 + docs/examples/time.tsx | 2 +- src/panels/DatetimePanel/index.tsx | 20 ++++++++++++++++++++ tests/disabledTime.spec.tsx | 21 +++++++++++++++++++++ 4 files changed, 43 insertions(+), 1 deletion(-) 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();