Skip to content
Extraits de code Groupes Projets
Valider 12f5f13f rédigé par ThibG's avatar ThibG Validation de Eugen Rochko
Parcourir les fichiers

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

parent 519119f6
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
...@@ -32,6 +32,10 @@ class PrivacyDropdownMenu extends React.PureComponent { ...@@ -32,6 +32,10 @@ class PrivacyDropdownMenu extends React.PureComponent {
onChange: PropTypes.func.isRequired, onChange: PropTypes.func.isRequired,
}; };
state = {
mounted: false,
};
handleDocumentClick = e => { handleDocumentClick = e => {
if (this.node && !this.node.contains(e.target)) { if (this.node && !this.node.contains(e.target)) {
this.props.onClose(); this.props.onClose();
...@@ -54,6 +58,7 @@ class PrivacyDropdownMenu extends React.PureComponent { ...@@ -54,6 +58,7 @@ class PrivacyDropdownMenu extends React.PureComponent {
componentDidMount () { componentDidMount () {
document.addEventListener('click', this.handleDocumentClick, false); document.addEventListener('click', this.handleDocumentClick, false);
document.addEventListener('touchend', this.handleDocumentClick, listenerOptions); document.addEventListener('touchend', this.handleDocumentClick, listenerOptions);
this.setState({ mounted: true });
} }
componentWillUnmount () { componentWillUnmount () {
...@@ -66,12 +71,16 @@ class PrivacyDropdownMenu extends React.PureComponent { ...@@ -66,12 +71,16 @@ class PrivacyDropdownMenu extends React.PureComponent {
} }
render () { render () {
const { mounted } = this.state;
const { style, items, value } = this.props; const { style, items, value } = this.props;
return ( 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 }) }}> <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 }) => ( {({ 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 => ( {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 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'> <div className='privacy-dropdown__option__icon'>
...@@ -107,9 +116,10 @@ export default class PrivacyDropdown extends React.PureComponent { ...@@ -107,9 +116,10 @@ export default class PrivacyDropdown extends React.PureComponent {
state = { state = {
open: false, open: false,
placement: null,
}; };
handleToggle = () => { handleToggle = ({ target }) => {
if (this.props.isUserTouching()) { if (this.props.isUserTouching()) {
if (this.state.open) { if (this.state.open) {
this.props.onModalClose(); this.props.onModalClose();
...@@ -120,6 +130,8 @@ export default class PrivacyDropdown extends React.PureComponent { ...@@ -120,6 +130,8 @@ export default class PrivacyDropdown extends React.PureComponent {
}); });
} }
} else { } else {
const { top } = target.getBoundingClientRect();
this.setState({ placement: top * 2 < innerHeight ? 'bottom' : 'top' });
this.setState({ open: !this.state.open }); this.setState({ open: !this.state.open });
} }
} }
...@@ -136,7 +148,7 @@ export default class PrivacyDropdown extends React.PureComponent { ...@@ -136,7 +148,7 @@ export default class PrivacyDropdown extends React.PureComponent {
handleKeyDown = e => { handleKeyDown = e => {
switch(e.key) { switch(e.key) {
case 'Enter': case 'Enter':
this.handleToggle(); this.handleToggle(e);
break; break;
case 'Escape': case 'Escape':
this.handleClose(); this.handleClose();
...@@ -165,7 +177,7 @@ export default class PrivacyDropdown extends React.PureComponent { ...@@ -165,7 +177,7 @@ export default class PrivacyDropdown extends React.PureComponent {
render () { render () {
const { value, intl } = this.props; const { value, intl } = this.props;
const { open } = this.state; const { open, placement } = this.state;
const valueOption = this.options.find(item => item.value === value); const valueOption = this.options.find(item => item.value === value);
...@@ -185,7 +197,7 @@ export default class PrivacyDropdown extends React.PureComponent { ...@@ -185,7 +197,7 @@ export default class PrivacyDropdown extends React.PureComponent {
/> />
</div> </div>
<Overlay show={open} placement='bottom' target={this}> <Overlay show={open} placement={placement} target={this}>
<PrivacyDropdownMenu <PrivacyDropdownMenu
items={this.options} items={this.options}
value={value} value={value}
......
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter