Place composer dropdown menus top if they are closer to the bottom of the viewport
This commit is contained in:
		
							parent
							
								
									3ab6a8b8be
								
							
						
					
					
						commit
						e74e5c7eb9
					
				@ -13,7 +13,6 @@ import { assignHandlers } from 'flavours/glitch/util/react_helpers';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
//  Handlers.
 | 
					//  Handlers.
 | 
				
			||||||
const handlers = {
 | 
					const handlers = {
 | 
				
			||||||
 | 
					 | 
				
			||||||
  //  When the document is clicked elsewhere, we close the dropdown.
 | 
					  //  When the document is clicked elsewhere, we close the dropdown.
 | 
				
			||||||
  handleDocumentClick ({ target }) {
 | 
					  handleDocumentClick ({ target }) {
 | 
				
			||||||
    const { node } = this;
 | 
					    const { node } = this;
 | 
				
			||||||
@ -45,6 +44,10 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    //  Instance variables.
 | 
					    //  Instance variables.
 | 
				
			||||||
    this.node = null;
 | 
					    this.node = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.state = {
 | 
				
			||||||
 | 
					      mounted: false,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  //  On mounting, we add our listeners.
 | 
					  //  On mounting, we add our listeners.
 | 
				
			||||||
@ -52,6 +55,7 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent
 | 
				
			|||||||
    const { handleDocumentClick } = this.handlers;
 | 
					    const { handleDocumentClick } = this.handlers;
 | 
				
			||||||
    document.addEventListener('click', handleDocumentClick, false);
 | 
					    document.addEventListener('click', handleDocumentClick, false);
 | 
				
			||||||
    document.addEventListener('touchend', handleDocumentClick, withPassive);
 | 
					    document.addEventListener('touchend', handleDocumentClick, withPassive);
 | 
				
			||||||
 | 
					    this.setState({ mounted: true });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  //  On unmounting, we remove our listeners.
 | 
					  //  On unmounting, we remove our listeners.
 | 
				
			||||||
@ -63,6 +67,7 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  //  Rendering.
 | 
					  //  Rendering.
 | 
				
			||||||
  render () {
 | 
					  render () {
 | 
				
			||||||
 | 
					    const { mounted } = this.state;
 | 
				
			||||||
    const { handleRef } = this.handlers;
 | 
					    const { handleRef } = this.handlers;
 | 
				
			||||||
    const {
 | 
					    const {
 | 
				
			||||||
      items,
 | 
					      items,
 | 
				
			||||||
@ -87,13 +92,16 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent
 | 
				
			|||||||
        }}
 | 
					        }}
 | 
				
			||||||
      >
 | 
					      >
 | 
				
			||||||
        {({ opacity, scaleX, scaleY }) => (
 | 
					        {({ 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
 | 
				
			||||||
          <div
 | 
					          <div
 | 
				
			||||||
            className='composer--options--dropdown--content'
 | 
					            className='composer--options--dropdown--content'
 | 
				
			||||||
            ref={handleRef}
 | 
					            ref={handleRef}
 | 
				
			||||||
            style={{
 | 
					            style={{
 | 
				
			||||||
              ...style,
 | 
					              ...style,
 | 
				
			||||||
              opacity: opacity,
 | 
					              opacity: opacity,
 | 
				
			||||||
              transform: `scale(${scaleX}, ${scaleY})`,
 | 
					              transform: mounted ? `scale(${scaleX}, ${scaleY})` : null,
 | 
				
			||||||
            }}
 | 
					            }}
 | 
				
			||||||
          >
 | 
					          >
 | 
				
			||||||
            {items ? items.map(
 | 
					            {items ? items.map(
 | 
				
			||||||
 | 
				
			|||||||
@ -29,7 +29,7 @@ const handlers = {
 | 
				
			|||||||
    } = this.handlers;
 | 
					    } = this.handlers;
 | 
				
			||||||
    switch (key) {
 | 
					    switch (key) {
 | 
				
			||||||
    case 'Enter':
 | 
					    case 'Enter':
 | 
				
			||||||
      handleToggle();
 | 
					      handleToggle(key);
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    case 'Escape':
 | 
					    case 'Escape':
 | 
				
			||||||
      handleClose();
 | 
					      handleClose();
 | 
				
			||||||
@ -79,7 +79,7 @@ const handlers = {
 | 
				
			|||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  //  Toggles opening and closing the dropdown.
 | 
					  //  Toggles opening and closing the dropdown.
 | 
				
			||||||
  handleToggle () {
 | 
					  handleToggle ({ target }) {
 | 
				
			||||||
    const { handleMakeModal } = this.handlers;
 | 
					    const { handleMakeModal } = this.handlers;
 | 
				
			||||||
    const { onModalOpen } = this.props;
 | 
					    const { onModalOpen } = this.props;
 | 
				
			||||||
    const { open } = this.state;
 | 
					    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.
 | 
					    //  Otherwise, we just set our state to open.
 | 
				
			||||||
    this.setState({ open: !open });
 | 
					    this.setState({ open: !open });
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
@ -129,6 +131,7 @@ export default class ComposerOptionsDropdown extends React.PureComponent {
 | 
				
			|||||||
    this.state = {
 | 
					    this.state = {
 | 
				
			||||||
      needsModalUpdate: false,
 | 
					      needsModalUpdate: false,
 | 
				
			||||||
      open: false,
 | 
					      open: false,
 | 
				
			||||||
 | 
					      placement: null,
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -161,7 +164,7 @@ export default class ComposerOptionsDropdown extends React.PureComponent {
 | 
				
			|||||||
      onChange,
 | 
					      onChange,
 | 
				
			||||||
      value,
 | 
					      value,
 | 
				
			||||||
    } = this.props;
 | 
					    } = this.props;
 | 
				
			||||||
    const { open } = this.state;
 | 
					    const { open, placement } = this.state;
 | 
				
			||||||
    const computedClass = classNames('composer--options--dropdown', {
 | 
					    const computedClass = classNames('composer--options--dropdown', {
 | 
				
			||||||
      active,
 | 
					      active,
 | 
				
			||||||
      open,
 | 
					      open,
 | 
				
			||||||
@ -188,7 +191,7 @@ export default class ComposerOptionsDropdown extends React.PureComponent {
 | 
				
			|||||||
        />
 | 
					        />
 | 
				
			||||||
        <Overlay
 | 
					        <Overlay
 | 
				
			||||||
          containerPadding={20}
 | 
					          containerPadding={20}
 | 
				
			||||||
          placement='bottom'
 | 
					          placement={placement}
 | 
				
			||||||
          show={open}
 | 
					          show={open}
 | 
				
			||||||
          target={this}
 | 
					          target={this}
 | 
				
			||||||
        >
 | 
					        >
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user