UNPKG

react-bootstrap

Version:

Bootstrap 3 components build with React

174 lines (143 loc) 4.95 kB
define(function (require, exports, module) {/* global document:false */ var React = require('react'); var joinClasses = require('./utils/joinClasses'); var classSet = require('./utils/classSet'); var BootstrapMixin = require('./BootstrapMixin'); var FadeMixin = require('./FadeMixin'); var EventListener = require('./utils/EventListener'); // TODO: // - aria-labelledby // - Add `modal-body` div if only one child passed in that doesn't already have it // - Tests var Modal = React.createClass({displayName: "Modal", mixins: [BootstrapMixin, FadeMixin], propTypes: { title: React.PropTypes.node, backdrop: React.PropTypes.oneOf(['static', true, false]), keyboard: React.PropTypes.bool, closeButton: React.PropTypes.bool, animation: React.PropTypes.bool, onRequestHide: React.PropTypes.func.isRequired }, getDefaultProps: function () { return { bsClass: 'modal', backdrop: true, keyboard: true, animation: true, closeButton: true }; }, render: function () { var modalStyle = {display: 'block'}; var dialogClasses = this.getBsClassSet(); delete dialogClasses.modal; dialogClasses['modal-dialog'] = true; var classes = { modal: true, fade: this.props.animation, 'in': !this.props.animation || !document.querySelectorAll }; var modal = ( React.createElement("div", React.__spread({}, this.props, {title: null, tabIndex: "-1", role: "dialog", style: modalStyle, className: joinClasses(this.props.className, classSet(classes)), onClick: this.props.backdrop === true ? this.handleBackdropClick : null, ref: "modal"}), React.createElement("div", {className: classSet(dialogClasses)}, React.createElement("div", {className: "modal-content", style: {overflow: 'hidden'}}, this.props.title ? this.renderHeader() : null, this.props.children ) ) ) ); return this.props.backdrop ? this.renderBackdrop(modal) : modal; }, renderBackdrop: function (modal) { var classes = { 'modal-backdrop': true, 'fade': this.props.animation }; classes['in'] = !this.props.animation || !document.querySelectorAll; var onClick = this.props.backdrop === true ? this.handleBackdropClick : null; return ( React.createElement("div", null, React.createElement("div", {className: classSet(classes), ref: "backdrop", onClick: onClick}), modal ) ); }, renderHeader: function () { var closeButton; if (this.props.closeButton) { closeButton = ( React.createElement("button", {type: "button", className: "close", "aria-hidden": "true", onClick: this.props.onRequestHide}, "×") ); } var style = this.props.bsStyle; var classes = { 'modal-header': true }; classes['bg-' + style] = style; classes['text-' + style] = style; var className = classSet(classes); return ( React.createElement("div", {className: className}, closeButton, this.renderTitle() ) ); }, renderTitle: function () { return ( React.isValidElement(this.props.title) ? this.props.title : React.createElement("h4", {className: "modal-title"}, this.props.title) ); }, iosClickHack: function () { // IOS only allows click events to be delegated to the document on elements // it considers 'clickable' - anchors, buttons, etc. We fake a click handler on the // DOM nodes themselves. Remove if handled by React: https://github.com/facebook/react/issues/1169 this.refs.modal.getDOMNode().onclick = function () {}; this.refs.backdrop.getDOMNode().onclick = function () {}; }, componentDidMount: function () { this._onDocumentKeyupListener = EventListener.listen(document, 'keyup', this.handleDocumentKeyUp); var container = (this.props.container && this.props.container.getDOMNode()) || document.body; container.className += container.className.length ? ' modal-open' : 'modal-open'; if (this.props.backdrop) { this.iosClickHack(); } }, componentDidUpdate: function (prevProps) { if (this.props.backdrop && this.props.backdrop !== prevProps.backdrop) { this.iosClickHack(); } }, componentWillUnmount: function () { this._onDocumentKeyupListener.remove(); var container = (this.props.container && this.props.container.getDOMNode()) || document.body; container.className = container.className.replace(/ ?modal-open/, ''); }, handleBackdropClick: function (e) { if (e.target !== e.currentTarget) { return; } this.props.onRequestHide(); }, handleDocumentKeyUp: function (e) { if (this.props.keyboard && e.keyCode === 27) { this.props.onRequestHide(); } } }); module.exports = Modal; });