Drawer
trovecn/drawerFreeComponent
Edge-anchored panel with real drag-to-dismiss on top and bottom.
Install it
npx shadcn@latest add https://trovecn.dev/r/drawer.jsonSource
1"use client";23import {4 createContext,5 useCallback,6 useContext,7 useLayoutEffect,8 useRef,9 useState,10 type ReactNode,11} from "react";12import { Dialog as DrawerPrimitive } from "@base-ui/react/dialog";13import { motion, useDragControls, type PanInfo } from "motion/react";1415import { cn } from "@/lib/utils";16import { spring } from "@/lib/springs";1718type Side = "top" | "right" | "bottom" | "left";1920const VELOCITY_THRESHOLD = 400;21const CLOSE_THRESHOLD_RATIO = 0.25;22const FALLBACK_SIZE = 400;2324interface DrawerContextValue {25 actionsRef: React.RefObject<DrawerPrimitive.Root.Actions | null>;26}2728const DrawerContext = createContext<DrawerContextValue | null>(null);2930function Drawer({ children, ...props }: DrawerPrimitive.Root.Props) {31 const actionsRef = useRef<DrawerPrimitive.Root.Actions>(null);32 return (33 <DrawerContext.Provider value={{ actionsRef }}>34 <DrawerPrimitive.Root data-slot="drawer" actionsRef={actionsRef} {...props}>35 {children}36 </DrawerPrimitive.Root>37 </DrawerContext.Provider>38 );39}4041function DrawerTrigger({ ...props }: DrawerPrimitive.Trigger.Props) {42 return <DrawerPrimitive.Trigger data-slot="drawer-trigger" {...props} />;43}4445function DrawerClose({ ...props }: DrawerPrimitive.Close.Props) {46 return <DrawerPrimitive.Close data-slot="drawer-close" {...props} />;47}4849function DrawerPortal({ ...props }: DrawerPrimitive.Portal.Props) {50 return <DrawerPrimitive.Portal data-slot="drawer-portal" {...props} />;51}5253function DrawerOverlay({ className, ...props }: DrawerPrimitive.Backdrop.Props) {54 return (55 <DrawerPrimitive.Backdrop56 data-slot="drawer-overlay"57 render={(backdropProps, state) => {58 const exiting = state.transitionStatus === "ending";59 return (60 <motion.div61 {...(backdropProps as Record<string, unknown>)}62 className={cn("fixed inset-0 z-50 bg-black/30 backdrop-blur-none", className)}63 initial={{ opacity: 0 }}64 animate={{ opacity: exiting ? 0 : 1 }}65 transition={exiting ? spring.slow.exit : spring.slow.enter}66 />67 );68 }}69 {...props}70 />71 );72}7374function DrawerContent({75 className,76 children,77 side = "right",78 showHandle = side === "top" || side === "bottom",79 ...props80}: DrawerPrimitive.Popup.Props & {81 side?: Side;82 showHandle?: boolean;83}) {84 const ctx = useContext(DrawerContext);85 const dragControls = useDragControls();86 const panelRef = useRef<HTMLDivElement>(null);87// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from trovecn
All 26 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Accordionaccordion | trovecn | Components | Free | 3 deps | |
| Agent Activityagent-activity | trovecn | Components | Free | 2 deps | |
| Approval Requestapproval-request | trovecn | Components | Free | 2 deps | |
| Buttonbutton | trovecn | Components | Free | 2 deps | |
| Checkboxcheckbox | trovecn | Components | Free | 2 deps | |
| Checkbox Groupcheckbox-group | trovecn | Components | Free | 2 deps | |
| Comboboxcombobox | trovecn | Components | Free | 3 deps | |
| Comparison Slidercomparison-slider | trovecn | Components | Free | 1 dep |
