From d9f8f8e5e3a72c380f7bdb0ce496b6a5cb405fe7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=8C=E8=B4=A7=E6=9C=BA=E5=99=A8=E4=BA=BA?= Date: Fri, 5 Dec 2025 15:59:27 +0800 Subject: [PATCH] fix: blur unique logic not trigger close --- src/BaseSelect/index.tsx | 12 ++++++++---- tests/Combobox.test.tsx | 2 ++ tests/focus.test.tsx | 21 +++++++++++++++++++++ 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/BaseSelect/index.tsx b/src/BaseSelect/index.tsx index 6734b883..b80e4fe0 100644 --- a/src/BaseSelect/index.tsx +++ b/src/BaseSelect/index.tsx @@ -21,7 +21,7 @@ import type { RefTriggerProps } from '../SelectTrigger'; import SelectTrigger from '../SelectTrigger'; import { getSeparatedContent, isValidCount } from '../utils/valueUtil'; import Polite from './Polite'; -import useOpen from '../hooks/useOpen'; +import useOpen, { macroTask } from '../hooks/useOpen'; import { useEvent } from '@rc-component/util'; import type { SelectInputRef } from '../SelectInput'; import SelectInput from '../SelectInput'; @@ -547,8 +547,7 @@ const BaseSelect = React.forwardRef((props, ref) useSelectTriggerControl(getSelectElements, mergedOpen, triggerOpen, !!mergedComponents.root); // ========================== Focus / Blur ========================== - /** Record real focus status */ - // const focusRef = React.useRef(false); + const internalMouseDownRef = React.useRef(false); const onInternalFocus: React.FocusEventHandler = (event) => { setFocused(true); @@ -565,7 +564,7 @@ const BaseSelect = React.forwardRef((props, ref) const onRootBlur = () => { // Delay close should check the activeElement - if (mergedOpen) { + if (mergedOpen && !internalMouseDownRef.current) { triggerOpen(false, { cancelFun: () => isInside(getSelectElements(), document.activeElement as HTMLElement), }); @@ -605,6 +604,11 @@ const BaseSelect = React.forwardRef((props, ref) } onMouseDown?.(event, ...restArgs); + + internalMouseDownRef.current = true; + macroTask(() => { + internalMouseDownRef.current = false; + }); }; // ============================ Dropdown ============================ diff --git a/tests/Combobox.test.tsx b/tests/Combobox.test.tsx index 8f23e6f7..dac9c229 100644 --- a/tests/Combobox.test.tsx +++ b/tests/Combobox.test.tsx @@ -500,6 +500,8 @@ describe('Select.Combobox', () => { for (let i = 0; i < 10; i += 1) { fireEvent.mouseDown(container.querySelector('input')!); expectOpen(container); + + await delay(100); } fireEvent.blur(container.querySelector('input')!); diff --git a/tests/focus.test.tsx b/tests/focus.test.tsx index 104352fe..dc13cc52 100644 --- a/tests/focus.test.tsx +++ b/tests/focus.test.tsx @@ -118,4 +118,25 @@ describe('Select.Focus', () => { expect(onPopupVisibleChange).toHaveBeenCalledWith(false); }); + + it('click inner that no have focusable element should not close the popup', () => { + const onPopupVisibleChange = jest.fn(); + + const { container } = render( +