"use client" import { memo, useState } from "react" import { IconCheck, IconChevronDown } from "@tabler/icons-react" import { cn } from "@/lib/utils" import { Button } from "@kandev/ui/button" import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, } from "@kandev/ui/command" import { Popover, PopoverContent, PopoverTrigger, } from "@kandev/ui/popover" export type ComboboxOption = { value: string label: string description?: string renderLabel?: () => React.ReactNode } interface ComboboxProps { options: ComboboxOption[] value: string onValueChange: (value: string) => void dropdownLabel?: string placeholder?: string searchPlaceholder?: string emptyMessage?: string disabled?: boolean className?: string triggerClassName?: string showSearch?: boolean } export const Combobox = memo(function Combobox({ options, value, onValueChange, dropdownLabel, placeholder = "Select option...", searchPlaceholder = "Search...", emptyMessage = "No option found.", disabled = false, className, triggerClassName, showSearch = true, }: ComboboxProps) { const [open, setOpen] = useState(false) // Track the highlighted item. Defaults to the selected value so the current // selection is highlighted when the popover opens (not the first item). const [highlighted, setHighlighted] = useState("") const selectedOption = options.find((option) => option.value === value) return ( { setOpen(next) if (next) setHighlighted(value) }}> {dropdownLabel ? (
{dropdownLabel}
) : null} {showSearch && } {emptyMessage} {options.map((option) => ( { onValueChange(option.value === value ? "" : option.value) setOpen(false) }} className="relative pr-7" >
{option.renderLabel ? option.renderLabel() : option.label}
))}
) });