From 72a709ee392c9706a142afd86493b89d8a90bb6b 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: Mon, 1 Dec 2025 15:34:58 +0800 Subject: [PATCH] fix: mouseDown on the hidden element should not trigger close --- src/SelectInput/index.tsx | 6 +++++ src/hooks/useSelectTriggerControl.ts | 2 ++ tests/Select.test.tsx | 40 ++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/src/SelectInput/index.tsx b/src/SelectInput/index.tsx index db0bc308..619be16e 100644 --- a/src/SelectInput/index.tsx +++ b/src/SelectInput/index.tsx @@ -172,6 +172,12 @@ export default React.forwardRef(function Selec // ====================== Open ====================== const onInternalMouseDown: SelectInputProps['onMouseDown'] = useEvent((event) => { if (!disabled) { + // https://github.com/ant-design/ant-design/issues/56002 + // Tell `useSelectTriggerControl` to ignore this event + // When icon is dynamic render, the parentNode will miss + // so we need to mark the event directly + (event.nativeEvent as any)._ignore_global_close = true; + const inputDOM = getDOM(inputRef.current); if (inputDOM && event.target !== inputDOM && !inputDOM.contains(event.target as Node)) { event.preventDefault(); diff --git a/src/hooks/useSelectTriggerControl.ts b/src/hooks/useSelectTriggerControl.ts index 79ced5d0..3d1de438 100644 --- a/src/hooks/useSelectTriggerControl.ts +++ b/src/hooks/useSelectTriggerControl.ts @@ -21,6 +21,8 @@ export default function useSelectTriggerControl( if ( open && + // Marked by SelectInput mouseDown event + !(event as any)._ignore_global_close && elements() .filter((element) => element) .every((element) => !element.contains(target) && element !== target) diff --git a/tests/Select.test.tsx b/tests/Select.test.tsx index 53f59d40..e311e1a4 100644 --- a/tests/Select.test.tsx +++ b/tests/Select.test.tsx @@ -389,6 +389,46 @@ describe('Select.Basic', () => { expect(container.querySelector('input').getAttribute('readonly')).toBeFalsy(); }); + it('dynamic change icon should not trigger close', () => { + const Demo = () => { + const [open, setOpen] = React.useState(false); + + return ( +