import { splitProps, type JSX } from "solid-js" export interface ResizeHandleProps extends Omit, "onResize"> { direction: "horizontal" | "vertical" edge?: "start" | "end" size: number min: number max: number onResize: (size: number) => void onCollapse?: () => void /** Called while dragging when size crosses `collapseThreshold`. */ onCollapseChange?: (collapsed: boolean) => void collapseThreshold?: number } export function ResizeHandle(props: ResizeHandleProps) { const [local, rest] = splitProps(props, [ "direction", "edge", "size", "min", "max", "onResize", "onCollapse", "onCollapseChange", "collapseThreshold", "class", "classList", ]) const handleMouseDown = (e: MouseEvent) => { if (e.detail > 1) return e.preventDefault() const edge = local.edge ?? (local.direction === "vertical" ? "start" : "end") const start = local.direction === "horizontal" ? e.clientX : e.clientY const startSize = local.size const min = local.min const max = local.max const threshold = local.collapseThreshold ?? 0 const onResize = local.onResize const onCollapse = local.onCollapse const onCollapseChange = local.onCollapseChange let current = startSize let collapsed = false document.body.style.userSelect = "none" document.body.style.overflow = "hidden" const onMouseMove = (moveEvent: MouseEvent) => { const pos = local.direction === "horizontal" ? moveEvent.clientX : moveEvent.clientY const delta = local.direction === "vertical" ? edge === "end" ? pos - start : start - pos : edge === "start" ? start - pos : pos - start current = startSize + delta const nextCollapsed = threshold > 0 && current < threshold if (nextCollapsed !== collapsed) { collapsed = nextCollapsed onCollapseChange?.(collapsed) } onResize(Math.min(max, Math.max(min, current))) } const onMouseUp = () => { document.body.style.userSelect = "" document.body.style.overflow = "" document.removeEventListener("mousemove", onMouseMove) document.removeEventListener("mouseup", onMouseUp) if (collapsed) { onCollapse?.() return } onCollapseChange?.(false) } document.addEventListener("mousemove", onMouseMove) document.addEventListener("mouseup", onMouseUp) } return (
) }