| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646 | 
							- /* eslint-disable prefer-destructuring, max-lines-per-function, react/no-find-dom-node, max-len, @typescript-eslint/no-empty-function */
 
- import React, { isValidElement, cloneElement } from 'react';
 
- import ReactDOM from 'react-dom';
 
- import classNames from 'classnames';
 
- import PropTypes from 'prop-types';
 
- import { throttle, noop, get, omit, each, isEmpty } from 'lodash-es';
 
- import { BASE_CLASS_PREFIX } from '@douyinfe/semi-foundation/base/constants';
 
- import warning from '@douyinfe/semi-foundation/utils/warning';
 
- import Event from '@douyinfe/semi-foundation/utils/Event';
 
- import { ArrayElement } from '@douyinfe/semi-foundation/utils/type';
 
- import { convertDOMRectToObject, DOMRectLikeType } from '@douyinfe/semi-foundation/utils/dom';
 
- import TooltipFoundation, { TooltipAdapter, Position, PopupContainerDOMRect } from '@douyinfe/semi-foundation/tooltip/foundation';
 
- import { strings, cssClasses, numbers } from '@douyinfe/semi-foundation/tooltip/constants';
 
- import '@douyinfe/semi-foundation/tooltip/tooltip.scss';
 
- import BaseComponent, { BaseProps } from '../_base/baseComponent';
 
- import { isHTMLElement } from '../_base/reactUtils';
 
- import { stopPropagation } from '../_utils';
 
- import Portal from '../_portal/index';
 
- import ConfigContext from '../configProvider/context';
 
- import TriangleArrow from './TriangleArrow';
 
- import TriangleArrowVertical from './TriangleArrowVertical';
 
- import TooltipTransition from './TooltipStyledTransition';
 
- import ArrowBoundingShape from './ArrowBoundingShape';
 
- import { Motion } from '../_base/base';
 
- export { TooltipTransitionProps } from './TooltipStyledTransition';
 
- export type Trigger = ArrayElement<typeof strings.TRIGGER_SET>;
 
- export interface ArrowBounding {
 
-     offsetX?: number;
 
-     offsetY?: number;
 
-     width?: number;
 
-     height?: number;
 
- }
 
- export interface TooltipProps extends BaseProps {
 
-     children?: React.ReactNode;
 
-     motion?: Motion;
 
-     autoAdjustOverflow?: boolean;
 
-     position?: Position;
 
-     getPopupContainer?: () => HTMLElement;
 
-     mouseEnterDelay?: number;
 
-     mouseLeaveDelay?: number;
 
-     trigger?: Trigger;
 
-     className?: string;
 
-     clickToHide?: boolean;
 
-     visible?: boolean;
 
-     style?: React.CSSProperties;
 
-     content?: React.ReactNode;
 
-     prefixCls?: string;
 
-     onVisibleChange?: (visible: boolean) => void;
 
-     onClickOutSide?: (e: React.MouseEvent) => void;
 
-     spacing?: number;
 
-     showArrow?: boolean | React.ReactNode;
 
-     zIndex?: number;
 
-     rePosKey?: string | number;
 
-     arrowBounding?: ArrowBounding;
 
-     transformFromCenter?: boolean;
 
-     arrowPointAtCenter?: boolean;
 
-     wrapWhenSpecial?: boolean;
 
-     stopPropagation?: boolean;
 
-     clickTriggerToHide?: boolean;
 
-     wrapperClassName?: string;
 
- }
 
- interface TooltipState {
 
-     visible: boolean;
 
-     transitionState: string;
 
-     triggerEventSet: {
 
-         [key: string]: any;
 
-     };
 
-     portalEventSet: {
 
-         [key: string]: any;
 
-     };
 
-     containerStyle: React.CSSProperties;
 
-     isInsert: boolean;
 
-     placement: Position;
 
-     transitionStyle: Record<string, any>;
 
- }
 
- const prefix = cssClasses.PREFIX;
 
- const positionSet = strings.POSITION_SET;
 
- const triggerSet = strings.TRIGGER_SET;
 
- const blockDisplays = ['flex', 'block', 'table', 'flow-root', 'grid'];
 
- const defaultGetContainer = () => document.body;
 
- export default class Tooltip extends BaseComponent<TooltipProps, TooltipState> {
 
-     static contextType = ConfigContext;
 
-     static propTypes = {
 
-         children: PropTypes.node,
 
-         motion: PropTypes.oneOfType([PropTypes.bool, PropTypes.object, PropTypes.func]),
 
-         autoAdjustOverflow: PropTypes.bool,
 
-         position: PropTypes.oneOf(positionSet),
 
-         getPopupContainer: PropTypes.func,
 
-         mouseEnterDelay: PropTypes.number,
 
-         mouseLeaveDelay: PropTypes.number,
 
-         trigger: PropTypes.oneOf(triggerSet).isRequired,
 
-         className: PropTypes.string,
 
-         wrapperClassName: PropTypes.string,
 
-         clickToHide: PropTypes.bool,
 
-         // used with trigger === hover, private
 
-         clickTriggerToHide: PropTypes.bool,
 
-         visible: PropTypes.bool,
 
-         style: PropTypes.object,
 
-         content: PropTypes.node,
 
-         prefixCls: PropTypes.string,
 
-         onVisibleChange: PropTypes.func,
 
-         onClickOutSide: PropTypes.func,
 
-         spacing: PropTypes.number,
 
-         showArrow: PropTypes.oneOfType([PropTypes.bool, PropTypes.node]),
 
-         zIndex: PropTypes.number,
 
-         rePosKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
 
-         arrowBounding: ArrowBoundingShape,
 
-         transformFromCenter: PropTypes.bool, // Whether to change from the center of the trigger (for dynamic effects)
 
-         arrowPointAtCenter: PropTypes.bool,
 
-         stopPropagation: PropTypes.bool,
 
-         // private
 
-         wrapWhenSpecial: PropTypes.bool, // when trigger has special status such as "disabled" or "loading", wrap span
 
-     };
 
-     static defaultProps = {
 
-         transformFromCenter: true,
 
-         arrowPointAtCenter: true,
 
-         wrapWhenSpecial: true,
 
-         motion: true,
 
-         zIndex: numbers.DEFAULT_Z_INDEX,
 
-         trigger: 'hover',
 
-         position: 'top',
 
-         prefixCls: prefix,
 
-         autoAdjustOverflow: true,
 
-         mouseEnterDelay: numbers.MOUSE_ENTER_DELAY,
 
-         mouseLeaveDelay: numbers.MOUSE_LEAVE_DELAY,
 
-         onVisibleChange: noop,
 
-         onClickOutSide: noop,
 
-         spacing: numbers.SPACING,
 
-         showArrow: true,
 
-         arrowBounding: numbers.ARROW_BOUNDING,
 
-     };
 
-     eventManager: Event;
 
-     triggerEl: React.RefObject<unknown>;
 
-     containerEl: React.RefObject<unknown>;
 
-     clickOutsideHandler: any;
 
-     resizeHandler: any;
 
-     isWrapped: boolean;
 
-     mounted: any;
 
-     scrollHandler: any;
 
-     getPopupContainer: () => HTMLElement;
 
-     containerPosition: string;
 
-     constructor(props: TooltipProps) {
 
-         super(props);
 
-         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: {},
 
-         };
 
-         this.foundation = new TooltipFoundation(this.adapter);
 
-         this.eventManager = new Event();
 
-         this.triggerEl = React.createRef();
 
-         this.containerEl = React.createRef();
 
-         this.clickOutsideHandler = null;
 
-         this.resizeHandler = null;
 
-         this.isWrapped = false; // Identifies whether a span element is wrapped
 
-         this.containerPosition = undefined;
 
-     }
 
-     setContainerEl = (node: HTMLDivElement) => (this.containerEl = { current: node });
 
-     get adapter(): TooltipAdapter<TooltipProps, TooltipState> {
 
-         return {
 
-             ...super.adapter,
 
-             // eslint-disable-next-line @typescript-eslint/ban-ts-comment
 
-             // @ts-ignore
 
-             on: (...args: any[]) => this.eventManager.on(...args),
 
-             // eslint-disable-next-line @typescript-eslint/ban-ts-comment
 
-             // @ts-ignore
 
-             off: (...args: any[]) => this.eventManager.off(...args),
 
-             insertPortal: (content: string, { position, ...containerStyle }: { position: Position }) => {
 
-                 this.setState(
 
-                     {
 
-                         isInsert: true,
 
-                         transitionState: 'enter',
 
-                         containerStyle: { ...this.state.containerStyle, ...containerStyle },
 
-                     },
 
-                     () => {
 
-                         /**
 
-                          * Dangerous: remove setTimeout from here fix #1301
 
-                          * setTimeout may emit portalInserted event after hiding portal
 
-                          * Hiding portal will remove portalInserted event listener(normal process)
 
-                          * then portal can't hide because _togglePortalVisible(false) will found isVisible=false and nowVisible=false(bug here)
 
-                          */
 
-                         this.eventManager.emit('portalInserted');
 
-                     }
 
-                 );
 
-             },
 
-             removePortal: () => {
 
-                 this.setState({ isInsert: false });
 
-             },
 
-             getEventName: () => ({
 
-                 mouseEnter: 'onMouseEnter',
 
-                 mouseLeave: 'onMouseLeave',
 
-                 mouseOut: 'onMouseOut',
 
-                 mouseOver: 'onMouseOver',
 
-                 click: 'onClick',
 
-                 focus: 'onFocus',
 
-                 blur: 'onBlur',
 
-             }),
 
-             registerTriggerEvent: (triggerEventSet: Record<string, any>) => {
 
-                 this.setState({ triggerEventSet });
 
-             },
 
-             unregisterTriggerEvent: () => {},
 
-             registerPortalEvent: (portalEventSet: Record<string, any>) => {
 
-                 this.setState({ portalEventSet });
 
-             },
 
-             unregisterPortalEvent: () => {},
 
-             getTriggerBounding: () => {
 
-                 // eslint-disable-next-line
 
-                 // 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
 
-                 let triggerDOM = this.triggerEl.current;
 
-                 if (!isHTMLElement(this.triggerEl.current)) {
 
-                     const realDomNode = ReactDOM.findDOMNode(this.triggerEl.current as React.ReactInstance);
 
-                     (this.triggerEl as any).current = realDomNode;
 
-                     triggerDOM = realDomNode;
 
-                 }
 
-                 return triggerDOM && (triggerDOM as Element).getBoundingClientRect();
 
-             },
 
-             // Gets the outer size of the specified container
 
-             getPopupContainerRect: () => {
 
-                 const container = this.getPopupContainer();
 
-                 let rect: PopupContainerDOMRect = null;
 
-                 if (container && isHTMLElement(container)) {
 
-                     const boundingRect: DOMRectLikeType = convertDOMRectToObject(container.getBoundingClientRect());
 
-                     rect = {
 
-                         ...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 as Element).getBoundingClientRect();
 
-             },
 
-             getDocumentElementBounding: () => document.documentElement.getBoundingClientRect(),
 
-             setPosition: ({ position, ...style }: { position: Position }) => {
 
-                 this.setState(
 
-                     { containerStyle: { ...this.state.containerStyle, ...style }, placement: position },
 
-                     () => {
 
-                         this.eventManager.emit('positionUpdated');
 
-                     }
 
-                 );
 
-             },
 
-             updatePlacementAttr: (placement: Position) => {
 
-                 this.setState({ placement });
 
-             },
 
-             togglePortalVisible: (visible: boolean, cb: () => void) => {
 
-                 const willUpdateStates: Partial<TooltipState> = {};
 
-                 if (this.adapter.canMotion()) {
 
-                     willUpdateStates.transitionState = visible ? 'enter' : 'leave';
 
-                     willUpdateStates.visible = visible;
 
-                 } else {
 
-                     willUpdateStates.visible = visible;
 
-                 }
 
-                 this.setState(willUpdateStates as TooltipState, () => {
 
-                     cb();
 
-                 });
 
-             },
 
-             registerClickOutsideHandler: (cb: () => void) => {
 
-                 if (this.clickOutsideHandler) {
 
-                     this.adapter.unregisterClickOutsideHandler();
 
-                 }
 
-                 this.clickOutsideHandler = (e: React.MouseEvent): any => {
 
-                     if (!this.mounted) {
 
-                         return false;
 
-                     }
 
-                     let el = this.triggerEl && this.triggerEl.current;
 
-                     let popupEl = this.containerEl && this.containerEl.current;
 
-                     el = ReactDOM.findDOMNode(el as React.ReactInstance);
 
-                     popupEl = ReactDOM.findDOMNode(popupEl as React.ReactInstance);
 
-                     if (
 
-                         (el && !(el as any).contains(e.target) && popupEl && !(popupEl as any).contains(e.target)) ||
 
-                         this.props.clickTriggerToHide
 
-                     ) {
 
-                         this.props.onClickOutSide(e);
 
-                         cb();
 
-                     }
 
-                 };
 
-                 document.addEventListener('click', this.clickOutsideHandler, false);
 
-             },
 
-             unregisterClickOutsideHandler: () => {
 
-                 if (this.clickOutsideHandler) {
 
-                     document.removeEventListener('click', this.clickOutsideHandler, false);
 
-                     this.clickOutsideHandler = null;
 
-                 }
 
-             },
 
-             registerResizeHandler: (cb: (e: any) => void) => {
 
-                 if (this.resizeHandler) {
 
-                     this.adapter.unregisterResizeHandler();
 
-                 }
 
-                 this.resizeHandler = throttle((e): any => {
 
-                     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: boolean) => {
 
-                 this.props.onVisibleChange(visible);
 
-             },
 
-             registerScrollHandler: (rePositionCb: (arg: { x: number; y: number }) => void) => {
 
-                 if (this.scrollHandler) {
 
-                     this.adapter.unregisterScrollHandler();
 
-                 }
 
-                 this.scrollHandler = throttle((e): any => {
 
-                     if (!this.mounted) {
 
-                         return false;
 
-                     }
 
-                     let triggerDOM = this.triggerEl.current;
 
-                     if (!isHTMLElement(this.triggerEl.current)) {
 
-                         triggerDOM = ReactDOM.findDOMNode(this.triggerEl.current as React.ReactInstance);
 
-                     }
 
-                     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 container = this.getPopupContainer();
 
-                 if (container && isHTMLElement(container)) {
 
-                     // getComputedStyle need first parameter is Element type
 
-                     const computedStyle = window.getComputedStyle(container);
 
-                     const position = computedStyle.getPropertyValue('position');
 
-                     this.containerPosition = position;
 
-                 }
 
-             },
 
-             getContainerPosition: () => this.containerPosition,
 
-         };
 
-     }
 
-     componentDidMount() {
 
-         this.mounted = true;
 
-         this.getPopupContainer = this.props.getPopupContainer || this.context.getPopupContainer || defaultGetContainer;
 
-         this.foundation.init();
 
-     }
 
-     componentWillUnmount() {
 
-         this.mounted = false;
 
-         this.foundation.destroy();
 
-     }
 
-     isSpecial = (elem: React.ReactNode | HTMLElement | any) => {
 
-         if (isHTMLElement(elem)) {
 
-             return Boolean(elem.disabled);
 
-         } else if (isValidElement(elem)) {
 
-             const disabled = get(elem, 'props.disabled');
 
-             if (disabled) {
 
-                 return strings.STATUS_DISABLED;
 
-             }
 
-             const loading = get(elem, 'props.loading');
 
-             /* Only judge the loading state of the Button, and no longer judge other components */
 
-             const isButton = !isEmpty(elem)
 
-                 && !isEmpty(elem.type)
 
-                 && (elem.type as any).name === 'Button'
 
-                 || (elem.type as any).name === 'IconButton';
 
-             if (loading && isButton) {
 
-                 return strings.STATUS_LOADING;
 
-             }
 
-         }
 
-         return false;
 
-     };
 
-     willEnter = () => {
 
-         this.foundation.calcPosition();
 
-         /**
 
-          * Dangerous: remove setState in motion fix #1379
 
-          * because togglePortalVisible callback function will use visible state to notifyVisibleChange
 
-          * if visible state is old value, then notifyVisibleChange function will not be called
 
-          * we should ensure that after calling togglePortalVisible, callback function can get right visible value
 
-          */
 
-         // this.setState({ visible: true });
 
-     };
 
-     didLeave = () => {
 
-         this.adapter.unregisterClickOutsideHandler();
 
-         this.adapter.unregisterScrollHandler();
 
-         this.adapter.unregisterResizeHandler();
 
-         this.adapter.removePortal();
 
-     };
 
-     /** for transition - end */
 
-     rePosition() {
 
-         return this.foundation.calcPosition();
 
-     }
 
-     componentDidUpdate(prevProps: TooltipProps, prevState: TooltipState) {
 
-         warning(
 
-             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) {
 
-             this.props.visible ? this.foundation.delayShow() : this.foundation.delayHide();
 
-         }
 
-         if (prevProps.rePosKey !== this.props.rePosKey) {
 
-             this.rePosition();
 
-         }
 
-     }
 
-     renderIcon = () => {
 
-         const { placement } = this.state;
 
-         const { showArrow, prefixCls, style } = this.props;
 
-         let icon = null;
 
-         const triangleCls = classNames([`${prefixCls}-icon-arrow`]);
 
-         const bgColor = get(style, 'backgroundColor');
 
-         const iconComponent = placement.includes('left') || placement.includes('right') ?
 
-             <TriangleArrowVertical /> :
 
-             <TriangleArrow />;
 
-         if (showArrow) {
 
-             if (isValidElement(showArrow)) {
 
-                 icon = showArrow;
 
-             } else {
 
-                 icon = React.cloneElement(iconComponent, { className: triangleCls, style: { color: bgColor, fill: 'currentColor' } });
 
-             }
 
-         }
 
-         return icon;
 
-     };
 
-     handlePortalInnerClick = (e: React.MouseEvent) => {
 
-         if (this.props.clickToHide) {
 
-             this.foundation.hide();
 
-         }
 
-         if (this.props.stopPropagation) {
 
-             stopPropagation(e);
 
-         }
 
-     };
 
-     renderPortal = () => {
 
-         const { containerStyle = {}, visible, portalEventSet, placement, transitionState } = this.state;
 
-         const { prefixCls, content, showArrow, style, motion, zIndex } = this.props;
 
-         const { className: propClassName } = this.props;
 
-         const direction = this.context.direction;
 
-         const className = classNames(propClassName, {
 
-             [`${prefixCls}-wrapper`]: true,
 
-             [`${prefixCls}-wrapper-show`]: visible,
 
-             [`${prefixCls}-with-arrow`]: Boolean(showArrow),
 
-             [`${prefixCls}-rtl`]: direction === 'rtl',
 
-         });
 
-         const icon = this.renderIcon();
 
-         const portalInnerStyle = omit(containerStyle, motion ? ['transformOrigin'] : undefined);
 
-         const transformOrigin = get(containerStyle, 'transformOrigin');
 
-         const inner = motion ? (
 
-             <TooltipTransition position={placement} willEnter={this.willEnter} didLeave={this.didLeave} motion={motion}>
 
-                 {
 
-                     transitionState === 'enter' ?
 
-                         ({ animateCls, animateStyle, animateEvents }) => (
 
-                             <div
 
-                                 className={classNames(className, animateCls)}
 
-                                 style={{
 
-                                     visibility: 'visible',
 
-                                     ...animateStyle,
 
-                                     transformOrigin,
 
-                                     ...style,
 
-                                 }}
 
-                                 {...portalEventSet}
 
-                                 {...animateEvents}
 
-                                 x-placement={placement}
 
-                             >
 
-                                 {content}
 
-                                 {icon}
 
-                             </div>
 
-                         ) :
 
-                         null
 
-                 }
 
-             </TooltipTransition>
 
-         ) : (
 
-             <div className={className} {...portalEventSet} x-placement={placement} style={style}>
 
-                 {content}
 
-                 {icon}
 
-             </div>
 
-         );
 
-         return (
 
-             <Portal getPopupContainer={this.props.getPopupContainer} style={{ zIndex }}>
 
-                 <div
 
-                     className={`${BASE_CLASS_PREFIX}-portal-inner`}
 
-                     style={portalInnerStyle}
 
-                     ref={this.setContainerEl}
 
-                     onClick={this.handlePortalInnerClick}
 
-                 >
 
-                     {inner}
 
-                 </div>
 
-             </Portal>
 
-         );
 
-     };
 
-     wrapSpan = (elem: React.ReactNode | React.ReactElement) => {
 
-         const { wrapperClassName } = this.props;
 
-         const display = get(elem, 'props.style.display');
 
-         const block = get(elem, 'props.block');
 
-         const style: React.CSSProperties = {
 
-             display: 'inline-block',
 
-         };
 
-         if (block || blockDisplays.includes(display)) {
 
-             style.width = '100%';
 
-         }
 
-         return <span className={wrapperClassName} style={style}>{elem}</span>;
 
-     };
 
-     mergeEvents = (rawEvents: Record<string, any>, events: Record<string, any>) => {
 
-         const mergedEvents = {};
 
-         each(events, (handler: any, key) => {
 
-             if (typeof handler === 'function') {
 
-                 mergedEvents[key] = (...args: any[]) => {
 
-                     handler(...args);
 
-                     if (rawEvents && typeof rawEvents[key] === 'function') {
 
-                         rawEvents[key](...args);
 
-                     }
 
-                 };
 
-             }
 
-         });
 
-         return mergedEvents;
 
-     };
 
-     render() {
 
-         const { isInsert, triggerEventSet } = this.state;
 
-         const { wrapWhenSpecial } = this.props;
 
-         let { children } = this.props;
 
-         const childrenStyle = { ...get(children, 'props.style') };
 
-         const extraStyle: React.CSSProperties = {};
 
-         if (wrapWhenSpecial) {
 
-             const isSpecial = this.isSpecial(children);
 
-             if (isSpecial) {
 
-                 childrenStyle.pointerEvents = 'none';
 
-                 if (isSpecial === strings.STATUS_DISABLED) {
 
-                     extraStyle.cursor = 'not-allowed';
 
-                 }
 
-                 children = cloneElement(children as React.ReactElement, { style: childrenStyle });
 
-                 children = this.wrapSpan(children);
 
-                 this.isWrapped = true;
 
-             } else if (!isValidElement(children)) {
 
-                 children = this.wrapSpan(children);
 
-                 this.isWrapped = true;
 
-             }
 
-         }
 
-         // The incoming children is a single valid element, otherwise wrap a layer with span
 
-         const newChild = React.cloneElement(children as React.ReactElement, {
 
-             ...(children as React.ReactElement).props,
 
-             ...this.mergeEvents((children as React.ReactElement).props, triggerEventSet),
 
-             style: {
 
-                 ...get(children, 'props.style'),
 
-                 ...extraStyle,
 
-             },
 
-             className: classNames(
 
-                 get(children, 'props.className')
 
-                 // `${prefixCls}-trigger`
 
-             ),
 
-             // to maintain refs with callback
 
-             ref: (node: React.ReactNode) => {
 
-                 // Keep your own reference
 
-                 (this.triggerEl as any).current = node;
 
-                 // Call the original ref, if any
 
-                 const { ref } = children as any;
 
-                 // this.log('tooltip render() - get ref', ref);
 
-                 if (typeof ref === 'function') {
 
-                     ref(node);
 
-                 } else if (ref && typeof ref === 'object') {
 
-                     ref.current = node;
 
-                 }
 
-             },
 
-         });
 
-         // 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 (
 
-             <React.Fragment>
 
-                 {isInsert ? this.renderPortal() : null}
 
-                 {newChild}
 
-             </React.Fragment>
 
-         );
 
-     }
 
- }
 
- export { Position };
 
 
  |