UNPKG

10.5 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6
7var _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; };
8
9var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
10
11var _react = require('react');
12
13var _react2 = _interopRequireDefault(_react);
14
15var _reactDom = require('react-dom');
16
17var _reactDom2 = _interopRequireDefault(_reactDom);
18
19var _classnames = require('classnames');
20
21var _classnames2 = _interopRequireDefault(_classnames);
22
23var _lodash = require('lodash.omit');
24
25var _lodash2 = _interopRequireDefault(_lodash);
26
27var _reactAddonsTransitionGroup = require('react-addons-transition-group');
28
29var _reactAddonsTransitionGroup2 = _interopRequireDefault(_reactAddonsTransitionGroup);
30
31var _Fade = require('./Fade');
32
33var _Fade2 = _interopRequireDefault(_Fade);
34
35var _utils = require('./utils');
36
37function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
38
39function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
40
41function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
42
43function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
44
45function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
46
47function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
48
49var propTypes = {
50 isOpen: _react.PropTypes.bool,
51 size: _react.PropTypes.string,
52 toggle: _react.PropTypes.func,
53 keyboard: _react.PropTypes.bool,
54 backdrop: _react.PropTypes.oneOfType([_react.PropTypes.bool, _react.PropTypes.oneOf(['static'])]),
55 onEnter: _react.PropTypes.func,
56 onExit: _react.PropTypes.func,
57 children: _react.PropTypes.node,
58 className: _react.PropTypes.string,
59 wrapClassName: _react.PropTypes.string,
60 modalClassName: _react.PropTypes.string,
61 backdropClassName: _react.PropTypes.string,
62 contentClassName: _react.PropTypes.string,
63 cssModule: _react.PropTypes.object,
64 zIndex: _react.PropTypes.oneOfType([_react.PropTypes.number, _react.PropTypes.string])
65};
66
67var defaultProps = {
68 isOpen: false,
69 backdrop: true,
70 keyboard: true,
71 zIndex: 1050
72};
73
74var Modal = function (_React$Component) {
75 _inherits(Modal, _React$Component);
76
77 function Modal(props) {
78 _classCallCheck(this, Modal);
79
80 var _this = _possibleConstructorReturn(this, (Modal.__proto__ || Object.getPrototypeOf(Modal)).call(this, props));
81
82 _this.originalBodyPadding = null;
83 _this.isBodyOverflowing = false;
84 _this.togglePortal = _this.togglePortal.bind(_this);
85 _this.handleBackdropClick = _this.handleBackdropClick.bind(_this);
86 _this.handleEscape = _this.handleEscape.bind(_this);
87 _this.destroy = _this.destroy.bind(_this);
88 _this.onEnter = _this.onEnter.bind(_this);
89 _this.onExit = _this.onExit.bind(_this);
90 return _this;
91 }
92
93 _createClass(Modal, [{
94 key: 'componentDidMount',
95 value: function componentDidMount() {
96 if (this.props.isOpen) {
97 this.togglePortal();
98 }
99 }
100 }, {
101 key: 'componentDidUpdate',
102 value: function componentDidUpdate(prevProps) {
103 if (this.props.isOpen !== prevProps.isOpen) {
104 // handle portal events/dom updates
105 this.togglePortal();
106 } else if (this._element) {
107 // rerender portal
108 this.renderIntoSubtree();
109 }
110 }
111 }, {
112 key: 'componentWillUnmount',
113 value: function componentWillUnmount() {
114 this.onExit();
115 }
116 }, {
117 key: 'onEnter',
118 value: function onEnter() {
119 if (this.props.onEnter) {
120 this.props.onEnter();
121 }
122 }
123 }, {
124 key: 'onExit',
125 value: function onExit() {
126 this.destroy();
127 if (this.props.onExit) {
128 this.props.onExit();
129 }
130 }
131 }, {
132 key: 'handleEscape',
133 value: function handleEscape(e) {
134 if (this.props.keyboard && e.keyCode === 27 && this.props.toggle) {
135 this.props.toggle();
136 }
137 }
138 }, {
139 key: 'handleBackdropClick',
140 value: function handleBackdropClick(e) {
141 if (this.props.backdrop !== true) return;
142
143 var container = this._dialog;
144
145 if (e.target && !container.contains(e.target) && this.props.toggle) {
146 this.props.toggle();
147 }
148 }
149 }, {
150 key: 'togglePortal',
151 value: function togglePortal() {
152 if (this.props.isOpen) {
153 this._focus = true;
154 this.show();
155 } else {
156 this.hide();
157 }
158 }
159 }, {
160 key: 'destroy',
161 value: function destroy() {
162 if (this._element) {
163 _reactDom2.default.unmountComponentAtNode(this._element);
164 document.body.removeChild(this._element);
165 this._element = null;
166 }
167
168 var classes = document.body.className.replace('modal-open', '');
169 document.body.className = (0, _utils.mapToCssModules)((0, _classnames2.default)(classes).trim(), this.props.cssModule);
170 (0, _utils.setScrollbarWidth)(this.originalBodyPadding);
171 }
172 }, {
173 key: 'hide',
174 value: function hide() {
175 this.renderIntoSubtree();
176 }
177 }, {
178 key: 'show',
179 value: function show() {
180 var classes = document.body.className;
181 this._element = document.createElement('div');
182 this._element.setAttribute('tabindex', '-1');
183 this._element.style.position = 'relative';
184 this._element.style.zIndex = this.props.zIndex;
185 this.originalBodyPadding = (0, _utils.getOriginalBodyPadding)();
186
187 (0, _utils.conditionallyUpdateScrollbar)();
188
189 document.body.appendChild(this._element);
190
191 document.body.className = (0, _utils.mapToCssModules)((0, _classnames2.default)(classes, 'modal-open'), this.props.cssModule);
192
193 this.renderIntoSubtree();
194 }
195 }, {
196 key: 'renderIntoSubtree',
197 value: function renderIntoSubtree() {
198 _reactDom2.default.unstable_renderSubtreeIntoContainer(this, this.renderChildren(), this._element);
199
200 // check if modal should receive focus
201 if (this._focus) {
202 this._dialog.parentNode.focus();
203 this._focus = false;
204 }
205 }
206 }, {
207 key: 'renderChildren',
208 value: function renderChildren() {
209 var _this2 = this;
210
211 var _omit = (0, _lodash2.default)(this.props, ['toggle', 'keyboard', 'onEnter', 'onExit', 'zIndex']),
212 className = _omit.className,
213 wrapClassName = _omit.wrapClassName,
214 modalClassName = _omit.modalClassName,
215 backdropClassName = _omit.backdropClassName,
216 contentClassName = _omit.contentClassName,
217 cssModule = _omit.cssModule,
218 isOpen = _omit.isOpen,
219 size = _omit.size,
220 backdrop = _omit.backdrop,
221 children = _omit.children,
222 attributes = _objectWithoutProperties(_omit, ['className', 'wrapClassName', 'modalClassName', 'backdropClassName', 'contentClassName', 'cssModule', 'isOpen', 'size', 'backdrop', 'children']);
223
224 return _react2.default.createElement(
225 _reactAddonsTransitionGroup2.default,
226 { component: 'div', className: (0, _utils.mapToCssModules)(wrapClassName) },
227 isOpen && _react2.default.createElement(
228 _Fade2.default,
229 {
230 key: 'modal-dialog',
231 onEnter: this.onEnter,
232 onLeave: this.onExit,
233 transitionAppearTimeout: 300,
234 transitionEnterTimeout: 300,
235 transitionLeaveTimeout: 300,
236 onClickCapture: this.handleBackdropClick,
237 onKeyUp: this.handleEscape,
238 className: (0, _utils.mapToCssModules)((0, _classnames2.default)('modal', modalClassName), cssModule),
239 style: { display: 'block' },
240 tabIndex: '-1'
241 },
242 _react2.default.createElement(
243 'div',
244 _extends({
245 className: (0, _utils.mapToCssModules)((0, _classnames2.default)('modal-dialog', className, _defineProperty({}, 'modal-' + size, size)), cssModule),
246 role: 'document',
247 ref: function ref(c) {
248 return _this2._dialog = c;
249 }
250 }, attributes),
251 _react2.default.createElement(
252 'div',
253 { className: (0, _utils.mapToCssModules)((0, _classnames2.default)('modal-content', contentClassName), cssModule) },
254 children
255 )
256 )
257 ),
258 isOpen && backdrop && _react2.default.createElement(_Fade2.default, {
259 key: 'modal-backdrop',
260 transitionAppearTimeout: 150,
261 transitionEnterTimeout: 150,
262 transitionLeaveTimeout: 150,
263 className: (0, _utils.mapToCssModules)((0, _classnames2.default)('modal-backdrop', backdropClassName), cssModule)
264 })
265 );
266 }
267 }, {
268 key: 'render',
269 value: function render() {
270 return null;
271 }
272 }]);
273
274 return Modal;
275}(_react2.default.Component);
276
277Modal.propTypes = propTypes;
278Modal.defaultProps = defaultProps;
279
280exports.default = Modal;
\No newline at end of file