but
This commit is contained in:
@@ -1,23 +1,87 @@
|
||||
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 (
|
||||
<Box sx={{ minWidth: 0 }}>
|
||||
{showTitle ? (
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1.5, mb: 2 }}>
|
||||
<Typography variant="h5" sx={{ fontWeight: 700 }}>
|
||||
{title}
|
||||
</Typography>
|
||||
{titleAction}
|
||||
</Box>
|
||||
) : null}
|
||||
{children}
|
||||
</Box>
|
||||
<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>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user