{
  "name": "ai-voice",
  "type": "registry:component",
  "dependencies": [
    "motion",
    "lucide-react"
  ],
  "files": [
    {
      "type": "registry:component",
      "content": "\"use client\";\n\n/**\n * @author: @kokonutui\n * @description: AI Voice\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 { Mic } from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\nimport { cn } from \"@/lib/utils\";\n\nexport default function AI_Voice() {\n  const [submitted, setSubmitted] = useState(false);\n  const [time, setTime] = useState(0);\n  const [isClient, setIsClient] = useState(false);\n  const [isDemo, setIsDemo] = useState(true);\n\n  useEffect(() => {\n    setIsClient(true);\n  }, []);\n\n  useEffect(() => {\n    let intervalId: NodeJS.Timeout;\n\n    if (submitted) {\n      intervalId = setInterval(() => {\n        setTime((t) => t + 1);\n      }, 1000);\n    } else {\n      setTime(0);\n    }\n\n    return () => clearInterval(intervalId);\n  }, [submitted]);\n\n  const formatTime = (seconds: number) => {\n    const mins = Math.floor(seconds / 60);\n    const secs = seconds % 60;\n    return `${mins.toString().padStart(2, \"0\")}:${secs\n      .toString()\n      .padStart(2, \"0\")}`;\n  };\n\n  /**\n   * Remove that, only used for demo\n   */\n  useEffect(() => {\n    if (!isDemo) return;\n\n    let timeoutId: NodeJS.Timeout;\n    const runAnimation = () => {\n      setSubmitted(true);\n      timeoutId = setTimeout(() => {\n        setSubmitted(false);\n        timeoutId = setTimeout(runAnimation, 1000);\n      }, 3000);\n    };\n\n    const initialTimeout = setTimeout(runAnimation, 100);\n    return () => {\n      clearTimeout(timeoutId);\n      clearTimeout(initialTimeout);\n    };\n  }, [isDemo]);\n\n  const handleClick = () => {\n    if (isDemo) {\n      setIsDemo(false);\n      setSubmitted(false);\n    } else {\n      setSubmitted((prev) => !prev);\n    }\n  };\n\n  return (\n    <div className=\"w-full py-4\">\n      <div className=\"relative mx-auto flex w-full max-w-xl flex-col items-center gap-2\">\n        <button\n          className={cn(\n            \"group flex h-16 w-16 items-center justify-center rounded-xl transition-colors\",\n            submitted\n              ? \"bg-none\"\n              : \"bg-none hover:bg-black/5 dark:hover:bg-white/5\"\n          )}\n          onClick={handleClick}\n          type=\"button\"\n        >\n          {submitted ? (\n            <div\n              className=\"pointer-events-auto h-6 w-6 animate-spin cursor-pointer rounded-sm bg-black dark:bg-white\"\n              style={{ animationDuration: \"3s\" }}\n            />\n          ) : (\n            <Mic className=\"h-6 w-6 text-black/90 dark:text-white/90\" />\n          )}\n        </button>\n\n        <span\n          className={cn(\n            \"font-mono text-sm transition-opacity duration-300\",\n            submitted\n              ? \"text-black/70 dark:text-white/70\"\n              : \"text-black/30 dark:text-white/30\"\n          )}\n        >\n          {formatTime(time)}\n        </span>\n\n        <div className=\"flex h-4 w-64 items-center justify-center gap-0.5\">\n          {[...Array(48)].map((_, i) => (\n            <div\n              className={cn(\n                \"w-0.5 rounded-full transition-all duration-300\",\n                submitted\n                  ? \"animate-pulse bg-black/50 dark:bg-white/50\"\n                  : \"h-1 bg-black/10 dark:bg-white/10\"\n              )}\n              key={i}\n              style={\n                submitted && isClient\n                  ? {\n                      height: `${20 + Math.random() * 80}%`,\n                      animationDelay: `${i * 0.05}s`,\n                    }\n                  : undefined\n              }\n            />\n          ))}\n        </div>\n\n        <p className=\"h-4 text-black/70 text-xs dark:text-white/70\">\n          {submitted ? \"Listening...\" : \"Click to speak\"}\n        </p>\n      </div>\n    </div>\n  );\n}\n",
      "path": "/components/kokonutui/ai-voice.tsx",
      "target": "components/kokonutui/ai-voice.tsx"
    }
  ]
}