revenge-react-components
Version:
react-components for revenge https://github.com/buildo/revenge
269 lines (219 loc) • 9.05 kB
JavaScript
;
exports.__esModule = 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; };
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; }; })();
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 _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 _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _revenge = require('revenge');
var _classnames = require('classnames');
var _classnames2 = _interopRequireDefault(_classnames);
require('./popover.scss');
var Popover = (function (_React$Component) {
_inherits(Popover, _React$Component);
function Popover(props) {
var _this = this;
_classCallCheck(this, _Popover);
_React$Component.call(this, props);
this.getOffsetRect = function () {
var target = _this.refs.children.getDOMNode();
var box = target.getBoundingClientRect();
var body = document.body;
var docElem = document.documentElement;
var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop;
var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft;
var clientTop = docElem.clientTop || body.clientTop || 0;
var clientLeft = docElem.clientLeft || body.clientLeft || 0;
var top = Math.round(box.top + scrollTop - clientTop);
var left = Math.round(box.left + scrollLeft - clientLeft);
return {
top: top,
left: left
};
};
this.appendPopover = function () {
var positionClass = 'position-' + _this.props.position;
var anchorClass = 'anchor-' + _this.props.anchor;
var className = _classnames2['default']('popover-content', positionClass, anchorClass, _this.props.popoverClassName);
var hiddenPopover = _react2['default'].createElement(
'div',
{
className: className,
style: { position: 'absolute', visibility: 'hidden' } },
_this.props.content
);
_this.containerNode = document.createElement('div');
_this.containerNode.innerHTML = _react2['default'].renderToString(hiddenPopover);
_this.popoverNode = _this.containerNode.childNodes[0];
document.body.appendChild(_this.containerNode);
var style = _this.computePopoverStyle();
var popover = _react2['default'].createElement(
'div',
{
className: className,
style: style },
_this.props.content
);
_this.containerNode.innerHTML = _react2['default'].renderToString(popover);
_this.addOnScrollListener();
};
this.removePopover = function () {
if (_this.containerNode) {
document.body.removeChild(_this.containerNode);
_this.containerNode = null;
_this.removeOnScrollListener();
}
};
this.addOnScrollListener = function () {
if (_this.props.dismissOnScroll) {
if (window.attachEvent) {
//Internet Explorer
window.attachEvent('onmousewheel', _this.onScroll);
} else if (window.addEventListener) {
window.addEventListener('mousewheel', _this.onScroll, false);
}
}
};
this.removeOnScrollListener = function () {
if (_this.props.dismissOnScroll) {
if (window.detachEvent) {
//Internet Explorer
window.detachEvent('onmousewheel', _this.onScroll);
} else if (window.removeEventListener) {
window.removeEventListener('mousewheel', _this.onScroll, false);
}
}
};
this.callback = function () {
if (_this.state.isOpen) {
_this.props.onShow();
_this.appendPopover();
} else {
_this.props.onHide();
_this.removePopover();
}
};
this.showPopover = function () {
_this.setState({ isOpen: true }, _this.callback);
};
this.hidePopover = function () {
_this.setState({ isOpen: false }, _this.callback);
};
this.togglePopover = function () {
_this.setState({ isOpen: !_this.state.isOpen }, _this.callback);
};
this.onScroll = function () {
_this.hidePopover();
};
this.getEventCallbacks = function () {
var onHover = _this.props.event === 'hover';
var onClick = _this.props.event === 'click';
return {
onMouseEnter: onHover ? _this.showPopover : undefined,
onMouseLeave: onHover ? _this.hidePopover : undefined,
onClick: onClick ? _this.togglePopover : undefined
};
};
this.computePopoverStyle = function () {
var _refs$children$getDOMNode = _this.refs.children.getDOMNode();
var childWidth = _refs$children$getDOMNode.clientWidth;
var childHeight = _refs$children$getDOMNode.clientHeight;
var _popoverNode = _this.popoverNode;
var popoverHeight = _popoverNode.clientHeight;
var popoverWidth = _popoverNode.clientWidth;
var _getOffsetRect = _this.getOffsetRect();
var top = _getOffsetRect.top;
var left = _getOffsetRect.left;
var deltaX = undefined;
switch (_this.props.anchor) {
case 'left':
deltaX = 0;
break;
case 'center':
deltaX = (childWidth - popoverWidth) / 2;
break;
case 'right':
deltaX = childWidth - popoverWidth;
break;
}
var deltaY = undefined;
switch (_this.props.position) {
case 'top':
deltaY = -(popoverHeight + 5);
break;
case 'bottom':
deltaY = childHeight + 5;
break;
}
return {
position: 'absolute',
top: top + deltaY,
left: left + deltaX,
maxWidth: _this.props.popoverMaxWidth
};
};
this.state = {
isOpen: false
};
}
Popover.prototype.componentWillUnmount = function componentWillUnmount() {
this.removePopover();
};
Popover.prototype.getLocals = function getLocals() {
return _extends({}, this.props, {
eventCallbacks: this.getEventCallbacks()
});
};
Popover.prototype.template = function template(_ref) {
var children = _ref.children;
var style = _ref.style;
var className = _ref.className;
var eventCallbacks = _ref.eventCallbacks;
return _react2['default'].createElement(
'div',
_extends({
className: 'popover ' + className,
style: style,
ref: 'children'
}, eventCallbacks),
children
);
};
_createClass(Popover, null, [{
key: 'defaultProps',
value: {
event: 'hover',
position: 'top',
anchor: 'center',
onShow: function onShow() {},
onHide: function onHide() {},
popoverClassName: '',
dismissOnScroll: true,
className: '',
style: {}
},
enumerable: true
}]);
var _Popover = Popover;
Popover = _revenge.props({
children: _revenge.t.ReactNode,
content: _revenge.t.ReactNode,
event: _revenge.t.enums.of(['click', 'hover']),
position: _revenge.t.enums.of(['top', 'bottom']),
anchor: _revenge.t.enums.of(['left', 'center', 'right']),
onShow: _revenge.t.maybe(_revenge.t.Func),
onHide: _revenge.t.maybe(_revenge.t.Func),
popoverClassName: _revenge.t.maybe(_revenge.t.Str),
popoverMaxWidth: _revenge.t.maybe(_revenge.t.union([_revenge.t.Num, _revenge.t.Str])),
dismissOnScroll: _revenge.t.maybe(_revenge.t.Bool),
className: _revenge.t.maybe(_revenge.t.Str),
style: _revenge.t.maybe(_revenge.t.Obj)
})(Popover) || Popover;
Popover = _revenge.skinnable()(Popover) || Popover;
Popover = _revenge.pure(Popover) || Popover;
return Popover;
})(_react2['default'].Component);
exports['default'] = Popover;
module.exports = exports['default'];