Tooltip
Jetpack Compose Tooltip components for displaying contextual information on long-press.
Expo UI Tooltip matches the official Jetpack Compose Tooltip API. TooltipBox wraps anchor content and displays a tooltip. The tooltip content is provided via the TooltipBox.PlainTooltip or TooltipBox.RichTooltip compound components, which match PlainTooltip and RichTooltip respectively. Tooltips can be triggered by long-press or shown programmatically via ref.
Installation
- npx expo install @expo/uiIf you are installing this in an existing React Native app, make sure to install expo in your project.
Usage
Plain tooltip
Long-press the anchor content to display the tooltip.
import { Host, TooltipBox, Button, Text } from '@expo/ui/jetpack-compose'; export default function PlainTooltipExample() { return ( <Host matchContents> <TooltipBox> <TooltipBox.PlainTooltip> <Text>Add to favorites</Text> </TooltipBox.PlainTooltip> <Button onClick={() => {}}> <Text>Favorite</Text> </Button> </TooltipBox> </Host> ); }
Rich tooltip with title and body
Use TooltipBox.RichTooltip with Title and Text compound component pattern for more detailed contextual information.
import { Host, TooltipBox, Button, Text } from '@expo/ui/jetpack-compose'; export default function RichTooltipExample() { return ( <Host matchContents> <TooltipBox> <TooltipBox.RichTooltip> <TooltipBox.RichTooltip.Title> <Text>Camera</Text> </TooltipBox.RichTooltip.Title> <TooltipBox.RichTooltip.Text> <Text>Take photos and record videos with your device camera.</Text> </TooltipBox.RichTooltip.Text> </TooltipBox.RichTooltip> <Button onClick={() => {}}> <Text>Open Camera</Text> </Button> </TooltipBox> </Host> ); }
Rich tooltip with action
Add an interactive action with TooltipBox.RichTooltip.Action. Use isPersistent so the tooltip stays visible for the user to tap it. hasAction is automatically derived when an action slot is present.
import { Host, TooltipBox, Button, TextButton, Text } from '@expo/ui/jetpack-compose'; export default function RichTooltipActionExample() { return ( <Host matchContents> <TooltipBox isPersistent> <TooltipBox.RichTooltip> <TooltipBox.RichTooltip.Title> <Text>Permissions Required</Text> </TooltipBox.RichTooltip.Title> <TooltipBox.RichTooltip.Text> <Text>This feature requires camera and microphone access.</Text> </TooltipBox.RichTooltip.Text> <TooltipBox.RichTooltip.Action> <TextButton onClick={() => {}}> <Text>Learn More</Text> </TextButton> </TooltipBox.RichTooltip.Action> </TooltipBox.RichTooltip> <Button onClick={() => {}}> <Text>Record Video</Text> </Button> </TooltipBox> </Host> ); }
Programmatic show and dismiss
Use a ref to imperatively show() or dismiss() the tooltip without requiring a long-press.
import { useRef } from 'react'; import { Host, TooltipBox, type TooltipBoxRef, Button, Text, Row } from '@expo/ui/jetpack-compose'; export default function ProgrammaticTooltipExample() { const tooltipRef = useRef<TooltipBoxRef>(null); return ( <Host matchContents> <TooltipBox ref={tooltipRef} isPersistent> <TooltipBox.PlainTooltip> <Text>Shown programmatically!</Text> </TooltipBox.PlainTooltip> <Button onClick={() => {}}> <Text>Anchor</Text> </Button> </TooltipBox> <Row horizontalArrangement={{ spacedBy: 8 }}> <Button onClick={() => tooltipRef.current?.show()}> <Text>Show</Text> </Button> <Button onClick={() => tooltipRef.current?.dismiss()}> <Text>Dismiss</Text> </Button> </Row> </Host> ); }
API
import { TooltipBox } from '@expo/ui/jetpack-compose';
Component
Type: React.Element<TooltipBoxProps>
A container that wraps anchor content and shows a tooltip on long-press.
Provide the tooltip content via TooltipBox.PlainTooltip or TooltipBox.RichTooltip.
All other children are the anchor/trigger.
Use ref to imperatively show() or dismiss() the tooltip.
React.ReactNodeChildren containing a TooltipBox.PlainTooltip or TooltipBox.RichTooltip slot and the anchor/trigger content.
The anchor content triggers the tooltip on long-press.
boolean • Default: trueWhether user input (long-press, hover) triggers the tooltip.
booleanWhether the tooltip contains an action. Affects accessibility and dismiss behavior.
When not specified, this is automatically derived from the presence of a RichTooltip.Action slot.
boolean • Default: falseWhether the tooltip persists instead of auto-dismissing after a short timeout.