All files / src/components ResizeHandle.tsx

97.61% Statements 41/42
78.57% Branches 11/14
100% Functions 7/7
100% Lines 40/40

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75              107x 107x 107x 107x   107x   4x 4x 4x 4x 4x 4x         107x 39x 5x 4x 4x   4x 3x 2x 2x 2x   2x         39x 2x 2x 2x 2x   2x 1x 1x   2x 1x 1x         39x 39x 39x 39x 39x 39x       107x              
import { useCallback, useEffect, useRef } from 'react'
 
interface ResizeHandleProps {
  onResize: (delta: number) => void
}
 
export function ResizeHandle({ onResize }: ResizeHandleProps) {
  const isDragging = useRef(false)
  const lastX = useRef(0)
  const pendingDelta = useRef(0)
  const rafId = useRef(0)
 
  const handleMouseDown = useCallback(
    (e: React.MouseEvent) => {
      e.preventDefault()
      isDragging.current = true
      lastX.current = e.clientX
      pendingDelta.current = 0
      document.body.style.cursor = 'col-resize'
      document.body.style.userSelect = 'none'
    },
    [],
  )
 
  useEffect(() => {
    const handleMouseMove = (e: MouseEvent) => {
      if (!isDragging.current) return
      pendingDelta.current += e.clientX - lastX.current
      lastX.current = e.clientX
 
      if (!rafId.current) {
        rafId.current = requestAnimationFrame(() => {
          Eif (pendingDelta.current !== 0) {
            onResize(pendingDelta.current)
            pendingDelta.current = 0
          }
          rafId.current = 0
        })
      }
    }
 
    const handleMouseUp = () => {
      Eif (isDragging.current) {
        isDragging.current = false
        document.body.style.cursor = ''
        document.body.style.userSelect = ''
        // Flush any pending delta
        if (rafId.current) {
          cancelAnimationFrame(rafId.current)
          rafId.current = 0
        }
        if (pendingDelta.current !== 0) {
          onResize(pendingDelta.current)
          pendingDelta.current = 0
        }
      }
    }
 
    document.addEventListener('mousemove', handleMouseMove)
    document.addEventListener('mouseup', handleMouseUp)
    return () => {
      document.removeEventListener('mousemove', handleMouseMove)
      document.removeEventListener('mouseup', handleMouseUp)
      Iif (rafId.current) cancelAnimationFrame(rafId.current)
    }
  }, [onResize])
 
  return (
    <div
      className="-ml-1 w-1 shrink-0 cursor-col-resize bg-transparent transition-colors hover:bg-[var(--border)]"
      onMouseDown={handleMouseDown}
    />
  )
}