'use client';
import * as React from 'react';
import * as Button from '@/components/ui/button';
import * as Checkbox from '@/components/ui/checkbox';
import * as Divider from '@/components/ui/divider';
import * as Dropdown from '@/components/ui/dropdown';
type GroupItem = {
id: string;
label: string;
disabled?: boolean;
};
type Item = {
id: string;
label: string;
items: GroupItem[];
};
type Items = {
[key: string]: Item;
};
const items: Items = {
social: {
id: 'social',
label: 'Social Media',
items: [
{ id: 'google', label: 'Google' },
{ id: 'youtube', label: 'Youtube' },
{ id: 'instagram', label: 'Instagram' },
{
id: 'linkedin',
label: 'Linkedin',
disabled: true,
},
],
},
companies: {
id: 'companies',
label: 'Companies',
items: [
{ id: 'apex', label: 'Apex Tech' },
{ id: 'synergy', label: 'Synergy HR' },
],
},
};
export default function GroupedCheckboxDropdown() {
const [checkedItems, setCheckedItems] = React.useState(new Set(['linkedin']));
const getGroupState = (groupItems: GroupItem[]) => {
const checkedCount = groupItems.filter((item) =>
checkedItems.has(item.id),
).length;
return {
checked: checkedCount === groupItems.length,
indeterminate: checkedCount > 0 && checkedCount < groupItems.length,
};
};
const handleGroupCheck = (
groupItems: GroupItem[],
checked: boolean | string,
) => {
setCheckedItems((prev) => {
const next = new Set(prev);
groupItems.forEach((item) => {
if (!item.disabled) {
checked ? next.add(item.id) : next.delete(item.id);
}
});
return next;
});
};
const handleItemCheck = (id: string, checked: boolean | string) => {
setCheckedItems((prev) => {
const next = new Set(prev);
checked ? next.add(id) : next.delete(id);
return next;
});
};
const renderGroup = (group: Item) => {
const { checked, indeterminate } = getGroupState(group.items);
return (
{
e.preventDefault();
handleGroupCheck(group.items, !checked);
}}
>
handleGroupCheck(group.items, checked)
}
/>
{group.label}
{group.items.map((item) => (
{
e.preventDefault();
if (!item.disabled) {
handleItemCheck(item.id, !checkedItems.has(item.id));
}
}}
>
handleItemCheck(item.id, checked)}
/>
{item.label}
))}
);
};
return (
Open
{renderGroup(items.social!)}
{renderGroup(items.companies!)}
);
}