88 lines
2.4 KiB
JavaScript
88 lines
2.4 KiB
JavaScript
import { createContext, useContext, useState, useLayoutEffect } from 'react';
|
|
import { createPortal } from 'react-dom';
|
|
import Box from '@mui/material/Box';
|
|
import Typography from '@mui/material/Typography';
|
|
import { GRID_COLUMNS } from 'dashgui/panels';
|
|
|
|
export const PageTitleRightContext = createContext(null);
|
|
|
|
export function PageTitleRight({ children }) {
|
|
const contextNode = useContext(PageTitleRightContext);
|
|
const [domNode, setDomNode] = useState(
|
|
() => (typeof document !== 'undefined' ? document.getElementById('page-title-right') : null)
|
|
);
|
|
|
|
useLayoutEffect(() => {
|
|
if (!contextNode && typeof document !== 'undefined') {
|
|
const el = document.getElementById('page-title-right');
|
|
if (el && el !== domNode) {
|
|
setDomNode(el);
|
|
}
|
|
}
|
|
}, [contextNode, domNode]);
|
|
|
|
const target = contextNode || domNode;
|
|
if (!target) return null;
|
|
return createPortal(children, target);
|
|
}
|
|
|
|
export default function PageLayout({
|
|
title,
|
|
showTitle = true,
|
|
titleAction,
|
|
titleRightAction,
|
|
titleWide = 3,
|
|
children,
|
|
}) {
|
|
const [rightNode, setRightNode] = useState(null);
|
|
|
|
return (
|
|
<PageTitleRightContext.Provider value={rightNode}>
|
|
<Box sx={{ minWidth: 0 }}>
|
|
{showTitle ? (
|
|
<Box
|
|
sx={{
|
|
display: 'grid',
|
|
gridTemplateColumns: {
|
|
xs: '1fr',
|
|
sm: 'repeat(2, 1fr)',
|
|
md: `repeat(${GRID_COLUMNS}, 1fr)`,
|
|
},
|
|
gap: 2,
|
|
mb: 2,
|
|
}}
|
|
>
|
|
<Box
|
|
sx={{
|
|
gridColumn: {
|
|
xs: '1 / -1',
|
|
sm: titleWide >= 2 ? 'span 2' : 'span 1',
|
|
md: `span ${Math.min(Math.max(titleWide, 1), GRID_COLUMNS)}`,
|
|
},
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
gap: 1.5,
|
|
minWidth: 0,
|
|
}}
|
|
>
|
|
<Typography variant="h5" sx={{ fontWeight: 700 }}>
|
|
{title}
|
|
</Typography>
|
|
{titleAction}
|
|
<Box
|
|
id="page-title-right"
|
|
ref={setRightNode}
|
|
sx={{ ml: 'auto', display: 'flex', alignItems: 'center', gap: 1 }}
|
|
>
|
|
{titleRightAction}
|
|
</Box>
|
|
</Box>
|
|
</Box>
|
|
) : null}
|
|
{children}
|
|
</Box>
|
|
</PageTitleRightContext.Provider>
|
|
);
|
|
}
|
|
|