onBlur event handler firing when focusing on child components

Hi everyone! I'm having trouble with my onFocus and onBlur events. I have this div, which is a container for search bar:
<div
className="w-full relative"
onFocus={() => {
setSearchPopUpOpened(true);
}}
onBlur={() => {
setSearchPopUpOpened(false);
}}
>
{searchPopUpOpened && <SearchBarPopUp />}
<form
className="relative w-full"
onSubmit={(e) => {
e.preventDefault();
}}
>
<input
type="text"
placeholder="Search for products..."
className="border-2 rounded-xl p-2 w-full"
/>
<button type="submit" className="absolute top-[10px] right-3">
<FontAwesomeIcon icon={faMagnifyingGlass} />
</button>
</form>
</div>
<div
className="w-full relative"
onFocus={() => {
setSearchPopUpOpened(true);
}}
onBlur={() => {
setSearchPopUpOpened(false);
}}
>
{searchPopUpOpened && <SearchBarPopUp />}
<form
className="relative w-full"
onSubmit={(e) => {
e.preventDefault();
}}
>
<input
type="text"
placeholder="Search for products..."
className="border-2 rounded-xl p-2 w-full"
/>
<button type="submit" className="absolute top-[10px] right-3">
<FontAwesomeIcon icon={faMagnifyingGlass} />
</button>
</form>
</div>
On focus, it sets searchPopUpOpened to true and does the opposite on blur. <SearchBarPopUp /> is a child of this search bar container with onFocus and onBlur event handlers, but for some reason, if you click inside the <SearchBarPopUp />, focus is lostonBlur event handler fires, setting searchPopUpOpened to false. How to fix this behaviour? I need my main div to have focus while the user is clicking on its children, but for some reason, it doesn't work with my search bar pop-up.
6 Replies
Wolle
Wolle•17mo ago
I usually used a click handler on the document to close dorpdowns, in there you can check if the click was on or inside your search dropdown. CSS has :focus-within maybe there is an event for that, too?
Aleksandr M.
Aleksandr M.•17mo ago
You mean, add onClick on the document itself to make sure if user clicks anywhere but search bar, the searchPopUpOpened will be set to false?
Wolle
Wolle•17mo ago
It does not feel like an elegant solution, but I am not aware of a better solution atm.
Aleksandr M.
Aleksandr M.•17mo ago
I looked it up, the :focus-within equivalent is onBlur, which is the one I use 🥹 Perhaps I'll have to use it like a crutch, thanks though!
Wolle
Wolle•17mo ago
onBlur uses :focus (if i am not mistaken) A common thing, thats pretty close to your case are dropdowns (for selects or similar), maybe that helps your search for ideas.
Aleksandr M.
Aleksandr M.•17mo ago
Thanks. I've named it wrongly, it's definitely a dropdown, not a pop-up. I'll to rename it