UNPKG

wix-style-react

Version:
471 lines (402 loc) • 16.7 kB
'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;