{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "quick-option-picker",
  "type": "registry:component",
  "title": "Quick Option Picker",
  "description": "A sleek, interactive option picker with smooth roll animations and a premium feel.",
  "dependencies": [
    "lucide-react",
    "motion",
    "react-icons"
  ],
  "registryDependencies": [
    "utils"
  ],
  "files": [
    {
      "path": "components/watermelon/quick-option-picker.tsx",
      "type": "registry:component",
      "content": "'use client';\n\nimport { useState, useRef, useEffect, type FC } from 'react';\nimport {\n  motion,\n  AnimatePresence,\n  MotionConfig,\n} from 'motion/react';\nimport { ChevronDown, Globe } from 'lucide-react';\nimport { TbLockFilled } from 'react-icons/tb';\nimport type { IconType } from 'react-icons';\nimport { cn } from '@/lib/utils';\n\n\nexport interface Option {\n  id: string;\n  label: string;\n  icon: IconType;\n}\n\ninterface OptionPickerProps {\n  options?: Option[];\n}\n\n\nconst DEFAULT_OPTIONS: Option[] = [\n  { id: 'private', label: 'Private', icon: TbLockFilled },\n  { id: 'public', label: 'Public', icon: Globe },\n];\n\nexport const OptionPicker: FC<OptionPickerProps> = ({ options }) => {\n  const [isOpen, setIsOpen] = useState<boolean>(false);\n  const [selected, setSelected] = useState<Option>(\n    options?.[0] || DEFAULT_OPTIONS[0],\n  );\n  const containerRef = useRef<HTMLDivElement>(null);\n\n  useEffect(() => {\n    const handleClickOutside = (event: MouseEvent) => {\n      if (\n        containerRef.current &&\n        !containerRef.current.contains(event.target as Node)\n      ) {\n        setIsOpen(false);\n      }\n    };\n    document.addEventListener('mousedown', handleClickOutside);\n    return () => document.removeEventListener('mousedown', handleClickOutside);\n  }, []);\n\n  const toggleOpen = () => setIsOpen((prev) => !prev);\n  const handleSelect = (option: Option) => {\n    setSelected(option);\n    setIsOpen(false);\n  };\n\n\n  const data = options || DEFAULT_OPTIONS;\n\n  return (\n    <div\n      className=\"relative inline-block perspective-[1200px] transform-3d\"\n      ref={containerRef}\n    >\n      <MotionConfig\n        transition={{ type: 'spring', damping: 20, stiffness: 300 }}\n      >\n        <AnimatePresence>\n          {isOpen && (\n            <motion.div\n              initial={{\n                opacity: 0,\n                y: 10,\n                filter: 'blur(4px)',\n                scale: 1.1,\n                rotateX: -70,\n              }}\n              animate={{\n                opacity: 1,\n                y: -5,\n                filter: 'blur(0px)',\n                scale: 1,\n                rotateX: 0,\n              }}\n              exit={{\n                opacity: 0,\n                y: 10,\n                filter: 'blur(4px)',\n                scale: 1.1,\n                rotateX: -70,\n              }}\n              className=\"absolute bottom-full left-1/2 z-50 mb-2 origin-bottom -translate-x-1/2 transform-3d\"\n              role=\"menu\"\n              aria-label=\"Visibility options\"\n            >\n              <div className=\"relative flex min-w-max gap-2 rounded-full border border-neutral-100 bg-[#F3F3F3] p-1.5 py-1 whitespace-nowrap dark:border-neutral-700 dark:bg-neutral-800\">\n                {data.map((option, index) => {\n                  const isActive = selected.id === option.id;\n                  const isFirst = index === 0;\n                  const isLast = index === data.length - 1;\n\n                  const roundedClasses = `\n                    ${isFirst ? 'rounded-l-full rounded-r-2xl' : ''}\n                    ${isLast ? 'rounded-r-full rounded-l-2xl' : ''}\n                    ${!isFirst && !isLast ? 'rounded-none' : ''}\n                  `;\n\n                  return (\n                    <motion.button\n                      key={option.id}\n                      onClick={() => handleSelect(option)}\n                      whileTap={{ scale: 0.95 }}\n                      whileHover={{ y: -1 }}\n                      title={`Set as ${option.label}`}\n                      aria-label={`Select ${option.label}`}\n                      className={`relative flex items-center gap-2 px-5 py-3 text-[15px] font-semibold transition-all duration-300 ${roundedClasses} bg-[#FEFEFE] dark:bg-neutral-700 ${isActive ? 'text-[#010101] dark:text-white' : 'text-[#6E6E6E] dark:text-neutral-400'}`}\n                    >\n                      <motion.span>\n                        <option.icon size={22} />\n                      </motion.span>\n                      <span className=\"text-bold relative z-10 text-lg\">\n                        {option.label}\n                      </span>\n                    </motion.button>\n                  );\n                })}\n\n                <div className=\"absolute -bottom-1.5 left-1/2 h-3 w-3 -translate-x-1/2 rotate-45 border-r border-b border-neutral-100 bg-[#F3F3F3] dark:border-neutral-700 dark:bg-neutral-800\" />\n              </div>\n            </motion.div>\n          )}\n        </AnimatePresence>\n\n        <motion.button\n          layout=\"size\"\n          onClick={toggleOpen}\n          whileTap={{ scale: 0.97 }}\n          title=\"Change Visibility\"\n          aria-label={`Visibility is currently ${selected.label}. Click to change.`}\n          aria-expanded={isOpen}\n          className={`flex items-center justify-center gap-2 rounded-full border border-transparent px-4 py-4 transition-all duration-300 select-none ${isOpen ? 'bg-[#E5E5E5] dark:border-neutral-700 dark:bg-neutral-800' : 'bg-[#F4F4F4] dark:bg-neutral-900'}`}\n        >\n          <AnimatePresence mode=\"popLayout\" initial={false}>\n            <motion.div\n              key={selected.id}\n              initial={{ opacity: 0, scale: 0.5, filter: 'blur(4px)' }}\n              animate={{ opacity: 1, scale: 1, filter: 'blur(0px)' }}\n              exit={{ opacity: 0, scale: 0.5, filter: 'blur(4px)' }}\n              className=\"flex items-center gap-2\"\n            >\n              <selected.icon\n                size={24}\n                className={`transition-colors duration-300 ${isOpen ? 'text-[#AEAEAE] dark:text-neutral-500' : 'text-[#AFAFAF] dark:text-neutral-400'}`}\n              />\n            </motion.div>\n          </AnimatePresence>\n          <AnimatedText\n            value={selected.label}\n            className=\"text-lg font-semibold text-neutral-700 dark:text-neutral-100\"\n          />\n\n          <motion.div\n            animate={{ rotate: isOpen ? 180 : 0 }}\n            className=\"flex items-center\"\n          >\n            <ChevronDown\n              size={24}\n              className={`transition-colors duration-300 ${isOpen ? 'text-[#AEAEAE] dark:text-neutral-500' : 'text-[#AFAFAF] dark:text-neutral-400'}`}\n              strokeWidth={2.5}\n            />\n          </motion.div>\n        </motion.button>\n      </MotionConfig>\n    </div>\n  );\n};\n\nconst AnimatedText = ({\n  value,\n  className,\n}: {\n  value: string;\n  className?: string;\n}) => {\n  return (\n    <div\n      className={cn(\n        'flex text-lg tracking-tight will-change-transform',\n        className,\n      )}\n    >\n      <AnimatePresence mode=\"popLayout\" initial={false}>\n        {value.split('').map((char, index) => {\n          const displayChar = char === ' ' ? '\\u00A0' : char;\n\n          return (\n            <motion.span\n              key={char + index}\n              layout\n              initial={{ opacity: 0, y: 5, scale: 0.7 }}\n              animate={{\n                opacity: 1,\n                y: 0,\n                scale: 1,\n                transition: {\n                  type: 'spring',\n                  stiffness: 200,\n                  damping: 20,\n                  delay: 0.03 * index,\n                },\n              }}\n              exit={{ opacity: 0, y: -5, scale: 0.7 }}\n            >\n              {displayChar}\n            </motion.span>\n          );\n        })}\n      </AnimatePresence>\n    </div>\n  );\n};\n"
    }
  ]
}
