Search

Search components, tokens, patterns, architecture

Components

Bottom Sheets & Drawers

Every “more” in Peri is a sheet over the current context — never forward navigation. One motion spec, one drag behaviour, one anatomy, reused from the Log Activity drawer to every card detail.

The Log Activity drawer, live

Log Activity

Log Symptoms
Log Workout
Log Period
Log Sleep
The FAB's sheet — warm icon tiles, 16px labels; the FAB morphs into × at the bottom

Anatomy & motion

PartSpec
Scrim.modal-overlay
Sheetradius 24 top · max-height: 85vh · overflow-y: scroll · overscroll-behavior: contain
Handle48px drag handle
EntersheetRise 0.48s cubic-bezier(0.32, 0.72, 0, 1)
Exitcubic-bezier(1, 0, 0.68, 0.28), duration scaled to remaining distance
Drag-to-dismissuseSheetDrag() · 12px commit threshold — shared by every drawer

The .open gotcha

.modal-overlay is display: none without the .open class. Every sheet must toggle it — the most common integration bug in the codebase.

The sheet family

SheetRole
Log Activity drawerthe FAB's hub — six rows to the log screens
Card detail drawersDailyFocus / Sleep / Cycle / Symptoms / Trends — share .dfc-* section styles
PastEntryModalread/edit a historical day from Log History
SyncProgressModalblocking wearable import progress
Export sheetsscope → generating → PDF ready
Full-screen log pagesslide-in at z-600 — sheets grown to full height, same dismissal model

Excluded artifact

The Figma design-system frame “The Bottom Sheet” (node 15:2920) shows a purple FAB and lavender icon tiles — the legacy Tuluna version, superseded by the warm drawer above. It exists only in the divergence register.

Do

  • ·Reuse useSheetDrag for any new sheet
  • ·Keep one sheet level — sheets never stack on sheets
  • ·Pair drag-dismiss with an explicit × and scrim tap

Don't

  • ·Open a sheet from inside an accordion
  • ·Exceed 85vh — content beyond that belongs on a log page
  • ·Invent new easings — the two curves are the motion brand

Accessibility

  • Sheets need focus trap + aria-modal; focus returns to the trigger on dismiss.
  • Drag affordance is supplemented by visible close controls.
  • Background content is inert while a sheet is open (overscroll-behavior: contain + pointer guard).