All Docs
FeaturesCalmony Sanctions MonitorUpdated March 11, 2026

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:

  1. 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.
  2. 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

CapabilityDetail
Animated slide-inSmooth enter/exit transitions from any edge (top, bottom, left, right)
Focus trappingKeyboard focus stays inside the sheet while it is open
Escape key handlingPressing Escape dismisses the sheet automatically
Backdrop dismissClicking outside the sheet closes it
AccessibilityBuilt 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 required
  • src/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