// @flow import React from 'react' import ReactDOM from 'react-dom' import { Popper, Manager as PopperManager, PopperProps, Reference as PopperReference, } from 'react-popper' import { buildCss, noop } from '../utilities/props' import classnames from 'classnames' import { spacing } from '../utilities/spacing.js' type PbPopoverProps = { className?: String, closeOnClick?: "outside" | "inside", offset?: Boolean, reference: PopperReference, show?: Boolean, shouldClosePopover?: () => Boolean, } & PopperProps // Prop enabled default modifiers here // https://popper.js.org/docs/v2/modifiers const POPOVER_MODIFIERS = { offset: { //https://popper.js.org/docs/v2/modifiers/offset/ enabled: true, name: 'offset', options: { offset: [0, 20], }, phase: 'main', }, } const popoverModifiers = ({ modifiers, offset }) => { return offset ? modifiers.concat([POPOVER_MODIFIERS.offset]) : modifiers } const Popover = (props: PbPopoverProps) => { const { children, className, modifiers, offset, placement, referenceElement, zIndex, maxHeight, maxWidth, minHeight, minWidth, } = props const popoverSpacing = spacing(props) ? spacing(props) : 'p_sm' const overflowHandling = maxHeight || maxWidth ? 'overflow_handling' : '' const zIndexStyle = zIndex ? { zIndex: zIndex } : {} const widthHeightStyles = () => { return Object.assign( {}, maxHeight ? { maxHeight: maxHeight } : {}, maxWidth ? { maxWidth: maxWidth } : {}, minHeight ? { minHeight: minHeight } : {}, minWidth ? { minWidth: minWidth } : {} ) } return ( {({ placement, ref, style }) => { return (
{children}
) }}
) } export default class PbReactPopover extends React.Component { static defaultProps = { modifiers: [], offset: false, placement: 'left', portal: 'body', show: false, shouldClosePopover: noop, usePortal: true, } componentDidMount() { const { closeOnClick, shouldClosePopover } = this.props if (!closeOnClick) return document.body.addEventListener('click', ({ target }) => { const targetIsPopover = target.closest('[class^=pb_popover_tooltip]') !== null const targetIsReference = target.closest('.pb_popover_reference_wrapper') !== null if (targetIsReference) return switch (closeOnClick) { case 'outside': if (!targetIsPopover) { shouldClosePopover(true) } break case 'inside': if (targetIsPopover) { shouldClosePopover(true) } break case 'any': shouldClosePopover(true) break } }) } props: PbPopoverProps render() { const { className, children, modifiers, offset, placement, portal, reference, referenceElement, show, usePortal, zIndex, maxHeight, maxWidth, minHeight, minWidth, } = this.props const popoverComponent = ( {children} ) return ( {({ ref }) => ( )} {ReactDOM.createPortal( popoverComponent, document.querySelector(portal) )} {popoverComponent} ) } }