Bottom sheet
● Stable · v0.1A panel that rises from the bottom of the screen for a focused task — an entry form, capture, a picker. A grabber handle, a rounded top, an optional title/subtitle and close, over a dimmed backdrop that dismisses on tap.
In context
Purpose
A BottomSheet keeps the user in place while they do one focused thing — record a sale, pick a date, confirm details — without a full screen change. It's the reach-from-the-thumb surface for capture, which is DayTwo's core loop. Unlike a Modal, it's for a task, not a single yes/no decision.
Anatomy
- Backdrop — a dimmed scrim; tapping it dismisses.
- Grabber — a handle at the top signalling "drag/close" (toggle with
showHandle). - Title / subtitle (optional) + a close ×.
- Content — the form or picker you pass as children.
Variants
- Default — a real full-window sheet for shipping screens.
contained— an absolute overlay that fills the nearest positioned parent, for embedding inside a framed phone preview (as above).
Code
import { BottomSheet, Button, Input } from '@daytwo/components'const [open, setOpen] = useState(false)<BottomSheetvisible={open}onClose={() => setOpen(false)}title="Record a sale"subtitle="Add what you sold"><Input label="Amount" placeholder="0" keyboardType="numeric" /><Button fullWidth onPress={save}>Save sale</Button></BottomSheet>
When to use
- Capture and short forms the user should finish without leaving the screen.
- Pickers (date, category) invoked from a field.
When NOT to use
- A single yes/no decision — use a Modal.
- A whole workflow with several steps — that's a screen (or a flow of them).
- A passing confirmation — use a toast / ConfirmationState.
Good vs bad
- Good: tapping "Add sale" rises a sheet with an amount field and one "Save" button; saving drops it back to the same screen — the user never lost their place.
- Bad: a sheet that fills 92% of the screen with a five-section form and two primary buttons — at that size it's really a screen pretending to be a sheet.
Edge cases
Tall content
Sheet caps at ~92% height and scrolls inside
WhyContent must never push the grabber off-screen
Keyboard open
Keep the primary action reachable above the keyboard
WhyCapture needs the Save button in thumb reach
Dismiss mid-form
Backdrop tap closes; decide if partial input is kept
WhyInterrupted capture shouldn't silently lose data
Dark mode
Sheet + backdrop follow the theme surfaces/overlay
WhyThe panel must read in both schemes
A task, not a decision
If the sheet only asks one yes/no, it's a Modal. If it needs many steps, it's a screen. The sheet is the middle: one focused task, in place.
Tokens used
color.surface.primarycolor.overlaycolor.border.strongcolor.text.primarycolor.text.secondaryradius.2xlelevation.lgtypography.title2