admin管理员组文章数量:1123793
I'm building a dock like layout for react, similar to dockview. I have a recursive dock structure working, and I'm trying to get the resizing handles to work for different docks. It somewhat works, however when I resize a dock, if it has any children that are also docks then those children's sizes will be reset to their initial value.
To replicate this behavior with the below code, drag the slider between the Left of Top Right
and Right of Top Right
panels, then drag the vertical slider directly to the left of the Left of Top Right
panel. Notice how the slider between Left of Top Right
and Right of Top Right
returned to its original position.
import React, { useState, useEffect, useRef } from 'react';
const locationsCSS = {
full: "",
left: "self-start",
right: "self-end",
top: "self-start",
bottom: "self-end",
}
const directionCSS = {
horizontal: "flex-row",
vertical: "flex-col",
}
const baseCSS = "p-4"
const Dock = ({ location, children, width, height }) => {
const direction = children.length > 0
? ["left", "right"].includes(children[0]?.location) ? "horizontal" : "vertical"
: "";
const [firstDockSize, setFirstDockSize] = useState(() =>
direction === "horizontal" ? width / 2 : height / 2
);
const isResizing = useRef(false);
const startPos = useRef(0);
const initialSize = useRef(0);
const handleMouseDown = (e) => {
isResizing.current = true;
startPos.current = direction === "horizontal" ? e.clientX : e.clientY;
initialSize.current = firstDockSize;
document.addEventListener("mousemove", handleMouseMove);
document.addEventListener("mouseup", handleMouseUp);
};
const handleMouseMove = (e) => {
if (!isResizing.current) return;
const delta = direction === "horizontal"
? e.clientX - startPos.current
: e.clientY - startPos.current;
setFirstDockSize(
Math.max(
50,
Math.min(
initialSize.current + delta,
direction === "horizontal" ? width - 50 : height - 50
)
)
);
};
const handleMouseUp = () => {
isResizing.current = false;
document.removeEventListener("mousemove", handleMouseMove);
document.removeEventListener("mouseup", handleMouseUp);
};
useEffect(() => {
setFirstDockSize(direction === "horizontal" ? width / 2 : height / 2);
}, [width, height, direction]);
return (
<div
className={`flex ${direction === "horizontal" ? "flex-row" : "flex-col"}`}
style={{
width: `${width}px`,
height: `${height}px`,
overflow: "hidden",
}}
>
{Array.isArray(children) ? (
<>
{/* First Dock */}
<div
style={{
flexBasis: `${firstDockSize}px`,
flexGrow: 0,
flexShrink: 0,
overflow: "hidden",
}}
>
<Dock
location={children[0].location}
children={children[0].children}
width={direction === "horizontal" ? firstDockSize : width}
height={direction === "horizontal" ? height : firstDockSize}
/>
</div>
{/* Divider */}
<div
style={{
cursor: direction === "horizontal" ? "col-resize" : "row-resize",
backgroundColor: "#ccc",
width: direction === "horizontal" ? "3px" : "100%",
height: direction === "horizontal" ? "100%" : "3px",
}}
onMouseDown={handleMouseDown}
></div>
{/* Second Dock */}
<div
style={{
flexGrow: 1,
overflow: "hidden",
}}
>
<Dock
location={children[1].location}
children={children[1].children}
width={direction === "horizontal" ? width - firstDockSize : width}
height={direction === "horizontal" ? height : height - firstDockSize}
/>
</div>
</>
) : (
<div
style={{
overflow: "auto",
}}
>
{children}
<p>{width}x{height}</p>
</div>
)}
</div>
);
};
export default function Home() {
const [testState, setTestState] = useState(0);
const [windowWidth, setWindowWidth] = useState(0);
const [windowHeight, setWindowHeight] = useState(0);
useEffect(() => {
setWindowWidth(window.innerWidth);
setWindowHeight(window.innerHeight);
setInterval(() => {
setTestState((prev) => prev + 1);
}, 1000);
}, []);
const data = {
location: "full",
children: [
{
location: "left",
children: [
{
location: "top",
children: (
<p>Top Left {testState}</p>
)
},
{
location: "bottom",
children: [
{
location: "top",
children: (
<p>Top of Bottom Left</p>
)
},
{
location: "bottom",
children: (
<p>Bottom of Bottom Left</p>
)
}
]
}
]
},
{
location: "right",
children: [
{
location: "top",
children: [
{
location: "left",
children: (
<p>Left of Top Right</p>
)
},
{
location: "right",
children: (
<p>Right of Top Right</p>
)
}
]
},
{
location: "bottom",
children: (
<p>Bottom Right</p>
)
}
]
}
]
}
return (
<div className="w-screen h-screen">
<Dock location={data.location} children={data.children} width={windowWidth} height={windowHeight}/>
</div>
)
}
本文标签: reactjsResizing A Recursive Dock Layout Causing IssuesStack Overflow
版权声明:本文标题:reactjs - Resizing A Recursive Dock Layout Causing Issues - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736597199a1945167.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论