Sheet

Slides a panel in from the edge for details, filters or a quick choice.

Examples

Side

  • autodefault

  • bottom

  • right

  • left

Usage

When to use it
Use
Details about one item, such as a transaction, with the list still behind.
Use
Filters or sort options with several controls.
Use
A short choice on a phone, such as which account to pay from.
Not for
A short task with a few fields that stops the page. Use Dialog.
Not for
A decision that must be answered. Use Alert dialog.
Not for
A small panel by a control. Use Popover.
Not for
A multi-step flow. Make it a page with its own address.

Rules

8 rules
Should
Leave side on auto: bottom below 640px, right from there. Fix it only when the layout needs one edge.
Must
Include SheetTitle inside SheetHeader; the title names the sheet. Because a plain h2 is not tied to the dialog, so a screen reader announces an unnamed dialog.
Must
Put the content in SheetBody; it scrolls while the header and footer stay put. Because SheetContent is overflow-hidden, so rows outside SheetBody are cut off at 90% of the screen.
Should
End a sheet of live settings with one Done button; no Save and Cancel pair.
Must
Keep unsaved work out of a sheet. Because a swipe, a scrim tap or Escape closes it and drops the typing without asking.
Must
Pass side="left" in a right-to-left app that fixes the side. Because sides are physical, so "right" lands on the leading edge in a right-to-left app.
Never
Build a multi-step flow in a sheet; make it a page. Because one swipe down closes the sheet and throws away every step before it.
Never
Center a sheet or restyle a Dialog as one; a sheet is anchored to an edge. Because a restyled Dialog has no swipe to close, and a centered sheet swipes toward no edge.

Accessibility

4 checks
The sheet is a modal dialog: it traps focus, closes on Escape and returns focus to its trigger.
SheetTitle names it and SheetDescription describes it; the round close button is named Close.
The grab handle is decorative; the close button and Escape do the same as the swipe.
The footer keeps clear of the home indicator with the safe-area inset.

Edge cases

6 edge cases
Long content
SheetBody scrolls; the bottom sheet caps at 90% of the screen height.
Swipe
The panel follows the finger and the scrim fades with it; a short swipe springs back.
Bottom sheet on a wide screen
The bottom sheet centers at 512px.
Reduced motion
The sheet appears in place at once.
Dialog opened inside
It stacks above with its own scrim.
Inside a table or menu
It portals into the Lime scope and keeps its tokens.

API

6 props
Sheet side
'auto' | 'bottom' | 'right' | 'left' default 'auto'
Sheet
Base UI Drawer.Root props
SheetHeader showClose
boolean default true
SheetBody
Base UI Drawer.Content props
SheetFooter
div props
SheetClose
Base UI props

Tokens

11 tokens
--raised
#ffffff
--radius-sheet
24px
--sheet
400px
--shadow-overlay
0 24px 48px -12px rgb(var(--shadow-ink) / 0.24), 0 4px 12px rgb(var(--shadow-ink) / 0.08)
--scrim
rgb(15 15 13 / 0.5)
--line-strong
#cfcdc6
--text-lg
18px
--text-sm
14px
--fg-2
#4a4943
--dur-slow
280ms
--ease-out
cubic-bezier(0.16, 1, 0.3, 1)

Install

For your coding agent

GitHub

Please star me pookie

141

A new design system every week

Leave your email before you copy the prompt.