UNPKG

@douyinfe/semi-ui

Version:

A modern, comprehensive, flexible design system and UI library. Connect DesignOps & DevOps. Quickly build beautiful React apps. Maintained by Douyin-fe team.

748 lines (747 loc) 29.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _isEqual2 = _interopRequireDefault(require("lodash/isEqual")); var _isFunction2 = _interopRequireDefault(require("lodash/isFunction")); var _isEmpty2 = _interopRequireDefault(require("lodash/isEmpty")); var _each2 = _interopRequireDefault(require("lodash/each")); var _omit2 = _interopRequireDefault(require("lodash/omit")); var _get2 = _interopRequireDefault(require("lodash/get")); var _noop2 = _interopRequireDefault(require("lodash/noop")); var _throttle2 = _interopRequireDefault(require("lodash/throttle")); var _react = _interopRequireWildcard(require("react")); var _reactDom = _interopRequireWildcard(require("react-dom")); var _classnames = _interopRequireDefault(require("classnames")); var _propTypes = _interopRequireDefault(require("prop-types")); var _constants = require("@douyinfe/semi-foundation/lib/cjs/base/constants"); var _warning = _interopRequireDefault(require("@douyinfe/semi-foundation/lib/cjs/utils/warning")); var _Event = _interopRequireDefault(require("@douyinfe/semi-foundation/lib/cjs/utils/Event")); var _dom = require("@douyinfe/semi-foundation/lib/cjs/utils/dom"); var _foundation = _interopRequireDefault(require("@douyinfe/semi-foundation/lib/cjs/tooltip/foundation")); var _constants2 = require("@douyinfe/semi-foundation/lib/cjs/tooltip/constants"); var _uuid = require("@douyinfe/semi-foundation/lib/cjs/utils/uuid"); require("@douyinfe/semi-foundation/lib/cjs/tooltip/tooltip.css"); var _baseComponent = _interopRequireDefault(require("../_base/baseComponent")); var _reactUtils = require("../_base/reactUtils"); var _utils = require("../_utils"); var _index = _interopRequireDefault(require("../_portal/index")); var _context = _interopRequireDefault(require("../configProvider/context")); var _TriangleArrow = _interopRequireDefault(require("./TriangleArrow")); var _TriangleArrowVertical = _interopRequireDefault(require("./TriangleArrowVertical")); var _ArrowBoundingShape = _interopRequireDefault(require("./ArrowBoundingShape")); var _cssAnimation = _interopRequireDefault(require("../_cssAnimation")); function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } var __rest = void 0 && (void 0).__rest || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; const prefix = _constants2.cssClasses.PREFIX; const positionSet = _constants2.strings.POSITION_SET; const triggerSet = _constants2.strings.TRIGGER_SET; const blockDisplays = ['flex', 'block', 'table', 'flow-root', 'grid']; const defaultGetContainer = () => document.body; class Tooltip extends _baseComponent.default { constructor(props) { super(props); this.isAnimating = false; this.setContainerEl = node => this.containerEl = { current: node }; this.isSpecial = elem => { if ((0, _reactUtils.isHTMLElement)(elem)) { return Boolean(elem.disabled); } else if (/*#__PURE__*/(0, _react.isValidElement)(elem)) { const disabled = (0, _get2.default)(elem, 'props.disabled'); if (disabled) { return _constants2.strings.STATUS_DISABLED; } const loading = (0, _get2.default)(elem, 'props.loading'); /* Only judge the loading state of the Button, and no longer judge other components */ const isButton = !(0, _isEmpty2.default)(elem) && !(0, _isEmpty2.default)(elem.type) && ((0, _get2.default)(elem, 'type.elementType') === 'Button' || (0, _get2.default)(elem, 'type.elementType') === 'IconButton'); if (loading && isButton) { return _constants2.strings.STATUS_LOADING; } } return false; }; // willEnter = () => { // this.foundation.calcPosition(); // this.setState({ visible: true }); // }; this.didLeave = () => { if (this.props.keepDOM) { this.foundation.setDisplayNone(true); } else { this.foundation.removePortal(); } this.foundation.unBindEvent(); }; this.renderIcon = () => { const { placement } = this.state; const { showArrow, prefixCls, style } = this.props; let icon = null; const triangleCls = (0, _classnames.default)([`${prefixCls}-icon-arrow`]); const bgColor = (0, _get2.default)(style, 'backgroundColor'); const iconComponent = (placement === null || placement === void 0 ? void 0 : placement.includes('left')) || (placement === null || placement === void 0 ? void 0 : placement.includes('right')) ? /*#__PURE__*/_react.default.createElement(_TriangleArrowVertical.default, null) : /*#__PURE__*/_react.default.createElement(_TriangleArrow.default, null); if (showArrow) { if (/*#__PURE__*/(0, _react.isValidElement)(showArrow)) { icon = showArrow; } else { icon = /*#__PURE__*/_react.default.cloneElement(iconComponent, { className: triangleCls, style: { color: bgColor, fill: 'currentColor' } }); } } return icon; }; this.handlePortalInnerClick = e => { if (this.props.clickToHide) { this.foundation.hide(); } if (this.props.stopPropagation) { (0, _utils.stopPropagation)(e); } }; this.handlePortalMouseDown = e => { if (this.props.stopPropagation) { (0, _utils.stopPropagation)(e); } }; this.handlePortalFocus = e => { if (this.props.stopPropagation) { (0, _utils.stopPropagation)(e); } }; this.handlePortalBlur = e => { if (this.props.stopPropagation) { (0, _utils.stopPropagation)(e); } }; this.handlePortalInnerKeyDown = e => { this.foundation.handleContainerKeydown(e); }; this.renderContentNode = content => { const contentProps = { initialFocusRef: this.initialFocusRef }; return !(0, _isFunction2.default)(content) ? content : content(contentProps); }; this.renderPortal = () => { const { containerStyle = {}, visible, portalEventSet, placement, displayNone, transitionState, id, isPositionUpdated } = this.state; const { prefixCls, content, showArrow, style, motion, role, zIndex } = this.props; const contentNode = this.renderContentNode(content); const { className: propClassName } = this.props; const direction = this.context.direction; const className = (0, _classnames.default)(propClassName, { [`${prefixCls}-wrapper`]: true, [`${prefixCls}-wrapper-show`]: visible, [`${prefixCls}-with-arrow`]: Boolean(showArrow), [`${prefixCls}-rtl`]: direction === 'rtl' }); const icon = this.renderIcon(); const portalInnerStyle = (0, _omit2.default)(containerStyle, motion ? ['transformOrigin'] : undefined); const transformOrigin = (0, _get2.default)(containerStyle, 'transformOrigin'); const userOpacity = (0, _get2.default)(style, 'opacity', null); const opacity = userOpacity ? userOpacity : 1; const inner = /*#__PURE__*/_react.default.createElement(_cssAnimation.default, { fillMode: "forwards", animationState: transitionState, motion: motion && isPositionUpdated, startClassName: transitionState === 'enter' ? `${prefix}-animation-show` : `${prefix}-animation-hide`, onAnimationStart: () => this.isAnimating = true, onAnimationEnd: () => { var _a, _b; if (transitionState === 'leave') { this.didLeave(); (_b = (_a = this.props).afterClose) === null || _b === void 0 ? void 0 : _b.call(_a); } this.isAnimating = false; } }, _ref => { let { animationStyle, animationClassName, animationEventsNeedBind } = _ref; return /*#__PURE__*/_react.default.createElement("div", Object.assign({ className: (0, _classnames.default)(className, animationClassName), style: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, animationStyle), displayNone ? { display: "none" } : {}), { transformOrigin }), style), userOpacity ? { opacity: isPositionUpdated ? opacity : "0" } : {}) }, portalEventSet, animationEventsNeedBind, { role: role, "x-placement": placement, id: id }), /*#__PURE__*/_react.default.createElement("div", { className: `${prefix}-content` }, contentNode), icon); }); return /*#__PURE__*/_react.default.createElement(_index.default, { getPopupContainer: this.props.getPopupContainer, style: { zIndex } }, /*#__PURE__*/_react.default.createElement("div", { // listen keyboard event, don't move tabIndex -1 tabIndex: -1, className: `${_constants.BASE_CLASS_PREFIX}-portal-inner`, style: portalInnerStyle, ref: this.setContainerEl, onClick: this.handlePortalInnerClick, onFocus: this.handlePortalFocus, onBlur: this.handlePortalBlur, onMouseDown: this.handlePortalMouseDown, onKeyDown: this.handlePortalInnerKeyDown }, inner)); }; this.wrapSpan = elem => { const { wrapperClassName } = this.props; const display = (0, _get2.default)(elem, 'props.style.display'); const block = (0, _get2.default)(elem, 'props.block'); const isStringElem = typeof elem == 'string'; const style = {}; if (!isStringElem) { style.display = 'inline-block'; } if (block || blockDisplays.includes(display)) { style.width = '100%'; } // eslint-disable-next-line jsx-a11y/no-static-element-interactions return /*#__PURE__*/_react.default.createElement("span", { className: wrapperClassName, style: style }, elem); }; this.mergeEvents = (rawEvents, events) => { const mergedEvents = {}; (0, _each2.default)(events, (handler, key) => { if (typeof handler === 'function') { mergedEvents[key] = function () { handler(...arguments); if (rawEvents && typeof rawEvents[key] === 'function') { rawEvents[key](...arguments); } }; } }); return mergedEvents; }; this.getPopupId = () => { return this.state.id; }; this.state = { visible: false, /** * * Note: The transitionState parameter is equivalent to isInsert */ transitionState: '', triggerEventSet: {}, portalEventSet: {}, containerStyle: { // zIndex: props.zIndex, }, isInsert: false, placement: props.position || 'top', transitionStyle: {}, isPositionUpdated: false, id: props.wrapperId, displayNone: false }; this.foundation = new _foundation.default(this.adapter); this.eventManager = new _Event.default(); this.triggerEl = /*#__PURE__*/_react.default.createRef(); this.containerEl = /*#__PURE__*/_react.default.createRef(); this.initialFocusRef = /*#__PURE__*/_react.default.createRef(); this.clickOutsideHandler = null; this.resizeHandler = null; this.isWrapped = false; // Identifies whether a span element is wrapped this.containerPosition = undefined; } get adapter() { var _this = this; return Object.assign(Object.assign({}, super.adapter), { // @ts-ignore on: function () { return _this.eventManager.on(...arguments); }, // @ts-ignore off: function () { return _this.eventManager.off(...arguments); }, getAnimatingState: () => this.isAnimating, insertPortal: (content, _a) => { var { position } = _a, containerStyle = __rest(_a, ["position"]); this.setState({ isInsert: true, transitionState: 'enter', containerStyle: Object.assign(Object.assign({}, this.state.containerStyle), containerStyle) }, () => { setTimeout(() => { this.setState(oldState => { if (oldState.transitionState === 'enter') { this.eventManager.emit('portalInserted'); } return {}; }); // waiting child component mounted }, 0); }); }, removePortal: () => { this.setState({ isInsert: false, isPositionUpdated: false }); }, getEventName: () => ({ mouseEnter: 'onMouseEnter', mouseLeave: 'onMouseLeave', mouseOut: 'onMouseOut', mouseOver: 'onMouseOver', click: 'onClick', focus: 'onFocus', blur: 'onBlur', keydown: 'onKeyDown', contextMenu: 'onContextMenu' }), registerTriggerEvent: triggerEventSet => { this.setState({ triggerEventSet }); }, registerPortalEvent: portalEventSet => { this.setState({ portalEventSet }); }, getTriggerBounding: () => { // It may be a React component or an html element // There is no guarantee that triggerE l.current can get the real dom, so call findDOMNode to ensure that you can get the real dom const triggerDOM = this.adapter.getTriggerNode(); this.triggerEl.current = triggerDOM; return triggerDOM && triggerDOM.getBoundingClientRect(); }, // Gets the outer size of the specified container getPopupContainerRect: () => { const container = this.getPopupContainer(); let rect = null; if (container && (0, _reactUtils.isHTMLElement)(container)) { const boundingRect = (0, _dom.convertDOMRectToObject)(container.getBoundingClientRect()); rect = Object.assign(Object.assign({}, boundingRect), { scrollLeft: container.scrollLeft, scrollTop: container.scrollTop }); } return rect; }, containerIsBody: () => { const container = this.getPopupContainer(); return container === document.body; }, containerIsRelative: () => { const container = this.getPopupContainer(); const computedStyle = window.getComputedStyle(container); return computedStyle.getPropertyValue('position') === 'relative'; }, containerIsRelativeOrAbsolute: () => ['relative', 'absolute'].includes(this.containerPosition), // Get the size of the pop-up layer getWrapperBounding: () => { const el = this.containerEl && this.containerEl.current; return el && el.getBoundingClientRect(); }, getDocumentElementBounding: () => document.documentElement.getBoundingClientRect(), setPosition: _a => { var { position } = _a, style = __rest(_a, ["position"]); this.setState({ containerStyle: Object.assign(Object.assign({}, this.state.containerStyle), style), placement: position, isPositionUpdated: true }, () => { this.eventManager.emit('positionUpdated'); }); }, setDisplayNone: (displayNone, cb) => { this.setState({ displayNone }, cb); }, updatePlacementAttr: placement => { this.setState({ placement }); }, togglePortalVisible: (visible, cb) => { const willUpdateStates = {}; willUpdateStates.transitionState = visible ? 'enter' : 'leave'; willUpdateStates.visible = visible; this.mounted && this.setState(willUpdateStates, () => { cb(); }); }, registerClickOutsideHandler: cb => { if (this.clickOutsideHandler) { this.adapter.unregisterClickOutsideHandler(); } this.clickOutsideHandler = e => { if (!this.mounted) { return false; } let el = this.triggerEl && this.triggerEl.current; let popupEl = this.containerEl && this.containerEl.current; el = _reactDom.default.findDOMNode(el); popupEl = _reactDom.default.findDOMNode(popupEl); const target = e.target; const path = e.composedPath && e.composedPath() || [target]; const isClickTriggerToHide = this.props.clickTriggerToHide ? el && el.contains(target) || path.includes(el) : false; if (el && !el.contains(target) && popupEl && !popupEl.contains(target) && !(path.includes(popupEl) || path.includes(el)) || isClickTriggerToHide) { this.props.onClickOutSide(e); cb(); } }; window.addEventListener('mousedown', this.clickOutsideHandler); }, unregisterClickOutsideHandler: () => { if (this.clickOutsideHandler) { window.removeEventListener('mousedown', this.clickOutsideHandler); this.clickOutsideHandler = null; } }, registerResizeHandler: cb => { if (this.resizeHandler) { this.adapter.unregisterResizeHandler(); } this.resizeHandler = (0, _throttle2.default)(e => { if (!this.mounted) { return false; } cb(e); }, 10); window.addEventListener('resize', this.resizeHandler, false); }, unregisterResizeHandler: () => { if (this.resizeHandler) { window.removeEventListener('resize', this.resizeHandler, false); this.resizeHandler = null; } }, notifyVisibleChange: visible => { this.props.onVisibleChange(visible); }, registerScrollHandler: rePositionCb => { if (this.scrollHandler) { this.adapter.unregisterScrollHandler(); } this.scrollHandler = (0, _throttle2.default)(e => { if (!this.mounted) { return false; } const triggerDOM = this.adapter.getTriggerNode(); const isRelativeScroll = e.target.contains(triggerDOM); if (isRelativeScroll) { const scrollPos = { x: e.target.scrollLeft, y: e.target.scrollTop }; rePositionCb(scrollPos); } }, 10); // When it is greater than 16ms, it will be very obvious window.addEventListener('scroll', this.scrollHandler, true); }, unregisterScrollHandler: () => { if (this.scrollHandler) { window.removeEventListener('scroll', this.scrollHandler, true); this.scrollHandler = null; } }, canMotion: () => Boolean(this.props.motion), updateContainerPosition: () => { const positionInBody = document.body.getAttribute('data-position'); if (positionInBody) { this.containerPosition = positionInBody; return; } requestAnimationFrame(() => { const container = this.getPopupContainer(); if (container && (0, _reactUtils.isHTMLElement)(container)) { // getComputedStyle need first parameter is Element type const computedStyle = window.getComputedStyle(container); const position = computedStyle.getPropertyValue('position'); document.body.setAttribute('data-position', position); this.containerPosition = position; } }); }, getContainerPosition: () => this.containerPosition, getContainer: () => this.containerEl && this.containerEl.current, getTriggerNode: () => { let triggerDOM = this.triggerEl.current; if (!(0, _reactUtils.isHTMLElement)(this.triggerEl.current)) { triggerDOM = _reactDom.default.findDOMNode(this.triggerEl.current); } return triggerDOM; }, getFocusableElements: node => { return (0, _utils.getFocusableElements)(node); }, getActiveElement: () => { return (0, _utils.getActiveElement)(); }, setInitialFocus: () => { const { preventScroll } = this.props; const focusRefNode = (0, _get2.default)(this, 'initialFocusRef.current'); if (focusRefNode && 'focus' in focusRefNode) { focusRefNode.focus({ preventScroll }); } }, notifyEscKeydown: event => { this.props.onEscKeyDown(event); }, setId: () => { this.setState({ id: (0, _uuid.getUuidShort)() }); }, getTriggerDOM: () => { if (this.triggerEl.current) { return _reactDom.default.findDOMNode(this.triggerEl.current); } else { return null; } } }); } componentDidMount() { this.mounted = true; this.getPopupContainer = this.props.getPopupContainer || this.context.getPopupContainer || defaultGetContainer; this.foundation.init(); (0, _utils.runAfterTicks)(() => { let triggerEle = this.triggerEl.current; if (triggerEle) { if (!(triggerEle instanceof HTMLElement)) { triggerEle = (0, _reactDom.findDOMNode)(triggerEle); } } this.foundation.updateStateIfCursorOnTrigger(triggerEle); }, 1); } componentWillUnmount() { this.mounted = false; this.foundation.destroy(); } /** * focus on tooltip trigger */ focusTrigger() { this.foundation.focusTrigger(); } /** for transition - end */ rePosition() { return this.foundation.calcPosition(); } componentDidUpdate(prevProps, prevState) { (0, _warning.default)(this.props.mouseLeaveDelay < this.props.mouseEnterDelay, "[Semi Tooltip] 'mouseLeaveDelay' cannot be less than 'mouseEnterDelay', which may cause the dropdown layer to not be hidden."); if (prevProps.visible !== this.props.visible) { if (['hover', 'focus'].includes(this.props.trigger)) { this.props.visible ? this.foundation.delayShow() : this.foundation.delayHide(); } else { this.props.visible ? this.foundation.show() : this.foundation.hide(); } } if (!(0, _isEqual2.default)(prevProps.rePosKey, this.props.rePosKey)) { this.rePosition(); } } render() { const { isInsert, triggerEventSet, visible, id } = this.state; const { wrapWhenSpecial, role, trigger } = this.props; let { children } = this.props; const childrenStyle = Object.assign({}, (0, _get2.default)(children, 'props.style')); const extraStyle = {}; if (wrapWhenSpecial) { const isSpecial = this.isSpecial(children); if (isSpecial) { childrenStyle.pointerEvents = 'none'; if (isSpecial === _constants2.strings.STATUS_DISABLED) { extraStyle.cursor = 'not-allowed'; } children = /*#__PURE__*/(0, _react.cloneElement)(children, { style: childrenStyle }); if (trigger !== 'custom') { // no need to wrap span when trigger is custom, cause it don't need bind event children = this.wrapSpan(children); } this.isWrapped = true; } else if (! /*#__PURE__*/(0, _react.isValidElement)(children)) { children = this.wrapSpan(children); this.isWrapped = true; } } let ariaAttribute = {}; // Take effect when used by Popover component if (role === 'dialog') { ariaAttribute['aria-expanded'] = visible ? 'true' : 'false'; ariaAttribute['aria-haspopup'] = 'dialog'; ariaAttribute['aria-controls'] = id; } else { ariaAttribute['aria-describedby'] = id; } // The incoming children is a single valid element, otherwise wrap a layer with span const newChild = /*#__PURE__*/_react.default.cloneElement(children, Object.assign(Object.assign(Object.assign(Object.assign({}, ariaAttribute), children.props), this.mergeEvents(children.props, triggerEventSet)), { style: Object.assign(Object.assign({}, (0, _get2.default)(children, 'props.style')), extraStyle), className: (0, _classnames.default)((0, _get2.default)(children, 'props.className')), // to maintain refs with callback ref: node => { // Keep your own reference this.triggerEl.current = node; // Call the original ref, if any const { ref } = children; // this.log('tooltip render() - get ref', ref); if (typeof ref === 'function') { ref(node); } else if (ref && typeof ref === 'object') { ref.current = node; } }, tabIndex: children.props.tabIndex || 0, 'data-popupid': id })); // If you do not add a layer of div, in order to bind the events and className in the tooltip, you need to cloneElement children, but this time it may overwrite the children's original ref reference // So if the user adds ref to the content, you need to use callback ref: https://github.com/facebook/react/issues/8873 return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, isInsert ? this.renderPortal() : null, newChild); } } exports.default = Tooltip; Tooltip.contextType = _context.default; Tooltip.propTypes = { children: _propTypes.default.node, motion: _propTypes.default.bool, autoAdjustOverflow: _propTypes.default.bool, position: _propTypes.default.oneOf(positionSet), getPopupContainer: _propTypes.default.func, mouseEnterDelay: _propTypes.default.number, mouseLeaveDelay: _propTypes.default.number, trigger: _propTypes.default.oneOf(triggerSet).isRequired, className: _propTypes.default.string, wrapperClassName: _propTypes.default.string, clickToHide: _propTypes.default.bool, // used with trigger === hover, private clickTriggerToHide: _propTypes.default.bool, visible: _propTypes.default.bool, style: _propTypes.default.object, content: _propTypes.default.oneOfType([_propTypes.default.node, _propTypes.default.func]), prefixCls: _propTypes.default.string, onVisibleChange: _propTypes.default.func, onClickOutSide: _propTypes.default.func, spacing: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.object]), margin: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.object]), showArrow: _propTypes.default.oneOfType([_propTypes.default.bool, _propTypes.default.node]), zIndex: _propTypes.default.number, rePosKey: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number]), arrowBounding: _ArrowBoundingShape.default, transformFromCenter: _propTypes.default.bool, arrowPointAtCenter: _propTypes.default.bool, stopPropagation: _propTypes.default.bool, // private role: _propTypes.default.string, wrapWhenSpecial: _propTypes.default.bool, guardFocus: _propTypes.default.bool, returnFocusOnClose: _propTypes.default.bool, preventScroll: _propTypes.default.bool, keepDOM: _propTypes.default.bool }; Tooltip.__SemiComponentName__ = "Tooltip"; Tooltip.defaultProps = (0, _utils.getDefaultPropsFromGlobalConfig)(Tooltip.__SemiComponentName__, { arrowBounding: _constants2.numbers.ARROW_BOUNDING, autoAdjustOverflow: true, arrowPointAtCenter: true, trigger: 'hover', transformFromCenter: true, position: 'top', prefixCls: prefix, role: 'tooltip', mouseEnterDelay: _constants2.numbers.MOUSE_ENTER_DELAY, mouseLeaveDelay: _constants2.numbers.MOUSE_LEAVE_DELAY, motion: true, onVisibleChange: _noop2.default, onClickOutSide: _noop2.default, spacing: _constants2.numbers.SPACING, margin: _constants2.numbers.MARGIN, showArrow: true, wrapWhenSpecial: true, zIndex: _constants2.numbers.DEFAULT_Z_INDEX, closeOnEsc: false, guardFocus: false, returnFocusOnClose: false, onEscKeyDown: _noop2.default, disableFocusListener: false, disableArrowKeyDown: false, keepDOM: false });