Skip to content

Commit

Permalink
popover updates
Browse files Browse the repository at this point in the history
  • Loading branch information
chrismcv committed Nov 11, 2015
1 parent 1f2dfbd commit 932271b
Show file tree
Hide file tree
Showing 4 changed files with 206 additions and 19 deletions.
91 changes: 88 additions & 3 deletions docs/src/app/components/pages/components/popover.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ let PopoverPage = React.createClass({
selectValue:'1',
textValue:'here is a value',
activePopover:'none',
anchorOrigin:{horizontal:'left', vertical:'bottom'},
targetOrigin:{horizontal:'left', vertical:'top'},
}
},

Expand Down Expand Up @@ -60,7 +62,7 @@ let PopoverPage = React.createClass({
'which is useful for mobile devices.',
},
{
name: 'isOpen',
name: 'open',
type: 'bool',
header: 'default: false',
desc: 'Controls the visibility of the popover.',
Expand Down Expand Up @@ -98,12 +100,45 @@ let PopoverPage = React.createClass({
Click on me to show a popover
</a>
<br/>
<br/>

<a onClick={this.show.bind(this, "pop2")}>
Click on me to show a with a nested popover (SelectField)
</a>
<br />
<em>Note that in this version, the select field causes nasty scrolling,
an upcoming PR will fix, which updates SelectField to use the popover for itself!</em>

<br/>
<br/>
<br/>
<h2>Positioning Playground</h2>
<p>There are two important properties, <strong>anchorOrigin</strong> and <strong>targetOrigin</strong>.
The popover position will be the intersection of the two origins.
</p>
<div ref="anchor" style={{display:'block', width:'100%', border:'1px solid #ccc', position:'relative', padding:5}}>
<h3>AnchorOrigin</h3>
<p>This box is the anchor element for the Popover component. Click on a link to set what the anchorOrigin should be.</p>
<pre>anchorOrigin:{JSON.stringify(this.state.anchorOrigin)}</pre>
<div style={{display:'block', width:'100%', height:60, background:'#eee', position:'relative'}}>
<h4>Horizontal Position Modes</h4>
<a onClick={this.showPositionedPopover.bind(this, 'horizontal', 'left')} style={{position:'absolute', top: 30, left:0, background:'#eee', border:'1px solid ', width:50}}>Left</a>
<a onClick={this.showPositionedPopover.bind(this, 'horizontal', 'middle')} style={{position:'absolute', top: 30, left:'50%', background:'#eee', border:'1px solid ', width:50}}>Middle</a>
<a onClick={this.showPositionedPopover.bind(this, 'horizontal', 'right')} style={{position:'absolute', top: 30, right:0, background:'#eee', border:'1px solid ', width:50}}>Right</a>

</div>

<Popover isOpen={this.state.activePopover === 'pop'}
<div style={{display:'block', height:200, background:'#eee', position:'relative'}}>
<h4>Vertical Position Modes</h4>
<a onClick={this.showPositionedPopover.bind(this, 'vertical', 'top')} style={{position:'absolute', left:200, top:0, background:'#eee', border:'1px solid ', width:50}}>Top</a>
<a onClick={this.showPositionedPopover.bind(this, 'vertical', 'center')} style={{position:'absolute', left:200, top:'50%', background:'#eee', border:'1px solid ', width:50}}>Center</a>
<a onClick={this.showPositionedPopover.bind(this, 'vertical', 'bottom')} style={{position:'absolute', left:200, bottom:0, background:'#eee', border:'1px solid ', width:50}}>Bottom*</a>

<div style={{position:'absolute', left:260, bottom:0}}>* Popover auto positions to stay on screen, so note that a bottom anchor won't work unless your page is scrolled a bit!</div>
</div>
</div>

<Popover open={this.state.activePopover === 'pop'}
anchorEl={this.state.anchorEl}
onRequestClose={this.closePopover} >
<div style={{padding:20}}>
Expand All @@ -112,21 +147,50 @@ let PopoverPage = React.createClass({
<RaisedButton primary={true} label="Here is a button"/>
</div>
</Popover>
<Popover isOpen={this.state.activePopover === 'pop2'}
<Popover open={this.state.activePopover === 'pop2'}
anchorEl={this.state.anchorEl}
onRequestClose={this.closePopover} >
<div style={{padding:20}}>
<h2>Here is an arbitrary popover</h2>
<p>Hi - here is some content</p>
<SelectField menuItems={menuItems} onChange={this.onChangeSelect} value={this.state.selectValue} />
<br />
<TextField onChange={this.onChangeText} value={this.state.textValue} />
</div>
</Popover>



<Popover open={this.state.activePopover === 'anchors'}
anchorEl={this.state.anchorEl}
anchorOrigin={this.state.anchorOrigin}
targetOrigin={this.state.targetOrigin}>
<div style={{padding:20, width:400}}>
<h3>TargetOrigin</h3>
<p>This box is the anchor element for the Popover component. Click on a link to set what the anchorOrigin should be.</p>
<pre>targetOrigin:{JSON.stringify(this.state.targetOrigin)}</pre>
<div style={{display:'block', width:'100%', height:60, background:'#eee', position:'relative'}}>
<h4>Horizontal Position Modes</h4>
<a onClick={this.showTargetedPopover.bind(this, 'horizontal', 'left')} style={{position:'absolute', top: 30, left:0, background:'#eee', border:'1px solid ', width:50}}>Left</a>
<a onClick={this.showTargetedPopover.bind(this, 'horizontal', 'middle')} style={{position:'absolute', top: 30, left:'50%', background:'#eee', border:'1px solid ', width:50}}>Middle</a>
<a onClick={this.showTargetedPopover.bind(this, 'horizontal', 'right')} style={{position:'absolute', top: 30, right:0, background:'#eee', border:'1px solid ', width:50}}>Right</a>
</div>

<div style={{display:'block', height:200, background:'#eee', position:'relative'}}>
<h4>Vertical Position Modes</h4>
<a onClick={this.showTargetedPopover.bind(this, 'vertical', 'top')} style={{position:'absolute', left:200, top:0, background:'#eee', border:'1px solid ', width:50}}>Top</a>
<a onClick={this.showTargetedPopover.bind(this, 'vertical', 'center')} style={{position:'absolute', left:200, top:'50%', background:'#eee', border:'1px solid ', width:50}}>Center</a>
<a onClick={this.showTargetedPopover.bind(this, 'vertical', 'bottom')} style={{position:'absolute', left:200, bottom:0, background:'#eee', border:'1px solid ', width:50}}>Bottom</a>
</div>
</div>
</Popover>
</CodeExample>
</ComponentDoc>
);
},



show(key, e) {
this.setState({
activePopover:key,
Expand All @@ -140,6 +204,27 @@ let PopoverPage = React.createClass({
});
},

showPositionedPopover(positionElement, position ,e) {
let {anchorOrigin} = this.state;
anchorOrigin[positionElement] = position;

this.setState({
activePopover:'anchors',
anchorEl:this.refs.anchor,
anchorOrigin:anchorOrigin,
});
},

showTargetedPopover(positionElement, position ,e) {
let {targetOrigin} = this.state;
targetOrigin[positionElement] = position;

this.setState({
activePopover:'anchors',
anchorEl:this.refs.anchor,
targetOrigin:targetOrigin,
});
},
onChangeSelect(e) {
this.setState({
selectValue:e.target.value,
Expand Down
110 changes: 106 additions & 4 deletions docs/src/app/components/raw-code/popover-code.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,46 @@
<Popover isOpen={this.state.activePopover === 'pop'}
<a onClick={this.show.bind(this, "pop")}>
Click on me to show a popover
</a>
<br/>
<br/>

<a onClick={this.show.bind(this, "pop2")}>
Click on me to show a with a nested popover (SelectField)
</a>
<br />
<em>Note that in this version, the select field causes nasty scrolling,
an upcoming PR will fix, which updates SelectField to use the popover for itself!</em>

<br/>
<br/>
<br/>
<h2>Positioning Playground</h2>
<p>There are two important properties, <strong>anchorOrigin</strong> and <strong>targetOrigin</strong>.
The popover position will be the intersection of the two origins.
</p>
<div ref="anchor" style={{display:'block', width:'100%', border:'1px solid #ccc', position:'relative', padding:5}}>
<h3>AnchorOrigin</h3>
<p>This box is the anchor element for the Popover component. Click on a link to set what the anchorOrigin should be.</p>
<pre>anchorOrigin:{JSON.stringify(this.state.anchorOrigin)}</pre>
<div style={{display:'block', width:'100%', height:60, background:'#eee', position:'relative'}}>
<h4>Horizontal Position Modes</h4>
<a onClick={this.showPositionedPopover.bind(this, 'horizontal', 'left')} style={{position:'absolute', top: 30, left:0, background:'#eee', border:'1px solid ', width:50}}>Left</a>
<a onClick={this.showPositionedPopover.bind(this, 'horizontal', 'middle')} style={{position:'absolute', top: 30, left:'50%', background:'#eee', border:'1px solid ', width:50}}>Middle</a>
<a onClick={this.showPositionedPopover.bind(this, 'horizontal', 'right')} style={{position:'absolute', top: 30, right:0, background:'#eee', border:'1px solid ', width:50}}>Right</a>

</div>

<div style={{display:'block', height:200, background:'#eee', position:'relative'}}>
<h4>Vertical Position Modes</h4>
<a onClick={this.showPositionedPopover.bind(this, 'vertical', 'top')} style={{position:'absolute', left:200, top:0, background:'#eee', border:'1px solid ', width:50}}>Top</a>
<a onClick={this.showPositionedPopover.bind(this, 'vertical', 'center')} style={{position:'absolute', left:200, top:'50%', background:'#eee', border:'1px solid ', width:50}}>Center</a>
<a onClick={this.showPositionedPopover.bind(this, 'vertical', 'bottom')} style={{position:'absolute', left:200, bottom:0, background:'#eee', border:'1px solid ', width:50}}>Bottom*</a>

<div style={{position:'absolute', left:260, bottom:0}}>* Popover auto positions to stay on screen, so note that a bottom anchor won't work unless your page is scrolled a bit!</div>
</div>
</div>

<Popover open={this.state.activePopover === 'pop'}
anchorEl={this.state.anchorEl}
onRequestClose={this.closePopover} >
<div style={{padding:20}}>
Expand All @@ -7,18 +49,45 @@
<RaisedButton primary={true} label="Here is a button"/>
</div>
</Popover>

<Popover isOpen={this.state.activePopover === 'pop2'}
<Popover open={this.state.activePopover === 'pop2'}
anchorEl={this.state.anchorEl}
onRequestClose={this.closePopover} >
<div style={{padding:20}}>
<h2>Here is an arbitrary popover</h2>
<p>Hi - here is some content</p>
<SelectField menuItems={menuItems} onChange={this.onChangeSelect} value={this.state.selectValue} />
<br />
<TextField onChange={this.onChangeText} value={this.state.textValue} />
</div>
</Popover>



<Popover open={this.state.activePopover === 'anchors'}
anchorEl={this.state.anchorEl}
anchorOrigin={this.state.anchorOrigin}
targetOrigin={this.state.targetOrigin}>
<div style={{padding:20, width:400}}>
<h3>TargetOrigin</h3>
<p>This box is the anchor element for the Popover component. Click on a link to set what the anchorOrigin should be.</p>
<pre>targetOrigin:{JSON.stringify(this.state.targetOrigin)}</pre>
<div style={{display:'block', width:'100%', height:60, background:'#eee', position:'relative'}}>
<h4>Horizontal Position Modes</h4>
<a onClick={this.showTargetedPopover.bind(this, 'horizontal', 'left')} style={{position:'absolute', top: 30, left:0, background:'#eee', border:'1px solid ', width:50}}>Left</a>
<a onClick={this.showTargetedPopover.bind(this, 'horizontal', 'middle')} style={{position:'absolute', top: 30, left:'50%', background:'#eee', border:'1px solid ', width:50}}>Middle</a>
<a onClick={this.showTargetedPopover.bind(this, 'horizontal', 'right')} style={{position:'absolute', top: 30, right:0, background:'#eee', border:'1px solid ', width:50}}>Right</a>
</div>

<div style={{display:'block', height:200, background:'#eee', position:'relative'}}>
<h4>Vertical Position Modes</h4>
<a onClick={this.showTargetedPopover.bind(this, 'vertical', 'top')} style={{position:'absolute', left:200, top:0, background:'#eee', border:'1px solid ', width:50}}>Top</a>
<a onClick={this.showTargetedPopover.bind(this, 'vertical', 'center')} style={{position:'absolute', left:200, top:'50%', background:'#eee', border:'1px solid ', width:50}}>Center</a>
<a onClick={this.showTargetedPopover.bind(this, 'vertical', 'bottom')} style={{position:'absolute', left:200, bottom:0, background:'#eee', border:'1px solid ', width:50}}>Bottom</a>
</div>
</div>
</Popover>


show(key, e) {
this.setState({
activePopover:key,
Expand All @@ -30,4 +99,37 @@ closePopover() {
this.setState({
activePopover:'none',
});
},
},

showPositionedPopover(positionElement, position ,e) {
let {anchorOrigin} = this.state;
anchorOrigin[positionElement] = position;

this.setState({
activePopover:'anchors',
anchorEl:this.refs.anchor,
anchorOrigin:anchorOrigin,
});
},

showTargetedPopover(positionElement, position ,e) {
let {targetOrigin} = this.state;
targetOrigin[positionElement] = position;

this.setState({
activePopover:'anchors',
anchorEl:this.refs.anchor,
targetOrigin:targetOrigin,
});
},
onChangeSelect(e) {
this.setState({
selectValue:e.target.value,
});
},

onChangeText(e) {
this.setState({
textValue:e.target.value,
});
},
22 changes: 11 additions & 11 deletions src/popover/popover.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const Popover = React.createClass({
canAutoPosition: React.PropTypes.bool,
children: React.PropTypes.object,
className: React.PropTypes.string,
isOpen: React.PropTypes.bool,
open: React.PropTypes.bool,
onRequestClose: React.PropTypes.func,
style: React.PropTypes.object,
targetOrigin: PropTypes.origin,
Expand All @@ -45,7 +45,7 @@ const Popover = React.createClass({
autoCloseWhenOffScreen:true,
canAutoPosition:true,
onRequestClose: () => {},
isOpen:false,
open:false,
style: {},
targetOrigin: {
vertical:'top',
Expand All @@ -72,8 +72,8 @@ const Popover = React.createClass({
},

componentWillReceiveProps(nextProps) {
if (nextProps.isOpen !== this.state.isOpen) {
if (nextProps.isOpen)
if (nextProps.open !== this.state.open) {
if (nextProps.open)
this._showInternal(nextProps.anchorEl);
else
this._hideInternal();
Expand Down Expand Up @@ -106,7 +106,7 @@ const Popover = React.createClass({

let wrapperStyle = {
position: 'fixed',
top: anchor.top,
top: anchor.top,
left: anchor.left,
zIndex: 20,
opacity:1,
Expand Down Expand Up @@ -165,18 +165,18 @@ const Popover = React.createClass({

_showInternal(anchorEl) {
this.anchorEl = anchorEl || this.props.anchorEl;
this.setState({isOpen: true});
this.setState({open: true});
const popOverShowEvent = new CustomEvent('popOverOnShow', {detail: this});
document.dispatchEvent(popOverShowEvent);

},

_hideInternal() {
if (!this.state.isOpen) {
if (!this.state.open) {
return;
}
this.setState({
isOpen: false,
open: false,
}, () => {
this._animateClose();
const popOverHideEvent = new CustomEvent('popOverOnHide');
Expand Down Expand Up @@ -204,12 +204,12 @@ const Popover = React.createClass({
const rootStyle = inner.style;
const innerStyle = innerInner.style;

if (this.state.isOpen) {
if (this.state.open) {
value = '1';
}
else {
CssEvent.onTransitionEnd(inner, () => {
if (!this.state.isOpen)
if (!this.state.open)
this.requestClose();
});
}
Expand Down Expand Up @@ -254,7 +254,7 @@ const Popover = React.createClass({
},

setPlacement(el) {
if (!this.state.isOpen)
if (!this.state.open)
return;

const anchorEl = this.props.anchorEl || this.anchorEl;
Expand Down
2 changes: 1 addition & 1 deletion src/render-to-layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ const RenderToLayer = React.createClass({
},

_renderLayer() {
if (this.props.isOpen) {
if (this.props.open) {
if (!this._layer) {
this._layer = document.createElement('div');
document.body.appendChild(this._layer);
Expand Down

0 comments on commit 932271b

Please sign in to comment.