{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "signature-input",
  "title": "Signature Input",
  "description": "Canvas-based signature input that returns a PNG data URL.",
  "dependencies": [
    "lucide-react"
  ],
  "registryDependencies": [
    "button"
  ],
  "files": [
    {
      "path": "components/ui/signature-input.tsx",
      "content": "'use client'\n\nimport { useEffect, useState, useRef } from 'react'\nimport { Button } from '@/components/ui/button'\nimport { Eraser } from 'lucide-react'\n\ntype SignatureInputProps = {\n  canvasRef?: React.RefObject<HTMLCanvasElement | null>\n  onSignatureChange: (signature: string | null) => void\n}\n\nconst disableTouchScroll = (canvas: HTMLCanvasElement) => {\n  const preventScroll = (e: TouchEvent) => {\n    e.preventDefault() // Disable scroll\n  }\n\n  canvas.addEventListener('touchstart', preventScroll, { passive: false })\n  canvas.addEventListener('touchmove', preventScroll, { passive: false })\n  canvas.addEventListener('touchend', preventScroll, { passive: false })\n\n  return () => {\n    canvas.removeEventListener('touchstart', preventScroll)\n    canvas.removeEventListener('touchmove', preventScroll)\n    canvas.removeEventListener('touchend', preventScroll)\n  }\n}\n\nexport default function SignatureInput({\n  canvasRef: externalCanvasRef,\n  onSignatureChange,\n}: SignatureInputProps) {\n  const internalCanvasRef = useRef<HTMLCanvasElement>(null)\n  const canvasRef = externalCanvasRef ?? internalCanvasRef\n  const [isDrawing, setIsDrawing] = useState(false)\n  const [lastPosition, setLastPosition] = useState<{\n    x: number\n    y: number\n  } | null>(null)\n\n  useEffect(() => {\n    const canvas = canvasRef.current\n    if (!canvas) return\n\n    // Setup canvas context\n    const ctx = canvas.getContext('2d')\n    if (ctx) {\n      ctx.lineWidth = 2\n      ctx.lineCap = 'round'\n      ctx.lineJoin = 'round'\n    }\n\n    const updateStrokeColor = () => {\n      const ctx = canvas.getContext('2d')\n      if (!ctx) return\n\n      const isDarkClass = document.documentElement.classList.contains('dark')\n      const isLightClass = document.documentElement.classList.contains('light')\n\n      const systemPrefersDark = window.matchMedia(\n        '(prefers-color-scheme: dark)',\n      ).matches\n\n      const isDarkMode = isDarkClass || (!isLightClass && systemPrefersDark)\n\n      ctx.strokeStyle = isDarkMode ? '#ffffff' : '#000000'\n    }\n\n    updateStrokeColor()\n\n    // Disable touch scrolling while drawing\n    const cleanupTouchScroll = disableTouchScroll(canvas)\n\n    const observer = new MutationObserver(updateStrokeColor)\n    observer.observe(document.documentElement, {\n      attributes: true,\n      attributeFilter: ['class'],\n    })\n\n    const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')\n    mediaQuery.addEventListener('change', updateStrokeColor)\n\n    return () => {\n      cleanupTouchScroll()\n      observer.disconnect()\n      mediaQuery.removeEventListener('change', updateStrokeColor)\n    }\n  }, [canvasRef])\n\n  const startDrawing = (\n    e:\n      | React.MouseEvent<HTMLCanvasElement>\n      | React.TouchEvent<HTMLCanvasElement>,\n  ) => {\n    e.preventDefault()\n    setIsDrawing(true)\n    draw(e)\n  }\n\n  const stopDrawing = () => {\n    if (!isDrawing) return\n\n    setIsDrawing(false)\n    setLastPosition(null)\n    const canvas = canvasRef.current\n    const ctx = canvas?.getContext('2d')\n    if (canvas && ctx) {\n      ctx.beginPath()\n      const dataUrl = canvas.toDataURL()\n      onSignatureChange(dataUrl) // Pass data URL to the form's onChange\n    }\n  }\n\n  const draw = (\n    e:\n      | React.MouseEvent<HTMLCanvasElement>\n      | React.TouchEvent<HTMLCanvasElement>,\n  ) => {\n    e.preventDefault()\n    if (!isDrawing) return\n\n    const canvas = canvasRef.current\n    const ctx = canvas?.getContext('2d')\n    if (canvas && ctx) {\n      const rect = canvas.getBoundingClientRect()\n      const x = ('touches' in e ? e.touches[0].clientX : e.clientX) - rect.left\n      const y = ('touches' in e ? e.touches[0].clientY : e.clientY) - rect.top\n\n      if (lastPosition) {\n        const midX = (lastPosition.x + x) / 2\n        const midY = (lastPosition.y + y) / 2\n\n        ctx.beginPath()\n        ctx.moveTo(lastPosition.x, lastPosition.y)\n        ctx.quadraticCurveTo(midX, midY, x, y) // Smooth transition\n        ctx.stroke()\n      } else {\n        // For the first point, simply move to the position without a stroke\n        ctx.beginPath()\n        ctx.moveTo(x, y)\n      }\n\n      setLastPosition({ x, y })\n    }\n  }\n\n  const clearSignature = () => {\n    const canvas = canvasRef.current\n    const ctx = canvas?.getContext('2d')\n    if (canvas && ctx) {\n      ctx.clearRect(0, 0, canvas.width, canvas.height)\n      onSignatureChange(null) // Clear signature in the form as well\n    }\n  }\n\n  // Callback ref to sync both internal and external refs\n  const setCanvasRef = (element: HTMLCanvasElement | null) => {\n    // Update internal ref\n    ;(\n      internalCanvasRef as React.MutableRefObject<HTMLCanvasElement | null>\n    ).current = element\n    // Update external ref if provided\n    if (externalCanvasRef) {\n      ;(\n        externalCanvasRef as React.MutableRefObject<HTMLCanvasElement | null>\n      ).current = element\n    }\n  }\n\n  return (\n    <div className=\"border border-gray-300 rounded-md overflow-hidden relative w-[400px] h-[200px]\">\n      <canvas\n        ref={setCanvasRef}\n        width={400}\n        height={200}\n        className=\"w-full h-full\"\n        onMouseDown={startDrawing}\n        onMouseUp={stopDrawing}\n        onMouseOut={stopDrawing}\n        onMouseMove={draw}\n        onTouchStart={startDrawing}\n        onTouchEnd={stopDrawing}\n        onTouchMove={draw}\n      />\n      <Button\n        type=\"button\"\n        size=\"icon\"\n        variant=\"outline\"\n        className=\"absolute left-1 bottom-1 z-10 rounded-full\"\n        onClick={clearSignature}\n      >\n        <Eraser className=\"w-4 h-4 text-muted-foreground hover:text-primary\" />\n      </Button>\n    </div>\n  )\n}\n",
      "type": "registry:ui"
    }
  ],
  "categories": [
    "input"
  ],
  "type": "registry:ui"
}