55 lines
1.5 KiB
TypeScript
55 lines
1.5 KiB
TypeScript
import { useRef, useEffect } from "react"
|
|
|
|
interface Props {
|
|
onResize: (clientX: number) => void
|
|
}
|
|
|
|
export function ResizeHandle({ onResize }: Props) {
|
|
const ref = useRef<HTMLDivElement>(null)
|
|
const onResizeRef = useRef(onResize)
|
|
onResizeRef.current = onResize
|
|
|
|
useEffect(() => {
|
|
const el = ref.current
|
|
if (!el) return
|
|
|
|
const dragging = { active: false }
|
|
|
|
const handleMouseMove = (e: MouseEvent) => {
|
|
if (!dragging.active) return
|
|
onResizeRef.current(e.clientX)
|
|
}
|
|
|
|
const handleMouseUp = () => {
|
|
dragging.active = false
|
|
document.removeEventListener("mousemove", handleMouseMove)
|
|
document.removeEventListener("mouseup", handleMouseUp)
|
|
document.body.style.cursor = ""
|
|
document.body.style.userSelect = ""
|
|
}
|
|
|
|
const handleMouseDown = (e: MouseEvent) => {
|
|
e.preventDefault()
|
|
dragging.active = true
|
|
document.addEventListener("mousemove", handleMouseMove)
|
|
document.addEventListener("mouseup", handleMouseUp)
|
|
document.body.style.cursor = "col-resize"
|
|
document.body.style.userSelect = "none"
|
|
}
|
|
|
|
el.addEventListener("mousedown", handleMouseDown)
|
|
return () => {
|
|
el.removeEventListener("mousedown", handleMouseDown)
|
|
document.removeEventListener("mousemove", handleMouseMove)
|
|
document.removeEventListener("mouseup", handleMouseUp)
|
|
}
|
|
}, [])
|
|
|
|
return (
|
|
<div
|
|
ref={ref}
|
|
className="w-[5px] shrink-0 cursor-col-resize hover:bg-primary/40 active:bg-primary/60 transition-colors"
|
|
/>
|
|
)
|
|
}
|