From ee1c9efb3e2d3f014af2bdd730a5e3a9e1629278 Mon Sep 17 00:00:00 2001 From: David Uhlmann Date: Thu, 25 Apr 2024 19:01:36 +1000 Subject: [PATCH 1/5] fix: remove blur timeout from SelectInput container, use focusout --- .../inputs/SelectInput/SelectInput.tsx | 27 ++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/components/inputs/SelectInput/SelectInput.tsx b/src/components/inputs/SelectInput/SelectInput.tsx index ab722dc3a..be659f552 100644 --- a/src/components/inputs/SelectInput/SelectInput.tsx +++ b/src/components/inputs/SelectInput/SelectInput.tsx @@ -1,6 +1,6 @@ import { faAngleDown } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { ReactNode, useCallback, useState } from 'react'; +import { ReactNode, useCallback, useEffect, useRef, useState } from 'react'; import Drawer from '../../Drawer'; import RadioInput from '../../RadioInput'; import { OptionProps, RadioInputProps } from '../../RadioInput/RadioInput'; @@ -87,13 +87,34 @@ export default function SelectInput({ () => setExpanded((expanded) => !expanded), [] ); - const close = useCallback(() => setTimeout(() => setExpanded(false), 1), []); + + const containerRef = useRef(null); + useEffect(() => { + function handleClickOutside() { + const activeElement = document.activeElement; + if (!activeElement || !containerRef.current?.contains(activeElement)) { + setExpanded(false); + } + } + // Bind the event listener to document + if (expanded) { + // use focusout instead of blur because blur don't not always bubble + // - https://www.quirksmode.org/dom/events/blurfocus.html + // - https://developer.mozilla.org/en-US/docs/Web/API/Element/focusout_event + document.addEventListener('focusout', handleClickOutside); + return () => { + // Unbind the event listener on clean up + document.removeEventListener('focusout', handleClickOutside); + }; + } + }, [expanded]); + return (