mirror of https://github.com/vector-im/riot-web
Keep context menus that extend downwards vertically on screen
This fixes https://github.com/vector-im/riot-web/issues/3429 in the case of RoomList context menus *and* EventTile context menus. This was mostly stolen from #1903 and it would be good to factor things out at a later date such that #1903 is replaced with similar logic within ContextualMenu.pull/21833/head
parent
50e08c7560
commit
ffcba9498e
|
@ -63,6 +63,24 @@ export default class ContextualMenu extends React.Component {
|
|||
hasBackground: PropTypes.bool,
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.state = {
|
||||
contextMenuRect: null,
|
||||
};
|
||||
|
||||
this.collectContextMenuRect = this.collectContextMenuRect.bind(this);
|
||||
}
|
||||
|
||||
collectContextMenuRect(element) {
|
||||
// We don't need to clean up when unmounting, so ignore
|
||||
if (!element) return;
|
||||
|
||||
this.setState({
|
||||
contextMenuRect: element.getBoundingClientRect(),
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const position = {};
|
||||
let chevronFace = null;
|
||||
|
@ -83,6 +101,9 @@ export default class ContextualMenu extends React.Component {
|
|||
chevronFace = 'right';
|
||||
}
|
||||
|
||||
const contextMenuRect = this.state.contextMenuRect || null;
|
||||
const padding = 10;
|
||||
|
||||
const chevronOffset = {};
|
||||
if (props.chevronFace) {
|
||||
chevronFace = props.chevronFace;
|
||||
|
@ -90,7 +111,19 @@ export default class ContextualMenu extends React.Component {
|
|||
if (chevronFace === 'top' || chevronFace === 'bottom') {
|
||||
chevronOffset.left = props.chevronOffset;
|
||||
} else {
|
||||
chevronOffset.top = props.chevronOffset;
|
||||
const target = position.top;
|
||||
|
||||
// By default, no adjustment is made
|
||||
let adjusted = target;
|
||||
|
||||
// If we know the dimensions of the context menu, adjust its position
|
||||
// such that it does not leave the (padded) window.
|
||||
if (contextMenuRect) {
|
||||
adjusted = Math.min(position.top, document.body.clientHeight - contextMenuRect.height - padding);
|
||||
}
|
||||
|
||||
position.top = adjusted;
|
||||
chevronOffset.top = Math.max(props.chevronOffset, props.chevronOffset + target - adjusted);
|
||||
}
|
||||
|
||||
// To override the default chevron colour, if it's been set
|
||||
|
@ -154,7 +187,7 @@ export default class ContextualMenu extends React.Component {
|
|||
// FIXME: If a menu uses getDefaultProps it clobbers the onFinished
|
||||
// property set here so you can't close the menu from a button click!
|
||||
return <div className={className} style={position}>
|
||||
<div className={menuClasses} style={menuStyle}>
|
||||
<div className={menuClasses} style={menuStyle} ref={this.collectContextMenuRect}>
|
||||
{ chevron }
|
||||
<ElementClass {...props} onFinished={props.closeMenu} onResize={props.windowResize} />
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue