mirror of
https://github.com/element-hq/element-web
synced 2024-11-28 12:28:50 +03:00
Merge pull request #1952 from matrix-org/luke/context-menus-downwards-keep-vertically-on-screen
Keep context menus that extend downwards vertically on screen
This commit is contained in:
commit
b18a8c483e
1 changed files with 35 additions and 2 deletions
|
@ -63,6 +63,24 @@ export default class ContextualMenu extends React.Component {
|
||||||
hasBackground: PropTypes.bool,
|
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() {
|
render() {
|
||||||
const position = {};
|
const position = {};
|
||||||
let chevronFace = null;
|
let chevronFace = null;
|
||||||
|
@ -83,6 +101,9 @@ export default class ContextualMenu extends React.Component {
|
||||||
chevronFace = 'right';
|
chevronFace = 'right';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const contextMenuRect = this.state.contextMenuRect || null;
|
||||||
|
const padding = 10;
|
||||||
|
|
||||||
const chevronOffset = {};
|
const chevronOffset = {};
|
||||||
if (props.chevronFace) {
|
if (props.chevronFace) {
|
||||||
chevronFace = props.chevronFace;
|
chevronFace = props.chevronFace;
|
||||||
|
@ -90,7 +111,19 @@ export default class ContextualMenu extends React.Component {
|
||||||
if (chevronFace === 'top' || chevronFace === 'bottom') {
|
if (chevronFace === 'top' || chevronFace === 'bottom') {
|
||||||
chevronOffset.left = props.chevronOffset;
|
chevronOffset.left = props.chevronOffset;
|
||||||
} else {
|
} 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
|
// 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
|
// FIXME: If a menu uses getDefaultProps it clobbers the onFinished
|
||||||
// property set here so you can't close the menu from a button click!
|
// property set here so you can't close the menu from a button click!
|
||||||
return <div className={className} style={position}>
|
return <div className={className} style={position}>
|
||||||
<div className={menuClasses} style={menuStyle}>
|
<div className={menuClasses} style={menuStyle} ref={this.collectContextMenuRect}>
|
||||||
{ chevron }
|
{ chevron }
|
||||||
<ElementClass {...props} onFinished={props.closeMenu} onResize={props.windowResize} />
|
<ElementClass {...props} onFinished={props.closeMenu} onResize={props.windowResize} />
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in a new issue