{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "drawer",
  "title": "Drawer",
  "dependencies": [
    "@base-ui/react",
    "lucide-react"
  ],
  "registryDependencies": [
    "@fab-ui/button"
  ],
  "files": [
    {
      "path": "registry/default/ui/drawer.tsx",
      "content": "'use client';\n\nimport * as React from 'react';\n\nimport { Drawer as DrawerPrimitive } from '@base-ui/react/drawer';\n\nimport { cn } from '@/lib/utils';\n\nfunction Drawer({\n  swipeDirection = 'down',\n  ...props\n}: DrawerPrimitive.Root.Props) {\n  return (\n    <DrawerPrimitive.Root\n      data-slot='drawer'\n      swipeDirection={swipeDirection}\n      {...props}\n    />\n  );\n}\n\nfunction DrawerTrigger({ ...props }: DrawerPrimitive.Trigger.Props) {\n  return <DrawerPrimitive.Trigger data-slot='drawer-trigger' {...props} />;\n}\n\nfunction DrawerClose({ ...props }: DrawerPrimitive.Close.Props) {\n  return <DrawerPrimitive.Close data-slot='drawer-close' {...props} />;\n}\n\nfunction DrawerProvider({ ...props }: DrawerPrimitive.Provider.Props) {\n  return <DrawerPrimitive.Provider data-slot='drawer-provider' {...props} />;\n}\n\nfunction DrawerPortal({\n  className,\n  ...props\n}: Omit<DrawerPrimitive.Portal.Props, 'className'> & {\n  className?: string;\n}) {\n  return (\n    <DrawerPrimitive.Portal\n      data-slot='drawer-portal'\n      className={cn('z-50', className)}\n      {...props}\n    />\n  );\n}\n\nfunction DrawerOverlay({\n  className,\n  ...props\n}: Omit<DrawerPrimitive.Backdrop.Props, 'className'> & {\n  className?: string;\n}) {\n  return (\n    <DrawerPrimitive.Backdrop\n      data-slot='drawer-overlay'\n      className={cn(\n        'fixed inset-0 min-h-dvh bg-black opacity-[calc(var(--backdrop-opacity)*(1-var(--drawer-swipe-progress)))] transition-opacity duration-300 ease-[cubic-bezier(0.32,0.72,0,1)] [--backdrop-opacity:0.2] data-ending-style:opacity-0 data-ending-style:duration-[calc(var(--drawer-swipe-strength)*300ms)] data-starting-style:opacity-0 data-swiping:duration-0 supports-backdrop-filter:backdrop-blur-3xl supports-[-webkit-touch-callout:none]:absolute dark:[--backdrop-opacity:0.7]',\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction DrawerViewport({\n  className,\n  ...props\n}: Omit<DrawerPrimitive.Viewport.Props, 'className'> & {\n  className?: string;\n}) {\n  return (\n    <DrawerPrimitive.Viewport\n      data-slot='drawer-viewport'\n      className={cn(\n        'fixed inset-0 flex',\n        // Horizontal: stretch + viewport padding\n        'has-data-[swipe-direction=left]:items-stretch has-data-[swipe-direction=left]:justify-start has-data-[swipe-direction=left]:p-(--viewport-padding)',\n        'has-data-[swipe-direction=right]:items-stretch has-data-[swipe-direction=right]:justify-end has-data-[swipe-direction=right]:p-(--viewport-padding)',\n        '[--viewport-padding:0px] supports-[-webkit-touch-callout:none]:[--viewport-padding:0.625rem]',\n        // Vertical: center horizontally, align to edge\n        'has-data-[swipe-direction=down]:items-end has-data-[swipe-direction=down]:justify-center',\n        'has-data-[swipe-direction=up]:items-start has-data-[swipe-direction=up]:justify-center',\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction DrawerHandle({ className, ...props }: React.ComponentProps<'div'>) {\n  return (\n    <div\n      data-slot='drawer-handle'\n      className={cn(\n        'mx-auto mb-5 h-1 w-12 shrink-0 rounded-full bg-muted transition-opacity duration-200 group-data-nested-drawer-open/popup:opacity-0 group-data-nested-drawer-swiping/popup:opacity-100',\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction DrawerContent({\n  className,\n  ...props\n}: Omit<DrawerPrimitive.Content.Props, 'className'> & {\n  className?: string;\n}) {\n  return (\n    <DrawerPrimitive.Content\n      data-slot='drawer-content'\n      className={cn(\n        'transition-opacity duration-300 ease-[cubic-bezier(0.45,1.005,0,1.005)] group-data-nested-drawer-open/popup:opacity-0 group-data-nested-drawer-swiping/popup:opacity-100',\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction DrawerPopup({\n  className,\n  children,\n  container,\n  showHandle,\n  unstyled,\n  overlayClassName,\n  ...props\n}: Omit<DrawerPrimitive.Popup.Props, 'className'> & {\n  className?: string;\n  container?: DrawerPrimitive.Portal.Props['container'];\n  showHandle?: boolean;\n  unstyled?: boolean;\n  overlayClassName?: string;\n}) {\n  return (\n    <DrawerPortal container={container}>\n      <DrawerOverlay className={overlayClassName} />\n      <DrawerViewport>\n        <DrawerPrimitive.Popup\n          data-slot='drawer-popup'\n          className={\n            unstyled\n              ? className\n              : cn(\n                  'group/popup relative',\n                  'touch-auto overflow-y-auto overscroll-contain bg-background text-foreground ring-1 ring-foreground/5 data-swiping:select-none dark:ring-border',\n                  'data-ending-style:duration-[calc(var(--drawer-swipe-strength)*300ms)]',\n                  // Nested drawer stacking variables (no-ops when not nested)\n                  '[--bleed:3rem] [--height:max(0px,calc(var(--drawer-frontmost-height,var(--drawer-height))-var(--bleed)))] [--peek:1rem] [--scale-base:calc(max(0,1-(var(--nested-drawers)*var(--stack-step))))] [--scale:clamp(0,calc(var(--scale-base)+(var(--stack-step)*var(--stack-progress))),1)] [--shrink:calc(1-var(--scale))] [--stack-peek-offset:max(0px,calc((var(--nested-drawers)-var(--stack-progress))*var(--peek)))] [--stack-progress:clamp(0,var(--drawer-swipe-progress),1)] [--stack-step:0.05]',\n                  // Nested drawer overlay (::after pseudo-element)\n                  \"after:pointer-events-none after:absolute after:inset-0 after:rounded-[inherit] after:bg-transparent after:transition-[background-color] after:duration-300 after:ease-[cubic-bezier(0.32,0.72,0,1)] after:content-['']\",\n                  // Nested drawer states\n                  'data-nested-drawer-open:overflow-hidden data-nested-drawer-open:after:bg-black/5 data-nested-drawer-swiping:duration-0',\n                  // Shared horizontal (left & right)\n                  'data-[swipe-direction=left]:supports-[-webkit-touch-callout:none]:[--bleed:0px] data-[swipe-direction=right]:supports-[-webkit-touch-callout:none]:[--bleed:0px]',\n                  'data-[swipe-direction=left]:h-full data-[swipe-direction=right]:h-full',\n                  'data-[swipe-direction=left]:w-[calc(22rem+var(--bleed))] data-[swipe-direction=right]:w-[calc(22rem+var(--bleed))]',\n                  'data-[swipe-direction=left]:max-w-[calc(100vw-3rem+var(--bleed))] data-[swipe-direction=right]:max-w-[calc(100vw-3rem+var(--bleed))]',\n                  'data-[swipe-direction=left]:p-6 data-[swipe-direction=right]:p-6',\n                  'data-[swipe-direction=left]:supports-[-webkit-touch-callout:none]:w-[20rem] data-[swipe-direction=right]:supports-[-webkit-touch-callout:none]:w-[20rem]',\n                  'data-[swipe-direction=left]:supports-[-webkit-touch-callout:none]:max-w-[calc(100vw-20px)] data-[swipe-direction=right]:supports-[-webkit-touch-callout:none]:max-w-[calc(100vw-20px)]',\n                  'data-[swipe-direction=left]:supports-[-webkit-touch-callout:none]:rounded-[10px] data-[swipe-direction=right]:supports-[-webkit-touch-callout:none]:rounded-[10px]',\n                  // Right-only (with stacking transform + transition for box-shadow)\n                  'data-[swipe-direction=right]:-mr-(--bleed) data-[swipe-direction=right]:origin-[calc(100%-var(--bleed))_50%] data-[swipe-direction=right]:transform-[translateX(calc(var(--drawer-snap-point-offset,0px)+var(--drawer-swipe-movement-x)-var(--stack-peek-offset)-(var(--shrink)*100%)))_scale(var(--scale))] data-[swipe-direction=right]:rounded-l-xl data-[swipe-direction=right]:pr-[calc(1.5rem+var(--bleed))] data-[swipe-direction=right]:shadow-[-2px_0_10px_rgb(0_0_0/0.1)] data-[swipe-direction=right]:[transition:transform_300ms_cubic-bezier(0.32,0.72,0,1),box-shadow_300ms_cubic-bezier(0.32,0.72,0,1)] data-[swipe-direction=right]:data-ending-style:shadow-[-2px_0_10px_rgb(0_0_0/0)] data-[swipe-direction=right]:data-swiping:duration-0 data-[swipe-direction=right]:supports-[-webkit-touch-callout:none]:mr-0 data-[swipe-direction=right]:supports-[-webkit-touch-callout:none]:pr-6',\n                  // Right enter/exit\n                  'data-[swipe-direction=right]:data-ending-style:transform-[translateX(calc(100%-var(--bleed)+var(--viewport-padding)))] data-[swipe-direction=right]:data-starting-style:transform-[translateX(calc(100%-var(--bleed)+var(--viewport-padding)))]',\n                  // Left-only (with stacking transform + transition for box-shadow)\n                  'data-[swipe-direction=left]:-ml-(--bleed) data-[swipe-direction=left]:origin-[var(--bleed)_50%] data-[swipe-direction=left]:transform-[translateX(calc(var(--drawer-snap-point-offset,0px)+var(--drawer-swipe-movement-x)+var(--stack-peek-offset)+(var(--shrink)*100%)))_scale(var(--scale))] data-[swipe-direction=left]:rounded-r-xl data-[swipe-direction=left]:pl-[calc(1.5rem+var(--bleed))] data-[swipe-direction=left]:shadow-[2px_0_10px_rgb(0_0_0/0.1)] data-[swipe-direction=left]:[transition:transform_300ms_cubic-bezier(0.32,0.72,0,1),box-shadow_300ms_cubic-bezier(0.32,0.72,0,1)] data-[swipe-direction=left]:data-ending-style:shadow-[2px_0_10px_rgb(0_0_0/0)] data-[swipe-direction=left]:data-swiping:duration-0 data-[swipe-direction=left]:supports-[-webkit-touch-callout:none]:ml-0 data-[swipe-direction=left]:supports-[-webkit-touch-callout:none]:pl-6',\n                  // Left enter/exit\n                  'data-[swipe-direction=left]:data-ending-style:transform-[translateX(calc(-100%+var(--bleed)-var(--viewport-padding)))] data-[swipe-direction=left]:data-starting-style:transform-[translateX(calc(-100%+var(--bleed)-var(--viewport-padding)))]',\n                  // Shared vertical (up & down)\n                  'data-[swipe-direction=down]:w-full data-[swipe-direction=up]:w-full',\n                  'data-[swipe-direction=down]:max-h-[calc(80vh+var(--bleed))] data-[swipe-direction=up]:max-h-[calc(80vh+var(--bleed))]',\n                  'data-[swipe-direction=down]:px-6 data-[swipe-direction=up]:px-6',\n                  // Down-only (with stacking transform + transitions for height & box-shadow)\n                  'data-[swipe-direction=down]:-mb-(--bleed) data-[swipe-direction=down]:h-(--drawer-height,auto) data-[swipe-direction=down]:origin-[50%_calc(100%-var(--bleed))] data-[swipe-direction=down]:transform-[translateY(calc(var(--drawer-snap-point-offset,0px)+var(--drawer-swipe-movement-y)-var(--stack-peek-offset)-(var(--shrink)*var(--height))))_scale(var(--scale))] data-[swipe-direction=down]:rounded-t-xl data-[swipe-direction=down]:pt-4 data-[swipe-direction=down]:pb-[calc(1.5rem+env(safe-area-inset-bottom,0px)+var(--bleed))] data-[swipe-direction=down]:shadow-[0_2px_10px_rgb(0_0_0/0.1)] data-[swipe-direction=down]:[transition:transform_300ms_cubic-bezier(0.32,0.72,0,1),height_300ms_cubic-bezier(0.32,0.72,0,1),box-shadow_300ms_cubic-bezier(0.32,0.72,0,1)] data-[swipe-direction=down]:data-ending-style:shadow-[0_2px_10px_rgb(0_0_0/0)] data-[swipe-direction=down]:data-nested-drawer-open:h-[calc(var(--height)+var(--bleed))] data-[swipe-direction=down]:data-swiping:duration-0',\n                  // Down enter/exit\n                  'data-[swipe-direction=down]:data-ending-style:transform-[translateY(calc(100%-var(--bleed)))] data-[swipe-direction=down]:data-starting-style:transform-[translateY(calc(100%-var(--bleed)))]',\n                  // Up-only (with stacking transform + transitions for height & box-shadow)\n                  'data-[swipe-direction=up]:-mt-(--bleed) data-[swipe-direction=up]:h-(--drawer-height,auto) data-[swipe-direction=up]:origin-[50%_var(--bleed)] data-[swipe-direction=up]:transform-[translateY(calc(var(--drawer-snap-point-offset,0px)+var(--drawer-swipe-movement-y)+var(--stack-peek-offset)+(var(--shrink)*var(--height))))_scale(var(--scale))] data-[swipe-direction=up]:rounded-b-xl data-[swipe-direction=up]:pt-[calc(1.5rem+env(safe-area-inset-top,0px)+var(--bleed))] data-[swipe-direction=up]:pb-6 data-[swipe-direction=up]:shadow-[0_-2px_10px_rgb(0_0_0/0.1)] data-[swipe-direction=up]:[transition:transform_300ms_cubic-bezier(0.32,0.72,0,1),height_300ms_cubic-bezier(0.32,0.72,0,1),box-shadow_300ms_cubic-bezier(0.32,0.72,0,1)] data-[swipe-direction=up]:data-ending-style:shadow-[0_-2px_10px_rgb(0_0_0/0)] data-[swipe-direction=up]:data-nested-drawer-open:h-[calc(var(--height)+var(--bleed))] data-[swipe-direction=up]:data-swiping:duration-0',\n                  // Up enter/exit\n                  'data-[swipe-direction=up]:data-ending-style:transform-[translateY(calc(-100%+var(--bleed)))] data-[swipe-direction=up]:data-starting-style:transform-[translateY(calc(-100%+var(--bleed)))]',\n                  className\n                )\n          }\n          {...props}\n        >\n          {!unstyled && showHandle !== false && (\n            <DrawerHandle\n              className={\n                showHandle\n                  ? undefined\n                  : 'hidden group-data-[swipe-direction=down]/popup:block group-data-[swipe-direction=up]/popup:block'\n              }\n            />\n          )}\n          {children}\n        </DrawerPrimitive.Popup>\n      </DrawerViewport>\n    </DrawerPortal>\n  );\n}\n\nfunction DrawerHeader({ className, ...props }: React.ComponentProps<'div'>) {\n  return (\n    <div\n      data-slot='drawer-header'\n      className={cn('flex flex-col gap-2', className)}\n      {...props}\n    />\n  );\n}\n\nfunction DrawerFooter({ className, ...props }: React.ComponentProps<'div'>) {\n  return (\n    <div\n      data-slot='drawer-footer'\n      className={cn(\n        'mt-4 flex flex-col-reverse gap-2 sm:flex-row sm:justify-end',\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction DrawerTitle({\n  className,\n  ...props\n}: Omit<DrawerPrimitive.Title.Props, 'className'> & {\n  className?: string;\n}) {\n  return (\n    <DrawerPrimitive.Title\n      data-slot='drawer-title'\n      className={cn(\n        'text-base font-medium text-foreground group-data-[swipe-direction=down]/popup:text-center group-data-[swipe-direction=up]/popup:text-center',\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction DrawerDescription({\n  className,\n  ...props\n}: Omit<DrawerPrimitive.Description.Props, 'className'> & {\n  className?: string;\n}) {\n  return (\n    <DrawerPrimitive.Description\n      data-slot='drawer-description'\n      className={cn(\n        'mt-1.5 text-sm text-muted-foreground group-data-[swipe-direction=down]/popup:text-center group-data-[swipe-direction=up]/popup:text-center',\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction DrawerIndentBackground({\n  className,\n  ...props\n}: DrawerPrimitive.IndentBackground.Props) {\n  return (\n    <DrawerPrimitive.IndentBackground\n      data-slot='drawer-indent-background'\n      className='absolute inset-0 isolate bg-foreground/70'\n      {...props}\n    />\n  );\n}\n\nfunction DrawerIndent({\n  className,\n  ...props\n}: Omit<DrawerPrimitive.Indent.Props, 'className'> & {\n  className?: string;\n}) {\n  return (\n    <DrawerPrimitive.Indent\n      data-slot='drawer-indent'\n      className={cn(\n        'relative origin-[center_top] transform-[scale(1)_translateY(0)] border bg-background p-4 duration-[calc(400ms*var(--indent-transition)),calc(250ms*var(--indent-transition))] will-change-transform [--indent-progress:var(--drawer-swipe-progress)] [--indent-radius:calc(1rem*(1-var(--indent-progress)))] [--indent-transition:calc(1-clamp(0,calc(var(--drawer-swipe-progress)*100000),1))] [transition:transform_0.4s_cubic-bezier(0.32,0.72,0,1),border-radius_0.25s_cubic-bezier(0.32,0.72,0,1)] data-active:transform-[scale(calc(0.98+(0.02*var(--indent-progress))))_translateY(calc(0.5rem*(1-var(--indent-progress))))] data-active:rounded-tl-(--indent-radius) data-active:rounded-tr-(--indent-radius)',\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nconst createDrawerHandle = DrawerPrimitive.createHandle;\n\nexport {\n  Drawer,\n  DrawerClose,\n  DrawerContent,\n  DrawerDescription,\n  DrawerFooter,\n  DrawerHandle,\n  DrawerHeader,\n  DrawerIndent,\n  DrawerIndentBackground,\n  DrawerOverlay,\n  DrawerPopup,\n  DrawerPortal,\n  DrawerProvider,\n  DrawerTitle,\n  DrawerTrigger,\n  DrawerViewport,\n  createDrawerHandle,\n};\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}