{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "edit-badge",
  "type": "registry:component",
  "title": "Edit Badge",
  "description": "A premium interactive badge component with an inline editor for real-time text, icon, and color customization.",
  "dependencies": [
    "lucide-react",
    "motion",
    "react-icons"
  ],
  "files": [
    {
      "path": "components/watermelon/edit-badge.tsx",
      "type": "registry:component",
      "content": "import React, { useState, useRef, useEffect } from 'react';\nimport {\n  motion,\n  AnimatePresence,\n  MotionConfig,\n  type Transition,\n} from 'motion/react';\nimport { X, Loader2 } from 'lucide-react';\nimport { BiSolidPencil } from 'react-icons/bi';\nimport { FaCircleCheck } from 'react-icons/fa6';\nimport { BsDashCircleFill } from 'react-icons/bs';\nimport { MdTimelapse } from 'react-icons/md';\nimport { LuTimer } from 'react-icons/lu';\nimport { HiPencil } from 'react-icons/hi2';\n\n/*  TYPES  */\n\nexport type BadgeIconType = 'loader' | 'clock' | 'timer' | 'check' | 'minus';\n\nexport interface BadgeConfig {\n  text: string;\n  icon: BadgeIconType;\n  color: string;\n}\n\nconst DEFAULT_BADGE: BadgeConfig = {\n  text: 'Completed',\n  icon: 'check',\n  color: 'green',\n};\n\nconst COLORS = [\n  {\n    id: 'blue',\n    bg: 'bg-[#016FFE]',\n    badgeBg: 'bg-[#E7F1FD] dark:bg-[#016FFE]/10',\n    text: 'text-[#016FFE] dark:text-[#3890FF]',\n  },\n  {\n    id: 'yellow',\n    bg: 'bg-[#2EBE52]',\n    badgeBg: 'bg-[#E0FAE7] dark:bg-[#2EBE52]/10',\n    text: 'text-[#2EBE52] dark:text-[#4ADE80]',\n  },\n  {\n    id: 'orange',\n    bg: 'bg-[#FFC405]',\n    badgeBg: 'bg-[#FBF1DE] dark:bg-[#FFC405]/10',\n    text: 'text-[#FFC405] dark:text-[#FFD700]',\n  },\n  {\n    id: 'green',\n    bg: 'bg-emerald-500',\n    badgeBg: 'bg-emerald-50 dark:bg-emerald-500/10',\n    text: 'text-emerald-600 dark:text-emerald-400',\n  },\n  {\n    id: 'red',\n    bg: 'bg-[#FE322B]',\n    badgeBg: 'bg-[#FCECEC] dark:bg-[#FE322B]/10',\n    text: 'text-[#FE322B] dark:text-[#FF5C57]',\n  },\n];\n\nconst ICONS: Record<BadgeIconType, React.ElementType> = {\n  loader: Loader2,\n  clock: MdTimelapse,\n  timer: LuTimer,\n  check: FaCircleCheck,\n  minus: BsDashCircleFill,\n};\n\nconst springTransition: Transition = {\n  type: 'spring',\n  stiffness: 400,\n  damping: 40,\n  mass: 1,\n};\n\ntype EditBadgeProps = {\n  initialBadge?: BadgeConfig;\n  onChange?: (badge: BadgeConfig) => void;\n};\n\nexport function EditBadge({\n  initialBadge = DEFAULT_BADGE,\n  onChange,\n}: EditBadgeProps) {\n  const [badge, setBadge] = useState<BadgeConfig>(initialBadge);\n  const [tempBadge, setTempBadge] = useState<BadgeConfig>(initialBadge);\n  const [isEditing, setIsEditing] = useState(false);\n  const containerRef = useRef<HTMLDivElement>(null);\n\n  const currentColor = COLORS.find((c) => c.id === badge.color) || COLORS[0];\n  const IconComponent = ICONS[badge.icon];\n\n  const handleOpen = () => {\n    setTempBadge(badge);\n    setIsEditing(true);\n  };\n\n  const handleUpdate = () => {\n    setBadge(tempBadge);\n    onChange?.(tempBadge);\n    setIsEditing(false);\n  };\n\n  useEffect(() => {\n    const handleClickOutside = (event: MouseEvent) => {\n      if (\n        containerRef.current &&\n        !containerRef.current.contains(event.target as Node)\n      ) {\n        setIsEditing(false);\n      }\n    };\n    if (isEditing) document.addEventListener('mousedown', handleClickOutside);\n    return () => document.removeEventListener('mousedown', handleClickOutside);\n  }, [isEditing]);\n\n  return (\n    <div\n      className=\"relative flex h-[400px] items-center justify-center\"\n      ref={containerRef}\n    >\n      <MotionConfig transition={springTransition}>\n        <AnimatePresence>\n          {!isEditing ? (\n            <div key=\"close\" className=\"flex items-center gap-3\">\n              <motion.div\n                layoutId=\"eb-container\"\n                style={{\n                  borderRadius: 32,\n                }}\n                initial={{ opacity: 0 }}\n                animate={{ opacity: 1 }}\n                exit={{ opacity: 0 }}\n              >\n                <motion.div\n                  layoutId=\"badge-container\"\n                  className={`flex items-center gap-2.5 rounded-full px-3 py-2.5 sm:px-4 sm:py-3.5 ${currentColor.badgeBg} ${currentColor.text} cursor-default font-bold select-none`}\n                >\n                  <motion.div layoutId={badge.icon}>\n                    <IconComponent\n                      className={`h-5 w-5 sm:h-[22px] sm:w-[22px] ${badge.icon === 'loader' ? 'animate-spin' : ''}`}\n                    />\n                  </motion.div>\n                  <motion.span\n                    layoutId=\"badge-text\"\n                    className=\"text-base tracking-tight capitalize sm:text-[18px]\"\n                  >\n                    {badge.text}\n                  </motion.span>\n                </motion.div>\n              </motion.div>\n              <motion.button\n                onClick={handleOpen}\n                whileHover={{ scale: 1.1 }}\n                whileTap={{ scale: 0.9 }}\n                className=\"flex h-[42px] w-[42px] items-center justify-center rounded-full border border-[#edecf0] bg-[#F6F5FA] text-[#28272A] sm:h-[50px] sm:w-[50px] dark:border-neutral-800 dark:bg-neutral-800 dark:text-neutral-100\"\n              >\n                <BiSolidPencil className=\"h-6 w-6 fill-current\" />\n              </motion.button>\n            </div>\n          ) : (\n            <motion.div\n              key=\"open\"\n              layoutId=\"eb-container\"\n              initial={{ opacity: 0 }}\n              animate={{ opacity: 1 }}\n              exit={{ opacity: 0, transition: { duration: 0 } }}\n              // transition={bounceTransition}\n              style={{\n                borderRadius: 24,\n              }}\n              className=\"absolute top-1/2 left-1/2 z-10 w-xs origin-left -translate-x-1/2 -translate-y-1/2 rounded-3xl border-2 border-[#EBEBF0] bg-[#fefefe] p-5 sm:w-[350px] sm:p-6 dark:border-neutral-800 dark:bg-neutral-900\"\n            >\n              <div className=\"mb-5 flex items-center justify-between\">\n                <h2 className=\"text-lg font-bold text-[#87868F] dark:text-neutral-400\">\n                  Edit Badge\n                </h2>\n                <button\n                  title=\"close\"\n                  onClick={() => setIsEditing(false)}\n                  className=\"flex h-7 w-7 items-center justify-center rounded-full bg-[#B0B0B7] text-[#fefefe] dark:bg-neutral-700 dark:text-neutral-300\"\n                >\n                  <X className=\"h-4 w-4\" strokeWidth={4} />\n                </button>\n              </div>\n\n              <div className=\"mb-6\">\n                <motion.input\n                  layoutId=\"badge-text\"\n                  type=\"text\"\n                  autoFocus\n                  value={tempBadge.text}\n                  onChange={(e) =>\n                    setTempBadge((prev) => ({ ...prev, text: e.target.value }))\n                  }\n                  className=\"w-full rounded-xl border-2 border-[#EBEBF0] bg-white px-3 py-2.5 text-base font-bold text-neutral-900 capitalize transition-colors focus:border-neutral-900 focus:outline-none sm:px-4 sm:py-3 sm:text-lg dark:border-neutral-800 dark:bg-neutral-950 dark:text-neutral-100 dark:focus:border-neutral-100\"\n                  placeholder=\"Enter status...\"\n                />\n              </div>\n\n              <div className=\"mb-6 grid grid-cols-5 gap-2\">\n                {(Object.keys(ICONS) as BadgeIconType[]).map((iconKey) => {\n                  const Icon = ICONS[iconKey];\n                  const isSelected = tempBadge.icon === iconKey;\n                  return (\n                    <motion.button\n                      key={iconKey}\n                      whileHover={{ scale: 1.05 }}\n                      whileTap={{ scale: 0.95 }}\n                      onClick={() =>\n                        setTempBadge((prev) => ({ ...prev, icon: iconKey }))\n                      }\n                      className={`relative flex aspect-square items-center justify-center rounded-xl border-2 border-[#EBEBF0] text-[#AFAEB7] transition-all dark:border-neutral-800 dark:text-neutral-300`}\n                    >\n                      {isSelected && (\n                        <motion.div\n                          layout\n                          layoutId=\"selected-pill\"\n                          className=\"absolute inset-0 rounded-xl border-2 border-[#28272A] bg-transparent dark:border-neutral-100\"\n                          transition={{\n                            type: 'spring',\n                            stiffness: 400,\n                            damping: 30,\n                          }}\n                        />\n                      )}\n\n                      <motion.div\n                        layoutId={isSelected ? `${badge.icon}` : undefined}\n                      >\n                        <Icon className=\"h-5 w-5 sm:h-6 sm:w-6\" />\n                      </motion.div>\n                    </motion.button>\n                  );\n                })}\n              </div>\n\n              <div className=\"mb-8 flex items-center justify-between gap-3 rounded-xl border-2 border-[#EBEBF0] p-2.5 dark:border-neutral-800\">\n                {COLORS.map((color) => {\n                  const isSelected = tempBadge.color === color.id;\n                  return (\n                    <motion.button\n                      key={color.id}\n                      whileHover={{ scale: 1.05 }}\n                      whileTap={{ scale: 0.95 }}\n                      onClick={() =>\n                        setTempBadge((prev) => ({ ...prev, color: color.id }))\n                      }\n                      className={`h-8 w-8 rounded-full ${color.bg} relative flex items-center justify-center shadow-sm`}\n                    >\n                      {isSelected && (\n                        <HiPencil className=\"h-4 w-4 text-[#fefefe]\" />\n                      )}\n                    </motion.button>\n                  );\n                })}\n              </div>\n\n              <motion.button\n                whileHover={{ scale: 1.02 }}\n                whileTap={{ scale: 0.97 }}\n                onClick={handleUpdate}\n                className=\"w-full rounded-full bg-[#28272A] py-3.5 text-base font-bold text-[#FBFBFD] shadow-lg sm:py-4 sm:text-lg dark:bg-neutral-100 dark:text-neutral-900\"\n              >\n                Update Badge\n              </motion.button>\n            </motion.div>\n          )}\n        </AnimatePresence>\n      </MotionConfig>\n    </div>\n  );\n}\n"
    }
  ]
}
