Skip to content
Snippets Groups Projects
Commit 12f5f13f authored by ThibG's avatar ThibG Committed by Eugen Rochko
Browse files

Place privacy dropdown menu top if it is closer to the bottom of the viewport (#7106)

parent 519119f6
No related branches found
No related tags found
No related merge requests found
......@@ -32,6 +32,10 @@ class PrivacyDropdownMenu extends React.PureComponent {
onChange: PropTypes.func.isRequired,
};
state = {
mounted: false,
};
handleDocumentClick = e => {
if (this.node && !this.node.contains(e.target)) {
this.props.onClose();
......@@ -54,6 +58,7 @@ class PrivacyDropdownMenu extends React.PureComponent {
componentDidMount () {
document.addEventListener('click', this.handleDocumentClick, false);
document.addEventListener('touchend', this.handleDocumentClick, listenerOptions);
this.setState({ mounted: true });
}
componentWillUnmount () {
......@@ -66,12 +71,16 @@ class PrivacyDropdownMenu extends React.PureComponent {
}
render () {
const { mounted } = this.state;
const { style, items, value } = this.props;
return (
<Motion defaultStyle={{ opacity: 0, scaleX: 0.85, scaleY: 0.75 }} style={{ opacity: spring(1, { damping: 35, stiffness: 400 }), scaleX: spring(1, { damping: 35, stiffness: 400 }), scaleY: spring(1, { damping: 35, stiffness: 400 }) }}>
{({ opacity, scaleX, scaleY }) => (
<div className='privacy-dropdown__dropdown' style={{ ...style, opacity: opacity, transform: `scale(${scaleX}, ${scaleY})` }} ref={this.setRef}>
// It should not be transformed when mounting because the resulting
// size will be used to determine the coordinate of the menu by
// react-overlays
<div className='privacy-dropdown__dropdown' style={{ ...style, opacity: opacity, transform: mounted ? `scale(${scaleX}, ${scaleY})` : null }} ref={this.setRef}>
{items.map(item => (
<div role='button' tabIndex='0' key={item.value} data-index={item.value} onKeyDown={this.handleClick} onClick={this.handleClick} className={classNames('privacy-dropdown__option', { active: item.value === value })}>
<div className='privacy-dropdown__option__icon'>
......@@ -107,9 +116,10 @@ export default class PrivacyDropdown extends React.PureComponent {
state = {
open: false,
placement: null,
};
handleToggle = () => {
handleToggle = ({ target }) => {
if (this.props.isUserTouching()) {
if (this.state.open) {
this.props.onModalClose();
......@@ -120,6 +130,8 @@ export default class PrivacyDropdown extends React.PureComponent {
});
}
} else {
const { top } = target.getBoundingClientRect();
this.setState({ placement: top * 2 < innerHeight ? 'bottom' : 'top' });
this.setState({ open: !this.state.open });
}
}
......@@ -136,7 +148,7 @@ export default class PrivacyDropdown extends React.PureComponent {
handleKeyDown = e => {
switch(e.key) {
case 'Enter':
this.handleToggle();
this.handleToggle(e);
break;
case 'Escape':
this.handleClose();
......@@ -165,7 +177,7 @@ export default class PrivacyDropdown extends React.PureComponent {
render () {
const { value, intl } = this.props;
const { open } = this.state;
const { open, placement } = this.state;
const valueOption = this.options.find(item => item.value === value);
......@@ -185,7 +197,7 @@ export default class PrivacyDropdown extends React.PureComponent {
/>
</div>
<Overlay show={open} placement='bottom' target={this}>
<Overlay show={open} placement={placement} target={this}>
<PrivacyDropdownMenu
items={this.options}
value={value}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment