{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "task-widget-disclosure",
  "type": "registry:component",
  "title": "Task Widget Disclosure",
  "description": "An interactive task widget with smooth disclosure animations and detailed progress tracking.",
  "dependencies": [
    "@hugeicons/core-free-icons",
    "@hugeicons/react",
    "lucide-react",
    "motion",
    "react-icons"
  ],
  "files": [
    {
      "path": "components/watermelon/task-widget-disclosure.tsx",
      "type": "registry:component",
      "content": "import React, { useState } from 'react';\nimport { motion, AnimatePresence, LayoutGroup } from 'motion/react';\nimport { MoreHorizontal, Check, ChevronDown } from 'lucide-react';\nimport { Flag01Icon, Settings03Icon } from '@hugeicons/core-free-icons';\nimport { HugeiconsIcon } from '@hugeicons/react';\nimport { BiSolidHourglassBottom } from 'react-icons/bi';\nimport { IoIosCheckmarkCircleOutline } from 'react-icons/io';\n\n// --- Types ---\nexport interface Subtask {\n  id: string;\n  title: string;\n  completed: boolean;\n}\n\nexport interface Assignee {\n  name: string;\n  avatar: string;\n  color: string;\n}\n\nexport interface TaskData {\n  title: string;\n  progress: number;\n  completedCount: number;\n  totalCount: number;\n  priority: string;\n  status: string;\n  subtasks: Subtask[];\n  assignees: Assignee[];\n}\n\ninterface Props {\n  data: TaskData;\n}\n\nexport const TaskWidget: React.FC<Props> = ({ data }) => {\n  const [isOpen, setIsOpen] = useState(false);\n\n  const Transition = {\n    ease: [0.25, 0.1, 0.25, 1],\n    duration: 0.3,\n  } as const;\n\n  return (\n    <LayoutGroup>\n      <motion.div\n        layout\n        initial={false}\n        onClick={() => setIsOpen(!isOpen)}\n        transition={Transition}\n        className={`relative w-full cursor-pointer overflow-hidden border-2 border-neutral-100 bg-white shadow-xl transition-colors select-none sm:w-[440px] dark:border-neutral-800 dark:bg-neutral-950 ${\n          isOpen\n            ? 'rounded-[24px] p-5 sm:rounded-[26px] sm:p-[22px]'\n            : 'rounded-[20px] p-3 sm:p-[12px]'\n        }`}\n      >\n        {/* --- Header Section --- */}\n        <div className=\"relative z-10 flex items-center justify-between gap-2\">\n          <motion.div\n            layout=\"position\"\n            transition={Transition}\n            className={`flex items-center gap-2 ${isOpen ? 'bg-transparent' : 'bg-neutral-50 dark:bg-neutral-900'} rounded-lg py-0.5 pr-2 pl-1.5 transition-colors sm:pr-2 sm:pl-1.5`}\n          >\n            <motion.div\n              layout\n              transition={Transition}\n              className={`my-0.5 flex items-center justify-center rounded-lg border-[1.7px] border-neutral-200 bg-white transition-colors dark:border-neutral-700 dark:bg-neutral-900 ${isOpen ? 'h-10 w-10 sm:h-12 sm:w-12' : 'size-7 sm:size-8'}`}\n            >\n              <HugeiconsIcon\n                icon={Settings03Icon}\n                size={isOpen ? 20 : 15}\n                className=\"text-neutral-400 sm:hidden dark:text-neutral-500\"\n                strokeWidth={1.5}\n              />\n              <HugeiconsIcon\n                icon={Settings03Icon}\n                size={isOpen ? 24 : 17}\n                className=\"hidden text-neutral-400 sm:block dark:text-neutral-500\"\n                strokeWidth={1.5}\n              />\n            </motion.div>\n            <motion.h2\n              layout\n              transition={Transition}\n              className={`origin-left font-sans font-semibold text-neutral-800 transition-colors dark:text-neutral-100 ${isOpen ? 'text-xl sm:text-3xl' : 'text-sm whitespace-nowrap sm:text-base'}`}\n            >\n              {data.title}\n            </motion.h2>\n          </motion.div>\n\n          <AnimatePresence mode=\"popLayout\" initial={false}>\n            {!isOpen ? (\n              <motion.div\n                key=\"collapsed-progress\"\n                initial={{ opacity: 0, scale: 0.9, x: 10 }}\n                animate={{ opacity: 1, scale: 1, x: 0 }}\n                exit={{ opacity: 0, scale: 0.9, x: 10 }}\n                transition={{ duration: 0.15 }}\n                className=\"flex items-center gap-3\"\n              >\n                <motion.div\n                  layoutId=\"progress-container\"\n                  className=\"relative h-2 w-16 overflow-hidden rounded-full bg-neutral-100 transition-colors sm:w-32 dark:bg-neutral-700\"\n                >\n                  <motion.div\n                    layoutId=\"progress-fill\"\n                    className=\"relative h-full overflow-hidden rounded-full bg-green-500\"\n                    style={{ width: `${data.progress}%` }}\n                  >\n                    <motion.div\n                      initial={{ x: '-100%' }}\n                      animate={{ x: '100%' }}\n                      transition={{\n                        repeat: Infinity,\n                        duration: 1.5,\n                        ease: 'linear',\n                      }}\n                      className=\"absolute inset-0 h-full w-full\"\n                      style={{\n                        background:\n                          'linear-gradient(90deg, transparent, rgba(255,255,255,0.4), transparent)',\n                      }}\n                    />\n                  </motion.div>\n                </motion.div>\n                <motion.span\n                  layoutId=\"progress-text\"\n                  className=\"text-xs font-medium text-neutral-500 transition-colors sm:text-base dark:text-neutral-400\"\n                >\n                  {data.progress}%\n                </motion.span>\n              </motion.div>\n            ) : (\n              <motion.button\n                key=\"more-btn\"\n                initial={{ opacity: 0, scale: 0.8 }}\n                animate={{ opacity: 1, scale: 1 }}\n                exit={{ opacity: 0, scale: 0.8 }}\n                transition={{ duration: 0.15 }}\n                className=\"rounded-md border-2 border-neutral-100 bg-white p-1.5 px-1.5 text-black transition-colors dark:border-neutral-800 dark:bg-neutral-950 dark:text-white\"\n              >\n                <MoreHorizontal size={22} />\n              </motion.button>\n            )}\n          </AnimatePresence>\n        </div>\n\n        {/* --- Collapsed Sub-Header --- */}\n        <AnimatePresence mode=\"popLayout\">\n          {!isOpen && (\n            <motion.div\n              layout\n              initial={{ opacity: 0, y: 5 }}\n              animate={{ opacity: 1, y: 0 }}\n              exit={{ opacity: 0, y: 5 }}\n              transition={{ duration: 0.15 }}\n              className=\"mt-3 flex items-center justify-between px-1\"\n            >\n              <div className=\"flex items-center gap-3 text-xs font-medium sm:gap-4 sm:text-sm\">\n                <div className=\"flex items-center gap-1 text-neutral-500 sm:gap-1.5 dark:text-neutral-400\">\n                  <motion.div\n                    layoutId=\"priority-icon\"\n                    className=\"flex items-center\"\n                  >\n                    <HugeiconsIcon\n                      icon={Flag01Icon}\n                      size={18}\n                      className=\"sm:hidden\"\n                      color=\"currentColor\"\n                      fill=\"currentColor\"\n                      strokeWidth={1.5}\n                    />\n                    <HugeiconsIcon\n                      icon={Flag01Icon}\n                      size={22}\n                      className=\"hidden sm:block\"\n                      color=\"currentColor\"\n                      fill=\"currentColor\"\n                      strokeWidth={1.5}\n                    />\n                  </motion.div>\n                  <motion.span layoutId=\"priority-text\">\n                    {data.priority}\n                  </motion.span>\n                </div>\n                <div className=\"flex items-center gap-1 text-neutral-500 sm:gap-1.5 dark:text-neutral-400\">\n                  <motion.div\n                    layoutId=\"status-icon\"\n                    className=\"flex items-center\"\n                  >\n                    <BiSolidHourglassBottom className=\"h-4 w-4 text-neutral-400 sm:h-[22px] sm:w-[22px]\" />\n                  </motion.div>\n                  <motion.span layoutId=\"status-text\">\n                    {data.status}\n                  </motion.span>\n                </div>\n              </div>\n              <div className=\"flex -space-x-2\">\n                {data.assignees.map((u, i) => (\n                  <motion.img\n                    layoutId={`avatar-${u.name}`}\n                    key={i}\n                    src={u.avatar}\n                    className=\"h-7 w-7 rounded-full border-2 border-neutral-200 shadow-lg sm:h-8 sm:w-8 dark:border-neutral-700\"\n                  />\n                ))}\n              </div>\n            </motion.div>\n          )}\n        </AnimatePresence>\n\n        {/* --- Expanded Content --- */}\n        <AnimatePresence mode=\"popLayout\">\n          {isOpen && (\n            <motion.div\n              layout\n              initial={{ opacity: 0, y: -20 }}\n              animate={{ opacity: 1, y: 0 }}\n              exit={{ opacity: 0, y: -20, transition: { duration: 0.1 } }}\n              transition={{ ...Transition, delay: 0.05 }}\n              className=\"mt-6 origin-top\"\n            >\n              {/* Progress Bar Container */}\n              <div className=\"mb-7 flex w-fit items-center gap-1.5 rounded-full border-[1.5px] border-neutral-200 bg-neutral-50/50 px-2 py-1 transition-colors sm:gap-2 sm:px-2.5 sm:py-1.5 dark:border-neutral-700 dark:bg-neutral-800/50\">\n                <div className=\"flex h-5 w-5 items-center justify-center rounded-full\">\n                  <IoIosCheckmarkCircleOutline\n                    size={24}\n                    className=\"text-neutral-300 dark:text-neutral-600\"\n                  />\n                </div>\n                <span className=\"text-sm font-semibold text-neutral-400 dark:text-neutral-500\">\n                  <span className=\"text-neutral-400 dark:text-neutral-500\">\n                    {data.completedCount}\n                  </span>{' '}\n                  of {data.totalCount}\n                </span>\n                <motion.div\n                  layoutId=\"progress-container\"\n                  className=\"mx-1 h-2 w-20 rounded-full bg-neutral-100 transition-colors sm:w-28 dark:bg-neutral-700\"\n                >\n                  <motion.div\n                    layoutId=\"progress-fill\"\n                    className=\"relative h-full overflow-hidden rounded-full bg-green-500\"\n                    style={{ width: `${data.progress}%` }}\n                  >\n                    <motion.div\n                      initial={{ x: '-100%' }}\n                      animate={{ x: '100%' }}\n                      transition={{\n                        repeat: Infinity,\n                        duration: 1.5,\n                        ease: 'linear',\n                      }}\n                      className=\"absolute inset-0 h-full w-full\"\n                      style={{\n                        background:\n                          'linear-gradient(90deg, transparent, rgba(255,255,255,0.4), transparent)',\n                      }}\n                    />\n                  </motion.div>\n                </motion.div>\n                <motion.span\n                  layoutId=\"progress-text\"\n                  className=\"text-sm font-semibold text-neutral-600 dark:text-neutral-200\"\n                >\n                  {data.progress}%\n                </motion.span>\n              </div>\n\n              {/* Subtasks */}\n              <div className=\"relative mb-8 ml-6 flex flex-col gap-5\">\n                <motion.div\n                  initial={{ scaleY: 0 }}\n                  animate={{ scaleY: 1 }}\n                  className=\"absolute top-0 bottom-4 left-0 w-[1.7px] origin-top bg-neutral-300 transition-colors dark:bg-neutral-700\"\n                />\n                {data.subtasks.map((task, idx) => (\n                  <motion.div\n                    key={task.id}\n                    initial={{ opacity: 0, x: -10 }}\n                    animate={{ opacity: 1, x: 0 }}\n                    transition={{ delay: 0.1 + idx * 0.03 }}\n                    className=\"relative flex items-center pl-8\"\n                  >\n                    <div className=\"absolute top-[-10px] left-0 h-[30px] w-4 rounded-bl-xl border-b-[1.7px] border-l-[1.7px] border-neutral-300 transition-colors sm:w-5 dark:border-neutral-700\" />\n                    <div\n                      className={`flex h-5 w-5 items-center justify-center rounded-full border-[1.7px] transition-colors ${task.completed ? 'border-neutral-600 bg-neutral-600 dark:border-neutral-200 dark:bg-neutral-200' : 'border-neutral-300 bg-white dark:border-neutral-600 dark:bg-transparent'}`}\n                    >\n                      {task.completed && (\n                        <Check\n                          size={12}\n                          className=\"text-white dark:text-black\"\n                          strokeWidth={3}\n                        />\n                      )}\n                    </div>\n                    <span\n                      className={`ml-3 text-base font-medium transition-colors ${task.completed ? 'text-neutral-400 dark:text-neutral-500' : 'text-neutral-500 dark:text-neutral-300'}`}\n                    >\n                      {task.title}\n                    </span>\n                  </motion.div>\n                ))}\n              </div>\n\n              {/* Priority & Status */}\n              <div className=\"mb-6 space-y-4\">\n                {[\n                  {\n                    label: 'Priority',\n                    val: data.priority,\n                    icon: (\n                      <HugeiconsIcon\n                        icon={Flag01Icon}\n                        size={22}\n                        className=\"text-neutral-400\"\n                        strokeWidth={1.5}\n                      />\n                    ),\n                    badge:\n                      'bg-red-100 text-red-600 dark:bg-red-950 dark:text-red-400',\n                    chevronWrap: 'bg-red-50 dark:bg-neutral-900',\n                    chevron: 'text-red-700 dark:text-red-400',\n                    layoutId: 'priority',\n                  },\n                  {\n                    label: 'Status',\n                    val: data.status,\n                    icon: (\n                      <BiSolidHourglassBottom\n                        className=\"text-neutral-400\"\n                        size={22}\n                      />\n                    ),\n                    badge:\n                      'bg-amber-100 text-amber-700 dark:bg-amber-950 dark:text-amber-300',\n                    chevronWrap: 'bg-amber-50 dark:bg-neutral-900',\n                    chevron: 'text-amber-700 dark:text-amber-300',\n                    layoutId: 'status',\n                  },\n                ].map((item, i) => (\n                  <motion.div\n                    key={i}\n                    className=\"flex items-center gap-4 px-1 font-medium sm:gap-8\"\n                  >\n                    <div className=\"flex min-w-[80px] items-center gap-3 text-neutral-600 transition-colors sm:min-w-[100px] dark:text-neutral-200\">\n                      <motion.div\n                        layoutId={`${item.layoutId}-icon`}\n                        className=\"flex items-center\"\n                      >\n                        {item.icon}\n                      </motion.div>\n                      {item.label}\n                    </div>\n                    <div\n                      className={`${item.badge} flex items-center gap-2 rounded-lg px-3 py-1 text-sm font-bold opacity-85 transition-colors`}\n                    >\n                      <motion.span layoutId={`${item.layoutId}-text`}>\n                        {item.val}\n                      </motion.span>\n                      <span\n                        className={`${item.chevronWrap} border-0.5 flex items-center justify-center rounded-sm p-px transition-colors`}\n                      >\n                        <ChevronDown\n                          size={16}\n                          className={item.chevron}\n                          strokeWidth={2}\n                        />\n                      </span>\n                    </div>\n                  </motion.div>\n                ))}\n              </div>\n\n              {/* Assignees */}\n              <div className=\"flex flex-wrap gap-2\">\n                {data.assignees.map((user, i) => (\n                  <motion.div\n                    key={i}\n                    className=\"flex items-center gap-2 rounded-full border-[1.58px] border-neutral-200 py-1 pr-4 pl-1.5 shadow-sm transition-colors dark:border-neutral-700 dark:bg-neutral-800\"\n                  >\n                    <motion.img\n                      layoutId={`avatar-${user.name}`}\n                      title=\"avatar\"\n                      src={user.avatar}\n                      className=\"h-7 w-7 rounded-full object-cover\"\n                    />\n                    <span className=\"text-sm font-semibold text-neutral-500 transition-colors dark:text-neutral-200\">\n                      {user.name}\n                    </span>\n                  </motion.div>\n                ))}\n              </div>\n            </motion.div>\n          )}\n        </AnimatePresence>\n      </motion.div>\n    </LayoutGroup>\n  );\n};\n"
    }
  ]
}
