{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "responsive-modal",
  "dependencies": [
    "motion",
    "lucide-react"
  ],
  "devDependencies": [],
  "registryDependencies": [],
  "files": [
    {
      "path": "./components/ui/responsive-modal.tsx",
      "content": "'use client';\n\nimport { cn } from '@/lib/utils';\nimport { X } from 'lucide-react';\nimport { AnimatePresence, motion } from 'motion/react';\nimport React, { createContext, type ReactNode, useContext, useEffect, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport { Drawer as VaulDrawer } from 'vaul';\n\ninterface DrawerContextProps {\n  open: boolean;\n  setOpen: (open: boolean) => void;\n}\n\nconst DrawerContext = createContext<DrawerContextProps | undefined>(undefined);\n\nexport const useResponsiveModal = () => {\n  const context = useContext(DrawerContext);\n  if (!context) {\n    throw new Error('useResponsiveModal must be used within a ResponsiveModalProvider');\n  }\n  return context;\n};\n\ninterface ResponsiveModalProps {\n  children: ReactNode;\n  open?: boolean;\n  setOpen?: (open: boolean) => void;\n  classname?: string;\n  clsBtnClassname?: string;\n}\n\nexport function ResponsiveModal({\n  children,\n  open: controlledOpen,\n  setOpen: controlledSetOpen,\n  classname,\n  clsBtnClassname,\n}: ResponsiveModalProps) {\n  const [internalOpen, setInternalOpen] = useState(false);\n  const [isDesktop, setIsDesktop] = useState(false);\n  const [mounted, setMounted] = useState(false);\n\n  const open = controlledOpen !== undefined ? controlledOpen : internalOpen;\n  const setOpen = controlledSetOpen || setInternalOpen;\n\n  useEffect(() => {\n    setMounted(true);\n    const mediaQuery = window.matchMedia('(min-width: 768px)');\n    const handleMediaChange = (event: MediaQueryListEvent) => {\n      setIsDesktop(event.matches);\n    };\n\n    setIsDesktop(mediaQuery.matches);\n    mediaQuery.addEventListener('change', handleMediaChange);\n    return () => mediaQuery.removeEventListener('change', handleMediaChange);\n  }, []);\n\n  const trigger = React.Children.toArray(children).find(\n    (child: any) => child.type === ResponsiveModalTrigger\n  );\n  const content = React.Children.toArray(children).filter(\n    (child: any) => child.type !== ResponsiveModalTrigger\n  );\n\n  const desktopModal =\n    isDesktop && mounted\n      ? createPortal(\n          <AnimatePresence>\n            {open && (\n              <motion.div\n                initial={{ opacity: 0 }}\n                animate={{ opacity: 1 }}\n                exit={{ opacity: 0 }}\n                className='fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-xs cursor-zoom-out'\n                onClick={() => setOpen(false)}\n              >\n                <motion.div\n                  initial={{ scale: 0.9, opacity: 0 }}\n                  animate={{ scale: 1, opacity: 1 }}\n                  exit={{ scale: 0.9, opacity: 0 }}\n                  transition={{ type: 'spring', duration: 0.5 }}\n                  onClick={(e) => e.stopPropagation()}\n                  className={cn(\n                    'relative w-full max-w-md border bg-white dark:bg-neutral-900 rounded-lg cursor-default',\n                    classname\n                  )}\n                >\n                  <button\n                    className={cn(\n                      'absolute top-2 right-2 bg-primary text-background p-2 border z-1 rounded-md',\n                      clsBtnClassname\n                    )}\n                    onClick={() => setOpen(false)}\n                    aria-label='Close'\n                  >\n                    <X />\n                  </button>\n                  {content}\n                </motion.div>\n              </motion.div>\n            )}\n          </AnimatePresence>,\n          document.body\n        )\n      : null;\n\n  return (\n    <DrawerContext.Provider value={{ open, setOpen }}>\n      {trigger}\n\n      {desktopModal}\n\n      {!isDesktop && (\n        <VaulDrawer.Root shouldScaleBackground open={open} onOpenChange={setOpen}>\n          <VaulDrawer.Portal>\n            <VaulDrawer.Overlay className='fixed inset-0 z-50 bg-white/50 dark:bg-black/50 backdrop-blur-xs' />\n            <VaulDrawer.Content className='fixed bottom-0 left-0 z-50 w-full max-h-[96%] bg-white dark:bg-neutral-900'>\n              <div className='mx-auto w-16 h-[0.30rem] shrink-0 rounded-full bg-neutral-600 my-4' />\n              <div className='w-full mx-auto max-h-[96vh] overflow-auto px-4 pb-2'>{content}</div>\n            </VaulDrawer.Content>\n          </VaulDrawer.Portal>\n        </VaulDrawer.Root>\n      )}\n    </DrawerContext.Provider>\n  );\n}\n\nexport function ResponsiveModalContent({\n  children,\n  className,\n}: {\n  children: ReactNode;\n  className?: string;\n}) {\n  return <div className={cn('', className)}>{children}</div>;\n}\n\ninterface ResponsiveModalTriggerProps {\n  children: ReactNode;\n  asChild?: boolean;\n}\n\nexport function ResponsiveModalTrigger({ children, asChild = false }: ResponsiveModalTriggerProps) {\n  const { setOpen } = useResponsiveModal();\n\n  if (asChild) {\n    // Clone the child element and add onClick handler\n    const child = React.Children.only(children) as React.ReactElement<any>;\n    return React.cloneElement(child, {\n      ...child.props,\n      onClick: (e: React.MouseEvent) => {\n        setOpen(true);\n        // Call original onClick if it exists\n        child.props.onClick?.(e);\n      },\n    } as any);\n  }\n\n  return <div onClick={() => setOpen(true)}>{children}</div>;\n}\n",
      "type": "registry:component"
    }
  ],
  "type": "registry:component"
}