wix-style-react
Version:
wix-style-react
471 lines (402 loc) • 16.7 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = undefined;
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; }; }();
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
var _class, _temp;
var _noop = require('lodash/noop');
var _noop2 = _interopRequireDefault(_noop);
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _propTypes = require('prop-types');
var _propTypes2 = _interopRequireDefault(_propTypes);
var _WixComponent2 = require('../../BaseComponents/WixComponent');
var _WixComponent3 = _interopRequireDefault(_WixComponent2);
var _Tooltip = require('./Tooltip.scss');
var _Tooltip2 = _interopRequireDefault(_Tooltip);
var _popper = require('popper.js');
var _popper2 = _interopRequireDefault(_popper);
var _classnames = require('classnames');
var _classnames2 = _interopRequireDefault(_classnames);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _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; }
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 TooltipRefreshRate = 20;
var Tooltip = (_temp = _class = function (_WixComponent) {
_inherits(Tooltip, _WixComponent);
function Tooltip(props) {
_classCallCheck(this, Tooltip);
var _this = _possibleConstructorReturn(this, (Tooltip.__proto__ || Object.getPrototypeOf(Tooltip)).call(this, props));
_this.placementFlipMap = {
top: 'bottom',
left: 'right',
right: 'left',
bottom: 'top'
};
_this.alignmentMap = {
top: 'start',
right: 'end',
bottom: 'end',
left: 'start',
center: ''
};
_this.state = {
placement: _this.getPopperPlacement(props.placement, props.alignment),
active: props.active
};
_this.handlePopperUpdate = _this.handlePopperUpdate.bind(_this);
_this.handleHideTrigger = _this.handleHideTrigger.bind(_this);
_this.handleShowTrigger = _this.handleShowTrigger.bind(_this);
return _this;
}
_createClass(Tooltip, [{
key: 'componentElements',
value: function componentElements() {
return [this.target.children[0], this.content.children[0]];
}
}, {
key: 'componentDidMount',
value: function componentDidMount() {
_get(Tooltip.prototype.__proto__ || Object.getPrototypeOf(Tooltip.prototype), 'componentDidMount', this).call(this);
var placement = this.state.placement;
var target = this.target.children[0];
var content = this.content.children[0];
this.popper = new _popper2.default(target, content, {
placement: placement,
modifiers: {
applyStyle: { enabled: false }
},
onUpdate: this.handlePopperUpdate,
onCreate: this.handlePopperUpdate
});
}
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
_get(Tooltip.prototype.__proto__ || Object.getPrototypeOf(Tooltip.prototype), 'componentWillUnmount', this).call(this);
this.popper.destroy();
clearInterval(this.scheduleInterval);
}
}, {
key: 'componentWillReceiveProps',
value: function componentWillReceiveProps(nextProps) {
this.handleNextActive(nextProps);
this.handleNextMoveBy(nextProps);
}
//Schedule popper updates periodically, only when the tooltip is visible (for
//tooltip repositioning - e.g. when the target dimensions change).
}, {
key: 'componentDidUpdate',
value: function componentDidUpdate(prevProps) {
var _this2 = this;
_get(Tooltip.prototype.__proto__ || Object.getPrototypeOf(Tooltip.prototype), 'componentDidUpdate', this).call(this, prevProps);
if (this.state.active && !this.scheduleInterval) {
this.scheduleInterval = setInterval(function () {
_this2.popper.scheduleUpdate();
}, TooltipRefreshRate);
this.props.onShow();
} else if (!this.state.active) {
clearInterval(this.scheduleInterval);
this.scheduleInterval = null;
}
}
}, {
key: 'onClickOutside',
value: function onClickOutside(e) {
if (this.props.shouldCloseOnClickOutside) {
this.hide();
} else {
this.props.onClickOutside(e);
}
}
}, {
key: 'hide',
value: function hide() {
this.toggleActive(false);
}
}, {
key: 'toggleActive',
value: function toggleActive(active) {
this.setState({ active: active });
}
}, {
key: 'handleNextMoveBy',
value: function handleNextMoveBy(nextProps) {
var hasChanged = nextProps.moveBy.x !== this.props.moveBy.x || nextProps.moveBy.y !== this.props.moveBy.y;
if (hasChanged) {
this.moveBy = nextProps.moveBy;
this.popper.update();
}
}
}, {
key: 'handleNextActive',
value: function handleNextActive(nextProps) {
var nextActive = nextProps.active;
var currentlyActive = this.props.active;
if (nextProps.showTrigger === 'custom' && nextActive && !currentlyActive) {
this.toggleActive(true);
} else if (nextProps.hideTrigger === 'custom' && !nextActive && currentlyActive) {
this.toggleActive(false);
}
}
}, {
key: 'handlePopperUpdate',
value: function handlePopperUpdate(data) {
var hasChangedPlacement = data.placement !== this.state.placement;
if (hasChangedPlacement) {
this.setState({
placement: data.placement
});
}
this.setState({ popperData: data });
}
}, {
key: 'handleTrigger',
value: function handleTrigger() {
var originalCallback = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _noop2.default;
var triggerType = arguments[1];
var _props = this.props,
showTrigger = _props.showTrigger,
hideTrigger = _props.hideTrigger;
var active = this.state.active;
if (showTrigger === hideTrigger && showTrigger === triggerType) {
if (active) {
this.handleHideTrigger();
} else {
this.handleShowTrigger();
}
} else if (showTrigger === triggerType) {
this.handleShowTrigger();
} else if (hideTrigger === triggerType) {
this.handleHideTrigger();
}
originalCallback();
}
}, {
key: 'handleHideTrigger',
value: function handleHideTrigger() {
this.handleToggleWithDelay(false);
}
}, {
key: 'handleShowTrigger',
value: function handleShowTrigger() {
this.handleToggleWithDelay(true);
}
}, {
key: 'handleToggleWithDelay',
value: function handleToggleWithDelay(toggle) {
var _this3 = this;
clearTimeout(this.mouseTimeout);
this.mouseTimeout = setTimeout(function () {
_this3.toggleActive(toggle);
}, toggle ? this.props.showDelay : this.props.hideDelay);
}
}, {
key: 'getPopperPlacement',
value: function getPopperPlacement(placement, alignment) {
var popperAlignment = this.alignmentMap[alignment];
if (alignment) {
return placement + '-' + popperAlignment;
}
return placement;
}
}, {
key: 'getArrowPlacement',
value: function getArrowPlacement(popperPlacement) {
var overrideArrowPlacement = this.props.arrowPlacement;
return overrideArrowPlacement || this.placementFlipMap[popperPlacement];
}
}, {
key: 'placementWithoutAlignment',
value: function placementWithoutAlignment(placement) {
return placement.replace(/-.*/, '');
}
}, {
key: 'getPopperStyle',
value: function getPopperStyle() {
var data = this.state.popperData;
if (!data) {
return {};
}
var left = Math.round(data.offsets.popper.left);
var top = Math.round(data.offsets.popper.top);
var transform = 'translate3d(' + left + 'px, ' + top + 'px, 0)';
return {
position: data.offsets.popper.position,
transform: transform,
WebkitTransform: transform,
left: this.props.moveBy.x,
top: this.props.moveBy.y
};
}
}, {
key: 'getArrowStyle',
value: function getArrowStyle() {
var _props2 = this.props,
moveArrowTo = _props2.moveArrowTo,
arrowStyle = _props2.arrowStyle;
var placement = this.placementWithoutAlignment(this.props.placement);
var isVertical = placement === 'top' || placement === 'bottom';
var isHorizontal = placement === 'left' || placement === 'right';
if (moveArrowTo) {
var repositionStyle = {};
if (isVertical) {
if (moveArrowTo > 0) {
repositionStyle.left = moveArrowTo;
repositionStyle.right = 'inherit';
} else {
repositionStyle.right = -1 * moveArrowTo;
repositionStyle.left = 'inherit';
}
} else if (isHorizontal) {
if (moveArrowTo > 0) {
repositionStyle.top = moveArrowTo;
repositionStyle.bottom = 'inherit';
} else {
repositionStyle.bottom = -1 * moveArrowTo;
repositionStyle.top = 'inherit';
}
}
return _extends({}, repositionStyle, arrowStyle);
}
return arrowStyle;
}
}, {
key: 'render',
value: function render() {
var _this4 = this;
var _props3 = this.props,
theme = _props3.theme,
bounce = _props3.bounce,
disabled = _props3.disabled,
maxWidth = _props3.maxWidth,
zIndex = _props3.zIndex,
textAlign = _props3.textAlign,
size = _props3.size,
targetStyle = _props3.targetStyle;
var placement = this.placementWithoutAlignment(this.state.placement);
var arrowPlacement = this.getArrowPlacement(placement);
var active = this.state.active;
active = active && !disabled;
var clonedTarget = _react2.default.cloneElement(this.props.children, {
onMouseEnter: function onMouseEnter() {
return _this4.handleTrigger(_this4.props.children.props.onMouseEnter, 'mouseenter');
},
onMouseLeave: function onMouseLeave() {
return _this4.handleTrigger(_this4.props.children.props.onMouseLeave, 'mouseleave');
},
onClick: function onClick() {
return _this4.handleTrigger(_this4.props.children.props.onClick, 'click');
},
onFocus: function onFocus() {
return _this4.handleTrigger(_this4.props.children.props.onFocus, 'focus');
},
onBlur: function onBlur() {
return _this4.handleTrigger(_this4.props.children.props.onBlur, 'blur');
}
});
var popperStyle = this.getPopperStyle();
var arrowStyle = this.getArrowStyle();
return _react2.default.createElement(
'div',
{ className: _Tooltip2.default.root, style: targetStyle },
_react2.default.createElement(
'div',
{
ref: function ref(r) {
return _this4.target = r;
},
'data-hook': 'target',
className: 'targetWrapper'
},
clonedTarget
),
_react2.default.createElement(
'div',
{ ref: function ref(r) {
return _this4.content = r;
} },
_react2.default.createElement(
'div',
{
className: (0, _classnames2.default)(_Tooltip2.default.tooltip, _defineProperty({}, _Tooltip2.default.active, active)),
style: _extends({ zIndex: zIndex }, popperStyle),
'data-hook': 'tooltip'
},
_react2.default.createElement(
'div',
{
className: (0, _classnames2.default)(_defineProperty({}, _Tooltip2.default['bounce-' + arrowPlacement], bounce))
},
_react2.default.createElement(
'div',
{
className: (0, _classnames2.default)(_Tooltip2.default.tooltipInner, _Tooltip2.default[theme], _Tooltip2.default[placement], _Tooltip2.default[size], _defineProperty({}, _Tooltip2.default.active, active)),
style: { maxWidth: maxWidth },
'data-hook': 'tooltip-inner'
},
_react2.default.createElement(
'div',
{ 'data-hook': 'tooltip-content', style: { textAlign: textAlign } },
this.props.content
),
_react2.default.createElement('div', {
className: (0, _classnames2.default)(_Tooltip2.default.arrow, _Tooltip2.default[arrowPlacement]),
style: arrowStyle
})
)
)
)
)
);
}
}]);
return Tooltip;
}(_WixComponent3.default), _class.propTypes = {
content: _propTypes2.default.any.isRequired,
children: _propTypes2.default.node.isRequired,
placement: _propTypes2.default.oneOf(['top', 'right', 'bottom', 'left']),
alignment: _propTypes2.default.oneOf(['top', 'right', 'bottom', 'left', 'center']),
theme: _propTypes2.default.oneOf(['light', 'dark', 'error']),
showDelay: _propTypes2.default.number,
hideDelay: _propTypes2.default.number,
showTrigger: _propTypes2.default.oneOf(['custom', 'mouseenter', 'mouseleave', 'click', 'focus', 'blur']),
hideTrigger: _propTypes2.default.oneOf(['custom', 'mouseenter', 'mouseleave', 'click', 'focus', 'blur']),
active: _propTypes2.default.bool,
arrowPlacement: _propTypes2.default.string,
arrowStyle: _propTypes2.default.object,
moveBy: _propTypes2.default.object,
disabled: _propTypes2.default.bool,
maxWidth: _propTypes2.default.string,
zIndex: _propTypes2.default.number,
textAlign: _propTypes2.default.string,
moveArrowTo: _propTypes2.default.number,
targetStyle: _propTypes2.default.any,
bounce: _propTypes2.default.bool,
shouldCloseOnClickOutside: _propTypes2.default.bool,
onClickOutside: _propTypes2.default.func,
onShow: _propTypes2.default.func,
size: _propTypes2.default.oneOf(['normal', 'large'])
}, _class.defaultProps = {
placement: 'top',
theme: 'light',
showDelay: 200,
hideDelay: 500,
showTrigger: 'mouseenter',
hideTrigger: 'mouseleave',
active: false,
moveBy: { x: 0, y: 0 },
disabled: false,
maxWidth: '1200px',
zIndex: 2000,
textAlign: 'center',
onClickOutside: _noop2.default,
onShow: _noop2.default,
size: 'normal'
}, _temp);
exports.default = Tooltip;