{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "drawer",
  "title": "Drawer",
  "description": "A panel that slides in from the edge of the screen.",
  "dependencies": [
    "@base-ui/react",
    "class-variance-authority"
  ],
  "registryDependencies": [
    "utils",
    "@lumi-ui/button"
  ],
  "files": [
    {
      "path": "registry/ui/drawer.tsx",
      "content": "\"use client\";\n\nimport { Drawer as BaseDrawer } from \"@base-ui/react/drawer\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport type * as React from \"react\";\nimport { cn } from \"@/registry/lib/utils\";\n\nfunction DrawerProvider({ ...props }: BaseDrawer.Provider.Props) {\n  return <BaseDrawer.Provider data-slot=\"drawer-provider\" {...props} />;\n}\n\nfunction DrawerIndent({ className, ...props }: BaseDrawer.Indent.Props) {\n  return (\n    <BaseDrawer.Indent\n      className={cn(\n        \"drawer-indent relative bg-background text-foreground min-h-svh\",\n        className,\n      )}\n      data-slot=\"drawer-indent\"\n      {...props}\n    />\n  );\n}\n\nfunction DrawerIndentBackground({\n  className,\n  ...props\n}: BaseDrawer.IndentBackground.Props) {\n  return (\n    <BaseDrawer.IndentBackground\n      className={cn(\"absolute inset-0 bg-foreground/10\", className)}\n      data-slot=\"drawer-indent-background\"\n      {...props}\n    />\n  );\n}\n\nfunction Drawer<Payload>(props: BaseDrawer.Root.Props<Payload>) {\n  return <BaseDrawer.Root data-slot=\"drawer\" {...props} />;\n}\n\nfunction DrawerTrigger<Payload>({\n  className,\n  ...props\n}: BaseDrawer.Trigger.Props<Payload>) {\n  return (\n    <BaseDrawer.Trigger\n      className={className}\n      data-slot=\"drawer-trigger\"\n      {...props}\n    />\n  );\n}\n\nfunction DrawerSwipeArea({ className, ...props }: BaseDrawer.SwipeArea.Props) {\n  return (\n    <BaseDrawer.SwipeArea\n      className={cn(\"fixed\", className)}\n      data-slot=\"drawer-swipe-area\"\n      {...props}\n    />\n  );\n}\n\nfunction DrawerPortal({ ...props }: BaseDrawer.Portal.Props) {\n  return <BaseDrawer.Portal data-slot=\"drawer-portal\" {...props} />;\n}\n\nfunction DrawerBackdrop({ className, ...props }: BaseDrawer.Backdrop.Props) {\n  return (\n    <BaseDrawer.Backdrop\n      className={cn(\n        \"fixed inset-0 min-h-dvh transition-opacity bg-black/20 backdrop-blur-sm\",\n        \"opacity-[calc(0.6*(1-var(--drawer-swipe-progress)))]\",\n        \"duration-450 ease-[cubic-bezier(0.32,0.72,0,1)]\",\n        \"data-[swiping]:duration-0\",\n        \"data-[starting-style]:opacity-0 data-[ending-style]:opacity-0\",\n        \"data-[ending-style]:duration-[calc(var(--drawer-swipe-strength)*400ms)]\",\n        \"supports-[-webkit-touch-callout:none]:absolute\",\n        className,\n      )}\n      data-slot=\"drawer-backdrop\"\n      {...props}\n    />\n  );\n}\n\nfunction DrawerViewport({ className, ...props }: BaseDrawer.Viewport.Props) {\n  return (\n    <BaseDrawer.Viewport\n      className={cn(\"group fixed inset-0\", className)}\n      data-slot=\"drawer-viewport\"\n      {...props}\n    />\n  );\n}\n\nfunction DrawerPopup({\n  className,\n  children,\n  ...props\n}: BaseDrawer.Popup.Props) {\n  return (\n    <BaseDrawer.Popup\n      className={cn(\"group bg-background text-foreground\", className)}\n      data-slot=\"drawer-popup\"\n      {...props}\n    >\n      {children}\n    </BaseDrawer.Popup>\n  );\n}\n\nfunction DrawerSelectable({ className, ...props }: BaseDrawer.Content.Props) {\n  return (\n    <BaseDrawer.Content\n      className={cn(\n        \"mx-auto w-full flex flex-col gap-4 *:data-[slot=scroll-area-root]:min-h-0\",\n        className,\n      )}\n      data-slot=\"drawer-selectable\"\n      {...props}\n    />\n  );\n}\n\nfunction DrawerTitle({ className, ...props }: BaseDrawer.Title.Props) {\n  return (\n    <BaseDrawer.Title\n      className={cn(\"text-lg font-semibold\", className)}\n      data-slot=\"drawer-title\"\n      {...props}\n    />\n  );\n}\n\nfunction DrawerDescription({\n  className,\n  ...props\n}: BaseDrawer.Description.Props) {\n  return (\n    <BaseDrawer.Description\n      className={cn(\"text-muted-foreground text-sm\", className)}\n      data-slot=\"drawer-description\"\n      {...props}\n    />\n  );\n}\n\nfunction DrawerClose({ className, ...props }: BaseDrawer.Close.Props) {\n  return (\n    <BaseDrawer.Close\n      className={cn(\"select-none\", className)}\n      data-slot=\"drawer-close\"\n      {...props}\n    />\n  );\n}\n\nfunction DrawerHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      className={cn(\n        \"flex flex-col gap-0.5 md:gap-1 group-data-[side=bottom]/drawer-content:text-center\",\n        className,\n      )}\n      data-slot=\"drawer-header\"\n      {...props}\n    />\n  );\n}\n\nfunction DrawerFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      className={cn(\"flex flex-col gap-2 mt-auto\", className)}\n      data-slot=\"drawer-footer\"\n      {...props}\n    />\n  );\n}\n\nfunction DrawerDragHandle({\n  className,\n  stacked,\n  ...props\n}: React.ComponentProps<\"div\"> & { stacked?: boolean }) {\n  return (\n    <div\n      className={cn(\n        \"w-12 h-1 flex-none mx-auto rounded-full bg-muted\",\n        stacked &&\n          \"transition-opacity duration-200 group-data-[nested-drawer-open]/popup:opacity-0 group-data-[nested-drawer-swiping]/popup:opacity-100\",\n        className,\n      )}\n      data-slot=\"drawer-drag-handle\"\n      {...props}\n    />\n  );\n}\n\ntype DrawerLayout = \"fullBleed\" | \"inset\" | \"responsive\";\n\nconst viewportVariants = cva(\"fixed inset-0 flex\", {\n  defaultVariants: {\n    side: \"bottom\",\n    layout: \"fullBleed\",\n  },\n  variants: {\n    side: {\n      bottom: \"items-end justify-center\",\n      left: \"items-stretch justify-start\",\n      right: \"items-stretch justify-end\",\n      top: \"items-start justify-center\",\n    },\n    layout: {\n      fullBleed: \"\",\n      inset: \"\",\n      responsive: \"\",\n    },\n  },\n  compoundVariants: [\n    { side: \"right\", layout: \"inset\", class: \"p-4 sm:p-6\" },\n    { side: \"right\", layout: \"responsive\", class: \"p-4 sm:p-0\" },\n    { side: \"bottom\", layout: \"inset\", class: \"p-4 sm:p-6\" },\n    { side: \"bottom\", layout: \"responsive\", class: \"p-4 sm:p-0\" },\n    { side: \"top\", layout: \"inset\", class: \"p-4 sm:p-6\" },\n    { side: \"top\", layout: \"responsive\", class: \"p-4 sm:p-0\" },\n    { side: \"left\", layout: \"inset\", class: \"p-4 sm:p-6\" },\n    { side: \"left\", layout: \"responsive\", class: \"p-4 sm:p-0\" },\n  ],\n});\n\nconst popupVariants = cva(\n  cn(\n    \"relative flex flex-col gap-2 bg-background text-foreground outline outline-border\",\n    \"drawer-popup overflow-y-auto overscroll-contain group/drawer-content *:data-[slot=scroll-area-root]:min-h-0\",\n  ),\n  {\n    defaultVariants: {\n      side: \"bottom\",\n      layout: \"fullBleed\",\n    },\n    variants: {\n      side: {\n        bottom: cn(\n          \"w-full h-auto\",\n          \"px-4 pt-2 pb-[calc(1rem+env(safe-area-inset-bottom,0px)+var(--drawer-bleed))]\",\n          \"sm:px-6 sm:pt-4 sm:pb-[calc(1.5rem+env(safe-area-inset-bottom,0px)+var(--drawer-bleed))]\",\n        ),\n        left: cn(\"p-4 sm:p-6\"),\n        right: cn(\"p-4 sm:p-6\"),\n        top: cn(\n          \"w-full h-auto\",\n          \"px-4 pb-4 pt-[calc(1rem+env(safe-area-inset-top,0px)+var(--drawer-bleed))]\",\n          \"sm:px-6 sm:pb-6 sm:pt-[calc(1.5rem+env(safe-area-inset-top,0px)+var(--drawer-bleed))]\",\n        ),\n      },\n      layout: {\n        fullBleed: \"\",\n        inset: \"\",\n        responsive: \"\",\n      },\n    },\n    compoundVariants: [\n      { side: \"right\", layout: \"fullBleed\", class: \"rounded-none\" },\n      { side: \"right\", layout: \"inset\", class: \"rounded-2xl\" },\n      {\n        side: \"right\",\n        layout: \"responsive\",\n        class: \"rounded-2xl sm:rounded-none\",\n      },\n      { side: \"bottom\", layout: \"fullBleed\", class: \"rounded-t-2xl\" },\n      { side: \"bottom\", layout: \"inset\", class: \"rounded-2xl\" },\n      {\n        side: \"bottom\",\n        layout: \"responsive\",\n        class: \"rounded-2xl sm:rounded-b-none\",\n      },\n      { side: \"top\", layout: \"fullBleed\", class: \"rounded-b-2xl\" },\n      { side: \"top\", layout: \"inset\", class: \"rounded-2xl\" },\n      {\n        side: \"top\",\n        layout: \"responsive\",\n        class: \"rounded-2xl sm:rounded-t-none\",\n      },\n      { side: \"left\", layout: \"fullBleed\", class: \"rounded-none\" },\n      { side: \"left\", layout: \"inset\", class: \"rounded-2xl\" },\n      {\n        side: \"left\",\n        layout: \"responsive\",\n        class: \"rounded-2xl sm:rounded-none\",\n      },\n    ],\n  },\n);\n\nfunction DrawerContent({\n  className,\n  children,\n  side = \"bottom\",\n  layout = \"fullBleed\",\n  ...props\n}: BaseDrawer.Popup.Props &\n  Omit<VariantProps<typeof popupVariants>, \"layout\"> & {\n    layout?: DrawerLayout;\n  }) {\n  return (\n    <DrawerPortal>\n      <DrawerBackdrop />\n      <BaseDrawer.Viewport\n        className={viewportVariants({ side, layout })}\n        data-side={side}\n        data-slot=\"drawer-viewport\"\n      >\n        <BaseDrawer.Popup\n          className={cn(popupVariants({ side, layout }), className)}\n          data-layout={layout}\n          data-side={side}\n          data-slot=\"drawer-content\"\n          {...props}\n        >\n          {children}\n        </BaseDrawer.Popup>\n      </BaseDrawer.Viewport>\n    </DrawerPortal>\n  );\n}\n\nfunction SnapDrawerContent({\n  className,\n  children,\n  layout = \"fullBleed\",\n  ...props\n}: BaseDrawer.Popup.Props & {\n  layout?: DrawerLayout;\n}) {\n  return (\n    <DrawerPortal>\n      <DrawerBackdrop />\n      <BaseDrawer.Viewport\n        className={cn(\n          \"fixed inset-0 flex items-end justify-center touch-none\",\n          layout === \"inset\" && \"p-4 sm:p-6\",\n          layout === \"responsive\" && \"p-4 sm:p-0\",\n        )}\n        data-side=\"bottom\"\n        data-slot=\"drawer-viewport\"\n      >\n        <BaseDrawer.Popup\n          className={cn(\n            \"relative flex flex-col bg-background text-foreground outline outline-border\",\n            \"drawer-snap-popup w-full\",\n            layout === \"inset\" && \"rounded-2xl\",\n            layout === \"fullBleed\" && \"rounded-t-2xl\",\n            layout === \"responsive\" &&\n              \"rounded-2xl sm:rounded-t-2xl sm:rounded-b-none\",\n            className,\n          )}\n          data-layout={layout}\n          data-side=\"bottom\"\n          data-slot=\"drawer-content\"\n          {...props}\n        >\n          {children}\n        </BaseDrawer.Popup>\n      </BaseDrawer.Viewport>\n    </DrawerPortal>\n  );\n}\n\nfunction StackedDrawerContent({\n  className,\n  children,\n  layout = \"fullBleed\",\n  ...props\n}: BaseDrawer.Popup.Props & {\n  layout?: DrawerLayout;\n}) {\n  return (\n    <DrawerPortal>\n      <DrawerBackdrop />\n      <BaseDrawer.Viewport\n        className={cn(\n          \"fixed inset-0 flex items-end justify-center\",\n          layout === \"inset\" && \"p-4 sm:p-6\",\n          layout === \"responsive\" && \"p-4 sm:p-0\",\n        )}\n        data-side=\"bottom\"\n        data-slot=\"drawer-viewport\"\n      >\n        <BaseDrawer.Popup\n          className={cn(\n            \"drawer-stacked-popup group/popup\",\n            \"relative flex flex-col gap-4 bg-background text-foreground outline outline-border w-full\",\n            \"px-4 pt-4 pb-[calc(1rem+env(safe-area-inset-bottom,0px)+var(--drawer-bleed))]\",\n            \"sm:px-6 sm:pt-6 sm:pb-[calc(1.5rem+env(safe-area-inset-bottom,0px)+var(--drawer-bleed))]\",\n            \"overflow-y-auto overscroll-contain\",\n            \"*:data-[slot=scroll-area-root]:min-h-0\",\n            layout === \"inset\" && \"rounded-2xl\",\n            layout === \"fullBleed\" && \"rounded-t-2xl\",\n            layout === \"responsive\" &&\n              \"rounded-2xl sm:rounded-t-2xl sm:rounded-b-none\",\n            className,\n          )}\n          data-layout={layout}\n          data-side=\"bottom\"\n          data-slot=\"stacked-drawer-content\"\n          {...props}\n        >\n          {children}\n        </BaseDrawer.Popup>\n      </BaseDrawer.Viewport>\n    </DrawerPortal>\n  );\n}\n\nfunction StackedDrawerSelectable({\n  className,\n  ...props\n}: BaseDrawer.Content.Props) {\n  return (\n    <DrawerSelectable\n      className={cn(\n        \"flex flex-col gap-4\",\n        \"transition-opacity duration-300 ease-smooth\",\n        \"group-data-[nested-drawer-open]/popup:opacity-0\",\n        \"group-data-[nested-drawer-swiping]/popup:opacity-100\",\n        className,\n      )}\n      data-slot=\"stacked-drawer-selectable\"\n      {...props}\n    />\n  );\n}\n\nconst createDrawerHandle = BaseDrawer.createHandle;\n\nexport {\n  Drawer,\n  DrawerBackdrop,\n  DrawerClose,\n  DrawerDescription,\n  DrawerFooter,\n  DrawerHeader,\n  DrawerIndent,\n  DrawerIndentBackground,\n  DrawerSelectable,\n  DrawerPopup,\n  DrawerPortal,\n  DrawerProvider,\n  DrawerSwipeArea,\n  DrawerTitle,\n  DrawerTrigger,\n  DrawerViewport,\n  DrawerDragHandle,\n  createDrawerHandle,\n  // Composite components\n  DrawerContent,\n  SnapDrawerContent,\n  StackedDrawerContent,\n  StackedDrawerSelectable,\n};\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}