Spaces:
Runtime error
Runtime error
import { Combobox } from "@headlessui/react"; | |
import clsx from "clsx"; | |
import type { ReactNode } from "react"; | |
import { useState } from "react"; | |
import { HiCheck, HiChevronDown } from "react-icons/hi2"; | |
interface Props<T> { | |
label: string; | |
items: T[]; | |
value: T | undefined; | |
valueMapper: (e: T) => string; | |
onChange: (value: T) => void; | |
icon?: ReactNode; | |
} | |
const Combo = <T,>({ items, ...props }: Props<T>) => { | |
const [query, setQuery] = useState(""); | |
const filtered = | |
query === "" | |
? items | |
: items.filter((e) => props.valueMapper(e).toLowerCase().includes(query.toLowerCase())); | |
return ( | |
<Combobox as="div" value={props.value} onChange={props.onChange}> | |
<Combobox.Label className="flex items-center gap-2 text-sm font-bold leading-6 text-slate-12"> | |
{props.icon} | |
{props.label} | |
</Combobox.Label> | |
<div className="relative mt-1"> | |
<Combobox.Input | |
className="w-full rounded-md border-0 bg-slate-1 py-1.5 pl-3 pr-10 text-slate-12 shadow-depth-1 transition-colors sm:text-sm sm:leading-6" | |
onChange={(event) => setQuery(event.target.value)} | |
displayValue={(e) => props.valueMapper(e as T)} | |
/> | |
<Combobox.Button className="absolute inset-y-0 right-0 flex items-center rounded-r-md px-2 focus:outline-none"> | |
<HiChevronDown className="h-5 w-5 text-gray-400" aria-hidden="true" /> | |
</Combobox.Button> | |
{filtered.length > 0 && ( | |
<Combobox.Options className="absolute z-10 mt-1 max-h-60 w-full overflow-auto rounded-md bg-slate-1 py-1 text-slate-12 shadow-lg ring-opacity-5 focus:outline-none sm:text-sm"> | |
{filtered.map((e, i) => ( | |
<Combobox.Option | |
key={i} | |
value={e} | |
className={({ active }) => | |
clsx( | |
"relative cursor-default select-none py-2 pl-3 pr-9 ", | |
active ? "hover:bg-slate-3" : "text-slate-12" | |
) | |
} | |
> | |
{({ selected }) => ( | |
<> | |
<span className={clsx("block truncate", selected && "font-semibold")}> | |
{props.valueMapper(e)} | |
</span> | |
{selected && ( | |
<span | |
className={clsx( | |
"absolute inset-y-0 right-0 flex items-center pr-4 text-slate-12" | |
)} | |
> | |
<HiCheck className="h-5 w-5" aria-hidden="true" /> | |
</span> | |
)} | |
</> | |
)} | |
</Combobox.Option> | |
))} | |
</Combobox.Options> | |
)} | |
</div> | |
</Combobox> | |
); | |
}; | |
export default Combo; | |