Popover
Atom
Floating panel with a title, supporting text, rich content such as form fields, and a single follow-up action, anchored to its trigger. Pass children to host custom content in the panel body, between the description and the action.
Playground
Every control sets a real prop of PopoverProps. The JSX below updates as you go.
Web
iOS
Android
JSX · PopoverProps
Variants
5 examples from src/atoms/popover/popover.md, each rendered live from its own JSX.
Anatomy
1
Trigger
2
Panel
3
Arrow
4
Title
5
Description
6
Action
Dimmed parts appear only in some states or variants.
Props
20 props on PopoverProps, grouped as they are declared in source. Required props are marked *.
Accessibility and keyboard
Keyboard
Tab
Shift+Tab
Cycles focus inside the panel
Escape
Closes when dismissible
Enter
Confirms in forms
Semantics
Roles
dialog
ARIA on web
aria-describedby
aria-label
aria-labelledby
aria-modal
From the docs
The trigger is a button that announces its popup as a dialog and whether it is expanded. Opening the card moves keyboard focus into the panel, once its placement has settled: a dialog named by its title (by the trigger's label when it has none) and described by its supporting line. A card pinned open (a controlled open with no change handler) is part of the page and takes no focus as it appears.
With a keyboard, Tab moves through the panel's controls as if the card sat right after its trigger, then on to the control after the trigger, and the card stays open: the anchored popover is non-modal on the web. Shift+Tab from the panel returns to the trigger, and Tab from the trigger re-enters the card. Escape closes it, and focus goes back to whatever opened it.
The sheet on phones is modal, as it covers and dims the page: its dialog is announced as modal, Tab and Shift+Tab keep to its controls and wrap at their ends, and a Tab from anywhere on the page behind it goes into it. Escape, the action or a tap on the scrim closes it, and focus goes back to whatever opened it.
On iOS and Android the open card is modal to VoiceOver and TalkBack: the page behind it is hidden from them, their focus moves to the card's first line, and when the card closes it returns to the trigger. The escape gesture and the Android back button close the card. Touch closes it with a tap anywhere outside it, and on phones a tap on the scrim above the sheet.
Platform skins
The playground's props on each platform: same tree, native shapes, type and touch sizes.
Usage
On the web and Android the panel is the v4 card: 280 wide at the menu corner, the field hairline and the large shadow, a 15px display heading over its 14px description in the muted ink, and in solid mode a small diamond beak on the edge facing its trigger. iOS keeps the iPad popover, a rounder borderless card with a tapered beak toward its trigger.
The triggered card opens below its button by default and above it with top; either way it flips to the other side when its own lacks room, and the beak follows the side it took. At phone width a triggered card that can close is presented as a sheet on the bottom edge of the window, over the tab bar and a dimming scrim that glass on the web also blurs, its content kept clear of the home indicator: Dark Factory's sheet on the web, the iOS sheet on iPhone and the Material 3 bottom sheet on Android.
In glass mode the triggered card is a functional-layer glass panel beside its button, and the sheet a dense-layer one, legible over its scrim; focus enters once the card's placement has committed, and the inline card is a static in-flow panel. Solid mode paints the skin's own panel.
Tokens
Read from the playground render. Values follow the scheme and the ion hue.
--bf
--bls
--bw
--f-dp
--fd
--ft
--gl
--hl
--ion
--ion-fg
--ln2
--sf2
--sf3
--sf4
--sh-lg
--tx
--tx2