Drawer
Overlay bottom-sheet mobile-first dengan focus trap, scroll lock, dan animasi slide-up.
bun x bosia@latest add drawerSheet yang menempel di bawah dan meluncur naik di atas halaman. Dibuat untuk action sheet mobile, picker, dan alur konfirmasi di mana Dialog yang terpusat terasa salah di layar kecil. Memerangkap fokus, mengunci scroll body, dan menutup saat Escape atau klik backdrop. Sepenuhnya aksesibel dengan role="dialog", aria-modal, aria-labelledby, dan aria-describedby.
Preview
Props
DrawerContent
| Prop | Type | Default |
|---|---|---|
closeOnBackdropClick |
boolean |
true |
showHandle |
boolean |
true |
class |
string |
"" |
Drawer
| Prop | Type | Default |
|---|---|---|
open |
boolean |
false |
Sub-komponen
Drawer— penyedia konteks root, mengelola state openDrawerTrigger— tombol yang membuka drawerDrawerContent— panel tetap menempel di bawah dengan focus trap dan animasi slide-upDrawerClose— membungkus elemen apa pun untuk menutup saat diklikDrawerHeader— kontainer flex untuk area judulDrawerTitle—<h2>ditautkan viaaria-labelledbyDrawerDescription— teks muted ditautkan viaaria-describedbyDrawerFooter— footer dengan layout tombol aksi
Penggunaan
<script lang="ts">
import {
Drawer,
DrawerTrigger,
DrawerContent,
DrawerHeader,
DrawerTitle,
DrawerDescription,
DrawerFooter,
DrawerClose,
} from "$lib/components/ui/drawer";
import { Button } from "$lib/components/ui/button";
</script>
<Drawer>
<DrawerTrigger>
<Button variant="outline">Open Drawer</Button>
</DrawerTrigger>
<DrawerContent>
<DrawerHeader>
<DrawerTitle>Move Goal</DrawerTitle>
<DrawerDescription>Set a daily activity target.</DrawerDescription>
</DrawerHeader>
<DrawerFooter>
<Button>Save</Button>
<DrawerClose>
<Button variant="outline">Cancel</Button>
</DrawerClose>
</DrawerFooter>
</DrawerContent>
</Drawer>State Open Terkontrol
<script lang="ts">
let open = $state(false);
</script>
<Drawer bind:open>
<DrawerTrigger>
<Button>Open</Button>
</DrawerTrigger>
<DrawerContent>
<DrawerHeader>
<DrawerTitle>Controlled Drawer</DrawerTitle>
</DrawerHeader>
<p>You can control this drawer programmatically.</p>
</DrawerContent>
</Drawer>
<p>Drawer is {open ? "open" : "closed"}</p>Sembunyikan Handle Geser
<DrawerContent showHandle={false}>
<!-- No visual handle bar at the top -->
</DrawerContent>Nonaktifkan Tutup Backdrop
<DrawerContent closeOnBackdropClick={false}>
<!-- Only closes via Escape key or DrawerClose button -->
</DrawerContent>Kapan Digunakan
- Drawer — action sheet mobile, picker, alur konfirmasi. Menempel di bawah, lebar penuh.
- Dialog — modal desktop, terpusat, lebar terbatas. Gunakan saat halaman lebar dan aksi tidak terpaut ke tepi bawah.
Pola umum adalah beralih di antara keduanya pada satu breakpoint: Dialog di desktop, Drawer di mobile.
Aksesibilitas
role="dialog"danaria-modal="true"pada panel kontenaria-labelledbyditautkan keDrawerTitlearia-describedbyditautkan keDrawerDescription- Fokus terperangkap di dalam drawer (Tab berputar melalui elemen yang bisa difokuskan)
- Fokus kembali ke elemen trigger saat drawer ditutup
- Tombol Escape menutup drawer
- Scroll body terkunci selama terbuka
- Handle geser bersifat
aria-hidden(hanya dekoratif — drawer ini tap-to-close)