{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "run-action-button",
  "type": "registry:component",
  "title": "Run Action Button",
  "description": "An animated action button that executes a sequence of steps with smooth visual transitions.",
  "dependencies": [
    "lucide-react",
    "motion",
    "react-icons"
  ],
  "files": [
    {
      "path": "components/watermelon/run-action-button.tsx",
      "type": "registry:component",
      "content": "import React, { useState, useEffect } from 'react';\nimport { motion, AnimatePresence, type Transition } from 'motion/react';\nimport { Zap } from 'lucide-react';\nimport { HiBadgeCheck } from 'react-icons/hi';\nimport { IoCloseSharp } from 'react-icons/io5';\nimport { FaInbox } from 'react-icons/fa6';\nimport { RiBubbleChartFill } from 'react-icons/ri';\nimport { BsFileTextFill, BsSendFill, BsTagFill } from 'react-icons/bs';\nimport { TbClockHour12Filled } from 'react-icons/tb';\n\n\n\nfunction AnimatedText({\n  text,\n  className,\n  delayStep = 0.014,\n}: {\n  text: string;\n  className?: string;\n  delayStep?: number;\n}) {\n  const chars = text.split('');\n\n  return (\n    <span className={className} style={{ display: 'inline-flex' }}>\n      <AnimatePresence mode=\"popLayout\" initial={false}>\n        <motion.span\n          key={text}\n          style={{ display: 'inline-flex', willChange: 'transform' }}\n        >\n          {chars.map((char, i) => (\n            <motion.span\n              key={i}\n              initial={{\n                y: 10,\n                opacity: 0,\n                scale: 0.5,\n                filter: 'blur(2px)',\n              }}\n              animate={{\n                y: 0,\n                opacity: 1,\n                scale: 1,\n                filter: 'blur(0px)',\n              }}\n              exit={{\n                y: -10,\n                opacity: 0,\n                scale: 0.5,\n                filter: 'blur(2px)',\n              }}\n              transition={{\n                type: 'spring',\n                stiffness: 240,\n                damping: 16,\n                mass: 1.2,\n                delay: i * delayStep,\n              }}\n              style={{\n                display: 'inline-block',\n                whiteSpace: char === ' ' ? 'pre' : undefined,\n              }}\n            >\n              {char}\n            </motion.span>\n          ))}\n        </motion.span>\n      </AnimatePresence>\n    </span>\n  );\n}\n\nconst spring: Transition = {\n  type: 'spring',\n  stiffness: 260,\n  damping: 22,\n  mass: 0.8,\n};\nconst DEFAULT_STEPS = [\n  { id: 1, label: 'Importing Survey Data', icon: FaInbox },\n  { id: 2, label: 'Refining Responses', icon: RiBubbleChartFill },\n  { id: 3, label: 'Labelling Responses', icon: BsTagFill },\n  { id: 4, label: 'Analyzing Sentiment', icon: TbClockHour12Filled },\n  { id: 5, label: 'Creating Reports', icon: BsFileTextFill },\n  { id: 6, label: 'Sharing Survey Report', icon: BsSendFill },\n];\n\ntype StepItem = {\n  id: number;\n  label: string;\n  icon: React.ComponentType<any>;\n};\n\ntype RunActionButtonProps = {\n  steps?: StepItem[];\n};\n\nexport function RunActionButton({\n  steps = DEFAULT_STEPS,\n}: RunActionButtonProps) {\n  const [status, setStatus] = useState<'idle' | 'running' | 'done'>('idle');\n  const [currentStep, setCurrentStep] = useState(0);\n\n  const startAction = () => {\n    setStatus('running');\n    setCurrentStep(0);\n  };\n\n  const reset = () => {\n    setStatus('idle');\n    setCurrentStep(0);\n  };\n\n  useEffect(() => {\n    if (status !== 'running') return;\n\n    const interval = setInterval(() => {\n      setCurrentStep((prev) => {\n        if (prev < steps.length - 1) return prev + 1;\n        setStatus('done');\n        return prev;\n      });\n    }, 1200);\n\n    return () => clearInterval(interval);\n  }, [status, steps.length]);\n\n\n\n  const widths = {\n    idle: 180,\n    running: 360,\n    done: 200,\n  };\n\n  return (\n    <div className=\"flex items-center justify-center\">\n      <motion.div\n        initial={{ width: 180 }}\n        animate={{ width: widths[status] }}\n        transition={spring}\n        className={`relative flex h-[64px] items-center justify-between overflow-hidden rounded-full ${status === 'running'\n            ? 'border-2 border-dashed border-[#D6D6DD] dark:border-white/20'\n            : 'border-2 border-transparent'\n          } `}\n      >\n        <AnimatePresence mode=\"popLayout\" initial={false}>\n          {status === 'idle' && (\n            <motion.button\n              key=\"idle\"\n              onClick={startAction}\n              initial={{ opacity: 0, scale: 0.8, filter: 'blur(4px)' }}\n              animate={{ opacity: 1, scale: 1, filter: 'blur(0px)' }}\n              exit={{ opacity: 0, scale: 0.8, filter: 'blur(4px)' }}\n              transition={spring}\n              className=\"flex flex-1 items-center gap-2 rounded-full bg-[#F4F4F9] px-5 py-3 whitespace-nowrap dark:bg-zinc-800\"\n            >\n              <Zap className=\"h-6 w-6 text-[#26262B] dark:text-zinc-100\" />\n\n              <AnimatedText\n                text=\"Run Action\"\n                className=\"text-[18px] font-medium text-[#26262B] dark:text-zinc-100\"\n              />\n            </motion.button>\n          )}\n\n          {status === 'running' && (\n            <motion.div\n              key=\"running\"\n              initial={{ opacity: 0, scale: 0.8, filter: 'blur(4px)' }}\n              animate={{ opacity: 1, scale: 1, filter: 'blur(0px)' }}\n              exit={{ opacity: 0, scale: 0.8, filter: 'blur(4px)' }}\n              transition={spring}\n              className=\"flex flex-1 items-center justify-between gap-3 px-4 whitespace-nowrap\"\n            >\n              <div className=\"flex items-center gap-2\">\n                <AnimatePresence mode=\"popLayout\">\n                  <motion.div\n                    key={currentStep}\n                    initial={{ opacity: 0, scale: 0, filter: 'blur(4px)' }}\n                    animate={{ opacity: 1, scale: 1, filter: 'blur(0px)' }}\n                    exit={{ opacity: 0, scale: 0, filter: 'blur(4px)' }}\n                    transition={spring}\n                  >\n                    {React.createElement(steps[currentStep].icon, {\n                      className: 'w-6 h-6 text-[#28272A]  dark:text-zinc-100',\n                    })}\n                  </motion.div>\n                </AnimatePresence>\n                <AnimatedText\n                  text={steps[currentStep].label}\n                  className=\"text-[18px] font-bold text-[#28272A]  dark:text-zinc-100\"\n                />\n              </div>\n\n              <motion.button\n                onClick={reset}\n                initial={{ opacity: 0, scale: 0.8, filter: 'blur(4px)' }}\n                animate={{ opacity: 1, scale: 1, filter: 'blur(0px)' }}\n                exit={{ opacity: 0, scale: 0.8, filter: 'blur(4px)' }}\n                transition={{ ...spring, delay: 0.15 }}\n                className=\"ml-1 rounded-full bg-[#D6D5E2] dark:bg-white p-1.5\"\n              >\n                <IoCloseSharp className=\"h-4 w-4 text-white dark:text-black\" />\n              </motion.button>\n            </motion.div>\n          )}\n\n          {status === 'done' && (\n            <motion.button\n              key=\"done\"\n              onClick={reset}\n              initial={{ opacity: 0, scale: 0.8, filter: 'blur(4px)' }}\n              animate={{ opacity: 1, scale: 1, filter: 'blur(0px)' }}\n              exit={{ opacity: 0, scale: 0.8, filter: 'blur(4px)' }}\n              transition={spring}\n              className=\"flex flex-1 items-center gap-2 rounded-full bg-[#EAF9EA] dark:bg-green-200 px-5 py-3 whitespace-nowrap\"\n            >\n              <HiBadgeCheck className=\"h-6 w-6 text-[#22c55e]\" />\n\n              <AnimatedText\n                text=\"Action Done\"\n                className=\"text-[18px] font-bold text-[#22c55e]\"\n              />\n            </motion.button>\n          )}\n        </AnimatePresence>\n      </motion.div>\n    </div>\n  );\n}\n"
    }
  ]
}
