Yvonne Priscilla
update
58a84ad
"use client";
import { Badge } from "@/components/ui/badge";
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
} from "@/components/ui/command";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";
import { cn } from "@/lib/utils";
import { Check, ChevronsUpDown } from "lucide-react";
import * as React from "react";
export function MultiSelect({
options,
value,
onChange,
placeholder = 'Select...',
}: {
options: { label: string; value: string }[];
value: string[];
onChange: (values: string[]) => void;
placeholder?: string;
}) {
const [open, setOpen] = React.useState(false);
const toggleValue = (val: string) => {
if (value.includes(val)) {
onChange(value.filter((v) => v !== val));
} else {
onChange([...value, val]);
}
// Don't close the popover - keep it open for multiple selections
};
return (
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>
<div
className={cn(
"border w-full min-h-[40px] px-3 py-2 rounded-md flex items-center justify-between cursor-pointer gap-2",
value.length === 0 && "text-muted-foreground"
)}
>
<div className="flex flex-wrap gap-1 flex-1">
{value.length === 0 ? (
<span>{placeholder}</span>
) : (
value.map((val) => (
<Badge
key={val}
variant="secondary"
className="text-xs px-2 py-0.5 gap-1"
>
{val}
</Badge>
))
)}
</div>
<ChevronsUpDown className="h-4 w-4 opacity-50 shrink-0" />
</div>
</PopoverTrigger>
<PopoverContent className="p-0 w-[250px]">
<Command>
<CommandInput placeholder="Search..." />
<CommandList>
<CommandEmpty>No results found.</CommandEmpty>
<CommandGroup>
{options.map((option) => {
const selected = value.includes(option.value);
return (
<CommandItem
key={option.value}
onSelect={() => toggleValue(option.value)}
className="flex items-center gap-2 cursor-pointer"
>
<div
className={cn(
"h-4 w-4 border rounded-sm flex items-center justify-center",
selected ? "bg-primary border-primary" : "border-input"
)}
>
{selected && <Check className="h-3 w-3 text-primary-foreground" />}
</div>
{option.label}
</CommandItem>
);
})}
</CommandGroup>
</CommandList>
</Command>
</PopoverContent>
</Popover>
);
}