Factor out ContextualMenu component

pull/21833/head
Luke Barnard 2018-05-10 16:00:58 +01:00
parent 6a0bff6685
commit d503c86576
1 changed files with 47 additions and 41 deletions

View File

@ -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};
}, },