mirror of https://github.com/vector-im/riot-web
Factor out ContextualMenu component
parent
6a0bff6685
commit
d503c86576
|
@ -26,9 +26,21 @@ import PropTypes from 'prop-types';
|
||||||
// of doing reusable widgets like dialog boxes & menus where we go and
|
// of doing reusable widgets like dialog boxes & menus where we go and
|
||||||
// pass in a custom control as the actual body.
|
// pass in a custom control as the actual body.
|
||||||
|
|
||||||
module.exports = {
|
const ContextualMenuContainerId = "mx_ContextualMenu_Container";
|
||||||
ContextualMenuContainerId: "mx_ContextualMenu_Container",
|
|
||||||
|
|
||||||
|
function getOrCreateContainer() {
|
||||||
|
let container = document.getElementById(ContextualMenuContainerId);
|
||||||
|
|
||||||
|
if (!container) {
|
||||||
|
container = document.createElement("div");
|
||||||
|
container.id = ContextualMenuContainerId;
|
||||||
|
document.body.appendChild(container);
|
||||||
|
}
|
||||||
|
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ContextualMenu extends React.Component {
|
||||||
propTypes: {
|
propTypes: {
|
||||||
top: PropTypes.number,
|
top: PropTypes.number,
|
||||||
bottom: PropTypes.number,
|
bottom: PropTypes.number,
|
||||||
|
@ -45,39 +57,14 @@ module.exports = {
|
||||||
menuPaddingRight: PropTypes.number,
|
menuPaddingRight: PropTypes.number,
|
||||||
menuPaddingBottom: PropTypes.number,
|
menuPaddingBottom: PropTypes.number,
|
||||||
menuPaddingLeft: PropTypes.number,
|
menuPaddingLeft: PropTypes.number,
|
||||||
},
|
}
|
||||||
|
|
||||||
getOrCreateContainer: function() {
|
|
||||||
let container = document.getElementById(this.ContextualMenuContainerId);
|
|
||||||
|
|
||||||
if (!container) {
|
|
||||||
container = document.createElement("div");
|
|
||||||
container.id = this.ContextualMenuContainerId;
|
|
||||||
document.body.appendChild(container);
|
|
||||||
}
|
|
||||||
|
|
||||||
return container;
|
|
||||||
},
|
|
||||||
|
|
||||||
createMenu: function(Element, props) {
|
|
||||||
const self = this;
|
|
||||||
|
|
||||||
const closeMenu = function(...args) {
|
|
||||||
ReactDOM.unmountComponentAtNode(self.getOrCreateContainer());
|
|
||||||
|
|
||||||
if (props && props.onFinished) {
|
|
||||||
props.onFinished.apply(null, args);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Close the menu on window resize
|
|
||||||
const windowResize = function() {
|
|
||||||
closeMenu();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
render() {
|
||||||
const position = {};
|
const position = {};
|
||||||
let chevronFace = null;
|
let chevronFace = null;
|
||||||
|
|
||||||
|
const props = this.props;
|
||||||
|
|
||||||
if (props.top) {
|
if (props.top) {
|
||||||
position.top = props.top;
|
position.top = props.top;
|
||||||
} else {
|
} else {
|
||||||
|
@ -158,20 +145,39 @@ module.exports = {
|
||||||
menuStyle["paddingRight"] = props.menuPaddingRight;
|
menuStyle["paddingRight"] = props.menuPaddingRight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ElementClass = props.elementClass;
|
||||||
|
|
||||||
// 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!
|
||||||
const menu = (
|
return <div className={className} style={position}>
|
||||||
<div className={className} style={position}>
|
<div className={menuClasses} style={menuStyle}>
|
||||||
<div className={menuClasses} style={menuStyle}>
|
{ chevron }
|
||||||
{ chevron }
|
<ElementClass {...props} onFinished={props.closeMenu} onResize={props.windowResize} />
|
||||||
<Element {...props} onFinished={closeMenu} onResize={windowResize} />
|
|
||||||
</div>
|
|
||||||
<div className="mx_ContextualMenu_background" onClick={closeMenu}></div>
|
|
||||||
<style>{ chevronCSS }</style>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
<div className="mx_ContextualMenu_background" onClick={props.closeMenu}></div>
|
||||||
|
<style>{ chevronCSS }</style>
|
||||||
|
</div>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ReactDOM.render(menu, this.getOrCreateContainer());
|
module.exports = {
|
||||||
|
createMenu: function(ElementClass, props) {
|
||||||
|
const closeMenu = function(...args) {
|
||||||
|
ReactDOM.unmountComponentAtNode(getOrCreateContainer());
|
||||||
|
|
||||||
|
if (props && props.onFinished) {
|
||||||
|
props.onFinished.apply(null, args);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const menu = <ContextualMenu
|
||||||
|
{...props}
|
||||||
|
elementClass={ElementClass}
|
||||||
|
closeMenu={closeMenu}
|
||||||
|
windowResize={closeMenu}
|
||||||
|
/>;
|
||||||
|
|
||||||
|
ReactDOM.render(menu, getOrCreateContainer());
|
||||||
|
|
||||||
return {close: closeMenu};
|
return {close: closeMenu};
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue