Popover
Show content with a trigger in a floating pane
Popover positions focused content around a trigger and can adapt the same content into a Sheet on smaller screens.
Features
Optional arrow pointing to content
Positioning within page bounds
Twelve anchor positions
Shared Sheet handoff with Dialog and Select
Popover shows content only while its trigger is pressed, floating above the current content. It automatically stacks above other content.
Popovers are not a recommended pattern for mobile apps. Use Adapt to render them as a Sheet instead, or conditionally render native UI.
Installation
Popover is already installed in tamagui, or you can install it independently:
yarn
npm
bun
pnpm
For native apps, we recommend setting up native portals to preserve React context inside Popover content.
Anatomy
Scoping
Popover supports scoping which lets you mount one or more Popover instances at the root of your app, while having a deeply nested child Trigger or Content attach to the proper parent Popover instance.
In performance sensitive areas you may want to take advantage of this as it allows you to only render the Popover.Trigger inside the sensitive area. Popover isn’t the cheapest component - it has a lot of functionality inside of it like scroll management, focus management, and tracking position.
Here’s the basic anatomy of using scope and placing your Popover higher up
for performance:
_layout.tsx
UserAvatar.tsx
Note that the Trigger scope ties to the Popover scope.
API reference
In v3, Popover uses the same Adapt handoff path as Dialog. Adapted content stays mounted through the sheet exit animation and unmounts after the sheet reports that it is fully hidden.
Popover
Contains every component for the popover.
Props
children (required)
React.ReactNode
Must contain Popover.Content
placement
Placement
'top' | 'right' | 'bottom' | 'left' | 'top-start' | 'top-end' | 'right-start' | 'right-end' | 'bottom-start' | 'bottom-end' | 'left-start' | 'left-end'
open
boolean
Controlled open state of the popover.
defaultOpen
boolean
Initial open state when uncontrolled.
onOpenChange
(open: boolean, via?: 'hover' | 'press') => void
Called when the popover opens or closes. The optional second argument indicates how it was triggered - 'hover' for hover events (when using the hoverable prop) or 'press' for click/press events.
keepChildrenMounted
boolean | "lazy"
By default, Popover removes children from DOM/rendering when fully hidden. Setting true will keep children mounted even when hidden. This can be beneficial for performance if your popover content is expensive to render. The "lazy" value will only initially mount the children after a React startTransition, and then keep them mounted thereafter.
disableDismissable
boolean
Disables the dismissable layer (escape key, outside click handling). Useful when using keepChildrenMounted for popovers that stay mounted but are visually hidden - set this to true when the popover is hidden to prevent it from capturing escape key presses.
stayInFrame
ShiftProps | boolean
Default:
{ padding: 10 }Shifts the popover horizontally to stay within viewport bounds. Pass an object to customize shift behavior (mainAxis, crossAxis, padding).
allowFlip
FlipProps | boolean
Moves the Popover to other sides when space allows it, see floating-ui flip().
offset
OffsetOptions
Determines the distance the Popover appears from the target, see floating-ui offset().
hoverable
boolean | UseFloatingProps
Allows hovering on the trigger to open the popover. See UseFloatingProps from floating-ui: accepts boolean or object of { delay: number, restMs: number, handleClose: Function, mouseOnly: boolean, move: boolean }
disableFocus
boolean
Default:
!hoverableDisable opening when the trigger receives keyboard focus. Ordinary popovers open on click, Enter, or Space. Set false to open on focus; hoverable popovers enable this behavior by default.
resize
SizeProps | boolean
Will set maxWidth and maxHeight of Content to fit inside outer window when it won't fit, see floating-ui size().
zIndex
number
Override the automatic z-index stacking. By default, Tamagui automatically stacks overlays so later-opened content appears above earlier content. Only set this if you need to override the automatic behavior.
For most of these properties, you’ll want to reference the floating-ui docs.
Popover.Arrow
Popover.Arrow can be used to show an arrow that points at the Trigger element. In order for the Arrow to show you must have a Trigger element within your Popover. Arrows extend YStack, see Stacks.
Props
animatePosition
boolean
Enable smooth animation when the arrow position changes.
size
number
Size of the arrow in pixels.
offset
number
Offset from the content edge.
Popover.Trigger
Used to trigger opening of the popover when uncontrolled, just renders a YStack, see Stacks.
Popover.Content
Extends PopperContent which extends a YStack (see Stacks). Used to display the content of the popover.
Props
animatePosition
boolean | 'even-when-repositioning'
Enable smooth animation when the content position changes (e.g., when flipping sides).
transformOrigin
boolean
Default:
trueAutomatically sets CSS transform-origin based on placement and arrow position. Updates when the popover flips. Enables natural scale animations that grow from the arrow point.
unstyled
boolean
Removes all default Tamagui styles.
trapFocus
boolean
Whether focus should be trapped within the `Popover`
disableFocusScope
boolean
Whether popover should not focus contents on open
onOpenAutoFocus
FocusScopeProps['onMountAutoFocus']
Event handler called when auto-focusing on open. Can be prevented.
onCloseAutoFocus
FocusScopeProps['onUnmountAutoFocus'] | false
Event handler called when auto-focusing on close. Can be prevented.
lazyMount
boolean
Delays mounting content until first open.
forceMount
boolean
Disables part presence gating so the content stays mounted. Matches Dialog forceMount semantics.
Popover.Anchor
Renders as YStack, see Stacks.
When you want the Trigger to be in another location from where the Popover attaches, use Anchor. When used, Anchor is where the Popover will attach, while Trigger will open it.
Sheet (with Adapt)
When used with Adapt, you can render a Sheet when that breakpoint
is active. Import Sheet directly from tamagui or @tamagui/sheet.
See Sheet for more props.
Must use Adapt.Contents inside the Sheet.Container to insert the
contents given to Popover.Content
Popover.FocusScope
Provides access to the underlying FocusScope component used by Popover for focus management. Can be used to control focus behavior from a parent component.
Props
enabled
boolean
Default:
trueWhether focus management is enabled
loop
boolean
Default:
falseWhen true, tabbing from last item will focus first tabbable and shift+tab from first item will focus last tabbable
trapped
boolean
Default:
falseWhen true, focus cannot escape the focus scope via keyboard, pointer, or programmatic focus
noFocus
boolean
Default:
falseZero focus mode. While active, focus is allowed neither inside nor outside the scope. Web only.
focusOnIdle
boolean | number
Default:
trueWhen true, waits for idle before focusing. When a number, waits that many ms. This prevents reflows during animations
onMountAutoFocus
(event: Event) => void
Event handler called when auto-focusing on mount. Can be prevented
onUnmountAutoFocus
(event: Event) => void
Event handler called when auto-focusing on unmount. Can be prevented
Popover.ScrollView
Must be nested inside Content. Renders as a plain React Native ScrollView. If
used alongside <Adapt /> and Sheet, Tamagui will automatically know to remove
this ScrollView when swapping into the Sheet, as the Sheet must use its own
ScrollView that handles special logic for interactions with dragging.
Utility functions
These functions allow you to programmatically manage open popovers.
closeOpenPopovers
Closes all currently open popovers. Returns true if any popovers were closed, false if none were open.
closeLastOpenedPopover
Closes only the most recently opened popover. Returns true if a popover was closed, false if none were open.
hasOpenPopovers
Returns true if there are any open popovers, false otherwise.
Source
v2-look Popover: token-based padding and radius with theme background and arrow border styling, over the unstyled @tamagui/ui Popover behavior. This is the exact source the registry ships — copy it into your app and the examples above import from your copy.
components/tamagui/Popover.tsxDependencies
yarn add @tamagui/core @tamagui/popoverExpects theme tokens: background, border-color. Native: requires a Portal provider at the app root for the popover to mount above content
Need raw behavior without any skin? tamagui/unstyled re-exports the @tamagui/ui primitives (advanced).