Files
20260512-skg-tk/web/components/nodes/resize-handle.tsx

56 lines
2.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client"
import { type PointerEvent } from "react"
import { useReactFlow } from "@xyflow/react"
/** 节点右边缘 resize 把手:手写 pointer 事件改 node.width自适应 viewport zoom不走 xyflow NodeResizeControl在 glass-node overflow:hidden 下不工作)。 */
export function ResizeRight({ minWidth = 240, maxWidth = 1200 }: { minWidth?: number; maxWidth?: number }) {
const { setNodes, getZoom } = useReactFlow()
const onPointerDown = (e: PointerEvent<HTMLDivElement>) => {
console.log("[ResizeRight] pointerDown", e.clientX, e.clientY)
e.preventDefault()
e.stopPropagation()
const target = e.currentTarget
const nodeEl = target.closest(".react-flow__node") as HTMLElement | null
const nodeId = nodeEl?.getAttribute("data-id")
console.log("[ResizeRight] nodeId", nodeId)
if (!nodeId || !nodeEl) return
target.setPointerCapture(e.pointerId)
const startX = e.clientX
const zoom = getZoom() || 1
const startWidth = parseFloat(getComputedStyle(nodeEl).width) / zoom
const onMove = (ev: globalThis.PointerEvent) => {
const dx = (ev.clientX - startX) / zoom
const next = Math.max(minWidth, Math.min(maxWidth, startWidth + dx))
console.log("[ResizeRight] move", dx, next)
setNodes((nodes) => nodes.map((n) => (n.id === nodeId ? { ...n, width: next, style: { ...n.style, width: next } } : n)))
}
const onUp = () => {
console.log("[ResizeRight] up")
window.removeEventListener("pointermove", onMove)
window.removeEventListener("pointerup", onUp)
try { target.releasePointerCapture(e.pointerId) } catch {}
}
window.addEventListener("pointermove", onMove)
window.addEventListener("pointerup", onUp)
}
return (
<div
onPointerDown={onPointerDown}
title="拖动调整宽度"
className="nodrag absolute z-20 hover:bg-violet-400/60 active:bg-violet-400/80 transition rounded-r"
style={{
right: 0,
top: 12,
bottom: 12,
width: 6,
cursor: "ew-resize",
touchAction: "none",
}}
/>
)
}