const React = window.React; class Modal extends React.Component { constructor(props) { super(props); this.state = { open: false, onOpen: props.onOpen || () => {}, onClose: props.onClose || () => {}, } } componentDidMount() { this.keydownHandler = (e) => { // Close modal on escape if (e.keyCode === 27) { this.close(); } } document.addEventListener('keydown', this.keydownHandler); } componentWillUnmount() { document.removeEventListener('keydown', this.keydownHandler); } open() { this.setState({open: true}); this.state.onOpen(); } close() { this.setState({open: false}); this.state.onClose(); } // type can be 'button' or 'div'. // Always closes modal after the callback renderActionElem({title, type = 'button', action = () => {}, className = ""}) { const callback = (e) => { action(e); this.close(); } if (type === 'button') { return ( ) } return (
{title}
) } render() { const activator = (
this.open.call(this)} > {this.props.openLink.text}
) if (!this.state.open) { return activator; } const actionElems = []; if (this.props.actionElems) { for (const config of this.props.actionElems) { actionElems.push(this.renderActionElem(config)); } } return (
{activator}
this.close.call(this)}>
{this.props.children} {actionElems}
) } } Modal.propTypes = { openLink: React.PropTypes.object, className: React.PropTypes.string, id: React.PropTypes.string, onOpen: React.PropTypes.func, onClose: React.PropTypes.func, actionElems: React.PropTypes.arrayOf(React.PropTypes.object), } window.Modal = Modal;