# 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}
        />
      )
    }