Skip to content

Instantly share code, notes, and snippets.

@bautistaaa
Last active May 4, 2020 16:15
Show Gist options
  • Save bautistaaa/364d86cfb72a2e3e8727c371962bd188 to your computer and use it in GitHub Desktop.
Save bautistaaa/364d86cfb72a2e3e8727c371962bd188 to your computer and use it in GitHub Desktop.
const Sidebar = (props) => {
const { links } = props;
const [selectedMenus, setSelectedMenus] = useState([]);
const handleMenuSelection = (label, depth) => {
setSelectedMenus((selectedMenus) => {
const newSelectedMenus = [...selectedMenus];
// trim any menus after the depth
newSelectedMenus.length = depth;
if (label !== '') {
newSelectedMenus[depth] = label;
}
return newSelectedMenus;
});
};
return (
<Sidebar.Wrapper>
<Sidebar.List onMouseLeave={() => setSelectedMenus([])}>
{links.map((link) => {
return (
<SidebarItem
link={link}
handleMenuSelection={handleMenuSelection}
key={link.label}
selectedMenus={selectedMenus}
/>
);
})}
</Sidebar.List>
</Sidebar.Wrapper>
);
};
const SidebarItem = ({
link,
handleMenuSelection,
selectedMenus,
depth = 0,
}) => {
const { label, path, children = [] } = link;
return (
<>
{children.length > 0 ? (
<SidebarItem.Item>
<SidebarItem.Label
onMouseEnter={() => handleMenuSelection(label, depth)}
>
{label}
</SidebarItem.Label>
{selectedMenus[depth] === label && (
<SidebarItem.List depth={depth}>
{children.map((child, i) => {
const { label } = child;
const childDepth = depth + 1;
return (
<SidebarItem
link={child}
handleMenuSelection={handleMenuSelection}
key={`child-${label}-${i}`}
depth={childDepth}
selectedMenus={selectedMenus}
/>
);
})}
</SidebarItem.List>
)}
</SidebarItem.Item>
) : (
<SidebarItem.Item onMouseEnter={() => handleMenuSelection('', depth)}>
<SidebarItem.Anchor href={path}>{label}</SidebarItem.Anchor>
</SidebarItem.Item>
)}
</>
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment