You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
77 lines
2.3 KiB
77 lines
2.3 KiB
import { ReactNode, useCallback, useEffect, useRef, useState } from "react"
|
|
|
|
export interface SlideLayoutProps {
|
|
children: [ReactNode, ReactNode]
|
|
rightWidth: number
|
|
onRightWidthChange: (w: number) => void
|
|
}
|
|
|
|
export default function CurtainLayout({
|
|
children,
|
|
rightWidth,
|
|
onRightWidthChange,
|
|
}: SlideLayoutProps) {
|
|
const curtainRef = useRef<HTMLDivElement>(null)
|
|
const sliderRef = useRef<HTMLDivElement>(null)
|
|
|
|
const resize = useCallback(
|
|
(e: MouseEvent) => {
|
|
const sliderPosX = e.clientX
|
|
const curtainWidth =
|
|
curtainRef.current!.getBoundingClientRect().width
|
|
|
|
onRightWidthChange((sliderPosX / curtainWidth) * 100)
|
|
},
|
|
[curtainRef, onRightWidthChange],
|
|
)
|
|
|
|
const [resizing, setResizing] = useState(false)
|
|
|
|
useEffect(() => {
|
|
const curtain = curtainRef.current!
|
|
const slider = sliderRef.current!
|
|
|
|
if (resizing) {
|
|
const handleMouseUp = () => setResizing(false)
|
|
|
|
curtain.addEventListener("mousemove", resize)
|
|
curtain.addEventListener("mouseup", handleMouseUp)
|
|
return () => {
|
|
curtain.removeEventListener("mousemove", resize)
|
|
curtain.removeEventListener("mouseup", handleMouseUp)
|
|
}
|
|
}
|
|
|
|
const handleMouseDown = () => setResizing(true)
|
|
|
|
slider.addEventListener("mousedown", handleMouseDown)
|
|
|
|
return () => {
|
|
slider.removeEventListener("mousedown", handleMouseDown)
|
|
}
|
|
}, [sliderRef, curtainRef, resizing, setResizing, resize])
|
|
|
|
return (
|
|
<div className={"curtain"} ref={curtainRef} style={{ display: "flex" }}>
|
|
<div className={"curtain-left"} style={{ width: `${rightWidth}%` }}>
|
|
{children[0]}
|
|
</div>
|
|
<div
|
|
ref={sliderRef}
|
|
style={{
|
|
width: 4,
|
|
height: "100%",
|
|
backgroundColor: "grey",
|
|
cursor: "col-resize",
|
|
userSelect: "none",
|
|
}}></div>
|
|
|
|
<div
|
|
className={"curtain-right"}
|
|
style={{ width: `${100 - rightWidth}%` }}>
|
|
{children[1]}
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|