{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "floating-disclosure",
  "type": "registry:component",
  "title": "Floating Disclosure",
  "description": "A compact expandable action menu with animated resizing,  floating close button, and spring-based item reveal.",
  "dependencies": [
    "lucide-react",
    "motion",
    "react-icons",
    "react-use-measure"
  ],
  "registryDependencies": [
    "utils"
  ],
  "files": [
    {
      "path": "components/watermelon/floating-disclosure.tsx",
      "type": "registry:component",
      "content": "'use client';\n\nimport { useEffect, useState } from 'react';\nimport { motion, AnimatePresence, MotionConfig } from 'motion/react';\nimport { PlusIcon } from 'lucide-react';\nimport { BsFileTextFill } from 'react-icons/bs';\nimport { FaBell } from 'react-icons/fa6';\nimport { TbFileFilled } from 'react-icons/tb';\nimport { IoIosFolder } from 'react-icons/io';\nimport useMeasure from 'react-use-measure';\nimport { cn } from '@/lib/utils';\nimport type { IconType } from 'react-icons';\n\ninterface TooltipItem {\n  title: string;\n  description: string;\n  icon: IconType;\n}\ninterface FloatingDisclosureProps {\n  items: TooltipItem[];\n}\n\nexport const items = [\n  {\n    title: 'Task',\n    description: 'Create a new task',\n    icon: BsFileTextFill,\n  },\n  {\n    title: 'Reminder',\n    description: 'Create reminders',\n    icon: FaBell,\n  },\n  {\n    title: 'Note',\n    description: 'Capture ideas',\n    icon: TbFileFilled,\n  },\n  {\n    title: 'Project',\n    description: 'Organise projects',\n    icon: IoIosFolder,\n  },\n];\n\nexport const FloatingDisclosure = ({ items }: FloatingDisclosureProps) => {\n  const [isOpen, setIsOpen] = useState(false);\n  const [ref, bounds] = useMeasure({ offsetSize: true });\n\n  useEffect(() => {\n    console.log(bounds);\n  }, [isOpen, bounds]);\n\n  return (\n    <MotionConfig\n      transition={{\n        type: 'spring',\n        stiffness: 280,\n        damping: 26,\n      }}\n    >\n      <motion.div\n        className={cn(\n          'flex items-center justify-center overflow-hidden rounded-3xl bg-[rgb(241,236,231)] shadow-[0_0_0_1px_rgba(0,0,0,0.01),0_1px_2px_-1px_rgba(0,0,0,0.01),0_2px_4px_0_rgba(0,0,0,0.01)] transition-colors duration-400 ease-out dark:bg-neutral-700',\n          {\n            'border border-black/5 bg-neutral-50 dark:border-white/5 dark:bg-neutral-900':\n              isOpen,\n          },\n        )}\n        animate={{\n          width: bounds.width > 0 ? bounds.width : 'auto',\n          height: bounds.height > 0 ? bounds.height : 'auto',\n        }}\n      >\n        <AnimatePresence mode=\"popLayout\">\n          {isOpen && (\n            <motion.div\n              className=\"absolute z-10 flex cursor-pointer items-center gap-2 rounded-2xl border bg-[#F1ECE7] px-4 py-1.5 dark:border-white/5 dark:bg-neutral-900\"\n              initial={{\n                opacity: 0,\n                filter: 'blur(8px)',\n                y: 0,\n                top: '50%',\n                left: '50%',\n                x: '-50%',\n              }}\n              animate={{\n                opacity: 1,\n                filter: 'blur(0px)',\n                y: -170,\n                top: '50%',\n                left: '50%',\n                x: '-50%',\n                pointerEvents: 'auto',\n              }}\n              exit={{\n                opacity: 0,\n                filter: 'blur(8px)',\n                y: 0,\n              }}\n              transition={{\n                type: 'spring',\n                delay: 0.05,\n                duration: 0.6,\n                bounce: 0.3,\n              }}\n              onClick={() => setIsOpen(false)}\n            >\n              <PlusIcon\n                className={cn(\n                  'rotate-0 text-neutral-500 transition-transform duration-300 ease-in-out',\n                  isOpen && 'rotate-45',\n                )}\n              />\n            </motion.div>\n          )}\n        </AnimatePresence>\n        <div ref={ref} className={cn('p-2')}>\n          <AnimatePresence mode=\"popLayout\" initial={false}>\n            {!isOpen ? (\n              <motion.div\n                key=\"close\"\n                className=\"shrink-0 cursor-pointer px-6\"\n                initial={{ opacity: 0 }}\n                animate={{ opacity: 1 }}\n                exit={{ opacity: 0 }}\n                transition={{\n                  duration: 0.2,\n                  ease: 'easeOut',\n                }}\n                onClick={() => setIsOpen(!isOpen)}\n              >\n                <PlusIcon className=\"h-6 w-6 text-neutral-500 dark:text-neutral-100\" />\n              </motion.div>\n            ) : (\n              <motion.div key=\"open\" className=\"flex shrink-0 flex-col gap-3\">\n                {items.map((item) => (\n                  <motion.div\n                    key={item.title}\n                    className=\"flex flex-1 shrink-0 cursor-pointer items-center gap-2 rounded-xl p-1 hover:bg-[#f9f6f4] dark:hover:bg-white/5\"\n                    initial={{\n                      opacity: 0,\n                      filter: 'blur(4px)',\n                      y: 20,\n                      scale: 1,\n                    }}\n                    animate={{\n                      opacity: 1,\n                      filter: 'blur(0px)',\n                      y: 0,\n                      scale: 1,\n                    }}\n                    exit={{\n                      opacity: 0,\n                      filter: 'blur(4px)',\n                      transition: { duration: 0.2, ease: 'easeOut' },\n                    }}\n                    transition={{\n                      delay: 0.15,\n                      type: 'spring',\n                      stiffness: 200,\n                      damping: 20,\n                    }}\n                  >\n                    <div className=\"shrink-0 rounded-lg bg-[#F1ECE7] p-2 dark:bg-neutral-700\">\n                      <item.icon className=\"h-5 w-5 text-neutral-500 dark:text-neutral-100\" />\n                    </div>\n\n                    <div className=\"flex w-52 flex-col leading-none text-nowrap\">\n                      <p className=\"font-semibold text-zinc-700 dark:text-neutral-100\">\n                        {item.title}\n                      </p>\n                      <span className=\"text-sm text-zinc-500 dark:text-neutral-400\">\n                        {item.description}\n                      </span>\n                    </div>\n                  </motion.div>\n                ))}\n              </motion.div>\n            )}\n          </AnimatePresence>\n        </div>\n      </motion.div>\n    </MotionConfig>\n  );\n};\n"
    }
  ]
}
