UNPKG

antd

Version:

An enterprise-class UI design language and React-based implementation

203 lines (189 loc) 8.19 kB
import _defineProperty from 'babel-runtime/helpers/defineProperty'; import _classCallCheck from 'babel-runtime/helpers/classCallCheck'; import _createClass from 'babel-runtime/helpers/createClass'; import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn'; import _inherits from 'babel-runtime/helpers/inherits'; import _extends from 'babel-runtime/helpers/extends'; import * as React from 'react'; import { cloneElement } from 'react'; import { polyfill } from 'react-lifecycles-compat'; import RcTooltip from 'rc-tooltip'; import classNames from 'classnames'; import _getPlacements from './placements'; var splitObject = function splitObject(obj, keys) { var picked = {}; var omitted = _extends({}, obj); keys.forEach(function (key) { if (obj && key in obj) { picked[key] = obj[key]; delete omitted[key]; } }); return { picked: picked, omitted: omitted }; }; var Tooltip = function (_React$Component) { _inherits(Tooltip, _React$Component); function Tooltip(props) { _classCallCheck(this, Tooltip); var _this = _possibleConstructorReturn(this, (Tooltip.__proto__ || Object.getPrototypeOf(Tooltip)).call(this, props)); _this.onVisibleChange = function (visible) { var onVisibleChange = _this.props.onVisibleChange; if (!('visible' in _this.props)) { _this.setState({ visible: _this.isNoTitle() ? false : visible }); } if (onVisibleChange && !_this.isNoTitle()) { onVisibleChange(visible); } }; // 动态设置动画点 _this.onPopupAlign = function (domNode, align) { var placements = _this.getPlacements(); // 当前返回的位置 var placement = Object.keys(placements).filter(function (key) { return placements[key].points[0] === align.points[0] && placements[key].points[1] === align.points[1]; })[0]; if (!placement) { return; } // 根据当前坐标设置动画点 var rect = domNode.getBoundingClientRect(); var transformOrigin = { top: '50%', left: '50%' }; if (placement.indexOf('top') >= 0 || placement.indexOf('Bottom') >= 0) { transformOrigin.top = rect.height - align.offset[1] + 'px'; } else if (placement.indexOf('Top') >= 0 || placement.indexOf('bottom') >= 0) { transformOrigin.top = -align.offset[1] + 'px'; } if (placement.indexOf('left') >= 0 || placement.indexOf('Right') >= 0) { transformOrigin.left = rect.width - align.offset[0] + 'px'; } else if (placement.indexOf('right') >= 0 || placement.indexOf('Left') >= 0) { transformOrigin.left = -align.offset[0] + 'px'; } domNode.style.transformOrigin = transformOrigin.left + ' ' + transformOrigin.top; }; _this.saveTooltip = function (node) { _this.tooltip = node; }; _this.state = { visible: !!props.visible || !!props.defaultVisible }; return _this; } _createClass(Tooltip, [{ key: 'getPopupDomNode', value: function getPopupDomNode() { return this.tooltip.getPopupDomNode(); } }, { key: 'getPlacements', value: function getPlacements() { var _props = this.props, builtinPlacements = _props.builtinPlacements, arrowPointAtCenter = _props.arrowPointAtCenter, autoAdjustOverflow = _props.autoAdjustOverflow; return builtinPlacements || _getPlacements({ arrowPointAtCenter: arrowPointAtCenter, verticalArrowShift: 8, autoAdjustOverflow: autoAdjustOverflow }); } }, { key: 'isHoverTrigger', value: function isHoverTrigger() { var trigger = this.props.trigger; if (!trigger || trigger === 'hover') { return true; } if (Array.isArray(trigger)) { return trigger.indexOf('hover') >= 0; } return false; } // Fix Tooltip won't hide at disabled button // mouse events don't trigger at disabled button in Chrome // https://github.com/react-component/tooltip/issues/18 }, { key: 'getDisabledCompatibleChildren', value: function getDisabledCompatibleChildren(element) { if ((element.type.__ANT_BUTTON || element.type === 'button') && element.props.disabled && this.isHoverTrigger()) { // Pick some layout related style properties up to span // Prevent layout bugs like https://github.com/ant-design/ant-design/issues/5254 var _splitObject = splitObject(element.props.style, ['position', 'left', 'right', 'top', 'bottom', 'float', 'display', 'zIndex']), picked = _splitObject.picked, omitted = _splitObject.omitted; var spanStyle = _extends({ display: 'inline-block' }, picked, { cursor: 'not-allowed' }); var buttonStyle = _extends({}, omitted, { pointerEvents: 'none' }); var child = cloneElement(element, { style: buttonStyle, className: null }); return React.createElement( 'span', { style: spanStyle, className: element.props.className }, child ); } return element; } }, { key: 'isNoTitle', value: function isNoTitle() { var _props2 = this.props, title = _props2.title, overlay = _props2.overlay; return !title && !overlay; // overlay for old version compatibility } }, { key: 'render', value: function render() { var props = this.props, state = this.state; var prefixCls = props.prefixCls, title = props.title, overlay = props.overlay, openClassName = props.openClassName, getPopupContainer = props.getPopupContainer, getTooltipContainer = props.getTooltipContainer; var children = props.children; var visible = state.visible; // Hide tooltip when there is no title if (!('visible' in props) && this.isNoTitle()) { visible = false; } var child = this.getDisabledCompatibleChildren(React.isValidElement(children) ? children : React.createElement( 'span', null, children )); var childProps = child.props; var childCls = classNames(childProps.className, _defineProperty({}, openClassName || prefixCls + '-open', true)); return React.createElement( RcTooltip, _extends({}, this.props, { getTooltipContainer: getPopupContainer || getTooltipContainer, ref: this.saveTooltip, builtinPlacements: this.getPlacements(), overlay: overlay || title || '', visible: visible, onVisibleChange: this.onVisibleChange, onPopupAlign: this.onPopupAlign }), visible ? cloneElement(child, { className: childCls }) : child ); } }], [{ key: 'getDerivedStateFromProps', value: function getDerivedStateFromProps(nextProps) { if ('visible' in nextProps) { return { visible: nextProps.visible }; } return null; } }]); return Tooltip; }(React.Component); Tooltip.defaultProps = { prefixCls: 'ant-tooltip', placement: 'top', transitionName: 'zoom-big-fast', mouseEnterDelay: 0.1, mouseLeaveDelay: 0.1, arrowPointAtCenter: false, autoAdjustOverflow: true }; polyfill(Tooltip); export default Tooltip;