49 lines
No EOL
1.7 KiB
TypeScript
49 lines
No EOL
1.7 KiB
TypeScript
import { useLayoutEffect, useState } from "react";
|
|
import { ResizablePanelGroup, ResizablePanel, ResizableHandle } from "../ui/resizable";
|
|
import { NavList } from "./nav";
|
|
|
|
|
|
interface LayoutProps {
|
|
children?: React.ReactNode;
|
|
}
|
|
|
|
export default function Layout({ children }: LayoutProps) {
|
|
const MIN_SIZE_IN_PIXELS = 70;
|
|
const [minSize, setMinSize] = useState(MIN_SIZE_IN_PIXELS);
|
|
|
|
useLayoutEffect(() => {
|
|
const panelGroup = document.querySelector('[data-panel-group-id="main"]');
|
|
const resizeHandles = document.querySelectorAll(
|
|
"[data-panel-resize-handle-id]"
|
|
);
|
|
if (!panelGroup || !resizeHandles) return;
|
|
const observer = new ResizeObserver(() => {
|
|
let width = panelGroup?.clientWidth;
|
|
if (!width) return;
|
|
width -= [...resizeHandles].reduce((acc, resizeHandle) => acc + resizeHandle.clientWidth, 0);
|
|
// Minimum size in pixels is a percentage of the PanelGroup's height,
|
|
// less the (fixed) height of the resize handles.
|
|
setMinSize((MIN_SIZE_IN_PIXELS / width) * 100);
|
|
});
|
|
observer.observe(panelGroup);
|
|
for (const resizeHandle of resizeHandles) {
|
|
observer.observe(resizeHandle);
|
|
}
|
|
|
|
return () => {
|
|
observer.disconnect();
|
|
};
|
|
}, []);
|
|
|
|
return (
|
|
<ResizablePanelGroup direction="horizontal" id="main">
|
|
<ResizablePanel minSize={minSize} collapsible maxSize={minSize}>
|
|
<NavList />
|
|
</ResizablePanel>
|
|
<ResizableHandle withHandle />
|
|
<ResizablePanel >
|
|
{children}
|
|
</ResizablePanel>
|
|
</ResizablePanelGroup>
|
|
);
|
|
} |