{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "drawer",
  "type": "registry:ui",
  "title": "Drawer",
  "description": "Mobile-first bottom drawer with drag-to-dismiss physics (Vaul). The touch-friendly Sheet.",
  "dependencies": [
    "@saasflare/ui",
    "vaul"
  ],
  "files": [
    {
      "path": "components/ui/drawer.tsx",
      "type": "registry:ui",
      "content": "// @toreview\n\"use client\"\n\n/**\n * @fileoverview Drawer — slide-in panel powered by Vaul with touch-gesture support.\n * @module packages/ui/components/ui/drawer\n * @layer core\n *\n * Self-contained implementation built on the Vaul drawer primitive. Provides\n * a mobile-friendly slide-up panel with drag-to-dismiss gesture, overlay\n * backdrop, and composable header/footer/content slots.\n *\n * @requires vaul — peer dependency.\n *\n * @component\n * @example\n * import { Drawer, DrawerTrigger, DrawerContent, DrawerHeader, DrawerTitle } from \"@saasflare/ui\";\n *\n * <Drawer>\n *   <DrawerTrigger asChild><Button>Open Drawer</Button></DrawerTrigger>\n *   <DrawerContent>\n *     <DrawerHeader><DrawerTitle>Settings</DrawerTitle></DrawerHeader>\n *   </DrawerContent>\n * </Drawer>\n */\n\nimport * as React from \"react\"\nimport { Drawer as DrawerPrimitive } from \"vaul\"\nimport { cn } from \"@saasflare/ui\"\nimport { useSaasflareProps, type SaasflareComponentProps } from \"@saasflare/ui\"\n\n/** Root drawer state container; orchestrates open state and gesture context. */\nfunction Drawer({\n  ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Root>) {\n  return <DrawerPrimitive.Root data-slot=\"drawer\" {...props} />\n}\n\n/** Interactive element that toggles the drawer open. Use `asChild` to wrap a custom control. */\nfunction DrawerTrigger({\n  ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Trigger>) {\n  return <DrawerPrimitive.Trigger data-slot=\"drawer-trigger\" {...props} />\n}\n\n/** Portals drawer content (overlay + panel) outside the DOM hierarchy. */\nfunction DrawerPortal({\n  ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Portal>) {\n  return <DrawerPrimitive.Portal data-slot=\"drawer-portal\" {...props} />\n}\n\n/** Element that closes the drawer when activated. Use `asChild` to wrap a custom control. */\nfunction DrawerClose({\n  ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Close>) {\n  return <DrawerPrimitive.Close data-slot=\"drawer-close\" {...props} />\n}\n\n/** Dimmed backdrop rendered behind the drawer panel. */\nfunction DrawerOverlay({\n  className,\n  ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Overlay>) {\n  return (\n    <DrawerPrimitive.Overlay\n      data-slot=\"drawer-overlay\"\n      className={cn(\n        \"fixed inset-0 z-50 bg-black/50 backdrop-blur-[2px]\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\n/** Props for {@link DrawerContent}; adds the surface/radius/animated design-system axes. */\ninterface DrawerContentProps\n  extends Omit<React.ComponentProps<typeof DrawerPrimitive.Content>, keyof SaasflareComponentProps>,\n    SaasflareComponentProps {}\n\n/** Sliding panel surface that holds the drawer body; carries the surface/radius/animated axes. */\nfunction DrawerContent({\n  className,\n  children,\n  surface,\n  radius,\n  animated,\n  iconWeight,\n  ...props\n}: DrawerContentProps) {\n  const sf = useSaasflareProps({ surface, radius, animated, iconWeight })\n\n  return (\n    <DrawerPortal>\n      <DrawerOverlay />\n      <DrawerPrimitive.Content\n        {...props}\n        data-slot=\"drawer-content\"\n        data-surface={sf.surface}\n        data-radius={sf.radius}\n        data-animated={String(sf.animated)}\n        className={cn(\n          \"group/drawer-content fixed inset-x-0 bottom-0 z-50 mt-24 flex max-h-[96dvh] flex-col rounded-t-lg border-t surface-card\",\n          className\n        )}\n      >\n        <div className=\"mx-auto mt-4 h-1.5 w-12 shrink-0 rounded-full bg-muted\" />\n        {children}\n      </DrawerPrimitive.Content>\n    </DrawerPortal>\n  )\n}\n\n/** Vertical layout slot for the drawer's title and description. */\nfunction DrawerHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"drawer-header\"\n      className={cn(\"flex flex-col gap-1.5 p-4\", className)}\n      {...props}\n    />\n  )\n}\n\n/** Bottom-pinned layout slot for drawer actions. */\nfunction DrawerFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"drawer-footer\"\n      className={cn(\"mt-auto flex flex-col gap-2 p-4\", className)}\n      {...props}\n    />\n  )\n}\n\n/** Accessible heading for the drawer, announced to assistive technology. */\nfunction DrawerTitle({\n  className,\n  ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Title>) {\n  return (\n    <DrawerPrimitive.Title\n      data-slot=\"drawer-title\"\n      className={cn(\"text-lg leading-none font-semibold\", className)}\n      {...props}\n    />\n  )\n}\n\n/** Supporting descriptive text for the drawer, associated with the title for accessibility. */\nfunction DrawerDescription({\n  className,\n  ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Description>) {\n  return (\n    <DrawerPrimitive.Description\n      data-slot=\"drawer-description\"\n      className={cn(\"text-sm text-muted-foreground\", className)}\n      {...props}\n    />\n  )\n}\n\nexport {\n  Drawer,\n  DrawerClose,\n  DrawerContent,\n  DrawerDescription,\n  DrawerFooter,\n  DrawerHeader,\n  DrawerOverlay,\n  DrawerPortal,\n  DrawerTitle,\n  DrawerTrigger,\n  type DrawerContentProps,\n}\n",
      "target": "components/ui/drawer.tsx"
    }
  ],
  "$meta": {
    "source": "https://ui.saasflare.io/r/drawer.json"
  }
}
