diff --git a/src/OptionList.tsx b/src/OptionList.tsx index 62473f850..82ffa35fb 100644 --- a/src/OptionList.tsx +++ b/src/OptionList.tsx @@ -135,7 +135,7 @@ const OptionList: React.RefForwardingComponent< * `setActive` function will call root accessibility state update which makes re-render. * So we need to delay to let Input component trigger onChange first. */ - setTimeout(() => { + const timeoutId = setTimeout(() => { if (!multiple && open && values.size === 1) { const value: RawValueType = Array.from(values)[0]; const index = memoFlattenOptions.findIndex( @@ -145,6 +145,8 @@ const OptionList: React.RefForwardingComponent< scrollIntoView(index); } }); + + return () => clearTimeout(timeoutId); }, [open]); // ========================== Values ========================== diff --git a/src/generate.tsx b/src/generate.tsx index 22dc86b3c..a14606b02 100644 --- a/src/generate.tsx +++ b/src/generate.tsx @@ -780,6 +780,12 @@ export default function generateSelector< } }; + const activeTimeoutIds: number[] = []; + React.useEffect(() => () => { + activeTimeoutIds.forEach(timeoutId => clearTimeout(timeoutId)); + activeTimeoutIds.splice(0, activeTimeoutIds.length); + }, []); + const onInternalMouseDown: React.MouseEventHandler = (event, ...restArgs) => { const { target } = event; const popupElement: HTMLDivElement = @@ -787,12 +793,20 @@ export default function generateSelector< // We should give focus back to selector if clicked item is not focusable if (popupElement && popupElement.contains(target as HTMLElement)) { - setTimeout(() => { + const timeoutId = setTimeout(() => { + const index = activeTimeoutIds.indexOf(timeoutId); + if (index !== -1) { + activeTimeoutIds.splice(index, 1); + } + cancelSetMockFocused(); + if (!popupElement.contains(document.activeElement)) { selectorRef.current.focus(); } }); + + activeTimeoutIds.push(timeoutId); } if (onMouseDown) {