From 01a9c9840a99358ad12c99c232a2ed338d3963eb Mon Sep 17 00:00:00 2001 From: JiaQi <112228030+Yuiai01@users.noreply.github.com> Date: Tue, 19 Sep 2023 09:59:20 +0800 Subject: [PATCH] fix: resolves an issue that occurs when showTime and changeOnBlur exist at the same time (#676) * fix: Increase the priority of executing events in dateTime mode * chore: add test case --------- Co-authored-by: dujiaqi --- src/Picker.tsx | 1 + src/RangePicker.tsx | 15 ++++++----- src/hooks/usePickerInput.ts | 4 ++- tests/range.spec.tsx | 52 +++++++++++++++++++++++++++---------- 4 files changed, 50 insertions(+), 22 deletions(-) diff --git a/src/Picker.tsx b/src/Picker.tsx index c53b6631e..514d6088e 100644 --- a/src/Picker.tsx +++ b/src/Picker.tsx @@ -325,6 +325,7 @@ function InnerPicker(props: PickerProps) { const [inputProps, { focused, typing }] = usePickerInput({ blurToCancel: needConfirmButton, + changeOnBlur, open: mergedOpen, value: text, triggerOpen, diff --git a/src/RangePicker.tsx b/src/RangePicker.tsx index cd3de9572..941b5bd8b 100644 --- a/src/RangePicker.tsx +++ b/src/RangePicker.tsx @@ -573,13 +573,7 @@ function InnerRangePicker(props: RangePickerProps) { const onInternalBlur: React.FocusEventHandler = (e) => { if (delayOpen) { - if (changeOnBlur) { - const selectedIndexValue = getValue(selectedValue, mergedActivePickerIndex); - - if (selectedIndexValue) { - triggerChange(selectedValue, mergedActivePickerIndex); - } - } else if (needConfirmButton) { + if (needConfirmButton) { // when in dateTime mode, switching between two date input fields will trigger onCalendarChange. // when onBlur is triggered, the input field has already switched, // so it's necessary to obtain the value of the previous input field here. @@ -589,6 +583,12 @@ function InnerRangePicker(props: RangePickerProps) { if (selectedIndexValue) { triggerChange(selectedValue, needTriggerIndex, true); } + } else if (changeOnBlur) { + const selectedIndexValue = getValue(selectedValue, mergedActivePickerIndex); + + if (selectedIndexValue) { + triggerChange(selectedValue, mergedActivePickerIndex); + } } } @@ -597,6 +597,7 @@ function InnerRangePicker(props: RangePickerProps) { const getSharedInputHookProps = (index: 0 | 1, resetText: () => void) => ({ blurToCancel: !changeOnBlur && needConfirmButton, + changeOnBlur, forwardKeyDown, onBlur: onInternalBlur, isClickOutside: (target: EventTarget | null) => { diff --git a/src/hooks/usePickerInput.ts b/src/hooks/usePickerInput.ts index 6aec55bc2..0f3f119c2 100644 --- a/src/hooks/usePickerInput.ts +++ b/src/hooks/usePickerInput.ts @@ -12,6 +12,7 @@ export default function usePickerInput({ forwardKeyDown, onKeyDown, blurToCancel, + changeOnBlur, onSubmit, onCancel, onFocus, @@ -24,6 +25,7 @@ export default function usePickerInput({ forwardKeyDown: (e: React.KeyboardEvent) => boolean; onKeyDown: (e: React.KeyboardEvent, preventDefault: () => void) => void; blurToCancel?: boolean; + changeOnBlur?: boolean onSubmit: () => void | boolean; onCancel: () => void; onFocus?: React.FocusEventHandler; @@ -158,7 +160,7 @@ export default function usePickerInput({ raf(() => { preventBlurRef.current = false; }); - } else if (!blurToCancel && (!focused || clickedOutside)) { + } else if (!changeOnBlur && !blurToCancel && (!focused || clickedOutside)) { triggerOpen(false); } } diff --git a/tests/range.spec.tsx b/tests/range.spec.tsx index 52e732b29..c1f47d48e 100644 --- a/tests/range.spec.tsx +++ b/tests/range.spec.tsx @@ -1924,24 +1924,48 @@ describe('Picker.Range', () => { expect(document.querySelectorAll('.rc-picker-input')[1]).toHaveClass('rc-picker-input-active'); }); - it('dateTime mode switch should trigger onCalendarChange', () => { - const onCalendarChange = jest.fn(); - const { container } = render( - , - ); + describe('trigger onCalendarChange', () => { + const switchInput = (container: HTMLElement) => { + openPicker(container, 0); - openPicker(container, 0); + selectCell(8, 0); - selectCell(8, 0); + openPicker(container, 1); - openPicker(container, 1); + // onBlur is triggered when the switch is complete + closePicker(container, 0); + }; + + it('dateTime mode switch should trigger onCalendarChange', () => { + const onCalendarChange = jest.fn(); + const { container } = render( + , + ); + + switchInput(container); - // onBlur is triggered when the switch is complete - closePicker(container, 0); + expect(onCalendarChange).toHaveBeenCalled(); + }); - expect(onCalendarChange).toHaveBeenCalled(); + it('should only trigger onCalendarChange when showTime and changeOnBlur exist', () => { + const onCalendarChange = jest.fn(); + const onChange = jest.fn(); + const { container, baseElement } = render( + , + ); + + switchInput(container); + + // one of the panel should be open + expect(baseElement.querySelector('.rc-picker-dropdown')).toBeTruthy(); + + expect(onCalendarChange).toHaveBeenCalled(); + expect(onChange).not.toHaveBeenCalled(); + }); }); });