import { useState } from 'react';
import { Badge } from '@/shadcn-ui/components/ui/badge';
import { ShadCnButton } from '@/shadcn-ui/components/ui/button';
import {
DropdownMenu,
DropdownMenuCheckboxItem,
DropdownMenuContent,
DropdownMenuTrigger,
} from '@/shadcn-ui/components/ui/dropdown-menu';
import { Separator } from '@/shadcn-ui/components/ui/separator';
import { X } from 'lucide-react';
interface BusinessesFilterProps {
title?: string;
icon: JSX.Element;
options: {
label: string | null;
value: string;
}[];
onSelectedValues: (
value: {
label: string | null;
value: string;
}[],
) => void;
}
export function BusinessesFilter({
icon,
options,
title,
}: BusinessesFilterProps) {
const [isOpen, setIsOpen] = useState(false);
const [selectedItems, setSelectedItems] = useState<
{
label: string | null;
value: string;
}[]
>([]);
function handleItemsSelected(clickedItem: {
label: string | null;
value: string;
}) {
const itemAlreadyExist = selectedItems.find(
(item) => item.value === clickedItem.value,
);
if (itemAlreadyExist) {
setSelectedItems((prevItems) => {
const filteredItem = prevItems.filter(
(prevItem) => prevItem !== itemAlreadyExist,
);
return filteredItem;
});
} else {
setSelectedItems((prevItems) => {
const filteredItem = [...prevItems, clickedItem];
return filteredItem;
});
}
}
return (
<DropdownMenu open={isOpen}>
<DropdownMenuTrigger asChild onClick={() => setIsOpen(true)}>
<ShadCnButton
variant="outline"
size="default"
className="h-12 border-dashed flex gap-2"
>
{icon}
{title}
<Separator orientation="vertical" className="mx-2 h-4" />
<div>
{selectedItems && (
<Badge
variant="secondary"
className="rounded-sm px-1 font-normal"
>
{selectedItems.length}
</Badge>
)}
</div>
</ShadCnButton>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-[200px] p-0" align="start">
<div className="flex justify-between items-center p-2 border-b">
<span className="font-medium">{title}</span>
<ShadCnButton
variant="ghost"
size="sm"
className="h-8 w-8 p-0"
onClick={() => setIsOpen(false)}
>
<X className="h-4 w-4" />
</ShadCnButton>
</div>
<div className="flex flex-col gap-2 p-2">
{options.map(({ label, value }) => {
const isChecked = selectedItems.find(
(item) => item.value === value,
);
return (
<DropdownMenuCheckboxItem
checked={!!isChecked}
onCheckedChange={() => {
handleItemsSelected({ label, value });
}}
key={value}
>
{label}
</DropdownMenuCheckboxItem>
);
})}
</div>
</DropdownMenuContent>
</DropdownMenu>
);
}
Preview:
downloadDownload PNG
downloadDownload JPEG
downloadDownload SVG
Tip: You can change the style, width & colours of the snippet with the inspect tool before clicking Download!
Click to optimize width for Twitter