UNPKG

mui-nav-menu

Version:

Navigation menu component based on material ui

150 lines (149 loc) 5.69 kB
import { createElement as _createElement } from "react"; import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime"; import { ChevronRight, ExpandLess, ExpandMore } from "@mui/icons-material"; import { ListItemButton, ListItemIcon, ListItemText, Tooltip, } from "@mui/material"; import classNames from "classnames"; import { forwardRef, memo, useMemo } from "react"; import { makeStyles } from "tss-react/mui"; import { useMenuContext } from "./contexts/MenuContext"; const useStyle = makeStyles()((theme) => ({ root: { whiteSpace: "normal", wordBreak: "break-all", "&.Mui-selected": { "&.isNested:not(.isMini)": { color: theme.palette.primary.main, fontWeight: "bold", "&:not(:hover)": { background: "none", }, }, }, "&.isMini": { "& .MuiListItemIcon-root": { marginRight: 0, }, }, }, noWrap: { whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", }, label: { transition: "transform 300ms ease 0s, opacity 300ms ease 0s", opacity: 1, transform: "translate3d(0rem, 0, 0)", }, icon: { transition: "transform 300ms ease 0s, opacity 300ms ease 0s", opacity: 1, }, labelMini: { opacity: 0, overflow: "hidden", transform: "translate3d(-1.5625rem, 0, 0)", }, iconMini: { opacity: 0, }, tooltip: { "& .MuiTooltip-tooltip": { fontSize: 14, "&.MuiTooltip-tooltipPlacementRight": { margin: "0px 25px !important", }, }, }, headerMini: { textAlign: "center", padding: 0, }, focused: { outline: "3px solid " + theme.palette.primary.main, borderRadius: 4, }, })); const ListMenuItem = forwardRef((props, ref) => { const { classes } = useStyle(); const { id, label, subIsOpen, onClick, inlineIndent, isSelected, collapsed, connectedIdPath, mode, disabled, hasChildren, link, Content, icon, linkComponent: linkComponentProp, className, isFocused, onMouseEnter, onMouseLeave, renderContent: renderContentProp, collapseIcon = _jsx(ExpandLess, {}), expandIcon = _jsx(ExpandMore, {}), popupRootIcon = (_jsx(ChevronRight, { style: { transform: "rotate(90deg)" } })), popupSubIcon = _jsx(ChevronRight, {}), } = props; const { linkComponent } = useMenuContext(); const nestedLevel = useMemo(() => { return connectedIdPath.length; }, [connectedIdPath]); const hasLink = link && !hasChildren; const showLabel = !collapsed || nestedLevel > 1; const linkProps = useMemo(() => { if (typeof link == "object") { return { component: linkComponentProp ?? linkComponent, href: link.url, target: link.target ?? "_parent", }; } return { component: linkComponentProp ?? linkComponent, to: link, }; }, [link]); const inlineIndentPadding = useMemo(() => { if (mode !== "inline") { return undefined; } return nestedLevel > 1 ? inlineIndent.step * (nestedLevel - 2) + inlineIndent.base : undefined; }, [nestedLevel, mode, inlineIndent]); const renderArrow = () => { if (!hasChildren) { return null; } if (collapsed && nestedLevel == 1) { return null; } if (mode == "inline") { return subIsOpen ? collapseIcon : expandIcon; } if (nestedLevel == 1 && mode == "horizontal") { return popupRootIcon; } return popupSubIcon; }; const shouldUseTooltip = useMemo(() => { return collapsed && nestedLevel == 1 && !hasChildren; }, [collapsed, nestedLevel, hasChildren]); const textClasses = classNames(classes.label, { "Label-mini": !showLabel, [classes.labelMini]: !showLabel, }); const renderContent = () => { if (Content) { return (_jsx(Content, { ...{ nodeId: id, isSelected, itemProps: { textClasses, label }, } })); } if (renderContentProp) { return renderContentProp({ nodeId: id, isSelected, itemProps: { textClasses, label }, }); } return (_jsxs(_Fragment, { children: [icon && _jsx(ListItemIcon, { children: icon }), _jsx(ListItemText, { className: textClasses, primary: label })] })); }; const listItemNode = (_createElement(ListItemButton, { disableRipple: true, ...(hasLink && linkProps), ref: ref, key: id, disableTouchRipple: true, tabIndex: -1, disabled: disabled, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, className: classNames(className, classes.root, classes.noWrap, { isRoot: nestedLevel == 1, isNested: hasChildren, [classes.focused]: isFocused, isFocused: isFocused, isMini: collapsed && nestedLevel == 1, }), selected: isSelected, style: { paddingLeft: inlineIndentPadding, }, onClick: onClick }, renderContent(), hasChildren ? renderArrow() : null)); return (_jsx(Tooltip, { disableHoverListener: !shouldUseTooltip, classes: { popper: classes.tooltip }, title: label, arrow: true, placement: "right", children: listItemNode })); }); export default memo(ListMenuItem);