react-responsive-modal
Version:
A simple responsive react modal
229 lines (191 loc) • 8.63 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.useSheet = exports.jss = undefined;
var _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; }; }();
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _reactMinimalistPortal = require('react-minimalist-portal');
var _reactMinimalistPortal2 = _interopRequireDefault(_reactMinimalistPortal);
var _reactAddonsCssTransitionGroup = require('react-addons-css-transition-group');
var _reactAddonsCssTransitionGroup2 = _interopRequireDefault(_reactAddonsCssTransitionGroup);
var _classnames = require('classnames');
var _classnames2 = _interopRequireDefault(_classnames);
var _jss = require('jss');
var _reactJss = require('react-jss');
var _reactJss2 = _interopRequireDefault(_reactJss);
var _jssCamelCase = require('jss-camel-case');
var _jssCamelCase2 = _interopRequireDefault(_jssCamelCase);
var _jssPx = require('jss-px');
var _jssPx2 = _interopRequireDefault(_jssPx);
var _jssVendorPrefixer = require('jss-vendor-prefixer');
var _jssVendorPrefixer2 = _interopRequireDefault(_jssVendorPrefixer);
var _styles = require('./styles');
var _styles2 = _interopRequireDefault(_styles);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _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; }
function _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; }
var jss = exports.jss = (0, _jss.create)();
var useSheet = exports.useSheet = (0, _reactJss2.default)(jss);
jss.use((0, _jssCamelCase2.default)());
jss.use((0, _jssPx2.default)());
jss.use((0, _jssVendorPrefixer2.default)());
var Modal = function (_Component) {
_inherits(Modal, _Component);
function Modal(props) {
_classCallCheck(this, Modal);
var _this = _possibleConstructorReturn(this, (Modal.__proto__ || Object.getPrototypeOf(Modal)).call(this, props));
_this.handleKeydown = _this.handleKeydown.bind(_this);
_this.onClickOverlay = _this.onClickOverlay.bind(_this);
_this.onClickCloseIcon = _this.onClickCloseIcon.bind(_this);
_this.state = {
showPortal: props.open,
open: props.open
};
return _this;
}
_createClass(Modal, [{
key: 'componentDidMount',
value: function componentDidMount() {
if (this.props.closeOnEsc) {
document.addEventListener('keydown', this.handleKeydown);
}
}
}, {
key: 'componentWillReceiveProps',
value: function componentWillReceiveProps(nextProps) {
var _this2 = this;
if (nextProps.open) {
document.body.style.overflow = 'hidden';
this.setState({ open: true, showPortal: true });
}
if (this.props.open && !nextProps.open) {
this.setState({ open: false });
// Let the animation finish
this.timeout = setTimeout(function () {
_this2.setState({ showPortal: false });
document.body.style.overflow = null;
}, 500);
}
}
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
if (this.props.closeOnEsc) {
document.removeEventListener('keydown', this.handleKeydown);
}
document.body.style.overflow = null;
if (this.timeout) {
clearTimeout(this.timeout);
}
}
}, {
key: 'onClickOverlay',
value: function onClickOverlay(e) {
var _props = this.props;
var classes = _props.sheet.classes;
var closeOnOverlayClick = _props.closeOnOverlayClick;
if (!closeOnOverlayClick) return;
var className = e.target.className.split(' ');
if (className.indexOf(classes.overlay) !== -1) {
e.stopPropagation();
this.props.onClose();
}
}
}, {
key: 'onClickCloseIcon',
value: function onClickCloseIcon(e) {
e.stopPropagation();
this.props.onClose();
}
}, {
key: 'handleKeydown',
value: function handleKeydown(e) {
if (e.keyCode === 27) {
this.props.onClose();
}
}
}, {
key: 'render',
value: function render() {
var _props2 = this.props;
var little = _props2.little;
var classes = _props2.sheet.classes;
var overlayClassName = _props2.overlayClassName;
var modalClassName = _props2.modalClassName;
var closeIconClassName = _props2.closeIconClassName;
var overlayStyle = _props2.overlayStyle;
var modalStyle = _props2.modalStyle;
var showCloseIcon = _props2.showCloseIcon;
var _state = this.state;
var open = _state.open;
var showPortal = _state.showPortal;
if (!showPortal) return null;
return _react2.default.createElement(
_reactMinimalistPortal2.default,
null,
_react2.default.createElement(
_reactAddonsCssTransitionGroup2.default,
{
transitionName: {
appear: classes.transitionEnter,
appearActive: classes.transitionEnterActive,
enter: classes.transitionEnter,
enterActive: classes.transitionEnterActive,
leave: classes.transitionLeave,
leaveActive: classes.transitionLeaveActive
},
transitionAppear: true,
transitionLeave: true,
transitionAppearTimeout: 500,
transitionEnterTimeout: 500,
transitionLeaveTimeout: 500
},
open && _react2.default.createElement(
'div',
{
className: (0, _classnames2.default)(classes.overlay, little ? classes.overlayLittle : null, overlayClassName),
onClick: this.onClickOverlay,
style: overlayStyle
},
_react2.default.createElement(
'div',
{ className: (0, _classnames2.default)(classes.modal, modalClassName), style: modalStyle },
showCloseIcon ? _react2.default.createElement(
'svg',
{ className: (0, _classnames2.default)(classes.closeIcon, closeIconClassName), onClick: this.onClickCloseIcon, xmlns: 'http://www.w3.org/2000/svg', width: '36', height: '36', viewBox: '0 0 36 36' },
_react2.default.createElement('path', { d: 'M28.5 9.62L26.38 7.5 18 15.88 9.62 7.5 7.5 9.62 15.88 18 7.5 26.38l2.12 2.12L18 20.12l8.38 8.38 2.12-2.12L20.12 18z' })
) : null,
this.props.children
)
)
)
);
}
}]);
return Modal;
}(_react.Component);
Modal.propTypes = {
closeOnEsc: _react2.default.PropTypes.bool,
closeOnOverlayClick: _react2.default.PropTypes.bool,
onClose: _react2.default.PropTypes.func.isRequired,
open: _react2.default.PropTypes.bool.isRequired,
overlayClassName: _react2.default.PropTypes.string,
modalClassName: _react2.default.PropTypes.string,
closeIconClassName: _react2.default.PropTypes.string,
overlayStyle: _react2.default.PropTypes.object,
modalStyle: _react2.default.PropTypes.object,
children: _react2.default.PropTypes.node,
classes: _react2.default.PropTypes.object,
sheet: _react2.default.PropTypes.object,
little: _react2.default.PropTypes.bool,
showCloseIcon: _react2.default.PropTypes.bool
};
Modal.defaultProps = {
closeOnEsc: true,
closeOnOverlayClick: true,
showCloseIcon: true
};
exports.default = useSheet(Modal, _styles2.default);