Skip to content

Commit 1790cf0

Browse files
authored
fix: mouseDown on the hidden element should not trigger close (#1178)
1 parent 23fa3da commit 1790cf0

File tree

3 files changed

+48
-0
lines changed

3 files changed

+48
-0
lines changed

src/SelectInput/index.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,12 @@ export default React.forwardRef<SelectInputRef, SelectInputProps>(function Selec
172172
// ====================== Open ======================
173173
const onInternalMouseDown: SelectInputProps['onMouseDown'] = useEvent((event) => {
174174
if (!disabled) {
175+
// https://github.com/ant-design/ant-design/issues/56002
176+
// Tell `useSelectTriggerControl` to ignore this event
177+
// When icon is dynamic render, the parentNode will miss
178+
// so we need to mark the event directly
179+
(event.nativeEvent as any)._ignore_global_close = true;
180+
175181
const inputDOM = getDOM(inputRef.current);
176182
if (inputDOM && event.target !== inputDOM && !inputDOM.contains(event.target as Node)) {
177183
event.preventDefault();

src/hooks/useSelectTriggerControl.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ export default function useSelectTriggerControl(
2121

2222
if (
2323
open &&
24+
// Marked by SelectInput mouseDown event
25+
!(event as any)._ignore_global_close &&
2426
elements()
2527
.filter((element) => element)
2628
.every((element) => !element.contains(target) && element !== target)

tests/Select.test.tsx

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,46 @@ describe('Select.Basic', () => {
389389
expect(container.querySelector('input').getAttribute('readonly')).toBeFalsy();
390390
});
391391

392+
it('dynamic change icon should not trigger close', () => {
393+
const Demo = () => {
394+
const [open, setOpen] = React.useState(false);
395+
396+
return (
397+
<Select
398+
open={open}
399+
onPopupVisibleChange={setOpen}
400+
showSearch
401+
suffix={
402+
open ? (
403+
<span className="bamboo" key="bamboo" />
404+
) : (
405+
<span className="little" key="little" />
406+
)
407+
}
408+
/>
409+
);
410+
};
411+
412+
const { container } = render(<Demo />);
413+
const suffix = container.querySelector('.little');
414+
415+
const mouseDownEvent = createEvent.mouseDown(suffix);
416+
417+
// First click on the element and re-render to remove the node
418+
fireEvent(suffix, mouseDownEvent);
419+
act(() => {
420+
jest.runAllTimers();
421+
});
422+
423+
// Then popup to the window event (jsdom can not mock this. so we just fire directly)
424+
fireEvent(window, mouseDownEvent);
425+
act(() => {
426+
jest.runAllTimers();
427+
});
428+
429+
expectOpen(container);
430+
});
431+
392432
it('should keep dropdown open when clicking inside popup to prevent accidental close', async () => {
393433
const { container } = render(
394434
<Select

0 commit comments

Comments
 (0)