@etsoo/toolpad
Version:
Dashboard framework extention based on Toolpad Core
158 lines (157 loc) • 8.75 kB
JavaScript
"use client";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import * as React from "react";
import Avatar from "@mui/material/Avatar";
import Collapse from "@mui/material/Collapse";
import Divider from "@mui/material/Divider";
import List from "@mui/material/List";
import ListItem from "@mui/material/ListItem";
import ListItemButton from "@mui/material/ListItemButton";
import ListItemIcon from "@mui/material/ListItemIcon";
import ListItemText from "@mui/material/ListItemText";
import ListSubheader from "@mui/material/ListSubheader";
import Tooltip from "@mui/material/Tooltip";
import ExpandLessIcon from "@mui/icons-material/ExpandLess";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import { Link } from "../shared/Link";
import { getItemTitle, getPageItemFullPath, hasSelectedNavigationChildren, isPageItemSelected } from "../shared/navigation";
import { getDrawerSxTransitionMixin } from "./utils";
import { styled } from "@mui/material/styles";
import { useActivePage } from "../useActivePage/useActivePage";
const NavigationListItemButton = styled(ListItemButton)(({ theme }) => ({
borderRadius: 8,
"&.Mui-selected": {
"& .MuiListItemIcon-root": {
color: (theme.vars ?? theme).palette.primary.dark
},
"& .MuiTypography-root": {
color: (theme.vars ?? theme).palette.primary.dark
},
"& .MuiSvgIcon-root": {
color: (theme.vars ?? theme).palette.primary.dark
},
"& .MuiAvatar-root": {
backgroundColor: (theme.vars ?? theme).palette.primary.dark
},
"& .MuiTouchRipple-child": {
backgroundColor: (theme.vars ?? theme).palette.primary.dark
}
},
"& .MuiSvgIcon-root": {
color: (theme.vars ?? theme).palette.action.active
},
"& .MuiAvatar-root": {
backgroundColor: (theme.vars ?? theme).palette.action.active
}
}));
/**
* @ignore - internal component.
*/
function DashboardSidebarSubNavigation({ subNavigation, basePath = "", depth = 0, onLinkClick, isMini = false, isFullyExpanded = true, hasDrawerTransitions = false, selectedItemId }) {
const activePage = useActivePage();
const pathname = activePage?.sourcePath ?? "/";
const initialExpandedSidebarItemIds = React.useMemo(() => subNavigation
.map((navigationItem, navigationItemIndex) => ({
navigationItem,
originalIndex: navigationItemIndex
}))
.filter(({ navigationItem }) => hasSelectedNavigationChildren(navigationItem, basePath, pathname))
.map(({ originalIndex }) => `${depth}-${originalIndex}`), [basePath, depth, pathname, subNavigation]);
const [expandedSidebarItemIds, setExpandedSidebarItemIds] = React.useState(initialExpandedSidebarItemIds);
const handleOpenFolderClick = React.useCallback((itemId) => () => {
setExpandedSidebarItemIds((previousValue) => previousValue.includes(itemId)
? previousValue.filter((previousValueItemId) => previousValueItemId !== itemId)
: [...previousValue, itemId]);
}, []);
return (_jsx(List, { sx: { padding: 0, mb: depth === 0 ? 4 : 1, pl: 2 * depth }, children: subNavigation.map((navigationItem, navigationItemIndex) => {
if (navigationItem.kind === "header") {
return (_jsx(ListSubheader, { component: "div", sx: {
fontSize: 12,
fontWeight: "700",
height: isMini ? 0 : 40,
...(hasDrawerTransitions
? getDrawerSxTransitionMixin(isFullyExpanded, "height")
: {}),
px: 2,
overflow: "hidden",
textOverflow: "ellipsis",
whiteSpace: "nowrap",
zIndex: 2
}, children: getItemTitle(navigationItem) }, `subheader-${depth}-${navigationItemIndex}`));
}
if (navigationItem.kind === "divider") {
const nextItem = subNavigation[navigationItemIndex + 1];
return (_jsx(Divider, { sx: {
borderBottomWidth: 2,
mx: 1,
mt: 1,
mb: nextItem?.kind === "header" && !isMini ? 0 : 1,
...(hasDrawerTransitions
? getDrawerSxTransitionMixin(isFullyExpanded, "margin")
: {})
} }, `divider-${depth}-${navigationItemIndex}`));
}
if (navigationItem.hidden) {
return null;
}
let children = navigationItem.children?.filter((child) => child.kind === "divider" || child.kind === "header" || !child.hidden);
if (children && children.length === 0) {
children = undefined;
}
const navigationItemFullPath = getPageItemFullPath(basePath, navigationItem);
const navigationItemId = `${depth}-${navigationItemIndex}`;
const navigationItemTitle = getItemTitle(navigationItem);
const isNestedNavigationExpanded = expandedSidebarItemIds.includes(navigationItemId);
const nestedNavigationCollapseIcon = isNestedNavigationExpanded ? (_jsx(ExpandLessIcon, {})) : (_jsx(ExpandMoreIcon, {}));
const listItemIconSize = 34;
// If the item is selected, we don't want to select more
const isSelected = selectedItemId
? false
: isPageItemSelected(navigationItem, basePath, pathname) ||
navigationItem.children?.some((child) => (child.kind === "page" || child.kind == null) &&
child.hidden &&
isPageItemSelected(child, navigationItemFullPath, pathname));
if (isSelected && !selectedItemId) {
selectedItemId = navigationItemId;
}
const listItem = (_jsx(ListItem, { sx: {
py: 0,
px: 1,
overflowX: "hidden"
}, children: _jsxs(NavigationListItemButton, { selected: isSelected && (!children || isMini), sx: {
px: 1.4,
height: 48
}, ...(children && !isMini
? {
onClick: handleOpenFolderClick(navigationItemId)
}
: {
LinkComponent: Link,
href: navigationItemFullPath,
onClick: onLinkClick
}), children: [navigationItem.icon || isMini ? (_jsxs(ListItemIcon, { sx: {
minWidth: listItemIconSize,
mr: 1.2
}, children: [navigationItem.icon ?? null, !navigationItem.icon && isMini ? (_jsx(Avatar, { sx: {
width: listItemIconSize - 7,
height: listItemIconSize - 7,
fontSize: 12,
ml: "-2px"
}, children: navigationItemTitle
.split(" ")
.slice(0, 2)
.map((itemTitleWord) => itemTitleWord.charAt(0).toUpperCase()) })) : null] })) : null, _jsx(ListItemText, { primary: navigationItemTitle, sx: {
whiteSpace: "nowrap",
zIndex: 1,
"& .MuiTypography-root": {
fontWeight: "500"
}
} }), navigationItem.action && !isMini && isFullyExpanded
? navigationItem.action
: null, children && !isMini && isFullyExpanded
? nestedNavigationCollapseIcon
: null] }) }));
return (_jsxs(React.Fragment, { children: [isMini ? (_jsx(Tooltip, { title: navigationItemTitle, placement: "right", children: listItem })) : (listItem), children && !isMini ? (_jsx(Collapse, { in: isNestedNavigationExpanded, timeout: "auto", unmountOnExit: true, children: _jsx(DashboardSidebarSubNavigation, { subNavigation: children, basePath: navigationItemFullPath, depth: depth + 1, onLinkClick: onLinkClick, selectedItemId: selectedItemId }) })) : null] }, navigationItemId));
}) }));
}
export { DashboardSidebarSubNavigation };