{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "slider-captcha",
  "title": "Slider Captcha",
  "description": "A slider-based puzzle captcha verification component.",
  "dependencies": [
    "lucide-react",
    "motion"
  ],
  "files": [
    {
      "path": "registry/flowui/components/slider-captcha.tsx",
      "content": "\"use client\";\r\n\r\nimport { cn } from \"@/lib/utils\";\r\nimport { IconNode, LucideIcon, Puzzle } from \"lucide-react\";\r\nimport { motion } from \"motion/react\";\r\nimport { ReactNode, useEffect, useRef, useState } from \"react\";\r\n\r\ntype SliderCaptchaProps = {\r\n    className?: string,\r\n    puzzleClassName?: string,\r\n    targetClassName?: string,\r\n    puzzleIcon?: React.ReactNode;\r\n    tolerance?: number,\r\n    handleDrag?: () => void,\r\n    onSuccess?: () => void,\r\n    onFailure?: () => void,\r\n};\r\n\r\nexport const SliderCaptcha = ({\r\n    className,\r\n    puzzleClassName,\r\n    targetClassName,\r\n    puzzleIcon,\r\n    tolerance = 5,\r\n    handleDrag,\r\n    onSuccess,\r\n    onFailure,\r\n}: SliderCaptchaProps) => {\r\n    // Tracking the position of the target\r\n    const [xPos, setXPos] = useState<number>(0);\r\n\r\n    // Refs for the target, puzzle, and container elements\r\n    const targetRef = useRef<HTMLDivElement>(null);\r\n    const puzzleRef = useRef<HTMLDivElement>(null);\r\n    const containerRef = useRef<HTMLDivElement>(null);\r\n\r\n    // Generate the icon\r\n    const Icon = puzzleIcon || <Puzzle className=\"size-4\" />;\r\n\r\n    // Defaut drag end handler\r\n    const handleDragEnd = () => {\r\n        if (handleDrag) handleDrag();\r\n        else {\r\n            if (containerRef.current) {\r\n                // Get the positions of the target and the puzzle\r\n                const target = targetRef.current;\r\n                const puzzle = puzzleRef.current;\r\n\r\n                if (target && puzzle) {\r\n                    // Calculate the bounding rectangles of both elements\r\n                    const targetRect = target.getBoundingClientRect();\r\n                    const puzzleRect = puzzle.getBoundingClientRect();\r\n\r\n                    // Check if the puzzle is within the tolerance range of the target\r\n                    const isAligned = Math.abs(targetRect.left - puzzleRect.left) <= tolerance &&\r\n                        Math.abs(targetRect.right - puzzleRect.right) <= tolerance;\r\n\r\n                    if (isAligned) {\r\n                        if (onSuccess) onSuccess();\r\n                        else alert(\"Verification successful!\");\r\n                    } else {\r\n                        if (onFailure) onFailure();\r\n                        else alert(\"Verification failed. Please try again.\");\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    };\r\n\r\n    // Random position assignment for the target\r\n    useEffect(() => {\r\n        const container = containerRef.current;\r\n        const target = targetRef.current;\r\n\r\n        if (container && target instanceof HTMLElement) {\r\n            const max = container.offsetWidth - target.offsetWidth;\r\n            const random = Math.random() * max;\r\n\r\n            setXPos(random);\r\n        }\r\n    }, []);\r\n    return (\r\n        <div\r\n            className={cn(\r\n                \"flex items-center border rounded-4xl px-1 py-2\",\r\n                className\r\n            )}\r\n        >\r\n            <div\r\n                ref={containerRef}\r\n                className=\"relative h-full w-full flex justify-center items-center\"\r\n            >\r\n                <motion.div\r\n                    ref={puzzleRef}\r\n                    className={cn(\r\n                        \"absolute left-0 flex justify-center items-center size-8 rounded-full border cursor-grab hover:bg-accent transition-colors z-10\",\r\n                        puzzleClassName\r\n                    )}\r\n                    drag=\"x\"\r\n                    dragConstraints={containerRef}\r\n                    dragElastic={0}\r\n                    dragMomentum={false}\r\n                    onDragEnd={handleDragEnd}\r\n                >\r\n                    {Icon}\r\n                </motion.div>\r\n                <div\r\n                    ref={targetRef}\r\n                    className={cn(\r\n                        \"absolute size-8 border border-dashed rounded-2xl hover:border-gray-400 transition-colors\",\r\n                        targetClassName\r\n                    )}\r\n                    style={{\r\n                        left: xPos,\r\n                    }}\r\n                >\r\n                </div>\r\n            </div>\r\n        </div>\r\n    )\r\n}",
      "type": "registry:component"
    }
  ],
  "type": "registry:component"
}