@etsoo/toolpad
Version:
Dashboard framework extention based on Toolpad Core
87 lines (86 loc) • 3.83 kB
JavaScript
"use client";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import * as React from "react";
import Breadcrumbs from "@mui/material/Breadcrumbs";
import Link from "@mui/material/Link";
import Stack from "@mui/material/Stack";
import Typography from "@mui/material/Typography";
import useSlotProps from "@mui/utils/useSlotProps";
import { Link as ToolpadLink } from "../shared/Link";
import { PageContainerToolbar } from "./PageContainerToolbar";
import { getItemTitle } from "../shared/navigation";
import { useActivePage } from "../useActivePage";
import { styled } from "@mui/material/styles";
const PageContentHeader = styled("div")(({ theme }) => ({
display: "flex",
flexDirection: "row",
justifyContent: "space-between",
gap: theme.spacing(2)
}));
export const PageDataContext = React.createContext({ state: {}, dispatch: (value) => value });
function reducer(state, action) {
// Check if the action is 'reset'
if (action === true) {
return {};
}
return { ...state, ...action };
}
export function PageDataContextProvider(props) {
// Destruct
const { title, page, breadcrumbs, pageHeader, ...rest } = props;
// useReducer hook to manage state with our reducer function and initial state
const [state, dispatch] = React.useReducer(reducer, {
title,
page,
breadcrumbs,
pageHeader
});
// Provide the state and dispatch function to the context value
return _jsx(PageDataContext.Provider, { value: { state, dispatch }, ...rest });
}
function PageContainerBar(props) {
const { slots, slotProps, titleBar } = props;
const { state } = React.useContext(PageDataContext);
const activePage = useActivePage();
const ToolbarComponent = slots?.toolbar ?? PageContainerToolbar;
const toolbarSlotProps = useSlotProps({
elementType: ToolbarComponent,
ownerState: props,
externalSlotProps: slotProps?.toolbar,
additionalProps: {}
});
const breadcrumbs = [...(activePage?.breadcrumbs ?? [])];
const title = state.title ?? activePage?.title ?? "";
const pageHeader = state.pageHeader ?? activePage?.pageHeader ?? null;
// No page header
if (pageHeader === false)
return undefined;
// Custom page header
if (pageHeader != null)
return pageHeader;
if (state.page) {
breadcrumbs.push({ title: state.page, path: "#" });
}
const bc = typeof state.breadcrumbs === "function"
? state.breadcrumbs(breadcrumbs)
: state.breadcrumbs ?? breadcrumbs;
return (_jsxs(Stack, { children: [bc.length > 0 && (_jsx(Breadcrumbs, { "aria-label": "breadcrumb", children: bc.map((item, index) => {
return index < bc.length - 1 ? (_jsx(Link, { component: ToolpadLink, underline: "hover", color: "inherit", href: item.path, children: getItemTitle(item) }, item.path)) : (_jsx(Typography, { color: "text.primary", children: getItemTitle(item) }, item.path));
}) })), _jsxs(PageContentHeader, { children: [typeof titleBar === "function" ? (titleBar(title)) : titleBar === false ? undefined : (_jsx(Typography, { variant: "h4", children: title })), _jsx(ToolbarComponent, { ...toolbarSlotProps })] })] }));
}
/**
* A container component to provide a title and breadcrumbs for your pages.
*
* Demos:
*
* - [Page Container](https://mui.com/toolpad/core/react-page-container/)
*
* API:
*
* - [PageContainer API](https://mui.com/toolpad/core/api/page-container)
*/
function PageContainer(props) {
const { children, slots, slotProps, titleBar, ...rest } = props;
return (_jsxs(Stack, { sx: { mx: 3, my: 2 }, spacing: 2, ...rest, children: [_jsx(PageContainerBar, { slots: slots, slotProps: slotProps, titleBar: titleBar }), children] }));
}
export { PageContainer };