Untitled
unknown
plain_text
a month ago
3.7 kB
6
Indexable
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"; import { cn } from "@/utilities/cn"; import { useState } from "react"; import { Check, ChevronsUpDown, X } from "lucide-react"; import { UseFieldArrayAppend, UseFieldArrayRemove } from "react-hook-form"; type Props = { data: { value: string; label: string; id: string }[]; name: string; notFoundMessage?: string; inDialog?: boolean; onAppend: UseFieldArrayAppend<any>; onRemove: UseFieldArrayRemove; }; export function MultiSelectCombobox({ data, name, notFoundMessage, inDialog, onAppend, onRemove, }: Props) { const [open, setOpen] = useState(false); const [selectedItemsIds, setSelectedItemsIds] = useState<string[]>([]); const handleSetValue = (id: string) => { const existingIndex = selectedItemsIds.findIndex((item) => item === id); if (existingIndex > -1) { onRemove(existingIndex); setSelectedItemsIds((prev) => prev.filter((item) => item !== id)); } else { const item = data.find((item) => item.id === id)!; onAppend({ title: item.value, id: item.id, }); setSelectedItemsIds((prev) => [...prev, id]); } }; return ( <Popover modal={true} open={open} onOpenChange={setOpen}> <PopoverTrigger asChild> <Button variant="outline" role="combobox" aria-expanded={open} className="h-fit w-full justify-between" > <div className="flex flex-wrap justify-start gap-2"> {selectedItemsIds?.length ? selectedItemsIds.map((id, i) => ( <div key={i} className=" flex h-auto items-center gap-x-2 rounded-md bg-foreground px-2 py-1 text-xs font-medium text-background" > {data.find((item) => item.id === id)?.label} <X size={13} className="hover:text-destructive" onClick={() => handleSetValue(id)} /> </div> )) : `Select one or more ${name}...`} </div> <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" /> </Button> </PopoverTrigger> <PopoverContent className={`combobox-width p-0 ${inDialog && "z-[200]"}`}> <Command> <CommandInput placeholder={`Search ${name}...`} className="h-9" /> <CommandEmpty> {notFoundMessage ? notFoundMessage : `No ${name} found.`} </CommandEmpty> <CommandGroup> <CommandList> {data.map((item) => ( <CommandItem isMultiSelect={true} key={item.id} value={item.id} onSelect={() => { handleSetValue(item.id); }} > <Check className={cn( "mr-2 h-4 w-4", selectedItemsIds.includes(item.id) ? "opacity-100" : "opacity-0", )} /> {item.label} </CommandItem> ))} </CommandList> </CommandGroup> </Command> </PopoverContent> </Popover> ); }
Editor is loading...
Leave a Comment