diff --git a/src-docs/src/views/popover/popover_container.js b/src-docs/src/views/popover/popover_container.js
new file mode 100644
index 000000000000..39c0de0872ab
--- /dev/null
+++ b/src-docs/src/views/popover/popover_container.js
@@ -0,0 +1,69 @@
+import React, {
+ Component,
+} from 'react';
+
+import {
+ EuiButton,
+ EuiCode,
+ EuiPanel,
+ EuiPopover,
+ EuiSpacer,
+} from '../../../../src/components';
+
+export default class PopoverContainer extends Component {
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ isPopoverOpen: false,
+ };
+ }
+
+ onButtonClick = () => {
+ this.setState({
+ isPopoverOpen: !this.state.isPopoverOpen,
+ });
+ }
+
+ closePopover = () => {
+ this.setState({
+ isPopoverOpen: false,
+ });
+ }
+
+ setPanelRef = node => this.panel = node;
+
+ render() {
+ const button = (
+
+ Show constrained popover
+
+ );
+
+ return (
+
+
+
+ Popover is positioned downCenter but
+ constrained to fit within the panel.
+
+
+
+ {/* create adequate room for the popover */}
+
+
+
+ );
+ }
+}
diff --git a/src-docs/src/views/popover/popover_example.js b/src-docs/src/views/popover/popover_example.js
index 057b0c038498..356ad0fee10d 100644
--- a/src-docs/src/views/popover/popover_example.js
+++ b/src-docs/src/views/popover/popover_example.js
@@ -40,6 +40,10 @@ import PopoverHTMLElementAnchor from './popover_htmlelement_anchor';
const popoverHTMLElementAnchorSource = require('!!raw-loader!./popover_htmlelement_anchor');
const popoverHTMLElementAnchorHtml = renderToHtml(PopoverHTMLElementAnchor);
+import PopoverContainer from './popover_container';
+const popoverContainerSource = require('!!raw-loader!./popover_htmlelement_anchor');
+const popoverContainerHtml = renderToHtml(PopoverHTMLElementAnchor);
+
export const PopoverExample = {
title: 'Popover',
@@ -163,6 +167,25 @@ export const PopoverExample = {
),
demo: ,
+ }, {
+ title: 'Constraining a popover inside a container',
+ source: [{
+ type: GuideSectionTypes.JS,
+ code: popoverContainerSource,
+ }, {
+ type: GuideSectionTypes.HTML,
+ code: popoverContainerHtml,
+ }],
+ text: (
+
+
+ EuiPopover can accept a React or DOM element as
+ a container prop and restrict the popover from
+ overflowing that container.
+
+
+ ),
+ demo: ,
}, {
title: 'Popover using an HTMLElement as the anchor',
source: [{
diff --git a/src/components/popover/popover.js b/src/components/popover/popover.js
index 5a0afd770473..1e9e3957a0f1 100644
--- a/src/components/popover/popover.js
+++ b/src/components/popover/popover.js
@@ -224,6 +224,7 @@ export class EuiPopover extends Component {
if (this.button == null || this.panel == null) return;
const { top, left, position, arrow } = findPopoverPosition({
+ container: this.props.container,
position: getPopoverPositionFromAnchorPosition(this.props.anchorPosition),
align: getPopoverAlignFromAnchorPosition(this.props.anchorPosition),
anchor: this.button,
@@ -235,7 +236,7 @@ export class EuiPopover extends Component {
}
});
- // the popver's z-index must inherit from the button
+ // the popover's z-index must inherit from the button
// this keeps a button's popover under a flyout that would cover the button
// but a popover triggered inside a flyout will appear over that flyout
const zIndex = getElementZIndex(this.button, this.panel);
@@ -403,15 +404,16 @@ EuiPopover.propTypes = {
ownFocus: PropTypes.bool,
withTitle: PropTypes.bool,
closePopover: PropTypes.func.isRequired,
- button: PropTypes.oneOfType([
- PropTypes.node,
- PropTypes.instanceOf(HTMLElement),
- ]).isRequired,
+ button: PropTypes.node.isRequired,
children: PropTypes.node,
anchorPosition: PropTypes.oneOf(ANCHOR_POSITIONS),
panelClassName: PropTypes.string,
panelPaddingSize: PropTypes.oneOf(SIZES),
- popoverRef: PropTypes.func
+ popoverRef: PropTypes.func,
+ container: PropTypes.oneOfType([
+ PropTypes.node,
+ PropTypes.instanceOf(HTMLElement)
+ ]),
};
EuiPopover.defaultProps = {
diff --git a/src/components/popover/wrapping_popover.js b/src/components/popover/wrapping_popover.js
index 9f14f274ae1d..542d779af561 100644
--- a/src/components/popover/wrapping_popover.js
+++ b/src/components/popover/wrapping_popover.js
@@ -1,5 +1,6 @@
import React, { Component } from 'react';
import { findDOMNode } from 'react-dom';
+import PropTypes from 'prop-types';
import { EuiPopover } from './popover';
import { EuiPortal } from '../portal';
@@ -55,3 +56,7 @@ export class EuiWrappingPopover extends Component {
);
}
}
+
+EuiWrappingPopover.propTypes = {
+ button: PropTypes.instanceOf(HTMLElement),
+};