This commit is contained in:
seb
2026-09-22 07:59:00 +02:00
parent 5e13b8f9cd
commit 51d01a502b
5 changed files with 220 additions and 80 deletions

View File

@@ -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>
);
}