diff --git a/src/BaseSelect/index.tsx b/src/BaseSelect/index.tsx index dc8ddb8f..00b5217d 100644 --- a/src/BaseSelect/index.tsx +++ b/src/BaseSelect/index.tsx @@ -537,13 +537,13 @@ const BaseSelect = React.forwardRef((props, ref) } if (mergedOpen && (!isEnterKey || !keyLockRef.current)) { + // Lock the Enter key after it is pressed to avoid repeated triggering of the onChange event. + if (isEnterKey) { + keyLockRef.current = true; + } listRef.current?.onKeyDown(event, ...rest); } - if (isEnterKey) { - keyLockRef.current = true; - } - onKeyDown?.(event, ...rest); }; @@ -568,6 +568,11 @@ const BaseSelect = React.forwardRef((props, ref) }); }; + const onSelectorBlur = () => { + // Unlock the Enter key after the selector blur; otherwise, the Enter key needs to be pressed twice to trigger the correct effect. + keyLockRef.current = false; + }; + // ========================== Focus / Blur ========================== /** Record real focus status */ const focusRef = React.useRef(false); @@ -815,6 +820,7 @@ const BaseSelect = React.forwardRef((props, ref) onSearchSubmit={onInternalSearchSubmit} onRemove={onSelectorRemove} tokenWithEnter={tokenWithEnter} + onSelectorBlur={onSelectorBlur} /> )} diff --git a/src/Selector/Input.tsx b/src/Selector/Input.tsx index 706ec460..c4353e05 100644 --- a/src/Selector/Input.tsx +++ b/src/Selector/Input.tsx @@ -25,6 +25,7 @@ interface InputProps { onMouseDown: React.MouseEventHandler; onChange: React.ChangeEventHandler; onPaste: React.ClipboardEventHandler; + onBlur: React.FocusEventHandler; onCompositionStart: React.CompositionEventHandler< HTMLInputElement | HTMLTextAreaElement | HTMLElement >; @@ -52,6 +53,7 @@ const Input: React.ForwardRefRenderFunction = (props, ref) onPaste, onCompositionStart, onCompositionEnd, + onBlur, open, attrs, } = props; @@ -66,6 +68,7 @@ const Input: React.ForwardRefRenderFunction = (props, ref) onMouseDown: onOriginMouseDown, onCompositionStart: onOriginCompositionStart, onCompositionEnd: onOriginCompositionEnd, + onBlur: onOriginBlur, style, } = originProps; @@ -134,6 +137,12 @@ const Input: React.ForwardRefRenderFunction = (props, ref) } }, onPaste, + onBlur(event: React.FocusEvent) { + onBlur(event); + if (onOriginBlur) { + onOriginBlur(event); + } + }, }); return inputNode; diff --git a/src/Selector/MultipleSelector.tsx b/src/Selector/MultipleSelector.tsx index 751ae1b7..34d9268b 100644 --- a/src/Selector/MultipleSelector.tsx +++ b/src/Selector/MultipleSelector.tsx @@ -72,6 +72,7 @@ const SelectSelector: React.FC = (props) => { onInputMouseDown, onInputCompositionStart, onInputCompositionEnd, + onInputBlur, } = props; const measureRef = React.useRef(null); @@ -231,6 +232,7 @@ const SelectSelector: React.FC = (props) => { onPaste={onInputPaste} onCompositionStart={onInputCompositionStart} onCompositionEnd={onInputCompositionEnd} + onBlur={onInputBlur} tabIndex={tabIndex} attrs={pickAttrs(props, true)} /> diff --git a/src/Selector/SingleSelector.tsx b/src/Selector/SingleSelector.tsx index c384a59d..6fe56654 100644 --- a/src/Selector/SingleSelector.tsx +++ b/src/Selector/SingleSelector.tsx @@ -36,6 +36,7 @@ const SingleSelector: React.FC = (props) => { onInputPaste, onInputCompositionStart, onInputCompositionEnd, + onInputBlur, title, } = props; @@ -100,6 +101,7 @@ const SingleSelector: React.FC = (props) => { onPaste={onInputPaste} onCompositionStart={onInputCompositionStart} onCompositionEnd={onInputCompositionEnd} + onBlur={onInputBlur} tabIndex={tabIndex} attrs={pickAttrs(props, true)} maxLength={combobox ? maxLength : undefined} diff --git a/src/Selector/index.tsx b/src/Selector/index.tsx index 47a59a3a..bc068375 100644 --- a/src/Selector/index.tsx +++ b/src/Selector/index.tsx @@ -44,6 +44,7 @@ export interface InnerSelectorProps { onInputPaste: React.ClipboardEventHandler; onInputCompositionStart: React.CompositionEventHandler; onInputCompositionEnd: React.CompositionEventHandler; + onInputBlur: React.FocusEventHandler; } export interface RefSelectorProps { @@ -92,7 +93,8 @@ export interface SelectorProps { onSearchSubmit?: (searchText: string) => void; onRemove: (value: DisplayValueType) => void; onInputKeyDown?: React.KeyboardEventHandler; - + // on selector blur + onSelectorBlur?: () => void; /** * @private get real dom for trigger align. * This may be removed after React provides replacement of `findDOMNode` @@ -119,6 +121,7 @@ const Selector: React.ForwardRefRenderFunction onSearchSubmit, onToggleOpen, onInputKeyDown, + onSelectorBlur, domRef, } = props; @@ -270,6 +273,7 @@ const Selector: React.ForwardRefRenderFunction onInputPaste, onInputCompositionStart, onInputCompositionEnd, + onInputBlur: onSelectorBlur, }; const selectNode = diff --git a/tests/Select.test.tsx b/tests/Select.test.tsx index 6f49bff3..9c2b4610 100644 --- a/tests/Select.test.tsx +++ b/tests/Select.test.tsx @@ -28,6 +28,7 @@ import { keyUp, selectItem, toggleOpen, + waitFakeTimer, } from './utils/common'; describe('Select.Basic', () => { @@ -2367,4 +2368,53 @@ describe('Select.Basic', () => { expect(element[0]).not.toHaveClass('rc-select-item-option-disabled'); expect(element[1]).toHaveClass('rc-select-item-option-disabled'); }); + + it('release Enter key lock after customize input calls blur()', async () => { + let inputElem: HTMLInputElement | null = null; + const onBlur = jest.fn(); + const Demo: React.FC = () => { + const ref = React.useRef(null); + const onSelect = () => { + ref.current!.blur(); + fireEvent.blur(ref.current); + }; + const getInputElement = () => { + return ; + }; + return ( +