Dropdown with click outside pattern

What would be the best pattern to create a dropdown menu div or menu div with an onClick handler outside to auto close it? not a hover menu, mind you, but a click menu. I know how to show it, but I recall handling the onClick outside of the element actually implied something like portals or annoying dom manipulation in react, and I'm wondering if solid (or some community-made primitive) has a better idiomatic pattern for this? Currently my component looks like
export const FilteringDropdown = (props) => {
const [isShown, setIsShown] = createSignal(false)
return (
<div class="relative">
<button class="border-0 bg-transparent cursor-pointer m-0 p-2 whitespace-nowrap" onClick={() => setIsShown(!isShown())}>
<span class={`px-2 h-[24px] w-[24px] ${props.icon}`}></span>
{props.title}
<span class="h-[24px] w-[24px] i-material-symbols-keyboard-arrow-down"></span>
</button>
{isShown() && <div class="absolute top-10 left-0 w-lg bg-white border-1">FILTERS!</div>}
</div>
)
}
export const FilteringDropdown = (props) => {
const [isShown, setIsShown] = createSignal(false)
return (
<div class="relative">
<button class="border-0 bg-transparent cursor-pointer m-0 p-2 whitespace-nowrap" onClick={() => setIsShown(!isShown())}>
<span class={`px-2 h-[24px] w-[24px] ${props.icon}`}></span>
{props.title}
<span class="h-[24px] w-[24px] i-material-symbols-keyboard-arrow-down"></span>
</button>
{isShown() && <div class="absolute top-10 left-0 w-lg bg-white border-1">FILTERS!</div>}
</div>
)
}
obviously, it only opens or close on clicking the button.
10 Replies
thetarnav
thetarnav2y ago
solid-headless has a menu component that works based on focus. menu is open as long as it has focus. you click outside, it losses focus. There is solid-dismiss as well
<Alterion.Dev>
solid-dismiss looks like what I 'm thinking about
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
<Alterion.Dev>
I keep being reminded that I should start using solid-primitives to the same extent I use lodash dogkek
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
<Alterion.Dev>
yeah it's always a fine balance, at one point, you reach the threshold of "well I really should use that library even if it means I'll have to rewrite a few patterns"
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
<Alterion.Dev>
same with lodash when I finally gave in and used it for my enmap module - suddenly 100 lines of code changed because it was better to use isNil and isObject and isFunction everywhere since I was using get() anyway I haven't reached the threshold yet. I'm going to use solid-dismiss for now
lxsmnsyc
lxsmnsyc2y ago
the problem I have with this kind of implementation is that when it comes to nesting, it breaks immediately. Sure it works for simple cases
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View