Skip to content

Instantly share code, notes, and snippets.

@rjerue
Last active Jan 27, 2021
Embed
What would you like to do?
React Native Web Popovers
// Leverage off the shelf popovers for native and web
import React from 'react'
import { View } from 'react-native'
import Popover from './Popover'
export default function index({
visible = false,
position,
onClose = () => null,
children = null,
content = null,
popoverStyle,
arrowStyle,
}) {
return (
<View style={{ flexDirection: 'row' }}>
<Popover
{...{
visible,
position,
onClose,
content,
popoverStyle,
arrowStyle,
}}
>
{children}
</Popover>
<View style={{ flexGrow: 1 }} />
</View>
)
}
// web
import P, { ArrowContainer } from 'react-tiny-popover'
import React from 'react'
export default ({
visible = false,
position,
onClose,
children,
content = null,
popoverStyle,
arrowStyle,
}) => (
<P
isOpen={visible}
content={({ position: arrowPosition, targetRect, popoverRect }) => (
<ArrowContainer
arrowStyle={arrowStyle}
position={arrowPosition}
targetRect={targetRect}
popoverRect={popoverRect}
>
{content}
</ArrowContainer>
)}
onClickOutside={onClose}
containerStyle={popoverStyle}
position={position}
>
{children}
</P>
)
import React, { useState } from 'react'
import { View } from 'react-native'
import P from 'react-native-popover-view'
export default ({
visible = false,
position,
onClose = () => null,
children = null,
content = null,
popoverStyle,
arrowStyle,
}) => {
const [ref, setRef] = useState(null)
return (
<View>
<View ref={r => !ref && r && setRef(r)} renderToHardwareTextureAndroid collapsable={false}>
{children}
</View>
<P
popoverStyle={popoverStyle}
arrowStyle={arrowStyle}
isVisible={visible}
fromView={ref}
onClose={onClose}
placement={position}
showBackground={false}
>
{content}
</P>
</View>
)
}
import React, { useState } from 'react'
import { TouchableOpacity, Platform } from 'react-native'
import Popover from './Popover'
export default function Tooltip({
visible: visibleProp,
setVisible: setVisibleProp,
children,
content,
...props
}) {
if (typeof visibleProp !== 'undefined') {
console.error('Visible should be undefined, ignoreing value')
}
if (typeof setVisibleProp !== 'undefined') {
console.error('setVisible should be undefined, ignoreing value')
}
const [visible, setVisible] = useState(false)
const withMouse = Component => React.cloneElement(Component, {
onMouseEnter: () => setVisible(true),
onMouseLeave: () => setVisible(false),
})
return (
<Popover
{...{
visible,
content: Platform.OS === 'web' ? withMouse(content) : content,
onClose: () => setVisible(false),
...props,
}}
>
{Platform.OS === 'web' ? (
withMouse(children)
) : (
<TouchableOpacity onPress={() => setVisible(!visible)}>{children}</TouchableOpacity>
)}
</Popover>
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment