'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!)} ); }