Popover view for React Native via react-native-reanimated
npm install react-native-popover-reanimated
import { PopoverManager } from 'react-native-popover-reanimated';
Wrap your application render with the PopoverManager
component. Ensure react-native-gesture-handler
has already been set up with the GestureHandlerRootView
as well.
return (
<GestureHandlerRootView style={styles.flex}>
<PopoverManager>
{/* ... application ... */}
</PopoverManager>
</GestureHandlerRootView>
);
Additional props can be passed to the PopoverManager
to customize the positioning behavior of the popover view. The default values can be seen here:
<PopoverManager
originAnchor="bottom"
contentAnchor="top"
offsetX={0}
offsetY={0}
padding={16}>
- The anchors determine where the popover view will be presented
originAnchor
refers to the view marked as the origin (originRef
)contentAnchor
refers to the content rendered inside the popover view- The two views will line up on their respective anchors. With the default configuration above, the center-top of the content view will sit on the center-bottom of the origin view.
- Possible values are:
'top-left' | 'top' | 'top-right' | 'left' | 'center' | 'right' | 'bottom-left' | 'bottom' | 'bottom-right'
offsetX
/offsetY
: amount in pixels to offset the content view on the respective axispadding
: amount in pixels that the content view will be clamped to/spaced from the edge of the screen
import { usePopoverView } from 'react-native-popover-reanimated';
- Define a render function that returns the contents you wish to place inside the popover view. To avoid unnecessary rerenders, this method should be defined with the
useCallback
hook.
const renderContent = useCallback(() => (
<View>
<Text>Hello world</Text>
</View>
), []);
- Call the
usePopoverView
hook, passing the render function as the first argument, in order to access the popover handlers.
const { originRef, openPopover, closePopover } = usePopoverView(renderContent);
- Assign the
originRef
as theref
prop of a native view, such as aView
. This component determines the visual origin at which the popover will appear when theopenPopover
method is invoked. The component must be backed by a native view in order to make use of themeasure
function. React Native will attempt to optimize the native view hierarchy by not rendering a View it deems unnecessary. Add thecollapsable={false}
prop to prevent this from happening.
return (
<View ref={originRef} collapsable={false}>
<Button onPress={openPopover} title="Open popover" />
</View>
);
- Call the
openPopover
function from any source in order to present the popover view. Any touch down outside of the popover content bounds will instantly close the view.
The renderContent
callback also provides a closePopover
method as a parameter that can be used to trigger a close from within the popover content itself:
const renderContent = useCallback((closePopover) => (
<View>
<Text>Hello world</Text>
<Button title="Close" onPress={closePopover} />
</View>
), []);
To override the configuration props set on the PopoverManager
for a particular popover view, pass a partial configuration object as the second parameter of usePopoverView
:
const { originRef, openPopover } = usePopoverView(renderContent, {
originAnchor: 'bottom-right',
padding: 8,
});
export function Dropdown({ data, onSelect }) {
const renderContent = useCallback((closePopover) => {
const buttons = data.map((item) => (
<Button
title={item}
onPress={() => {
onSelect(item);
closePopover();
}}
/>
));
return (
<View style={styles.content}>{buttons}</View>
);
}, [data, onSelect]);
const { originRef, openPopover } = usePopoverView(renderContent);
return (
<View style={styles.container}>
<View ref={originRef} collapsable={false}>
<Button onPress={openPopover} title="Select item" />
</View>
</View>
);
}
export default function App() {
return (
<GestureHandlerRootView style={styles.flex}>
<PopoverManager>
<Dropdown
data={['One', 'Two', 'Three']}
onSelect={(item) => console.log('Selected', item)}
/>
</PopoverManager>
</GestureHandlerRootView>
);
}
- Popover styling, padding, animation configuration
- Accessibility setup
See the contributing guide to learn how to contribute to the repository and the development workflow.
MIT