diff --git a/src/Picker.tsx b/src/Picker.tsx index bceb4d039..5b5d37528 100644 --- a/src/Picker.tsx +++ b/src/Picker.tsx @@ -242,15 +242,12 @@ function InnerPicker(props: PickerProps) { } }; - const triggerOpen = (newOpen: boolean, preventChangeEvent: boolean = false) => { + const triggerOpen = (newOpen: boolean) => { if (disabled && newOpen) { return; } triggerInnerOpen(newOpen); - if (!newOpen && !preventChangeEvent) { - triggerChange(selectedValue); - } }; const forwardKeyDown = (e: React.KeyboardEvent) => { @@ -285,6 +282,7 @@ function InnerPicker(props: PickerProps) { const [inputProps, { focused, typing }] = usePickerInput({ blurToCancel: needConfirmButton, open: mergedOpen, + value: text, triggerOpen, forwardKeyDown, isClickOutside: target => @@ -295,12 +293,12 @@ function InnerPicker(props: PickerProps) { } triggerChange(selectedValue); - triggerOpen(false, true); + triggerOpen(false); resetText(); return true; }, onCancel: () => { - triggerOpen(false, true); + triggerOpen(false); setSelectedValue(mergedValue); resetText(); }, @@ -400,7 +398,7 @@ function InnerPicker(props: PickerProps) { e.preventDefault(); e.stopPropagation(); triggerChange(null); - triggerOpen(false, true); + triggerOpen(false); }} className={`${prefixCls}-clear`} > @@ -422,7 +420,7 @@ function InnerPicker(props: PickerProps) { if (type === 'submit' || (type !== 'key' && !needConfirmButton)) { // triggerChange will also update selected values triggerChange(date); - triggerOpen(false, true); + triggerOpen(false); } }; const popupPlacement = direction === 'rtl' ? 'bottomRight' : 'bottomLeft'; diff --git a/src/RangePicker.tsx b/src/RangePicker.tsx index 7c6b21edf..5ca56f2a7 100644 --- a/src/RangePicker.tsx +++ b/src/RangePicker.tsx @@ -541,11 +541,6 @@ function InnerRangePicker(props: RangePickerProps) { }, triggerOpen: (newOpen: boolean) => { triggerOpen(newOpen, index); - - // Only blur will close open - if (!newOpen && mergedOpen !== newOpen && mergedActivePickerIndex === index) { - triggerChange(selectedValue, index); - } }, onSubmit: () => { triggerChange(selectedValue, index); @@ -561,11 +556,13 @@ function InnerRangePicker(props: RangePickerProps) { const [startInputProps, { focused: startFocused, typing: startTyping }] = usePickerInput({ ...getSharedInputHookProps(0, resetStartText), open: startOpen, + value: startText, }); const [endInputProps, { focused: endFocused, typing: endTyping }] = usePickerInput({ ...getSharedInputHookProps(1, resetEndText), open: endOpen, + value: endText, }); // ============================= Sync ============================== diff --git a/src/hooks/usePickerInput.ts b/src/hooks/usePickerInput.ts index 4c03b66c5..f8f437f37 100644 --- a/src/hooks/usePickerInput.ts +++ b/src/hooks/usePickerInput.ts @@ -1,9 +1,11 @@ import * as React from 'react'; +import { useState, useEffect, useRef } from 'react'; import KeyCode from 'rc-util/lib/KeyCode'; import { addGlobalMouseDownEvent } from '../utils/uiUtil'; export default function usePickerInput({ open, + value, isClickOutside, triggerOpen, forwardKeyDown, @@ -14,6 +16,7 @@ export default function usePickerInput({ onBlur, }: { open: boolean; + value: string; isClickOutside: (clickElement: EventTarget | null) => boolean; triggerOpen: (open: boolean) => void; forwardKeyDown: (e: React.KeyboardEvent) => boolean; @@ -23,14 +26,16 @@ export default function usePickerInput({ onFocus?: React.FocusEventHandler; onBlur?: React.FocusEventHandler; }): [React.DOMAttributes, { focused: boolean; typing: boolean }] { - const [typing, setTyping] = React.useState(false); - const [focused, setFocused] = React.useState(false); + const [typing, setTyping] = useState(false); + const [focused, setFocused] = useState(false); /** * We will prevent blur to handle open event when user click outside, * since this will repeat trigger `onOpenChange` event. */ - const preventBlurRef = React.useRef(false); + const preventBlurRef = useRef(false); + + const valueChangedRef = useRef(false); const inputProps: React.DOMAttributes = { onMouseDown: () => { @@ -99,8 +104,12 @@ export default function usePickerInput({ onCancel(); } }, 0); - } else { + } else if (open) { triggerOpen(false); + + if (valueChangedRef.current) { + onSubmit(); + } } setFocused(false); @@ -110,8 +119,17 @@ export default function usePickerInput({ }, }; + // check if value changed + useEffect(() => { + valueChangedRef.current = false; + }, [open]); + + useEffect(() => { + valueChangedRef.current = true; + }, [value]); + // Global click handler - React.useEffect(() => + useEffect(() => addGlobalMouseDownEvent(({ target }: MouseEvent) => { if (open) { if (!isClickOutside(target)) { diff --git a/tests/range.spec.tsx b/tests/range.spec.tsx index f0a62082c..334b66497 100644 --- a/tests/range.spec.tsx +++ b/tests/range.spec.tsx @@ -1289,5 +1289,14 @@ describe('Picker.Range', () => { wrapper.closePicker(0); expect(wrapper.isOpen()).toBeFalsy(); }); + + it('not change: start not to end', () => { + const wrapper = mount( + , + ); + wrapper.openPicker(0); + wrapper.closePicker(0); + expect(wrapper.isOpen()).toBeFalsy(); + }); }); });