UNPKG

react-bootstrap

Version:

Bootstrap 3 components build with React

209 lines (165 loc) 6.61 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _classnames = require('classnames'); var _classnames2 = _interopRequireDefault(_classnames); var _BootstrapMixin = require('./BootstrapMixin'); var _BootstrapMixin2 = _interopRequireDefault(_BootstrapMixin); var _FadeMixin = require('./FadeMixin'); var _FadeMixin2 = _interopRequireDefault(_FadeMixin); var _utilsDomUtils = require('./utils/domUtils'); var _utilsDomUtils2 = _interopRequireDefault(_utilsDomUtils); var _utilsEventListener = require('./utils/EventListener'); var _utilsEventListener2 = _interopRequireDefault(_utilsEventListener); // TODO: // - aria-labelledby // - Add `modal-body` div if only one child passed in that doesn't already have it // - Tests var Modal = _react2['default'].createClass({ displayName: 'Modal', mixins: [_BootstrapMixin2['default'], _FadeMixin2['default']], propTypes: { title: _react2['default'].PropTypes.node, backdrop: _react2['default'].PropTypes.oneOf(['static', true, false]), keyboard: _react2['default'].PropTypes.bool, closeButton: _react2['default'].PropTypes.bool, animation: _react2['default'].PropTypes.bool, onRequestHide: _react2['default'].PropTypes.func.isRequired, dialogClassName: _react2['default'].PropTypes.string }, getDefaultProps: function getDefaultProps() { return { bsClass: 'modal', backdrop: true, keyboard: true, animation: true, closeButton: true }; }, render: function render() { 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 }; var modal = _react2['default'].createElement( 'div', _extends({}, this.props, { title: null, tabIndex: '-1', role: 'dialog', style: modalStyle, className: (0, _classnames2['default'])(this.props.className, classes), onClick: this.props.backdrop === true ? this.handleBackdropClick : null, ref: 'modal' }), _react2['default'].createElement( 'div', { className: (0, _classnames2['default'])(this.props.dialogClassName, dialogClasses) }, _react2['default'].createElement( 'div', { className: 'modal-content' }, this.props.title ? this.renderHeader() : null, this.props.children ) ) ); return this.props.backdrop ? this.renderBackdrop(modal) : modal; }, renderBackdrop: function renderBackdrop(modal) { var classes = { 'modal-backdrop': true, fade: this.props.animation, 'in': !this.props.animation }; var onClick = this.props.backdrop === true ? this.handleBackdropClick : null; return _react2['default'].createElement( 'div', null, _react2['default'].createElement('div', { className: (0, _classnames2['default'])(classes), ref: 'backdrop', onClick: onClick }), modal ); }, renderHeader: function renderHeader() { var closeButton = undefined; if (this.props.closeButton) { closeButton = _react2['default'].createElement( 'button', { type: 'button', className: 'close', 'aria-hidden': 'true', onClick: this.props.onRequestHide }, '×' ); } return _react2['default'].createElement( 'div', { className: 'modal-header' }, closeButton, this.renderTitle() ); }, renderTitle: function renderTitle() { return _react2['default'].isValidElement(this.props.title) ? this.props.title : _react2['default'].createElement( 'h4', { className: 'modal-title' }, this.props.title ); }, iosClickHack: function iosClickHack() { // 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 _react2['default'].findDOMNode(this.refs.modal).onclick = function () {}; _react2['default'].findDOMNode(this.refs.backdrop).onclick = function () {}; }, componentDidMount: function componentDidMount() { this._onDocumentKeyupListener = _utilsEventListener2['default'].listen(_utilsDomUtils2['default'].ownerDocument(this), 'keyup', this.handleDocumentKeyUp); var container = this.props.container && _react2['default'].findDOMNode(this.props.container) || _utilsDomUtils2['default'].ownerDocument(this).body; container.className += container.className.length ? ' modal-open' : 'modal-open'; this.focusModalContent(); if (this.props.backdrop) { this.iosClickHack(); } }, componentDidUpdate: function componentDidUpdate(prevProps) { if (this.props.backdrop && this.props.backdrop !== prevProps.backdrop) { this.iosClickHack(); } }, componentWillUnmount: function componentWillUnmount() { this._onDocumentKeyupListener.remove(); var container = this.props.container && _react2['default'].findDOMNode(this.props.container) || _utilsDomUtils2['default'].ownerDocument(this).body; container.className = container.className.replace(/ ?modal-open/, ''); this.restoreLastFocus(); }, handleBackdropClick: function handleBackdropClick(e) { if (e.target !== e.currentTarget) { return; } this.props.onRequestHide(); }, handleDocumentKeyUp: function handleDocumentKeyUp(e) { if (this.props.keyboard && e.keyCode === 27) { this.props.onRequestHide(); } }, focusModalContent: function focusModalContent() { this.lastFocus = _utilsDomUtils2['default'].ownerDocument(this).activeElement; var modalContent = _react2['default'].findDOMNode(this.refs.modal); modalContent.focus(); }, restoreLastFocus: function restoreLastFocus() { if (this.lastFocus) { this.lastFocus.focus(); this.lastFocus = null; } } }); exports['default'] = Modal; module.exports = exports['default'];