{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "use-pointer-drag",
  "title": "usePointerDrag",
  "author": "Stickies <https://stickies.live>",
  "description": "Dragging with the pointer, for moving or resizing anything, with pointer capture and zoom.",
  "files": [
    {
      "path": "registry/stickies/hooks/use-pointer-drag.ts",
      "content": "\"use client\"\n\nimport { useRef, useState } from \"react\"\n\nexport interface PointerDragDelta {\n  /** How far the pointer has moved since the drag began, divided by `scale`. */\n  dx: number\n  dy: number\n}\n\nexport interface UsePointerDragOptions {\n  /** Called as the pointer moves, with the distance from where the drag began. */\n  onDrag: (delta: PointerDragDelta, event: React.PointerEvent) => void\n  onDragStart?: (event: React.PointerEvent) => void\n  onDragEnd?: (delta: PointerDragDelta) => void\n  /** The zoom of whatever is being dragged, so it moves as far as the pointer did on screen. */\n  scale?: number\n  disabled?: boolean\n}\n\n/**\n * Dragging with the pointer, for moving or resizing anything. Spread `handlers` on the\n * element to hold; the pointer is captured, so the drag carries on outside it.\n */\nexport function usePointerDrag({ onDrag, onDragStart, onDragEnd, scale = 1, disabled = false }: UsePointerDragOptions) {\n  const start = useRef<{ x: number; y: number; id: number } | null>(null)\n  const last = useRef<PointerDragDelta>({ dx: 0, dy: 0 })\n  const [dragging, setDragging] = useState(false)\n\n  function end() {\n    if (!start.current) return\n    start.current = null\n    setDragging(false)\n    onDragEnd?.(last.current)\n  }\n\n  const handlers = {\n    onPointerDown(e: React.PointerEvent) {\n      if (disabled || e.button !== 0) return\n      e.currentTarget.setPointerCapture(e.pointerId)\n      start.current = { x: e.clientX, y: e.clientY, id: e.pointerId }\n      last.current = { dx: 0, dy: 0 }\n      setDragging(true)\n      onDragStart?.(e)\n    },\n    onPointerMove(e: React.PointerEvent) {\n      const s = start.current\n      if (!s || e.pointerId !== s.id) return\n      last.current = { dx: (e.clientX - s.x) / scale, dy: (e.clientY - s.y) / scale }\n      onDrag(last.current, e)\n    },\n    onPointerUp: end,\n    onPointerCancel: end,\n    onLostPointerCapture: end,\n  }\n\n  return { handlers, dragging }\n}\n",
      "type": "registry:hook"
    }
  ],
  "docs": "See https://stickies.live/docs#use-pointer-drag for usage.",
  "categories": [
    "stickies"
  ],
  "type": "registry:hook"
}