Thành phần
Drawer
Drawer on Base UI: paper panel from any edge, heavy 3px ink rule as the handle, swipe to dismiss, focus trapped.
Nội dung tham khảo viết bằng tiếng Anh; mục “Vietnamese” có ví dụ tiếng Việt.
Xem trước
Install
bash
npx shadcn add @eloquent/drawerUsage
tsx
import { Button } from "@/components/ui/button";
import {
Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerTitle, DrawerTrigger,
} from "@/components/ui/drawer";
<Drawer>
<DrawerTrigger render={<Button variant="outline" />}>Open the edition</DrawerTrigger>
<DrawerContent closeLabel="Close">
<DrawerHeader>
<DrawerTitle>Today's edition</DrawerTitle>
<DrawerDescription>Sections in this morning's paper.</DrawerDescription>
</DrawerHeader>
<DrawerFooter>
<DrawerClose render={<Button />}>Done</DrawerClose>
</DrawerFooter>
</DrawerContent>
</Drawer>swipeDirection on Drawer sets the edge: down (default, a bottom drawer), up, left or right. The corner ✕ renders only when you pass closeLabel.
This is built on Base UI's own Drawer (stable in @base-ui/react 1.9.0), so there is no vaul dependency.
States
| State | Treatment |
|---|---|
| Open | Paper panel, heavy 3px ink rule on the edge facing the page; backdrop paper at 85%, no blur |
| Swiping | The panel follows the pointer, then fades out |
| Focus | 2px ink outline, 2px offset |
| Close pressed | tint-1 fill on the 44px ✕; no hover effect |
Keyboard
| Key | Action |
|---|---|
| Tab / Shift+Tab | From the page, reach the trigger. While open, move between the drawer's controls; focus wraps and never leaves the drawer |
| Enter / Space | Open from the trigger; activate a control |
| Esc | Close; focus returns to the trigger |
Swiping is an extra gesture. Esc, DrawerClose and the corner ✕ do everything it does.
Vietnamese
Ink adaptation
Upstream shadcn's grab pill, shadow, rounded top corners and dark overlay are removed. The heavy 3px rule on the edge that faces the page is the handle; the backdrop is paper at 85% with no blur. Entering and leaving are an opacity fade (none under reduced motion); the swipe still moves the panel with the pointer. Built on Base UI Drawer.