From e74e5c7eb903d6e9aa88629e975a81574fe49159 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Tue, 10 Apr 2018 20:04:55 +0200 Subject: [PATCH] Place composer dropdown menus top if they are closer to the bottom of the viewport --- .../composer/options/dropdown/content/index.js | 12 ++++++++++-- .../features/composer/options/dropdown/index.js | 11 +++++++---- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/app/javascript/flavours/glitch/features/composer/options/dropdown/content/index.js b/app/javascript/flavours/glitch/features/composer/options/dropdown/content/index.js index b3a472999..b76410561 100644 --- a/app/javascript/flavours/glitch/features/composer/options/dropdown/content/index.js +++ b/app/javascript/flavours/glitch/features/composer/options/dropdown/content/index.js @@ -13,7 +13,6 @@ import { assignHandlers } from 'flavours/glitch/util/react_helpers'; // Handlers. const handlers = { - // When the document is clicked elsewhere, we close the dropdown. handleDocumentClick ({ target }) { const { node } = this; @@ -45,6 +44,10 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent // Instance variables. this.node = null; + + this.state = { + mounted: false, + }; } // On mounting, we add our listeners. @@ -52,6 +55,7 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent const { handleDocumentClick } = this.handlers; document.addEventListener('click', handleDocumentClick, false); document.addEventListener('touchend', handleDocumentClick, withPassive); + this.setState({ mounted: true }); } // On unmounting, we remove our listeners. @@ -63,6 +67,7 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent // Rendering. render () { + const { mounted } = this.state; const { handleRef } = this.handlers; const { items, @@ -87,13 +92,16 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent }} > {({ opacity, scaleX, scaleY }) => ( + // It should not be transformed when mounting because the resulting + // size will be used to determine the coordinate of the menu by + // react-overlays
{items ? items.map( diff --git a/app/javascript/flavours/glitch/features/composer/options/dropdown/index.js b/app/javascript/flavours/glitch/features/composer/options/dropdown/index.js index d63d90a9f..b3462e25a 100644 --- a/app/javascript/flavours/glitch/features/composer/options/dropdown/index.js +++ b/app/javascript/flavours/glitch/features/composer/options/dropdown/index.js @@ -29,7 +29,7 @@ const handlers = { } = this.handlers; switch (key) { case 'Enter': - handleToggle(); + handleToggle(key); break; case 'Escape': handleClose(); @@ -79,7 +79,7 @@ const handlers = { }, // Toggles opening and closing the dropdown. - handleToggle () { + handleToggle ({ target }) { const { handleMakeModal } = this.handlers; const { onModalOpen } = this.props; const { open } = this.state; @@ -98,6 +98,8 @@ const handlers = { } } + const { top } = target.getBoundingClientRect(); + this.setState({ placement: top * 2 < innerHeight ? 'bottom' : 'top' }); // Otherwise, we just set our state to open. this.setState({ open: !open }); }, @@ -129,6 +131,7 @@ export default class ComposerOptionsDropdown extends React.PureComponent { this.state = { needsModalUpdate: false, open: false, + placement: null, }; } @@ -161,7 +164,7 @@ export default class ComposerOptionsDropdown extends React.PureComponent { onChange, value, } = this.props; - const { open } = this.state; + const { open, placement } = this.state; const computedClass = classNames('composer--options--dropdown', { active, open, @@ -188,7 +191,7 @@ export default class ComposerOptionsDropdown extends React.PureComponent { />