diff --git a/src/components/Popover/Popper.jsx b/src/components/Popover/Popper.jsx index 3e97951f1..5d413bba3 100644 --- a/src/components/Popover/Popper.jsx +++ b/src/components/Popover/Popper.jsx @@ -2,7 +2,7 @@ import _ from 'lodash'; import PropTypes from 'prop-types'; import React from 'react'; import { usePopper } from 'react-popper'; -import { popoverPlacements } from './constants'; +import { popoverPlacements, popoverStrategies } from './constants'; // default arrow position in pixel from the corresponding popover edge const DEFAULT_ARROW_POSITION = 12; @@ -47,6 +47,7 @@ const Popper = ({ arrowStyles, dts, placement: popperPlacement, + strategy, popoverClass, popoverContent, title, @@ -82,7 +83,8 @@ const Popper = ({ const { styles, attributes, update } = usePopper(refElement, popperElement, { modifiers: defaultModifiers.concat(modifiers), placement: popperPlacement, - wrapperStyles, + strategy, + ...wrapperStyles, }); const calculatedArrowStyles = renderArrowStyles(popperPlacement, arrowStyles, popperElement); @@ -123,6 +125,7 @@ Popper.propTypes = { dts: PropTypes.string, modifiers: PropTypes.oneOfType([PropTypes.object, PropTypes.arrayOf(PropTypes.object)]), // eslint-disable-line react/forbid-prop-types placement: PropTypes.oneOf(popoverPlacements), + strategy: PropTypes.oneOf(popoverStrategies), popoverClass: PropTypes.string, popoverContent: PropTypes.oneOfType([PropTypes.node, PropTypes.func]).isRequired, refElement: PropTypes.instanceOf(Element), diff --git a/src/components/Popover/WithRef.jsx b/src/components/Popover/WithRef.jsx index c10b19113..dc3044c00 100644 --- a/src/components/Popover/WithRef.jsx +++ b/src/components/Popover/WithRef.jsx @@ -4,7 +4,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; import PropTypes from 'prop-types'; import Popper from './Popper'; -import { themes, popoverPlacements } from './constants'; +import { themes, popoverPlacements, popoverStrategies } from './constants'; import './styles.scss'; const WithRef = ({ @@ -17,6 +17,7 @@ const WithRef = ({ modifiers, wrapperStyles, placement, + strategy, isOpen, arrowStyles, getContainer, @@ -39,6 +40,7 @@ const WithRef = ({ boundariesElement={boundariesElement} arrowStyles={arrowStyles} placement={placement} + strategy={strategy} modifiers={modifiers} popperRef={popperRef} />, @@ -56,6 +58,7 @@ WithRef.propTypes = { wrapperStyles: PropTypes.object, // eslint-disable-line react/forbid-prop-types modifiers: PropTypes.oneOfType([PropTypes.object, PropTypes.arrayOf(PropTypes.object)]), // eslint-disable-line react/forbid-prop-types placement: PropTypes.oneOf(popoverPlacements), + strategy: PropTypes.oneOf(popoverStrategies), popoverContent: PropTypes.oneOfType([PropTypes.node, PropTypes.func]).isRequired, isOpen: PropTypes.bool, popperRef: PropTypes.func, diff --git a/src/components/Popover/constants.js b/src/components/Popover/constants.js index 2cc2ad6ac..d265ccd08 100644 --- a/src/components/Popover/constants.js +++ b/src/components/Popover/constants.js @@ -4,3 +4,10 @@ export const themes = ['light', 'dark', 'warn', 'error', 'info', 'success']; const basePlacements = ['auto', 'top', 'right', 'bottom', 'left']; export const popoverPlacements = _.flatMap(basePlacements, trigger => [trigger, `${trigger}-start`, `${trigger}-end`]); + +/** + * Describes the positioning strategy to use. + * By default, it is absolute. + * If your reference element is in a fixed container, use the fixed strategy + */ +export const popoverStrategies = ['absolute', 'fixed']; diff --git a/src/components/Popover/index.jsx b/src/components/Popover/index.jsx index 89f3051c5..e40f54dda 100644 --- a/src/components/Popover/index.jsx +++ b/src/components/Popover/index.jsx @@ -3,7 +3,7 @@ import _ from 'lodash'; import classnames from 'classnames'; import PropTypes from 'prop-types'; import React, { useState } from 'react'; -import { themes, popoverPlacements } from './constants'; +import { themes, popoverPlacements, popoverStrategies } from './constants'; import WithRef from './WithRef'; import './styles.scss'; @@ -66,6 +66,7 @@ const Popover = props => { getContainer={props.getContainer} arrowStyles={props.arrowStyles} placement={props.placement} + strategy={props.strategy} modifiers={props.modifiers} isOpen={isPopoverOpen} popperRef={popperRef} @@ -86,6 +87,7 @@ Popover.propTypes = { wrapperStyles: PropTypes.object, // eslint-disable-line react/forbid-prop-types modifiers: PropTypes.oneOfType([PropTypes.object, PropTypes.arrayOf(PropTypes.object)]), // eslint-disable-line react/forbid-prop-types placement: PropTypes.oneOf(popoverPlacements), + strategy: PropTypes.oneOf(popoverStrategies), popoverContent: PropTypes.oneOfType([PropTypes.node, PropTypes.func]).isRequired, children: PropTypes.node.isRequired, triggers: PropTypes.oneOfType([triggerPropTypes, PropTypes.arrayOf(triggerPropTypes)]), @@ -98,6 +100,7 @@ Popover.propTypes = { Popover.defaultProps = { theme: 'light', placement: 'auto', + strategy: 'absolute', triggers: 'hover', isOpen: false, }; diff --git a/www/containers/props.json b/www/containers/props.json index 2e1f00fd5..e32fa3794 100644 --- a/www/containers/props.json +++ b/www/containers/props.json @@ -3202,6 +3202,19 @@ "computed": false } }, + "strategy": { + "type": { + "name": "enum", + "computed": true, + "value": "popoverStrategies" + }, + "required": false, + "description": "", + "defaultValue": { + "value": "'absolute'", + "computed": false + } + }, "popoverContent": { "type": { "name": "union", @@ -3334,6 +3347,15 @@ "required": false, "description": "" }, + "strategy": { + "type": { + "name": "enum", + "computed": true, + "value": "popoverStrategies" + }, + "required": false, + "description": "" + }, "popoverClass": { "type": { "name": "string"