{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "bottom-directional-drawer",
  "dependencies": [
    "motion",
    "lucide-react"
  ],
  "devDependencies": [],
  "registryDependencies": [],
  "files": [
    {
      "path": "./components/ui/directional-drawer.tsx",
      "content": "'use client';\nimport { cn } from '@/lib/utils';\nimport { X } from 'lucide-react';\nimport React, { createContext, type ReactNode, useContext, useEffect, useState } from 'react';\nimport { Drawer as VaulSidebar } from 'vaul';\n\ninterface DrawerContextProps {\n  open: boolean;\n  setOpen: (open: boolean) => void;\n}\n\nconst DrawerContext = createContext<DrawerContextProps | undefined>(undefined);\n\nexport const useDirectionalDrawer = () => {\n  const context = useContext(DrawerContext);\n  if (!context) {\n    throw new Error('useDirectionalDrawer must be used within a DirectionalDrawer');\n  }\n  return context;\n};\n\ninterface DirectionalDrawerProps {\n  children: ReactNode;\n  open?: boolean;\n  setOpen?: (open: boolean) => void;\n  direction?: 'left' | 'right' | 'top' | 'bottom';\n  outsideClose?: boolean;\n  className?: string;\n}\n\nexport function DirectionalDrawer({\n  children,\n  open: controlledOpen,\n  setOpen: controlledSetOpen,\n  direction = 'left',\n  outsideClose = true,\n  className,\n}: DirectionalDrawerProps) {\n  const [internalOpen, setInternalOpen] = useState(false);\n  const [isDesktop, setIsDesktop] = useState(false);\n\n  const open = controlledOpen !== undefined ? controlledOpen : internalOpen;\n  const setOpen = controlledSetOpen || setInternalOpen;\n\n  useEffect(() => {\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\n    return () => {\n      mediaQuery.removeEventListener('change', handleMediaChange);\n    };\n  }, []);\n\n  const trigger = React.Children.toArray(children).find(\n    (child: any) => child.type === DrawerTrigger\n  );\n  const content = React.Children.toArray(children).filter(\n    (child: any) => child.type !== DrawerTrigger\n  );\n\n  // Helper function to get positioning and sizing classes\n  const getDirectionClasses = () => {\n    switch (direction) {\n      case 'right':\n        return {\n          position: 'right-0 bottom-0',\n          size: outsideClose ? 'sm:w-[450px] w-[90%] h-full' : 'w-full h-full',\n          border: 'border-l',\n          handlePosition: 'top-[40%] left-2',\n          handleSize: 'h-16 w-[0.30rem]',\n        };\n      case 'top':\n        return {\n          position: 'top-0 left-0',\n          size: outsideClose ? 'w-full sm:h-[450px] h-[90%]' : 'w-full h-full',\n          border: 'border-b',\n          handlePosition: 'bottom-2 left-[40%]',\n          handleSize: 'w-16 h-[0.30rem]',\n        };\n      case 'bottom':\n        return {\n          position: 'bottom-0 left-0',\n          size: outsideClose ? 'w-full sm:h-[450px] h-[90%]' : 'w-full h-full',\n          border: 'border-t',\n          handlePosition: 'top-2 left-[40%]',\n          handleSize: 'w-16 h-[0.30rem]',\n        };\n      case 'left':\n      default:\n        return {\n          position: 'left-0 bottom-0',\n          size: outsideClose ? 'sm:w-[450px] w-[90%] h-full' : 'w-full h-full',\n          border: 'border-r',\n          handlePosition: 'top-[40%] right-2',\n          handleSize: 'h-16 w-[0.30rem]',\n        };\n    }\n  };\n\n  const directionClasses = getDirectionClasses();\n  const vaulDirection =\n    direction === 'right'\n      ? 'right'\n      : direction === 'top'\n        ? 'top'\n        : direction === 'bottom'\n          ? 'bottom'\n          : 'left';\n\n  return (\n    <DrawerContext.Provider value={{ open, setOpen }}>\n      {trigger}\n\n      <VaulSidebar.Root\n        open={open}\n        direction={vaulDirection}\n        onOpenChange={setOpen}\n        dismissible={isDesktop ? false : true}\n      >\n        <VaulSidebar.Portal>\n          <VaulSidebar.Overlay\n            className='fixed inset-0 dark:bg-black/40 bg-white/50 backdrop-blur-xs z-50'\n            onClick={() => setOpen(false)}\n          />\n          <VaulSidebar.Content\n            className={cn(\n              `${directionClasses.border} z-50 ${directionClasses.size} fixed ${directionClasses.position} ${\n                outsideClose ? 'dark:bg-zinc-950 bg-zinc-100' : ''\n              }`,\n              className\n            )}\n          >\n            <div\n              className={`${\n                outsideClose\n                  ? 'w-full h-full'\n                  : `dark:bg-neutral-900 relative bg-white ${directionClasses.border} ${directionClasses.size}`\n              }`}\n            >\n              {isDesktop ? (\n                <button\n                  className='flex justify-end w-full absolute right-2 top-2'\n                  onClick={() => setOpen(false)}\n                >\n                  <X />\n                </button>\n              ) : (\n                <div\n                  className={`absolute ${directionClasses.handlePosition} mx-auto ${directionClasses.handleSize} shrink-0 rounded-full bg-neutral-600 my-4`}\n                />\n              )}\n              {content}\n            </div>\n          </VaulSidebar.Content>\n        </VaulSidebar.Portal>\n      </VaulSidebar.Root>\n    </DrawerContext.Provider>\n  );\n}\n\nexport function DrawerContent({\n  children,\n  className,\n}: {\n  children: ReactNode;\n  className?: string;\n}) {\n  return <div className={cn('', className)}>{children}</div>;\n}\n\nexport function DrawerTrigger({ children }: { children: ReactNode }) {\n  const { setOpen } = useDirectionalDrawer();\n  return <div onClick={() => setOpen(true)}>{children}</div>;\n}\n",
      "type": "registry:component"
    },
    {
      "path": "./registry/components/drawer/bottom-directional-drawer.tsx",
      "content": "'use client';\nimport {\n  DirectionalDrawer,\n  DrawerContent,\n  DrawerTrigger,\n} from '@/components/ui/directional-drawer';\nimport { useMediaQuery } from '@/hooks/use-media-query';\nimport { Edit, X } from 'lucide-react';\nimport { motion } from 'motion/react';\nimport Image from 'next/image';\nimport { useState } from 'react';\nimport { Drawer } from 'vaul';\nexport default function BottomDirectionalDrawer() {\n  const [sidebarOpen, setSidebarOpen] = useState(false);\n  return (\n    <>\n      <DirectionalDrawer\n        open={sidebarOpen}\n        setOpen={setSidebarOpen}\n        direction={'bottom'}\n        outsideClose={true}\n      >\n        <DrawerContent className='w-full h-full flex justify-end'>\n          <div className='p-5 rounded-t-md grow w-full pt-14'>\n            <h1 className='font-medium  text-2xl'>Update Profile Image</h1>\n            <p className='text-sm text-muted-foreground'>\n              Upload a new profile image or remove the current one.\n            </p>\n            <div className='p-2 space-y-4 '>\n              <span className='relative flex justify-center overflow-hidden rounded-xl w-full '>\n                <span className='grid place-content-center h-40  w-40 rounded-xl dark:bg-neutral-800 bg-muted'>\n                  JP\n                </span>\n              </span>\n              <div className='mb-3'>\n                <input\n                  className='w-full border file:p-2 file:bg-black  file:border-none  file:text-white rounded-xs overflow-hidden'\n                  type='file'\n                  id='formFile'\n                />\n              </div>\n              <button\n                type='submit'\n                className='w-full rounded-xs dark:bg-white bg-black  p-2 dark:text-black text-white'\n              >\n                Submit\n              </button>\n            </div>\n          </div>\n        </DrawerContent>\n      </DirectionalDrawer>\n      <div className='flex justify-center'>\n        <figure className='h-96 w-96 relative'>\n          <Image\n            src={'/myself.webp'}\n            width={600}\n            height={600}\n            className='h-full w-full object-cover rounded-lg '\n            alt='profile_image'\n          />\n          <motion.button\n            whileTap={{ scale: 0.8 }}\n            onClick={() => setSidebarOpen(true)}\n            className='absolute left-2 bottom-2 p-4 dark:bg-black bg-white rounded-lg shadow-black'\n          >\n            <Edit />\n          </motion.button>\n        </figure>\n      </div>\n    </>\n  );\n}\n",
      "type": "registry:component"
    }
  ],
  "type": "registry:component"
}