Skip to content

Commit

Permalink
Add container prop to EuiPopover
Browse files Browse the repository at this point in the history
  • Loading branch information
chandlerprall committed Jul 11, 2018
1 parent d23e18a commit 5e3ee29
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 6 deletions.
69 changes: 69 additions & 0 deletions src-docs/src/views/popover/popover_container.js
Original file line number Diff line number Diff line change
@@ -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 = (
<EuiButton
iconType="arrowDown"
iconSide="right"
onClick={this.onButtonClick}
style={{ position: 'relative', left: 50 }}
>
Show constrained popover
</EuiButton>
);

return (
<EuiPanel panelRef={this.setPanelRef}>
<EuiPopover
id="popover"
button={button}
isOpen={this.state.isPopoverOpen}
closePopover={this.closePopover}
container={this.panel}
>
<div>
Popover is positioned <EuiCode>downCenter</EuiCode> but
constrained to fit within the panel.
</div>
</EuiPopover>

{/* create adequate room for the popover */}
<EuiSpacer size="xxl"/>
<EuiSpacer size="xxl"/>
</EuiPanel>
);
}
}
23 changes: 23 additions & 0 deletions src-docs/src/views/popover/popover_example.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -163,6 +167,25 @@ export const PopoverExample = {
</div>
),
demo: <PopoverWithTitlePadding />,
}, {
title: 'Constraining a popover inside a container',
source: [{
type: GuideSectionTypes.JS,
code: popoverContainerSource,
}, {
type: GuideSectionTypes.HTML,
code: popoverContainerHtml,
}],
text: (
<div>
<p>
<EuiCode>EuiPopover</EuiCode> can accept a React or DOM element as
a <EuiCode>container</EuiCode> prop and restrict the popover from
overflowing that container.
</p>
</div>
),
demo: <PopoverContainer />,
}, {
title: 'Popover using an HTMLElement as the anchor',
source: [{
Expand Down
14 changes: 8 additions & 6 deletions src/components/popover/popover.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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);
Expand Down Expand Up @@ -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 = {
Expand Down
5 changes: 5 additions & 0 deletions src/components/popover/wrapping_popover.js
Original file line number Diff line number Diff line change
@@ -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';

Expand Down Expand Up @@ -55,3 +56,7 @@ export class EuiWrappingPopover extends Component {
);
}
}

EuiWrappingPopover.propTypes = {
button: PropTypes.instanceOf(HTMLElement),
};

0 comments on commit 5e3ee29

Please sign in to comment.