@motor-js/cli
Version:
CLI tool for generating Qlik Sense Mashups
114 lines (110 loc) • 3.67 kB
JSX
import React, { useCallback } from "react";
import { getSiblings } from "../../../util";
import { useClickOutside } from "../../../hooks";
import {
StyledNavbar,
StyledNavitem,
StyledNavlink,
StyledSubmenu,
StyledSubNavItem,
StyledSubNavlink,
StyledMegaMenu,
StyledMegaMenuInner,
StyledMegamenuList,
StyledMegamenuLabel,
} from "./style";
export const Navbar = ({ menus }) => {
const clickHandler = (e, hasChildren) => {
if (hasChildren) {
e.preventDefault();
let target = e.currentTarget;
if (target.nodeName === "A") {
target = target.parentElement;
}
const submenu = target.querySelector(".submenu");
const siblings = getSiblings(target);
submenu?.classList.toggle("open");
siblings.forEach((sib) => {
sib.childNodes.forEach((child) => {
const childHT = child;
childHT?.classList?.remove("open");
});
});
}
};
const onClose = useCallback(() => {
const nav = document.querySelector(".navbar");
const submenu = nav?.querySelectorAll(".submenu");
submenu?.forEach((el) => el.classList.remove("open"));
}, []);
const containerRef = useClickOutside(onClose);
return (
<StyledNavbar ref={containerRef} className="navbar">
{menus &&
menus.map((nav) => {
const {
submenu,
megamenu,
id: navId,
Icon: NavIcon,
label: navLabel,
} = nav;
const hasSubmenu = !!submenu?.length;
const hasMegamenu = !!megamenu?.length;
const hasChildren = hasSubmenu || hasMegamenu;
return (
<StyledNavitem
$hasSubmenu={hasChildren}
key={navId}
onClick={(e) => clickHandler(e, hasChildren)}
>
<StyledNavlink path={hasChildren ? "#!" : nav.url}>
{NavIcon && <NavIcon />}
{navLabel}
</StyledNavlink>
{hasSubmenu && (
<StyledSubmenu className="submenu">
{submenu?.map(({ id, label, url, Icon }) => (
<StyledSubNavItem key={id}>
<StyledSubNavlink path={url}>
{Icon && <Icon />}
{label}
</StyledSubNavlink>
</StyledSubNavItem>
))}
</StyledSubmenu>
)}
{hasMegamenu && (
<StyledMegaMenu className="submenu">
<StyledMegaMenuInner>
{megamenu?.map((megaNav) => (
<StyledMegamenuList key={megaNav.id}>
<>
{megaNav?.title && (
<StyledMegamenuLabel>
{megaNav?.title}
</StyledMegamenuLabel>
)}
{megaNav?.submenu?.map(({ id, label, url, Icon }) => (
<StyledSubNavItem key={id}>
<StyledSubNavlink path={url}>
{Icon && <Icon />}
{label}
</StyledSubNavlink>
</StyledSubNavItem>
))}
</>
</StyledMegamenuList>
))}
</StyledMegaMenuInner>
</StyledMegaMenu>
)}
</StyledNavitem>
);
})}
</StyledNavbar>
);
};
Navbar.defaultProps = {
menus: [],
};