fiat combobox + happy utenti page uWu
parent
de28d3ad6e
commit
9a10fe1ff0
@ -0,0 +1,60 @@
|
||||
import { createContext, type ComponentChildren, type JSX } from 'preact'
|
||||
import { useState, useRef, useEffect } from 'preact/hooks'
|
||||
|
||||
export const ComboBox = ({
|
||||
value,
|
||||
setValue,
|
||||
children,
|
||||
}: {
|
||||
value: string
|
||||
setValue: (s: string) => void
|
||||
children: Record<string, ComponentChildren>
|
||||
}) => {
|
||||
const [cloak, setCloak] = useState(true)
|
||||
const [open, setOpen] = useState(true)
|
||||
const comboRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
useEffect(() => {
|
||||
const handleClick = (e: MouseEvent) => {
|
||||
if (comboRef.current && !comboRef.current.contains(e.target as Node)) {
|
||||
setOpen(false)
|
||||
}
|
||||
}
|
||||
document.addEventListener('mousedown', handleClick)
|
||||
return () => document.removeEventListener('mousedown', handleClick)
|
||||
}, [])
|
||||
|
||||
const [itemWidth, setItemWidth] = useState<number>(200)
|
||||
|
||||
useEffect(() => {
|
||||
setOpen(false)
|
||||
setCloak(false)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div class="combobox" ref={comboRef} style={{ width: itemWidth + 48 + 'px' }}>
|
||||
<div class="selected" onClick={() => setOpen(!open)}>
|
||||
<div class="content">{children[value]}</div>
|
||||
<span class="material-symbols-outlined">expand_more</span>
|
||||
</div>
|
||||
{open && (
|
||||
<div
|
||||
class={cloak ? 'dropdown invisible' : 'dropdown'}
|
||||
ref={el => el && setItemWidth(el.offsetWidth)}
|
||||
>
|
||||
{Object.keys(children).map(key => (
|
||||
<div
|
||||
class="option"
|
||||
onClick={() => {
|
||||
setValue(key)
|
||||
setOpen(false)
|
||||
}}
|
||||
>
|
||||
{children[key]}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
Loading…
Reference in New Issue