Tooltip.js 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
  2. import _typeof from "@babel/runtime/helpers/esm/typeof";
  3. import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
  4. import { resolveDirective as _resolveDirective, createVNode as _createVNode } from "vue";
  5. import { computed, watch, defineComponent, onMounted, ref } from 'vue';
  6. import VcTooltip from '../vc-tooltip';
  7. import classNames from '../_util/classNames';
  8. import PropTypes from '../_util/vue-types';
  9. import { PresetColorTypes } from '../_util/colors';
  10. import warning from '../_util/warning';
  11. import { getStyle, filterEmpty, isValidElement, initDefaultProps } from '../_util/props-util';
  12. import { cloneElement } from '../_util/vnode';
  13. import abstractTooltipProps from './abstractTooltipProps';
  14. import useConfigInject from '../_util/hooks/useConfigInject';
  15. import getPlacements from './placements';
  16. import firstNotUndefined from '../_util/firstNotUndefined';
  17. import raf from '../_util/raf';
  18. var splitObject = function splitObject(obj, keys) {
  19. var picked = {};
  20. var omitted = _objectSpread({}, obj);
  21. keys.forEach(function (key) {
  22. if (obj && key in obj) {
  23. picked[key] = obj[key];
  24. delete omitted[key];
  25. }
  26. });
  27. return {
  28. picked: picked,
  29. omitted: omitted
  30. };
  31. };
  32. var PresetColorRegex = new RegExp("^(".concat(PresetColorTypes.join('|'), ")(-inverse)?$"));
  33. export var tooltipProps = function tooltipProps() {
  34. return _objectSpread(_objectSpread({}, abstractTooltipProps()), {}, {
  35. title: PropTypes.any
  36. });
  37. };
  38. export var tooltipDefaultProps = function tooltipDefaultProps() {
  39. return {
  40. trigger: 'hover',
  41. transitionName: 'zoom-big-fast',
  42. align: {},
  43. placement: 'top',
  44. mouseEnterDelay: 0.1,
  45. mouseLeaveDelay: 0.1,
  46. arrowPointAtCenter: false,
  47. autoAdjustOverflow: true
  48. };
  49. };
  50. export default defineComponent({
  51. compatConfig: {
  52. MODE: 3
  53. },
  54. name: 'ATooltip',
  55. inheritAttrs: false,
  56. props: initDefaultProps(tooltipProps(), {
  57. trigger: 'hover',
  58. transitionName: 'zoom-big-fast',
  59. align: {},
  60. placement: 'top',
  61. mouseEnterDelay: 0.1,
  62. mouseLeaveDelay: 0.1,
  63. arrowPointAtCenter: false,
  64. autoAdjustOverflow: true
  65. }),
  66. slots: ['title'],
  67. // emits: ['update:visible', 'visibleChange'],
  68. setup: function setup(props, _ref) {
  69. var slots = _ref.slots,
  70. emit = _ref.emit,
  71. attrs = _ref.attrs,
  72. expose = _ref.expose;
  73. var _useConfigInject = useConfigInject('tooltip', props),
  74. prefixCls = _useConfigInject.prefixCls,
  75. getPopupContainer = _useConfigInject.getPopupContainer;
  76. var visible = ref(firstNotUndefined([props.visible, props.defaultVisible]));
  77. var tooltip = ref();
  78. onMounted(function () {
  79. warning(props.defaultVisible === undefined, 'Tooltip', "'defaultVisible' is deprecated, please use 'v-model:visible'");
  80. });
  81. var rafId;
  82. watch(function () {
  83. return props.visible;
  84. }, function (val) {
  85. raf.cancel(rafId);
  86. rafId = raf(function () {
  87. visible.value = !!val;
  88. });
  89. });
  90. var isNoTitle = function isNoTitle() {
  91. var _props$title;
  92. var title = (_props$title = props.title) !== null && _props$title !== void 0 ? _props$title : slots.title;
  93. return !title && title !== 0;
  94. };
  95. var handleVisibleChange = function handleVisibleChange(val) {
  96. var noTitle = isNoTitle();
  97. if (props.visible === undefined) {
  98. visible.value = noTitle ? false : val;
  99. }
  100. if (!noTitle) {
  101. emit('update:visible', val);
  102. emit('visibleChange', val);
  103. }
  104. };
  105. var getPopupDomNode = function getPopupDomNode() {
  106. return tooltip.value.getPopupDomNode();
  107. };
  108. expose({
  109. getPopupDomNode: getPopupDomNode,
  110. visible: visible,
  111. forcePopupAlign: function forcePopupAlign() {
  112. var _tooltip$value;
  113. return (_tooltip$value = tooltip.value) === null || _tooltip$value === void 0 ? void 0 : _tooltip$value.forcePopupAlign();
  114. }
  115. });
  116. var tooltipPlacements = computed(function () {
  117. var builtinPlacements = props.builtinPlacements,
  118. arrowPointAtCenter = props.arrowPointAtCenter,
  119. autoAdjustOverflow = props.autoAdjustOverflow;
  120. return builtinPlacements || getPlacements({
  121. arrowPointAtCenter: arrowPointAtCenter,
  122. autoAdjustOverflow: autoAdjustOverflow
  123. });
  124. });
  125. var isTrueProps = function isTrueProps(val) {
  126. return val || val === '';
  127. };
  128. var getDisabledCompatibleChildren = function getDisabledCompatibleChildren(ele) {
  129. var elementType = ele.type;
  130. if (_typeof(elementType) === 'object' && ele.props) {
  131. if ((elementType.__ANT_BUTTON === true || elementType === 'button') && isTrueProps(ele.props.disabled) || elementType.__ANT_SWITCH === true && (isTrueProps(ele.props.disabled) || isTrueProps(ele.props.loading))) {
  132. // Pick some layout related style properties up to span
  133. // Prevent layout bugs like https://github.com/ant-design/ant-design/issues/5254
  134. var _splitObject = splitObject(getStyle(ele), ['position', 'left', 'right', 'top', 'bottom', 'float', 'display', 'zIndex']),
  135. picked = _splitObject.picked,
  136. omitted = _splitObject.omitted;
  137. var spanStyle = _objectSpread(_objectSpread({
  138. display: 'inline-block'
  139. }, picked), {}, {
  140. cursor: 'not-allowed',
  141. lineHeight: 1,
  142. width: ele.props && ele.props.block ? '100%' : null
  143. });
  144. var buttonStyle = _objectSpread(_objectSpread({}, omitted), {}, {
  145. pointerEvents: 'none'
  146. });
  147. var child = cloneElement(ele, {
  148. style: buttonStyle
  149. }, true);
  150. return _createVNode("span", {
  151. "style": spanStyle,
  152. "class": "".concat(prefixCls.value, "-disabled-compatible-wrapper")
  153. }, [child]);
  154. }
  155. }
  156. return ele;
  157. };
  158. var getOverlay = function getOverlay() {
  159. var _props$title2, _slots$title;
  160. return (_props$title2 = props.title) !== null && _props$title2 !== void 0 ? _props$title2 : (_slots$title = slots.title) === null || _slots$title === void 0 ? void 0 : _slots$title.call(slots);
  161. };
  162. var onPopupAlign = function onPopupAlign(domNode, align) {
  163. var placements = tooltipPlacements.value;
  164. // 当前返回的位置
  165. var placement = Object.keys(placements).filter(function (key) {
  166. return placements[key].points[0] === align.points[0] && placements[key].points[1] === align.points[1];
  167. })[0];
  168. if (!placement) {
  169. return;
  170. }
  171. // 根据当前坐标设置动画点
  172. var rect = domNode.getBoundingClientRect();
  173. var transformOrigin = {
  174. top: '50%',
  175. left: '50%'
  176. };
  177. if (placement.indexOf('top') >= 0 || placement.indexOf('Bottom') >= 0) {
  178. transformOrigin.top = "".concat(rect.height - align.offset[1], "px");
  179. } else if (placement.indexOf('Top') >= 0 || placement.indexOf('bottom') >= 0) {
  180. transformOrigin.top = "".concat(-align.offset[1], "px");
  181. }
  182. if (placement.indexOf('left') >= 0 || placement.indexOf('Right') >= 0) {
  183. transformOrigin.left = "".concat(rect.width - align.offset[0], "px");
  184. } else if (placement.indexOf('right') >= 0 || placement.indexOf('Left') >= 0) {
  185. transformOrigin.left = "".concat(-align.offset[0], "px");
  186. }
  187. domNode.style.transformOrigin = "".concat(transformOrigin.left, " ").concat(transformOrigin.top);
  188. };
  189. return function () {
  190. var _filterEmpty, _slots$default, _classNames;
  191. var openClassName = props.openClassName,
  192. color = props.color,
  193. overlayClassName = props.overlayClassName;
  194. var children = (_filterEmpty = filterEmpty((_slots$default = slots.default) === null || _slots$default === void 0 ? void 0 : _slots$default.call(slots))) !== null && _filterEmpty !== void 0 ? _filterEmpty : null;
  195. children = children.length === 1 ? children[0] : children;
  196. var tempVisible = visible.value;
  197. // Hide tooltip when there is no title
  198. if (props.visible === undefined && isNoTitle()) {
  199. tempVisible = false;
  200. }
  201. if (!children) {
  202. return null;
  203. }
  204. var child = getDisabledCompatibleChildren(isValidElement(children) ? children : _createVNode("span", null, [children]));
  205. var childCls = classNames((_classNames = {}, _defineProperty(_classNames, openClassName || "".concat(prefixCls.value, "-open"), true), _defineProperty(_classNames, child.props && child.props.class, child.props && child.props.class), _classNames));
  206. var customOverlayClassName = classNames(overlayClassName, _defineProperty({}, "".concat(prefixCls.value, "-").concat(color), color && PresetColorRegex.test(color)));
  207. var formattedOverlayInnerStyle;
  208. var arrowContentStyle;
  209. if (color && !PresetColorRegex.test(color)) {
  210. formattedOverlayInnerStyle = {
  211. backgroundColor: color
  212. };
  213. arrowContentStyle = {
  214. backgroundColor: color
  215. };
  216. }
  217. var vcTooltipProps = _objectSpread(_objectSpread(_objectSpread({}, attrs), props), {}, {
  218. prefixCls: prefixCls.value,
  219. getPopupContainer: getPopupContainer.value,
  220. builtinPlacements: tooltipPlacements.value,
  221. visible: tempVisible,
  222. ref: tooltip,
  223. overlayClassName: customOverlayClassName,
  224. overlayInnerStyle: formattedOverlayInnerStyle,
  225. onVisibleChange: handleVisibleChange,
  226. onPopupAlign: onPopupAlign
  227. });
  228. return _createVNode(VcTooltip, vcTooltipProps, {
  229. default: function _default() {
  230. return [visible.value ? cloneElement(child, {
  231. class: childCls
  232. }) : child];
  233. },
  234. arrowContent: function arrowContent() {
  235. return _createVNode("span", {
  236. "class": "".concat(prefixCls.value, "-arrow-content"),
  237. "style": arrowContentStyle
  238. }, null);
  239. },
  240. overlay: getOverlay
  241. });
  242. };
  243. }
  244. });