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
Anatomy & motion
| Part | Spec |
|---|---|
| Scrim | .modal-overlay |
| Sheet | radius 24 top · max-height: 85vh · overflow-y: scroll · overscroll-behavior: contain |
| Handle | 48px drag handle |
| Enter | sheetRise 0.48s cubic-bezier(0.32, 0.72, 0, 1) |
| Exit | cubic-bezier(1, 0, 0.68, 0.28), duration scaled to remaining distance |
| Drag-to-dismiss | useSheetDrag() · 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
| Sheet | Role |
|---|---|
| Log Activity drawer | the FAB's hub — six rows to the log screens |
| Card detail drawers | DailyFocus / Sleep / Cycle / Symptoms / Trends — share .dfc-* section styles |
| PastEntryModal | read/edit a historical day from Log History |
| SyncProgressModal | blocking wearable import progress |
| Export sheets | scope → generating → PDF ready |
| Full-screen log pages | slide-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).