Drawer
A panel that slides in from the edge of the screen, typically from the bottom. Ideal for mobile-friendly interactions.
Drawer Title
Drawer description here.
top
right
bottom
left
#Installation
bunx --bun barefoot add drawer#Usage
Move Goal
Set your daily move goal.
350kcal/day
1import {2 Drawer,3 DrawerTrigger,4 DrawerOverlay,5 DrawerContent,6 DrawerHandle,7 DrawerHeader,8 DrawerTitle,9 DrawerDescription,10 DrawerFooter,11 DrawerClose,12} from '@/components/ui/drawer'#Examples
#Basic
Move Goal
Set your daily move goal.
350kcal/day
1"use client"23import { createSignal } from '@barefootjs/dom'4import {5 Drawer,6 DrawerTrigger,7 DrawerOverlay,8 DrawerContent,9 DrawerHandle,10 DrawerHeader,11 DrawerTitle,12 DrawerDescription,13 DrawerFooter,14 DrawerClose,15} from '@/components/ui/drawer'1617function BasicDrawer() {18 const [open, setOpen] = createSignal(false)1920 return (21 <Drawer open={open()} onOpenChange={setOpen}>22 <DrawerTrigger>Open Drawer</DrawerTrigger>23 <DrawerOverlay />24 <DrawerContent25 direction="bottom"26 ariaLabelledby="drawer-title"27 ariaDescribedby="drawer-description"28 >29 <DrawerHandle />30 <DrawerHeader>31 <DrawerTitle id="drawer-title">Move Goal</DrawerTitle>32 <DrawerDescription id="drawer-description">33 Set your daily move goal.34 </DrawerDescription>35 </DrawerHeader>36 <div className="p-4 pb-0">37 <div className="flex items-center justify-center space-x-2">38 <span className="text-7xl font-bold tracking-tighter">350</span>39 <span className="text-muted-foreground text-sm pb-2">kcal/day</span>40 </div>41 </div>42 <DrawerFooter>43 <DrawerClose>Cancel</DrawerClose>44 </DrawerFooter>45 </DrawerContent>46 </Drawer>47 )48}#Direction
Top Drawer
This drawer slides in from the top.
Right Drawer
This drawer slides in from the right.
Bottom Drawer
This drawer slides in from the bottom.
Left Drawer
This drawer slides in from the left.
1"use client"23import { createSignal } from '@barefootjs/dom'4import {5 Drawer,6 DrawerTrigger,7 DrawerOverlay,8 DrawerContent,9 DrawerHandle,10 DrawerHeader,11 DrawerTitle,12 DrawerDescription,13 DrawerFooter,14 DrawerClose,15} from '@/components/ui/drawer'1617function DrawerDirections() {18 const [openBottom, setOpenBottom] = createSignal(false)1920 return (21 <div className="flex flex-wrap gap-2">22 <Drawer open={openBottom()} onOpenChange={setOpenBottom}>23 <DrawerTrigger>Bottom</DrawerTrigger>24 <DrawerOverlay />25 <DrawerContent direction="bottom" ariaLabelledby="bottom-title">26 <DrawerHandle />27 <DrawerHeader>28 <DrawerTitle id="bottom-title">Bottom Drawer</DrawerTitle>29 <DrawerDescription>Slides from the bottom.</DrawerDescription>30 </DrawerHeader>31 <DrawerFooter>32 <DrawerClose>Close</DrawerClose>33 </DrawerFooter>34 </DrawerContent>35 </Drawer>3637 {/* Repeat for top, right, left with direction="top|right|left" */}38 </div>39 )40}#Form
Move Goal
Set your daily activity goal.
350
kcal/day
1"use client"23import { createSignal } from '@barefootjs/dom'4import {5 Drawer,6 DrawerTrigger,7 DrawerOverlay,8 DrawerContent,9 DrawerHandle,10 DrawerHeader,11 DrawerTitle,12 DrawerDescription,13 DrawerFooter,14 DrawerClose,15} from '@/components/ui/drawer'1617function GoalDrawer() {18 const [open, setOpen] = createSignal(false)19 const [goal, setGoal] = createSignal(350)20 const adjustGoal = (amount) => {21 setGoal((prev) => Math.max(100, prev + amount))22 }2324 return (25 <Drawer open={open()} onOpenChange={setOpen}>26 <DrawerTrigger>Set Goal</DrawerTrigger>27 <DrawerOverlay />28 <DrawerContent29 direction="bottom"30 ariaLabelledby="form-title"31 ariaDescribedby="form-description"32 >33 <DrawerHandle />34 <DrawerHeader>35 <DrawerTitle id="form-title">Move Goal</DrawerTitle>36 <DrawerDescription id="form-description">37 Set your daily activity goal.38 </DrawerDescription>39 </DrawerHeader>40 <div className="p-4 pb-0">41 <div className="flex items-center justify-center space-x-4">42 <button onClick={() => adjustGoal(-10)}>-</button>43 <span className="text-7xl font-bold">{goal()}</span>44 <button onClick={() => adjustGoal(10)}>+</button>45 </div>46 <p className="text-muted-foreground text-sm text-center mt-1">kcal/day</p>47 </div>48 <DrawerFooter>49 <DrawerClose>Submit</DrawerClose>50 <DrawerClose>Cancel</DrawerClose>51 </DrawerFooter>52 </DrawerContent>53 </Drawer>54 )55}#Accessibility
- Keyboard Navigation - ESC to close, Tab/Shift+Tab cycles within the drawer (focus trap)
- ARIA - role="dialog", aria-modal="true", aria-labelledby, aria-describedby
- Overlay Dismiss - Clicking outside the drawer closes it
- Screen Readers - State changes are announced via data-state attribute
#API Reference
Drawer
| Prop | Type | Default | Description |
|---|---|---|---|
| open | boolean | false | Whether the drawer is open. |
| onOpenChange | (open: boolean) => void | - | Event handler called when the open state should change. |
DrawerTrigger
| Prop | Type | Default | Description |
|---|---|---|---|
| disabled | boolean | false | Whether the trigger is disabled. |
| asChild | boolean | false | Render child element as trigger instead of built-in button. |
DrawerContent
| Prop | Type | Default | Description |
|---|---|---|---|
| direction | 'top' | 'right' | 'bottom' | 'left' | 'bottom' | Which edge of the screen the drawer slides from. |
| ariaLabelledby | string | - | ID of the element that labels the drawer (typically DrawerTitle). |
| ariaDescribedby | string | - | ID of the element that describes the drawer (typically DrawerDescription). |
DrawerHandle
| Prop | Type | Default | Description |
|---|---|---|---|
| class | string | - | Additional CSS classes for the handle bar. |
DrawerTitle
| Prop | Type | Default | Description |
|---|---|---|---|
| id | string | - | ID for aria-labelledby reference. |
DrawerDescription
| Prop | Type | Default | Description |
|---|---|---|---|
| id | string | - | ID for aria-describedby reference. |
DrawerClose
| Prop | Type | Default | Description |
|---|