From eed3d6d8148b46c9bbd52decb52b38a9aa0e3ba7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alfonso=20Mu=C3=B1oz-Pomer?= Date: Wed, 29 Mar 2017 16:15:03 +0100 Subject: [PATCH 1/2] Get the tooltip content in the render method using a function instead of setting it in state.placeholder. This allows for the tooltip contents to change dynamically (or be hidden if you return null in the getContent prop). --- src/index.js | 73 ++++++++++++++++++++++++++-------------------------- 1 file changed, 36 insertions(+), 37 deletions(-) diff --git a/src/index.js b/src/index.js index 15ebfe8ef..6d5d6c37e 100644 --- a/src/index.js +++ b/src/index.js @@ -59,7 +59,6 @@ class ReactTooltip extends Component { effect: 'float', // float or fixed show: false, border: false, - placeholder: '', offset: {}, extraClass: '', html: false, @@ -71,13 +70,16 @@ class ReactTooltip extends Component { currentTarget: null, // Current target of mouse event ariaProps: parseAria(props), // aria- and role attributes isEmptyTip: false, - disable: false + disable: false, + originTooltip: null, + isMultiline: false } this.bind([ 'showTooltip', 'updateTooltip', 'hideTooltip', + 'getTooltipContent', 'globalRebuild', 'globalShow', 'globalHide', @@ -205,6 +207,26 @@ class ReactTooltip extends Component { target.removeEventListener('mouseleave', this.hideTooltip) } + getTooltipContent () { + const {getContent, children} = this.props + + // Generate tooltip content + let content + if (getContent) { + if (Array.isArray(getContent)) { + content = getContent[0] && getContent[0]() + } else { + content = getContent() + } + } + + return getTipContent(this.state.originTooltip, children, content, this.state.isMultiline) + } + + isEmptyTip (placeholder) { + return typeof placeholder === 'string' && placeholder === '' || placeholder === null + } + /** * When mouse enter, show the tooltip */ @@ -217,22 +239,10 @@ class ReactTooltip extends Component { } // Get the tooltip content // calculate in this phrase so that tip width height can be detected - const {children, multiline, getContent} = this.props + const {multiline} = this.props const originTooltip = e.currentTarget.getAttribute('data-tip') const isMultiline = e.currentTarget.getAttribute('data-multiline') || multiline || false - // Generate tootlip content - let content - if (getContent) { - if (Array.isArray(getContent)) { - content = getContent[0] && getContent[0]() - } else { - content = getContent() - } - } - const placeholder = getTipContent(originTooltip, children, content, isMultiline) - const isEmptyTip = typeof placeholder === 'string' && placeholder === '' || placeholder === null - // If it is focus event or called by ReactTooltip.show, switch to `solid` effect const switchToSolid = e instanceof window.FocusEvent || isGlobalCall @@ -245,8 +255,8 @@ class ReactTooltip extends Component { } this.setState({ - placeholder, - isEmptyTip, + originTooltip: originTooltip, + isMultiline: isMultiline, place: e.currentTarget.getAttribute('data-place') || this.props.place || 'top', type: e.currentTarget.getAttribute('data-type') || this.props.type || 'dark', effect: switchToSolid && 'solid' || e.currentTarget.getAttribute('data-effect') || this.props.effect || 'float', @@ -266,20 +276,6 @@ class ReactTooltip extends Component { }, () => { if (scrollHide) this.addScrollListener(e) this.updateTooltip(e) - - if (getContent && Array.isArray(getContent)) { - this.intervalUpdateContent = setInterval(() => { - if (this.mount) { - const {getContent} = this.props - const placeholder = getTipContent(originTooltip, getContent[0](), isMultiline) - const isEmptyTip = typeof placeholder === 'string' && placeholder === '' - this.setState({ - placeholder, - isEmptyTip - }) - } - }, getContent[1]) - } }) } @@ -287,13 +283,13 @@ class ReactTooltip extends Component { * When mouse hover, updatetooltip */ updateTooltip (e) { - const {delayShow, show, isEmptyTip, disable} = this.state + const {delayShow, show, disable} = this.state const {afterShow} = this.props - let {placeholder} = this.state + const placeholder = this.getTooltipContent() const delayTime = show ? 0 : parseInt(delayShow, 10) const eventTarget = e.currentTarget - if (isEmptyTip || disable) return // if the tooltip is empty, disable the tooltip + if (this.isEmptyTip(placeholder) || disable) return // if the tooltip is empty, disable the tooltip const updateState = () => { if (Array.isArray(placeholder) && placeholder.length > 0 || placeholder) { const isInvisible = !this.state.show @@ -320,10 +316,11 @@ class ReactTooltip extends Component { * When mouse leave, hide tooltip */ hideTooltip (e, hasTarget) { - const {delayHide, isEmptyTip, disable} = this.state + const {delayHide, disable} = this.state const {afterHide} = this.props + const placeholder = this.getTooltipContent() if (!this.mount) return - if (isEmptyTip || disable) return // if the tooltip is empty, disable the tooltip + if (this.isEmptyTip(placeholder) || disable) return // if the tooltip is empty, disable the tooltip if (hasTarget) { // Don't trigger other elements belongs to other ReactTooltip const targetArray = this.getTargetArray(this.props.id) @@ -401,7 +398,9 @@ class ReactTooltip extends Component { } render () { - const {placeholder, extraClass, html, ariaProps, disable, isEmptyTip} = this.state + const {extraClass, html, ariaProps, disable} = this.state + const placeholder = this.getTooltipContent() + const isEmptyTip = this.isEmptyTip(placeholder) let tooltipClass = classname( '__react_component_tooltip', {'show': this.state.show && !disable && !isEmptyTip}, From cc37da9c56166c13c51cc66dd702fcef6a439bd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alfonso=20Mu=C3=B1oz-Pomer?= Date: Thu, 30 Mar 2017 00:33:33 +0100 Subject: [PATCH 2/2] Put back this.intervalUpdateContent to make the bottom examples in the demo page work again. --- src/index.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/index.js b/src/index.js index 6d5d6c37e..6893a2df6 100644 --- a/src/index.js +++ b/src/index.js @@ -239,7 +239,7 @@ class ReactTooltip extends Component { } // Get the tooltip content // calculate in this phrase so that tip width height can be detected - const {multiline} = this.props + const {multiline, getContent} = this.props const originTooltip = e.currentTarget.getAttribute('data-tip') const isMultiline = e.currentTarget.getAttribute('data-multiline') || multiline || false @@ -276,6 +276,19 @@ class ReactTooltip extends Component { }, () => { if (scrollHide) this.addScrollListener(e) this.updateTooltip(e) + + if (getContent && Array.isArray(getContent)) { + this.intervalUpdateContent = setInterval(() => { + if (this.mount) { + const {getContent} = this.props + const placeholder = getTipContent(originTooltip, getContent[0](), isMultiline) + const isEmptyTip = this.isEmptyTip(placeholder) + this.setState({ + isEmptyTip + }) + } + }, getContent[1]) + } }) }