Build a reusable bottom sheet component for use in the Mobile Page Previews experiment, designed to be product-agnostic so it can be upstreamed into Codex when possible.
Context
The Mobile Page Previews experiment (T418812) needs a slide-up panel to display preview content. MobileFrontend's reference drawer provides a similar interaction pattern already familiar to mobile Wikipedia readers.
Codex has a Sheet component planned (T366048) but it is still in early design stages with no spec or implementation yet. We should build a local implementation in ReaderExperiments that is generic enough to upstream later. This means the sheet component itself should have no knowledge of page preview content — all content should be passed in via slots and/or props. The sheet handles presentation (slide-up, dismiss, backdrop, accessibility) while the consumer handles what goes inside it.
Worth adding Mobile Page Previews as a known use case on T366048.
Requirements
- Slides up from the bottom of the viewport
- Dismiss via: X button, tap outside the sheet, or swipe down (stretch)
- Content passed in via slot; optional props for configuration (e.g., title, show/hide close button)
- Accessible: focus trapping, screen reader announcements, escape key dismissal
- Smooth animation, minimal layout shift
- Responsive to varying content heights
- Works across mobile browsers targeted by the experiment (Android Chrome, iOS Safari at minimum)
- Feature gating: loads on touch devices only
Open questions
- Should swipe-to-dismiss be included for the experiment, or is that a fast-follow?
- How should the sheet behave when the virtual keyboard is open (e.g., if the reader tapped a link while focused on search)?
- What props does the sheet need beyond a content slot? (title, closable, height constraints, backdrop opacity, etc.)
Prior Art
- Vue-bottom-sheet is worth studying as a reference implementation of what we want to do here