Popover
Popover
Positioned overlay anchored to a trigger with collision detection.
Usage
Wrap any floating panel such as tooltips, emoji pickers, or menus.
Highlights
- Portal + ScrollAware repositioning
- Arrow and offset configuration
When to use it
- Content must stay attached to a control.
- You need custom overlay surfaces beyond Menu.
Examples
Default
Preview (Web)
import { useState } from 'react'; import { StyleSheet, View } from 'react-native'; import { Button } from 'react-native-molecules/components/Button'; import { Popover } from 'react-native-molecules/components/Popover'; import { Text } from 'react-native-molecules/components/Text'; const styles = StyleSheet.create({ container: { padding: 48, alignItems: 'center', justifyContent: 'center', height: 260, }, content: { padding: 16, }, }); export default function Example() { const [open, setOpen] = useState(false); return ( <View style={styles.container}> <Popover isOpen={open} onClose={() => setOpen(false)}> <Popover.Trigger> <Button onPress={() => setOpen(o => !o)}>Show Popover</Button> </Popover.Trigger> <Popover.Content> <View style={styles.content}> <Text>I'm a popover</Text> </View> </Popover.Content> </Popover> </View> ); }
With Arrow
Compose <Popover.Arrow /> inside the content to render an arrow pointing at the trigger. Tune size and bump the Popover's offset to leave room for it.
Preview (Web)
import { useState } from 'react'; import { StyleSheet, View } from 'react-native'; import { Button } from 'react-native-molecules/components/Button'; import { Popover } from 'react-native-molecules/components/Popover'; import { Text } from 'react-native-molecules/components/Text'; const styles = StyleSheet.create({ container: { padding: 48, alignItems: 'center', justifyContent: 'center', height: 260, }, content: { padding: 16, }, }); export default function Example() { const [open, setOpen] = useState(false); return ( <View style={styles.container}> <Popover isOpen={open} onClose={() => setOpen(false)} offset={16}> <Popover.Trigger> <Button onPress={() => setOpen(o => !o)}>Show Popover</Button> </Popover.Trigger> <Popover.Content> <View style={styles.content}> <Text>I'm a popover with an arrow</Text> </View> <Popover.Arrow size={10} /> </Popover.Content> </Popover> </View> ); }
With Overlay (backdrop dismiss)
Compose <Popover.Overlay /> to render a full-screen backdrop that closes the popover on press. Useful on native where there's no document-level click-outside listener, or when you want a tinted scrim.
Preview (Web)
import { useState } from 'react'; import { StyleSheet, View } from 'react-native'; import { Button } from 'react-native-molecules/components/Button'; import { Popover } from 'react-native-molecules/components/Popover'; import { Text } from 'react-native-molecules/components/Text'; const styles = StyleSheet.create({ container: { padding: 48, alignItems: 'center', justifyContent: 'center', height: 260, }, content: { padding: 16, }, backdrop: { backgroundColor: 'rgba(0, 0, 0, 0.3)', }, }); export default function Example() { const [open, setOpen] = useState(false); return ( <View style={styles.container}> <Popover isOpen={open} onClose={() => setOpen(false)}> <Popover.Trigger> <Button onPress={() => setOpen(o => !o)}>Show Popover</Button> </Popover.Trigger> <Popover.Overlay style={styles.backdrop} /> <Popover.Content> <View style={styles.content}> <Text>Tap outside to close</Text> </View> </Popover.Content> </Popover> </View> ); }
Positioning
Use position, align, offset, and horizontalOffset to control placement. The popover auto-flips to the opposite side when it would overflow the viewport.
Preview (Web)
import { useState } from 'react'; import { StyleSheet, View } from 'react-native'; import { Button } from 'react-native-molecules/components/Button'; import { Popover } from 'react-native-molecules/components/Popover'; import { Text } from 'react-native-molecules/components/Text'; const styles = StyleSheet.create({ container: { padding: 80, alignItems: 'center', justifyContent: 'center', height: 260, }, content: { padding: 16, }, }); export default function Example() { const [open, setOpen] = useState(false); return ( <View style={styles.container}> <Popover isOpen={open} onClose={() => setOpen(false)} position="right" align="start" offset={12} horizontalOffset={4}> <Popover.Trigger> <Button onPress={() => setOpen(o => !o)}>Show Popover</Button> </Popover.Trigger> <Popover.Content> <View style={styles.content}> <Text>Positioned to the right</Text> </View> </Popover.Content> </Popover> </View> ); }