frontend/app/components/combobox.tsx
Nathan Lamy 938ed8a4df
Some checks failed
Deploy to Netlify / Deploy to Netlify (push) Failing after 1m10s
ui: add register page
2025-07-28 23:29:27 +02:00

81 lines
2.2 KiB
TypeScript

import * as React from "react"
import { CheckIcon, ChevronsUpDownIcon } from "lucide-react"
import { cn } from "~/lib/utils"
import { Button } from "~/components/ui/button"
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
} from "~/components/ui/command"
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "~/components/ui/popover"
export function Combobox({
values = [],
defaultText = "Select value...",
placeholderText = "Search...",
emptyText = "No value found.",
renderValue = (value) => value
? values.find((current) => current.value === value)?.label!
: defaultText,
}: {
values?: { value: string; label: string }[]
emptyText?: string
placeholderText?: string
defaultText?: string
renderValue?: (value: string) => string
}) {
const [open, setOpen] = React.useState(false)
const [current, setValue] = React.useState("")
return (
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>
<Button
variant="outline"
role="combobox"
aria-expanded={open}
className="w-full justify-between"
>
{renderValue(current)}
<ChevronsUpDownIcon className="ml-2 h-4 w-4 shrink-0 opacity-50" />
</Button>
</PopoverTrigger>
<PopoverContent className="w-[200px] p-0">
<Command>
<CommandInput placeholder={placeholderText} />
<CommandList>
<CommandEmpty>{emptyText}</CommandEmpty>
<CommandGroup>
{values.map(({ value, label }) => (
<CommandItem
key={value}
value={value}
onSelect={(currentValue) => {
setValue(currentValue === value ? "" : currentValue)
setOpen(false)
}}
>
<CheckIcon
className={cn(
"mr-2 h-4 w-4",
current === value ? "opacity-100" : "opacity-0"
)}
/>
{label}
</CommandItem>
))}
</CommandGroup>
</CommandList>
</Command>
</PopoverContent>
</Popover>
)
}