Creative Tim UICreative Tim UI

Shadcn Drawer

PreviousNext

A slide-out panel component that appears from the edge of the screen, perfect for navigation menus, forms, and additional content.

import { X } from "lucide-react"

import { Button } from "@/components/ui/button"
import {
  Drawer,
  DrawerClose,
  DrawerContent,
  DrawerDescription,
  DrawerFooter,
  DrawerHeader,
  DrawerTitle,
  DrawerTrigger,
} from "@/components/ui/drawer"

export function DrawerDemo() {
  return (
    <Drawer direction="right">
      <DrawerTrigger asChild>
        <Button>Open Drawer</Button>
      </DrawerTrigger>
      <DrawerContent>
        <DrawerHeader>
          <DrawerTitle>Creative Tim UI</DrawerTitle>
          <DrawerDescription className="mt-2">
            A collection of open-source UI Components, Blocks & AI Agents by
            Creative Tim on top of shadcn/ui. Integrate them in v0, Lovable,
            Claude, or your application.
          </DrawerDescription>
        </DrawerHeader>
        <DrawerClose asChild>
          <Button
            variant="ghost"
            size="icon"
            className="absolute top-4 right-4 h-8 w-8 rounded-full"
          >
            <X className="h-5 w-5" />
          </Button>
        </DrawerClose>
        <DrawerFooter className="px-4">
          <Button>Get Started</Button>
          <Button variant="secondary">Documentation</Button>
        </DrawerFooter>
      </DrawerContent>
    </Drawer>
  )
}

Installation

pnpm dlx @creative-tim/ui@latest add drawer

Usage

import DrawerDemo from "@/components/drawer-demo"
<DrawerDemo />

Examples

Drawer Placement

A drawer component with placement options for all four sides (top, right, bottom, left), allowing you to choose the most appropriate direction for your use case.

import { X } from "lucide-react"

import { Button } from "@/components/ui/button"
import {
  Drawer,
  DrawerClose,
  DrawerContent,
  DrawerDescription,
  DrawerFooter,
  DrawerHeader,
  DrawerTitle,
  DrawerTrigger,
} from "@/components/ui/drawer"

export function DrawerPlacement() {
  return (
    <div className="flex gap-4">
      <Drawer direction="top">
        <DrawerTrigger asChild>
          <Button className="w-auto">Open Drawer Top</Button>
        </DrawerTrigger>
        <DrawerContent>
          <DrawerHeader className="px-4 text-left">
            <DrawerTitle className="text-left">Creative Tim UI</DrawerTitle>
            <DrawerDescription className="mt-2 text-left">
              A collection of open-source UI Components, Blocks & AI Agents by
              Creative Tim on top of shadcn/ui. Integrate them in v0, Lovable,
              Claude, or your application.
            </DrawerDescription>
          </DrawerHeader>
          <DrawerClose asChild>
            <Button
              variant="ghost"
              size="icon"
              className="absolute top-4 right-4 h-8 w-8 rounded-full"
            >
              <X className="h-5 w-5" />
            </Button>
          </DrawerClose>
          <DrawerFooter className="flex-row gap-2 px-4">
            <Button className="w-auto">Get Started</Button>
            <Button variant="secondary" className="w-auto">
              Documentation
            </Button>
          </DrawerFooter>
        </DrawerContent>
      </Drawer>
      <Drawer direction="right">
        <DrawerTrigger asChild>
          <Button>Open Drawer Right</Button>
        </DrawerTrigger>
        <DrawerContent>
          <DrawerHeader>
            <DrawerTitle>Creative Tim UI</DrawerTitle>
          </DrawerHeader>
          <DrawerClose asChild>
            <Button
              variant="ghost"
              size="icon"
              className="absolute top-4 right-4 h-8 w-8 rounded-full"
            >
              <X className="h-5 w-5" />
            </Button>
          </DrawerClose>
          <DrawerDescription className="mt-2 mb-6 px-4">
            A collection of open-source UI Components, Blocks & AI Agents by
            Creative Tim on top of shadcn/ui. Integrate them in v0, Lovable,
            Claude, or your application.
          </DrawerDescription>
          <DrawerFooter className="px-4">
            <Button>Get Started</Button>
            <Button variant="secondary">Documentation</Button>
          </DrawerFooter>
        </DrawerContent>
      </Drawer>
      <Drawer direction="bottom">
        <DrawerTrigger asChild>
          <Button className="w-auto">Open Drawer Bottom</Button>
        </DrawerTrigger>
        <DrawerContent>
          <DrawerHeader className="px-4 text-left">
            <DrawerTitle className="text-left">Creative Tim UI</DrawerTitle>
            <DrawerDescription className="mt-2 text-left">
              A collection of open-source UI Components, Blocks & AI Agents by
              Creative Tim on top of shadcn/ui. Integrate them in v0, Lovable,
              Claude, or your application.
            </DrawerDescription>
          </DrawerHeader>
          <DrawerClose asChild>
            <Button
              variant="ghost"
              size="icon"
              className="absolute top-4 right-4 h-8 w-8 rounded-full"
            >
              <X className="h-5 w-5" />
            </Button>
          </DrawerClose>
          <DrawerFooter className="flex-row gap-2 px-4">
            <Button className="w-auto">Get Started</Button>
            <Button variant="secondary" className="w-auto">
              Documentation
            </Button>
          </DrawerFooter>
        </DrawerContent>
      </Drawer>
      <Drawer direction="left">
        <DrawerTrigger asChild>
          <Button>Open Drawer Left</Button>
        </DrawerTrigger>
        <DrawerContent>
          <DrawerHeader>
            <DrawerTitle>Creative Tim UI</DrawerTitle>
          </DrawerHeader>
          <DrawerClose asChild>
            <Button
              variant="ghost"
              size="icon"
              className="absolute top-4 right-4 h-8 w-8 rounded-full"
            >
              <X className="h-5 w-5" />
            </Button>
          </DrawerClose>
          <DrawerDescription className="mt-2 mb-6 px-4">
            A collection of open-source UI Components, Blocks & AI Agents by
            Creative Tim on top of shadcn/ui. Integrate them in v0, Lovable,
            Claude, or your application.
          </DrawerDescription>
          <DrawerFooter className="px-4">
            <Button>Get Started</Button>
            <Button variant="secondary">Documentation</Button>
          </DrawerFooter>
        </DrawerContent>
      </Drawer>
    </div>
  )
}

Drawer with Form

A drawer that contains a contact form with email, subject, and message fields, perfect for quick user interactions without navigating away from the current page.

import { X } from "lucide-react"

import { Button } from "@/components/ui/button"
import {
  Drawer,
  DrawerClose,
  DrawerContent,
  DrawerDescription,
  DrawerHeader,
  DrawerTitle,
  DrawerTrigger,
} from "@/components/ui/drawer"
import { Input } from "@/components/ui/input"
import { Textarea } from "@/components/ui/textarea"

export function DrawerWithForm() {
  return (
    <Drawer direction="right">
      <DrawerTrigger asChild>
        <Button>Open Drawer</Button>
      </DrawerTrigger>
      <DrawerContent>
        <DrawerHeader>
          <DrawerTitle>Contact Us</DrawerTitle>
        </DrawerHeader>
        <DrawerClose asChild>
          <Button
            variant="ghost"
            size="icon"
            className="absolute top-4 right-4 h-8 w-8 rounded-full"
          >
            <X className="h-5 w-5" />
          </Button>
        </DrawerClose>
        <DrawerDescription className="mt-4 mb-6 px-4">
          Write the message and then click button.
        </DrawerDescription>
        <div className="mt-6 space-y-4 px-4">
          <Input id="email" type="email" placeholder="Email" />
          <Input placeholder="Subject" />
          <Textarea placeholder="Message" />
          <Button className="w-full">Send message</Button>
        </div>
      </DrawerContent>
    </Drawer>
  )
}

Drawer with Navigation

A comprehensive navigation drawer featuring a search bar, menu items with badges, collapsible sections, and a promotional card, ideal for mobile navigation or sidebar menus.

"use client"

import * as React from "react"
import {
  Archive,
  ChevronRight,
  FileText,
  Folder,
  LayoutDashboard,
  LogOut,
  Mail,
  MoreHorizontal,
  Pin,
  Search,
  Send,
  Trash2,
  UserX,
  X,
} from "lucide-react"

import { cn } from "@/lib/utils"
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardFooter, CardHeader } from "@/components/ui/card"
import { Collapse, CollapseContent } from "@/components/ui/collapse"
import {
  Drawer,
  DrawerClose,
  DrawerContent,
  DrawerHeader,
  DrawerTitle,
  DrawerTrigger,
} from "@/components/ui/drawer"
import { Input } from "@/components/ui/input"
import {
  List,
  ListItem,
  ListItemEnd,
  ListItemStart,
} from "@/components/ui/list"
import { Separator } from "@/components/ui/separator"

const Links = [
  {
    icon: Mail,
    title: "Inbox",
    href: "#",
    badge: 14,
  },
  {
    icon: Send,
    title: "Sent",
    href: "#",
  },
  {
    icon: FileText,
    title: "Drafts",
    href: "#",
  },
  {
    icon: Pin,
    title: "Pins",
    href: "#",
  },
  {
    icon: Archive,
    title: "Archive",
    href: "#",
  },
  {
    icon: Trash2,
    title: "Trash",
    href: "#",
  },
]

export function DrawerWithNavigation() {
  const [isOpen, setIsOpen] = React.useState(false)

  return (
    <Drawer direction="left">
      <DrawerTrigger asChild>
        <Button>Open Drawer</Button>
      </DrawerTrigger>
      <DrawerContent className="p-0">
        <DrawerClose asChild>
          <Button
            variant="ghost"
            size="icon"
            className="absolute top-2 right-2 z-10 h-8 w-8 rounded-full"
          >
            <X className="h-5 w-5" />
          </Button>
        </DrawerClose>
        <Card className="border-none shadow-none">
          <CardHeader className="m-0 flex h-max items-center gap-2 px-3 pt-4 pb-3">
            <Avatar className="h-6 w-6">
              <AvatarImage
                src="https://www.creative-tim.com/ui/apple-touch-icon-square.jpg"
                alt="brand"
              />
              <AvatarFallback>CT</AvatarFallback>
            </Avatar>
            <DrawerTitle>Creative Tim UI</DrawerTitle>
          </CardHeader>
          <CardContent className="p-3">
            <div className="relative">
              <Search className="text-muted-foreground absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2" />
              <Input
                type="search"
                placeholder="Search here..."
                className="pl-9"
              />
            </div>
            <List className="mt-3">
              {Links.map(({ icon: Icon, title, href, badge }) => (
                <ListItem key={title} asChild>
                  <a href={href} className="flex items-center">
                    <ListItemStart>
                      <Icon className="h-[18px] w-[18px]" />
                    </ListItemStart>
                    {title}
                    {badge && (
                      <ListItemEnd>
                        <Badge variant="secondary" className="text-xs">
                          {badge}
                        </Badge>
                      </ListItemEnd>
                    )}
                  </a>
                </ListItem>
              ))}
              <Separator className="my-3" />
              <ListItem
                onClick={() => setIsOpen((cur) => !cur)}
                className="cursor-pointer"
              >
                <ListItemStart>
                  <MoreHorizontal className="h-[18px] w-[18px]" />
                </ListItemStart>
                More
                <ListItemEnd>
                  <ChevronRight
                    className={cn(
                      "h-4 w-4 transition-transform",
                      isOpen && "rotate-90"
                    )}
                  />
                </ListItemEnd>
              </ListItem>
              <Collapse open={isOpen}>
                <CollapseContent>
                  <List>
                    <ListItem asChild>
                      <a href="#" className="flex items-center">
                        <ListItemStart>
                          <Folder className="h-[18px] w-[18px]" />
                        </ListItemStart>
                        Spam
                      </a>
                    </ListItem>
                    <ListItem asChild>
                      <a href="#" className="flex items-center">
                        <ListItemStart>
                          <UserX className="h-[18px] w-[18px]" />
                        </ListItemStart>
                        Blocked
                      </a>
                    </ListItem>
                    <ListItem asChild>
                      <a href="#" className="flex items-center">
                        <ListItemStart>
                          <Folder className="h-[18px] w-[18px]" />
                        </ListItemStart>
                        Important
                      </a>
                    </ListItem>
                  </List>
                </CollapseContent>
              </Collapse>
              <Separator className="my-3" />
              <ListItem
                className="text-destructive hover:bg-destructive/10 hover:text-destructive focus:bg-destructive/10 focus:text-destructive cursor-pointer"
                asChild
              >
                <a href="#" className="flex items-center">
                  <ListItemStart>
                    <LogOut className="h-[18px] w-[18px]" />
                  </ListItemStart>
                  Logout
                </a>
              </ListItem>
            </List>
          </CardContent>
          <CardFooter className="p-3">
            <Card className="bg-primary shadow-none">
              <CardHeader className="m-3">
                <LayoutDashboard className="text-primary-foreground h-10 w-10" />
              </CardHeader>
              <CardContent>
                <h6 className="mb-1 text-white">Upgrade to PRO</h6>
                <p className="text-sm text-white/80">
                  Upgrade to Creative Tim UI PRO and get even more components,
                  plugins, advanced features and premium.
                </p>
              </CardContent>
              <CardFooter>
                <Button
                  size="sm"
                  asChild
                  className="border-white bg-white text-black hover:border-white hover:bg-white hover:text-black"
                >
                  <a href="#">Upgrade Now</a>
                </Button>
              </CardFooter>
            </Card>
          </CardFooter>
        </Card>
      </DrawerContent>
    </Drawer>
  )
}

Props

The drawer component is built using vaul and accepts the following props:

Drawer (Root Component)

PropTypeDefaultDescription
openboolean-Controls whether the drawer is open (controlled)
defaultOpenbooleanfalseThe default open state (uncontrolled)
onOpenChange(open: boolean) => void-Event handler called when the open state changes
direction"top" | "right" | "bottom" | "left""bottom"The direction from which the drawer slides in
dismissiblebooleantrueWhether the drawer can be dismissed by clicking the overlay
modalbooleantrueWhether the drawer should be modal (blocks interaction with background)

DrawerContent

PropTypeDefaultDescription
direction"top" | "right" | "bottom" | "left""bottom"The side from which the drawer slides in
classNamestring-Additional CSS classes for custom styling

DrawerTrigger

PropTypeDefaultDescription
asChildbooleanfalseMerge props with child element
classNamestring-Additional CSS classes to apply to the trigger button
childrenReactNode-The content to display in the trigger

DrawerClose

PropTypeDefaultDescription
asChildbooleanfalseMerge props with child element
classNamestring-Additional CSS classes to apply to the close button
childrenReactNode-The content to display in the close button

Best Practices

  • Use drawers for secondary actions or content that doesn't require full-screen attention
  • Choose the appropriate direction based on your layout and user flow
  • Keep drawer content focused and avoid overwhelming users with too much information
  • Provide clear close buttons or allow dismissal via overlay click
  • Consider mobile-first design when implementing drawer navigation
  • Use drawers for forms, filters, settings, or navigation menus
  • Ensure drawer content is scrollable if it exceeds viewport height

The drawer component provides a smooth, accessible way to display additional content without navigating away from the current page. It's ideal for mobile navigation, quick actions, forms, and contextual information.