MOB-22: Bottom Sheet Pattern — Installing the shadcn/ui Sheet Component
MOB-22: Bottom Sheet Pattern
Release: v0.1.22 · Category: Component Patterns
Background
An audit of src/components/ui/ revealed that the component library currently contains only accessible-form.tsx. No shadcn Sheet, Dialog, Drawer, or other overlay primitives are installed.
This absence has two immediate consequences:
- Mobile sidebar drawer (MOB-06): When the mobile navigation drawer is implemented, developers have no existing overlay primitive to build on and would need to build one from scratch.
- UserButton dropdown: On mobile, the UserButton menu renders via a custom positioned
div. This bypasses standard accessibility behaviour — there is no focus trapping, no escape-key dismissal, and no backdrop dismiss.
Recommended Solution
Install the shadcn/ui Sheet component. Sheet is a slide-in panel (built on Radix UI Dialog) that is well-suited to both mobile navigation drawers and dropdown-replacement bottom sheets.
Installation
npx shadcn@latest add sheet
This adds the Sheet component files into src/components/ui/ alongside the existing accessible-form.tsx.
What Sheet Provides
| Capability | Detail |
|---|---|
| Animated slide-in | Smooth enter/exit transitions from any edge (top, bottom, left, right) |
| Focus trapping | Keyboard focus stays inside the sheet while it is open |
| Escape key handling | Pressing Escape dismisses the sheet automatically |
| Backdrop dismiss | Clicking outside the sheet closes it |
| Accessibility | Built on Radix UI Dialog — ARIA roles and keyboard navigation included |
Planned Usage
Mobile Navigation Drawer (MOB-06)
The Sheet component can be used as a left-edge slide-in panel for the main navigation on mobile viewports:
import {
Sheet,
SheetContent,
SheetTrigger,
} from '@/components/ui/sheet';
<Sheet>
<SheetTrigger asChild>
<button aria-label="Open navigation">☰</button>
</SheetTrigger>
<SheetContent side="left">
{/* Navigation items */}
</SheetContent>
</Sheet>
UserButton Mobile Dropdown
The existing custom positioned div used by UserButton on mobile can be replaced with a bottom-anchored Sheet:
import {
Sheet,
SheetContent,
SheetTrigger,
} from '@/components/ui/sheet';
<Sheet>
<SheetTrigger asChild>
<UserAvatarButton />
</SheetTrigger>
<SheetContent side="bottom">
{/* User menu items */}
</SheetContent>
</Sheet>
Affected Files
src/components/ui/accessible-form.tsx— only current UI primitive; no changes requiredsrc/components/ui/sheet.tsx— to be created by the shadcn installer
Related Issues
- MOB-06 — Mobile sidebar drawer implementation (depends on this component being available)
- MOB-22 — This audit finding