{
  "name": "hold-button",
  "type": "registry:component",
  "dependencies": [
    "lucide-react",
    "motion"
  ],
  "registryDependencies": [
    "button"
  ],
  "files": [
    {
      "type": "registry:component",
      "content": "\"use client\";\n\n/**\n * @author: @dorianbaffier\n * @description: Hold Button\n * @version: 1.0.0\n * @date: 2025-06-26\n * @license: MIT\n * @website: https://kokonutui.com\n * @github: https://github.com/kokonut-labs/kokonutui\n */\n\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport {\n  AlertCircleIcon,\n  ArchiveXIcon,\n  BanIcon,\n  Trash2Icon,\n  XCircleIcon,\n} from \"lucide-react\";\nimport { motion, useAnimation } from \"motion/react\";\nimport { useState } from \"react\";\nimport { Button } from \"@/components/ui/button\";\nimport { cn } from \"@/lib/utils\";\n\nconst holdButtonVariants = cva(\"relative min-w-40 touch-none overflow-hidden\", {\n  variants: {\n    variant: {\n      red: [\n        \"bg-red-100 dark:bg-red-200\",\n        \"hover:bg-red-100 dark:hover:bg-red-200\",\n        \"text-red-500 dark:text-red-600\",\n        \"border border-red-200 dark:border-red-300\",\n      ],\n      green: [\n        \"bg-green-100 dark:bg-green-200\",\n        \"hover:bg-green-100 dark:hover:bg-green-200\",\n        \"text-green-500 dark:text-green-600\",\n        \"border border-green-200 dark:border-green-300\",\n      ],\n      blue: [\n        \"bg-blue-100 dark:bg-blue-200\",\n        \"hover:bg-blue-100 dark:hover:bg-blue-200\",\n        \"text-blue-500 dark:text-blue-600\",\n        \"border border-blue-200 dark:border-blue-300\",\n      ],\n      orange: [\n        \"bg-orange-100 dark:bg-orange-200\",\n        \"hover:bg-orange-100 dark:hover:bg-orange-200\",\n        \"text-orange-500 dark:text-orange-600\",\n        \"border border-orange-200 dark:border-orange-300\",\n      ],\n      grey: [\n        \"bg-gray-100 dark:bg-gray-200\",\n        \"hover:bg-gray-100 dark:hover:bg-gray-200\",\n        \"text-gray-500 dark:text-gray-600\",\n        \"border border-gray-200 dark:border-gray-300\",\n      ],\n    },\n  },\n  defaultVariants: {\n    variant: \"red\",\n  },\n});\n\ninterface HoldButtonProps\n  extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n    VariantProps<typeof holdButtonVariants> {\n  holdDuration?: number;\n}\n\nexport default function HoldButton({\n  className,\n  variant = \"red\",\n  holdDuration = 3000,\n  ...props\n}: HoldButtonProps) {\n  const [isHolding, setIsHolding] = useState(false);\n  const controls = useAnimation();\n\n  async function handleHoldStart() {\n    setIsHolding(true);\n    controls.set({ width: \"0%\" });\n    await controls.start({\n      width: \"100%\",\n      transition: {\n        duration: holdDuration / 1000,\n        ease: \"linear\",\n      },\n    });\n  }\n\n  function handleHoldEnd() {\n    setIsHolding(false);\n    controls.stop();\n    controls.start({\n      width: \"0%\",\n      transition: { duration: 0.1 },\n    });\n  }\n\n  return (\n    <Button\n      className={cn(holdButtonVariants({ variant, className }))}\n      onMouseDown={handleHoldStart}\n      onMouseLeave={handleHoldEnd}\n      onMouseUp={handleHoldEnd}\n      onTouchCancel={handleHoldEnd}\n      onTouchEnd={handleHoldEnd}\n      onTouchStart={handleHoldStart}\n      {...props}\n    >\n      <motion.div\n        animate={controls}\n        className={cn(\"absolute top-0 left-0 h-full\", {\n          \"bg-red-200/30 dark:bg-red-300/30\": variant === \"red\",\n          \"bg-green-200/30 dark:bg-green-300/30\": variant === \"green\",\n          \"bg-blue-200/30 dark:bg-blue-300/30\": variant === \"blue\",\n          \"bg-orange-200/30 dark:bg-orange-300/30\": variant === \"orange\",\n          \"bg-gray-200/30 dark:bg-gray-300/30\": variant === \"grey\",\n        })}\n        initial={{ width: \"0%\" }}\n      />\n      <span className=\"relative z-10 flex w-full items-center justify-center gap-2\">\n        {(variant === \"red\" || !variant) && <Trash2Icon className=\"h-4 w-4\" />}\n        {variant === \"green\" && <ArchiveXIcon className=\"h-4 w-4\" />}\n        {variant === \"blue\" && <XCircleIcon className=\"h-4 w-4\" />}\n        {variant === \"orange\" && <AlertCircleIcon className=\"h-4 w-4\" />}\n        {variant === \"grey\" && <BanIcon className=\"h-4 w-4\" />}\n        {isHolding ? \"Release\" : \"Hold me\"}\n      </span>\n    </Button>\n  );\n}\n",
      "path": "/components/kokonutui/hold-button.tsx",
      "target": "components/kokonutui/hold-button.tsx"
    }
  ]
}