Drawer
loomui/drawerFreeComponent
A panel that comes in from any edge and covers most of the screen, dragged anywhere on its face to send it back out.
Live preview
live · rendered by the registry
Rendered by loomui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://loomui.design/r/drawer.jsonSource
1"use client"23import * as React from "react"4import * as DialogPrimitive from "@radix-ui/react-dialog"56import { cn } from "@/lib/utils"78export type DrawerSide = "top" | "right" | "bottom" | "left"910export interface DrawerContentProps extends React.ComponentProps<11 typeof DialogPrimitive.Content12> {13 /** Edge the drawer comes in from. */14 side?: DrawerSide15 /** How much of the screen it covers when open. Any CSS length. */16 size?: string17 /** Draw the notch you take hold of. */18 showHandle?: boolean19 /** Allow the swipe, the overlay and `Escape` to close the drawer. */20 dismissible?: boolean21}2223/** Off screen, as a share of the panel. */24const CLOSED: Record<DrawerSide, string> = {25 top: "0 -100%",26 bottom: "0 100%",27 left: "-100% 0",28 right: "100% 0",29}3031const PANEL: Record<DrawerSide, string> = {32 top: "inset-x-0 top-0 h-[var(--drawer-size)] w-full rounded-b-2xl border-b",33 bottom:34 "inset-x-0 bottom-0 h-[var(--drawer-size)] w-full rounded-t-2xl border-t",35 left: "inset-y-0 left-0 h-full w-[var(--drawer-size)] rounded-r-2xl border-r",36 right:37 "inset-y-0 right-0 h-full w-[var(--drawer-size)] rounded-l-2xl border-l",38}3940/** Where the contents start from as they settle into the landed panel. */41const RISE: Record<DrawerSide, string> = {42 top: "0 -14px",43 bottom: "0 14px",44 left: "-14px 0",45 right: "14px 0",46}4748const HANDLE_POSITION: Record<DrawerSide, string> = {49 top: "inset-x-0 bottom-0 justify-center",50 bottom: "inset-x-0 top-0 justify-center",51 left: "inset-y-0 right-0 flex-col justify-center",52 right: "inset-y-0 left-0 flex-col justify-center",53}5455/** Milliseconds. Arriving and settling back. */56const OPEN_MS = 26057/** Leaving. An exit can be quicker than an entrance without feeling cut off. */58const CLOSE_MS = 20059/** Pixels per millisecond past which a flick closes on its own. */60const VELOCITY_THRESHOLD = 0.261/** Share of the panel dragged away before it closes. */62const CLOSE_THRESHOLD = 0.2563/** After the content is scrolled, this long before a drag can start. */64const SCROLL_LOCK_MS = 10065/** The drag waits this long after opening, so the arrival can be scrolled. */66const OPEN_GUARD_MS = OPEN_MS67/** Open: the whole panel on screen, against its edge. */68const AT_REST = "0 0"6970const isVertical = (side: DrawerSide) => side === "top" || side === "bottom"71/** Which way is out: down and right are positive, up and left are not. */72const outwardSign = (side: DrawerSide) =>73 side === "bottom" || side === "right" ? 1 : -174// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from loomui
All 91 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Aurora Backdropaurora-backdrop | loomui | Components | Free | no deps | |
| Bento Gridbento-grid | loomui | Components | Free | no deps | |
| Card Stackcard-stack | loomui | Components | Free | no deps | |
| Compare Slidercompare-slider | loomui | Components | Free | no deps | |
| Confetti Buttonconfetti-button | loomui | Components | Free | no deps | |
| Count Upcount-up | loomui | Components | Free | no deps | |
| Credit Cardcredit-card | loomui | Components | Free | no deps | |
| Elastic Tabselastic-tabs | loomui | Components | Free | no deps |
