From 2e95bb65600f3084a4d992746b167166fa40da4d Mon Sep 17 00:00:00 2001 From: dujiaqi Date: Sat, 7 Oct 2023 22:23:30 +0800 Subject: [PATCH 1/2] fix: interacting with footer components closes the date selection panel --- src/Picker.tsx | 2 ++ src/RangePicker.tsx | 1 + src/hooks/usePickerInput.ts | 12 ++++++++++-- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/Picker.tsx b/src/Picker.tsx index 514d6088e..eb36f88d9 100644 --- a/src/Picker.tsx +++ b/src/Picker.tsx @@ -196,6 +196,7 @@ function InnerPicker(props: PickerProps) { autoComplete = 'off', inputRender, changeOnBlur, + renderExtraFooter, } = props as MergedPickerProps; const inputRef = React.useRef(null); @@ -326,6 +327,7 @@ function InnerPicker(props: PickerProps) { const [inputProps, { focused, typing }] = usePickerInput({ blurToCancel: needConfirmButton, changeOnBlur, + hasExtraFooter: !!renderExtraFooter, open: mergedOpen, value: text, triggerOpen, diff --git a/src/RangePicker.tsx b/src/RangePicker.tsx index be155abaf..b5a4f3d59 100644 --- a/src/RangePicker.tsx +++ b/src/RangePicker.tsx @@ -599,6 +599,7 @@ function InnerRangePicker(props: RangePickerProps) { const getSharedInputHookProps = (index: 0 | 1, resetText: () => void) => ({ blurToCancel: !changeOnBlur && needConfirmButton, changeOnBlur, + hasExtraFooter: !!renderExtraFooter, forwardKeyDown, onBlur: onInternalBlur, isClickOutside: (target: EventTarget | null) => { diff --git a/src/hooks/usePickerInput.ts b/src/hooks/usePickerInput.ts index 0f3f119c2..1cad522fc 100644 --- a/src/hooks/usePickerInput.ts +++ b/src/hooks/usePickerInput.ts @@ -13,6 +13,7 @@ export default function usePickerInput({ onKeyDown, blurToCancel, changeOnBlur, + hasExtraFooter, onSubmit, onCancel, onFocus, @@ -25,7 +26,8 @@ export default function usePickerInput({ forwardKeyDown: (e: React.KeyboardEvent) => boolean; onKeyDown: (e: React.KeyboardEvent, preventDefault: () => void) => void; blurToCancel?: boolean; - changeOnBlur?: boolean + changeOnBlur?: boolean; + hasExtraFooter?: boolean; onSubmit: () => void | boolean; onCancel: () => void; onFocus?: React.FocusEventHandler; @@ -33,6 +35,7 @@ export default function usePickerInput({ }): [React.DOMAttributes, { focused: boolean; typing: boolean }] { const [typing, setTyping] = useState(false); const [focused, setFocused] = useState(false); + const [outside, setOutside] = useState(true); /** * We will prevent blur to handle open event when user click outside, @@ -108,7 +111,7 @@ export default function usePickerInput({ }, onBlur: (e) => { - if (preventBlurRef.current || !isClickOutside(document.activeElement)) { + if (preventBlurRef.current || !isClickOutside(document.activeElement) || !outside) { preventBlurRef.current = false; return; } @@ -152,6 +155,11 @@ export default function usePickerInput({ const target = getTargetFromEvent(e); const clickedOutside = isClickOutside(target); + if (hasExtraFooter) { + // Save whether the last click is inside the component when `extraFooter` exists. + setOutside(clickedOutside); + } + if (open) { if (!clickedOutside) { preventBlurRef.current = true; From 9b843e93a0de1ff3878e40798d3e498ac3728d55 Mon Sep 17 00:00:00 2001 From: dujiaqi Date: Sat, 7 Oct 2023 22:53:35 +0800 Subject: [PATCH 2/2] chore: add test case --- tests/picker.spec.tsx | 15 +++++++++++++++ tests/range.spec.tsx | 18 ++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/tests/picker.spec.tsx b/tests/picker.spec.tsx index 87b0237e6..39c8c3944 100644 --- a/tests/picker.spec.tsx +++ b/tests/picker.spec.tsx @@ -1145,4 +1145,19 @@ describe('Picker.Basic', () => { expect(container.querySelector('input')).toHaveValue('2023-09-04 21:05:10'); }); + + it('interacting with components within footer should not close the panel', () => { + const { container, baseElement } = render( + } />, + ); + + openPicker(container); + + fireEvent.click(baseElement.querySelector('.test-button')); + + // Simulate component behavior + fireEvent.blur(container.querySelector('input')); + + expect(baseElement.querySelector('.rc-picker-dropdown-hidden')).toBeFalsy(); + }); }); diff --git a/tests/range.spec.tsx b/tests/range.spec.tsx index 554c57836..0572e879f 100644 --- a/tests/range.spec.tsx +++ b/tests/range.spec.tsx @@ -1985,4 +1985,22 @@ describe('Picker.Range', () => { expect(onOpenChange).toHaveBeenCalledWith(false); }); + + // In line with the picker + it('interacting with components within footer should not close the panel', () => { + const { container, baseElement } = render( + } + />, + ); + + openPicker(container); + + fireEvent.click(baseElement.querySelector('.test-button')); + + // Simulate component behavior + fireEvent.blur(container.querySelector('input')); + + expect(baseElement.querySelector('.rc-picker-dropdown-hidden')).toBeFalsy(); + }); });