Popover

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.
On the web and Android the panel is Dark Factory's: a 12px card with a hairline and its soft popover shadow, Dark Factory's heading over its body in the muted ink. iOS keeps the iPad popover, a rounder borderless card with a beak toward its trigger, in the same type.
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 iOS 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, 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.
iOS
Android
Web
tsx
<Popover
trigger="Open popover"
title="Rename project"
description="Choose a name your team will recognize."
actionLabel="Rename"
>
<Input label="Project name" defaultValue="Identity Platform" />
</Popover>

Props

Prop
Description
trigger
string
Label for the trigger button.
title
string
Heading shown at the top of the floating card.
description
string
Supporting line beneath the title.
children
ReactNode
Custom panel content (an input, a form row, any node), rendered in the card body between the description and the action row. Composes with the data-driven props.
actionLabel
string
When set, renders a primary action button at the bottom of the card.
top
boolean
Anchor the card ABOVE the trigger (it flips below when the room above is short). Placement axis: `top` > `bottom`.
bottom
boolean
Anchor the card BELOW the trigger, the default (it flips above when the room below is short).
inline
boolean
Static mode: render the card on its own with no trigger button (an always-visible inline panel). When set, the card is always shown and `open` is ignored.
open
boolean
Controlled open state. Omit for uncontrolled (the trigger toggles it).
onOpenChange
(open: boolean) => void
Fired when the open state changes.
testID
string
E2E hook forwarded to the root element.
style
StyleProp<ViewStyle>
Outer layout composition only (width/flex within a parent), never a restyle hook.

Do & Don’t

Compact content

Don’t
Name
Email
Role
Team
A full form belongs in a dialog; in a floating popover it is cramped and easy to dismiss by accident.
Do
Rename this project?
Project name
Keep popovers compact: a focused prompt with one input and a clear action.

Triggered

Don’t
No anchor, no dismiss, no Close.
A trigger with no relative anchor and no way to dismiss leaves the panel floating loose and stuck open.
Do
Wrap the trigger in a relative anchor and dismiss on outside click so the panel positions and closes predictably.

Inline

Don’t
Street
City
Region
Postal code
An always-visible panel that scrolls internally is doing a card's or section's job; use the panel chrome only for short content.
Do
Saved to drafts. Publish when ready.
Reserve the static panel for a brief always-on message with a single follow-up action.

Accessibility

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.