Drawer

Overlay & Feedback

Slide-in panel from any screen edge.

Preview

Usage

example.jsx
import { Drawer } from "@/components/ui/drawer";

export default function Example() {
  return <Drawer />;
}

Source Code

Copy this file into components/ui/drawer.jsx in your project.

drawer.jsx
"use client";

import { forwardRef, useEffect } from "react";
import { cn } from "@/lib/utils";

const Drawer = forwardRef(({ className, open, onClose, side = "bottom", children, ...props }, ref) => {
  useEffect(() => {
    if (open) document.body.style.overflow = "hidden";
    return () => { document.body.style.overflow = ""; };
  }, [open]);

  if (!open) return null;
  return (
    <div className="fixed inset-0 z-50">
      <div className="fixed inset-0 bg-black/50 backdrop-blur-sm" onClick={onClose} />
      <div ref={ref}
        className={cn("fixed z-50 border bg-background shadow-lg transition-transform duration-300",
          side === "bottom" && "inset-x-0 bottom-0 rounded-t-xl",
          side === "top" && "inset-x-0 top-0 rounded-b-xl",
          side === "left" && "inset-y-0 left-0 w-80 rounded-r-xl",
          side === "right" && "inset-y-0 right-0 w-80 rounded-l-xl",
          className
        )}
        {...props}
      >
        {(side === "bottom" || side === "top") && (
          <div className="mx-auto mt-4 h-1.5 w-12 rounded-full bg-muted-foreground/20" />
        )}
        <div className="p-4">{children}</div>
      </div>
    </div>
  );
});
Drawer.displayName = "Drawer";

export { Drawer };

Quick Install

Make sure you have the cn() utility set up. It requires clsx and tailwind-merge.

npm install clsx tailwind-merge