@etsoo/toolpad
Version:
Dashboard framework extention based on Toolpad Core
231 lines (230 loc) • 13.7 kB
JavaScript
"use client";
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.DashboardLayout = DashboardLayout;
const jsx_runtime_1 = require("react/jsx-runtime");
const React = __importStar(require("react"));
const AppBar_1 = __importDefault(require("@mui/material/AppBar"));
const Box_1 = __importDefault(require("@mui/material/Box"));
const Drawer_1 = __importDefault(require("@mui/material/Drawer"));
const IconButton_1 = __importDefault(require("@mui/material/IconButton"));
const Stack_1 = __importDefault(require("@mui/material/Stack"));
const Toolbar_1 = __importDefault(require("@mui/material/Toolbar"));
const Tooltip_1 = __importDefault(require("@mui/material/Tooltip"));
const useMediaQuery_1 = __importDefault(require("@mui/material/useMediaQuery"));
const Menu_1 = __importDefault(require("@mui/icons-material/Menu"));
const MenuOpen_1 = __importDefault(require("@mui/icons-material/MenuOpen"));
const context_1 = require("../shared/context");
const Account_1 = require("../Account");
const DashboardSidebarSubNavigation_1 = require("./DashboardSidebarSubNavigation");
const ToolbarActions_1 = require("./ToolbarActions");
const ThemeSwitcher_1 = require("./ThemeSwitcher");
const utils_1 = require("./utils");
const TitleBar_1 = require("./TitleBar");
const LocaleContext_1 = require("../shared/locales/LocaleContext");
const styles_1 = require("@mui/material/styles");
/**
*
* Demos:
*
* - [Dashboard Layout](https://mui.com/toolpad/core/react-dashboard-layout/)
*
* API:
*
* - [DashboardLayout API](https://mui.com/toolpad/core/api/dashboard-layout)
*/
function DashboardLayout(props) {
const { children, disableCollapsibleSidebar = false, defaultSidebarCollapsed = false, hideNavigation = false, showThemeSwitcher = false, sidebarExpandedWidth = 320, slots, slotProps, sx } = props;
const theme = (0, styles_1.useTheme)();
const navigation = React.useContext(context_1.NavigationContext);
const appWindow = React.useContext(context_1.WindowContext);
const localeText = (0, LocaleContext_1.useLocaleText)();
const [isDesktopNavigationExpanded, setIsDesktopNavigationExpanded] = React.useState(!defaultSidebarCollapsed);
const [isMobileNavigationExpanded, setIsMobileNavigationExpanded] = React.useState(false);
const isUnderMdViewport = (0, useMediaQuery_1.default)(theme.breakpoints.down("md"), appWindow && {
matchMedia: appWindow.matchMedia
});
const isOverSmViewport = (0, useMediaQuery_1.default)(theme.breakpoints.up("sm"), appWindow && {
matchMedia: appWindow.matchMedia
});
const isNavigationExpanded = isUnderMdViewport
? isMobileNavigationExpanded
: isDesktopNavigationExpanded;
const setIsNavigationExpanded = React.useCallback((newExpanded) => {
if (isUnderMdViewport) {
setIsMobileNavigationExpanded(newExpanded);
}
else {
setIsDesktopNavigationExpanded(newExpanded);
}
}, [isUnderMdViewport]);
const [isNavigationFullyExpanded, setIsNavigationFullyExpanded] = React.useState(isNavigationExpanded);
React.useEffect(() => {
if (isNavigationExpanded) {
const drawerWidthTransitionTimeout = setTimeout(() => {
setIsNavigationFullyExpanded(true);
}, theme.transitions.duration.enteringScreen);
return () => clearTimeout(drawerWidthTransitionTimeout);
}
setIsNavigationFullyExpanded(false);
return () => { };
}, [isNavigationExpanded, theme]);
const selectedItemIdRef = React.useRef("");
const handleSetNavigationExpanded = React.useCallback((newExpanded) => () => {
setIsNavigationExpanded(newExpanded);
}, [setIsNavigationExpanded]);
const toggleNavigationExpanded = React.useCallback(() => {
setIsNavigationExpanded(!isNavigationExpanded);
}, [isNavigationExpanded, setIsNavigationExpanded]);
const handleNavigationLinkClick = React.useCallback(() => {
selectedItemIdRef.current = "";
setIsMobileNavigationExpanded(false);
}, [setIsMobileNavigationExpanded]);
// If useEffect was used, the reset would also happen on the client render after SSR which we don't need
React.useMemo(() => {
if (navigation) {
selectedItemIdRef.current = "";
}
}, [navigation]);
const isDesktopMini = !disableCollapsibleSidebar && !isDesktopNavigationExpanded;
const isMobileMini = !disableCollapsibleSidebar && !isMobileNavigationExpanded;
const getMenuIcon = React.useCallback((isExpanded) => {
return ((0, jsx_runtime_1.jsx)(Tooltip_1.default, { title: isExpanded
? localeText.collapseMenuTitle
: localeText.expandMenuTitle, enterDelay: 1000, children: (0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(IconButton_1.default, { "aria-label": isExpanded
? localeText.collapseNavMenuAriaLabel
: localeText.expandNavMenuAriaLabel, onClick: toggleNavigationExpanded, children: isExpanded ? (0, jsx_runtime_1.jsx)(MenuOpen_1.default, {}) : (0, jsx_runtime_1.jsx)(Menu_1.default, {}) }) }) }));
}, [toggleNavigationExpanded]);
const hasDrawerTransitions = isOverSmViewport && (disableCollapsibleSidebar || !isUnderMdViewport);
const TitlebarSlot = slots?.titlebar ?? TitleBar_1.TitleBar;
const ToolbarActionsSlot = slots?.toolbarActions ?? ToolbarActions_1.ToolbarActions;
const ToolbarAccountSlot = slots?.toolbarAccount ?? Account_1.Account;
const SidebarFooterSlot = slots?.sidebarFooter ?? null;
const getDrawerContent = React.useCallback((isMini, viewport) => ((0, jsx_runtime_1.jsxs)(React.Fragment, { children: [(0, jsx_runtime_1.jsx)(Toolbar_1.default, {}), (0, jsx_runtime_1.jsxs)(Box_1.default, { component: "nav", "aria-label": `${viewport.charAt(0).toUpperCase()}${viewport.slice(1)}`, sx: {
height: "100%",
display: "flex",
flexDirection: "column",
justifyContent: "space-between",
overflow: "auto",
pt: navigation[0]?.kind === "header" && !isMini ? 0 : 2,
...(hasDrawerTransitions
? (0, utils_1.getDrawerSxTransitionMixin)(isNavigationFullyExpanded, "padding")
: {})
}, children: [(0, jsx_runtime_1.jsx)(DashboardSidebarSubNavigation_1.DashboardSidebarSubNavigation, { subNavigation: navigation, onLinkClick: handleNavigationLinkClick, isMini: isMini, isFullyExpanded: isNavigationFullyExpanded, hasDrawerTransitions: hasDrawerTransitions, selectedItemId: selectedItemIdRef.current }), SidebarFooterSlot ? ((0, jsx_runtime_1.jsx)(SidebarFooterSlot, { mini: isMini, ...slotProps?.sidebarFooter })) : null] })] })), [
SidebarFooterSlot,
handleNavigationLinkClick,
hasDrawerTransitions,
isNavigationFullyExpanded,
navigation,
slotProps?.sidebarFooter
]);
const getDrawerSharedSx = React.useCallback((isMini, isTemporary) => {
const drawerWidth = isMini ? 64 : sidebarExpandedWidth;
return {
width: drawerWidth,
flexShrink: 0,
...(0, utils_1.getDrawerWidthTransitionMixin)(isNavigationExpanded),
...(isTemporary ? { position: "absolute" } : {}),
[`& .MuiDrawer-paper`]: {
position: "absolute",
width: drawerWidth,
boxSizing: "border-box",
backgroundImage: "none",
...(0, utils_1.getDrawerWidthTransitionMixin)(isNavigationExpanded)
}
};
}, [isNavigationExpanded, sidebarExpandedWidth]);
const layoutRef = React.useRef(null);
return ((0, jsx_runtime_1.jsxs)(Box_1.default, { ref: layoutRef, sx: {
position: "relative",
display: "flex",
overflow: "hidden",
height: "100vh",
width: "100vw",
...sx
}, children: [(0, jsx_runtime_1.jsx)(AppBar_1.default, { color: "inherit", position: "absolute", sx: (theme) => ({
borderWidth: 0,
borderBottomWidth: 1,
borderStyle: "solid",
borderColor: theme.palette.divider,
boxShadow: "none",
zIndex: theme.zIndex.drawer + 1
}), children: (0, jsx_runtime_1.jsxs)(Toolbar_1.default, { sx: { backgroundColor: "inherit", mx: { xs: -0.75, sm: -1.5 } }, children: [!hideNavigation ? ((0, jsx_runtime_1.jsxs)(React.Fragment, { children: [(0, jsx_runtime_1.jsx)(Box_1.default, { sx: {
mr: { sm: disableCollapsibleSidebar ? 0 : 1 },
display: { md: "none" }
}, children: getMenuIcon(isMobileNavigationExpanded) }), (0, jsx_runtime_1.jsx)(Box_1.default, { sx: {
display: {
xs: "none",
md: disableCollapsibleSidebar ? "none" : "block"
},
mr: disableCollapsibleSidebar ? 0 : 1
}, children: getMenuIcon(isDesktopNavigationExpanded) })] })) : null, (0, jsx_runtime_1.jsx)(Box_1.default, { sx: {
position: { xs: "absolute", md: "static" },
left: { xs: "50%", md: "auto" },
transform: { xs: "translateX(-50%)", md: "none" }
}, children: (0, jsx_runtime_1.jsx)(TitlebarSlot, { ...slotProps?.titlebar }) }), (0, jsx_runtime_1.jsx)(Box_1.default, { sx: { flexGrow: 1 } }), (0, jsx_runtime_1.jsxs)(Stack_1.default, { direction: "row", spacing: 1, children: [(0, jsx_runtime_1.jsx)(ToolbarActionsSlot, { ...slotProps?.toolbarActions }), showThemeSwitcher && (0, jsx_runtime_1.jsx)(ThemeSwitcher_1.ThemeSwitcher, {}), (0, jsx_runtime_1.jsx)(ToolbarAccountSlot, { ...slotProps?.toolbarAccount })] })] }) }), !hideNavigation ? ((0, jsx_runtime_1.jsxs)(React.Fragment, { children: [(0, jsx_runtime_1.jsx)(Drawer_1.default, { container: layoutRef.current, variant: "temporary", open: isMobileNavigationExpanded, onClose: handleSetNavigationExpanded(false), ModalProps: {
keepMounted: true // Better open performance on mobile.
}, sx: {
display: {
xs: "block",
sm: disableCollapsibleSidebar ? "block" : "none",
md: "none"
},
...getDrawerSharedSx(false, true)
}, children: getDrawerContent(false, "phone") }), (0, jsx_runtime_1.jsx)(Drawer_1.default, { variant: "permanent", sx: {
display: {
xs: "none",
sm: disableCollapsibleSidebar ? "none" : "block",
md: "none"
},
...getDrawerSharedSx(isMobileMini, false)
}, children: getDrawerContent(isMobileMini, "tablet") }), (0, jsx_runtime_1.jsx)(Drawer_1.default, { variant: "permanent", sx: {
display: { xs: "none", md: "block" },
...getDrawerSharedSx(isDesktopMini, false)
}, children: getDrawerContent(isDesktopMini, "desktop") })] })) : null, (0, jsx_runtime_1.jsxs)(Box_1.default, { sx: {
display: "flex",
flexDirection: "column",
flex: 1
}, children: [(0, jsx_runtime_1.jsx)(Toolbar_1.default, {}), (0, jsx_runtime_1.jsx)(Box_1.default, { component: "main", sx: {
display: "flex",
flexDirection: "column",
flex: 1,
overflow: "auto"
}, children: children })] })] }));
}