2025-08-17 23:22:06 +02:00

94 lines
3.3 KiB
TypeScript

'use client'
type ComboItem = { id: string; label: string }
type ComboBoxProps = {
value: string // ausgewählte ID
items: ComboItem[] // { id, label }
onSelect: (id: string) => void
}
export default function ComboBox({ value, items, onSelect }: ComboBoxProps) {
const selected = items.find(i => i.id === value)
return (
<div id="hs-combobox-basic-usage" className="relative" data-hs-combo-box="">
<div className="relative">
<input
className="py-2.5 sm:py-3 ps-4 pe-9 block w-full border-gray-200 rounded-lg sm:text-sm focus:border-blue-500 focus:ring-blue-500 dark:bg-neutral-900 dark:border-neutral-700 dark:text-neutral-400 dark:placeholder-neutral-500 dark:focus:ring-neutral-600"
type="text"
role="combobox"
aria-expanded="false"
value={selected?.label ?? ''}
data-hs-combo-box-input=""
readOnly
/>
<div
className="absolute top-1/2 end-3 -translate-y-1/2"
aria-expanded="false"
role="button"
data-hs-combo-box-toggle=""
>
<svg
className="shrink-0 size-3.5 text-gray-500 dark:text-neutral-500"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
strokeWidth="2"
>
<path d="m7 15 5 5 5-5" />
<path d="m7 9 5-5 5 5" />
</svg>
</div>
</div>
<div
className="absolute z-50 w-full max-h-72 p-1 mt-1 bg-white border border-gray-200 rounded-lg overflow-y-auto dark:bg-neutral-900 dark:border-neutral-700"
style={{ display: 'none' }}
role="listbox"
data-hs-combo-box-output=""
>
{items.map((item) => (
<div
key={item.id}
className="cursor-pointer py-2 px-4 w-full text-sm text-gray-800 hover:bg-gray-100 rounded-lg focus:outline-hidden focus:bg-gray-100 dark:bg-neutral-900 dark:hover:bg-neutral-800 dark:text-neutral-200 dark:focus:bg-neutral-800"
role="option"
tabIndex={0}
data-hs-combo-box-output-item=""
data-hs-combo-box-item-stored-data={JSON.stringify({ id: item.id, name: item.label })}
onClick={() => onSelect(item.id)}
>
<div className="flex justify-between items-center w-full">
<span
data-hs-combo-box-search-text={item.label}
data-hs-combo-box-value=""
>
{item.label}
</span>
{item.id === value && (
<span className="hidden hs-combo-box-selected:block">
<svg
className="shrink-0 size-3.5 text-blue-600 dark:text-blue-500"
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<path d="M20 6 9 17l-5-5" />
</svg>
</span>
)}
</div>
</div>
))}
</div>
</div>
)
}