{ "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,\n VariantProps {\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 \n \n \n {(variant === \"red\" || !variant) && }\n {variant === \"green\" && }\n {variant === \"blue\" && }\n {variant === \"orange\" && }\n {variant === \"grey\" && }\n {isHolding ? \"Release\" : \"Hold me\"}\n \n \n );\n}\n", "path": "/components/kokonutui/hold-button.tsx", "target": "components/kokonutui/hold-button.tsx" } ] }