@@ -38,13 +38,14 @@ class ReactTooltip extends Component {
3838 watchWindow : PropTypes . bool ,
3939 isCapture : PropTypes . bool ,
4040 globalEventOff : PropTypes . string ,
41- getContent : PropTypes . any
41+ getContent : PropTypes . any ,
42+ countTransform : PropTypes . bool
4243 }
4344
4445 constructor ( props ) {
4546 super ( props )
4647 this . state = {
47- place : 'top ' , // Direction of tooltip
48+ place : '' , // Direction of tooltip
4849 type : 'dark' , // Color theme of tooltip
4950 effect : 'float' , // float or fixed
5051 show : false ,
@@ -61,12 +62,29 @@ class ReactTooltip extends Component {
6162 currentTarget : null // Current target of mouse event
6263 }
6364
65+ this . bind ( [
66+ 'showTooltip' ,
67+ 'updateTooltip' ,
68+ 'hideTooltip' ,
69+ 'globalRebuild' ,
70+ 'onWindowResize'
71+ ] )
72+
6473 this . mount = true
6574 this . delayShowLoop = null
6675 this . delayHideLoop = null
6776 this . intervalUpdateContent = null
6877 }
6978
79+ /**
80+ * For unify the bind and unbind listener
81+ */
82+ bind ( methodArray ) {
83+ methodArray . forEach ( method => {
84+ this [ method ] = this [ method ] . bind ( this )
85+ } )
86+ }
87+
7088 componentDidMount ( ) {
7189 this . setStyleHeader ( ) // Set the style to the <link>
7290 this . bindListener ( ) // Bind listener for tooltip
@@ -115,27 +133,24 @@ class ReactTooltip extends Component {
115133 if ( target . getAttribute ( 'currentItem' ) === null ) {
116134 target . setAttribute ( 'currentItem' , 'false' )
117135 }
136+ this . unbindBasicListener ( target )
118137
119138 if ( this . isCustomEvent ( target ) ) {
120139 this . customBindListener ( target )
121140 return
122141 }
123142
124- target . removeEventListener ( 'mouseenter' , this . showTooltip )
125- target . addEventListener ( 'mouseenter' , ::this . showTooltip , isCaptureMode )
143+ target . addEventListener ( 'mouseenter' , this . showTooltip , isCaptureMode )
126144 if ( this . state . effect === 'float' ) {
127- target . removeEventListener ( 'mousemove' , this . updateTooltip )
128- target . addEventListener ( 'mousemove' , ::this . updateTooltip , isCaptureMode )
145+ target . addEventListener ( 'mousemove' , this . updateTooltip , isCaptureMode )
129146 }
130-
131- target . removeEventListener ( 'mouseleave' , this . hideTooltip )
132- target . addEventListener ( 'mouseleave' , ::this . hideTooltip , isCaptureMode )
147+ target . addEventListener ( 'mouseleave' , this . hideTooltip , isCaptureMode )
133148 } )
134149
135150 // Global event to hide tooltip
136151 if ( globalEventOff ) {
137152 window . removeEventListener ( globalEventOff , this . hideTooltip )
138- window . addEventListener ( globalEventOff , :: this . hideTooltip , false )
153+ window . addEventListener ( globalEventOff , this . hideTooltip , false )
139154 }
140155 }
141156
@@ -145,21 +160,25 @@ class ReactTooltip extends Component {
145160 unbindListener ( ) {
146161 const { id, globalEventOff} = this . props
147162 const targetArray = this . getTargetArray ( id )
148-
149163 targetArray . forEach ( target => {
150- if ( this . isCustomEvent ( target ) ) {
151- this . customUnbindListener ( target )
152- return
153- }
154-
155- target . removeEventListener ( 'mouseenter' , this . showTooltip )
156- target . removeEventListener ( 'mousemove' , this . updateTooltip )
157- target . removeEventListener ( 'mouseleave' , this . hideTooltip )
164+ this . unbindBasicListener ( target )
165+ if ( this . isCustomEvent ( target ) ) this . customUnbindListener ( target )
158166 } )
159167
160168 if ( globalEventOff ) window . removeEventListener ( globalEventOff , this . hideTooltip )
161169 }
162170
171+ /**
172+ * Invoke this before bind listener and ummount the compont
173+ * it is necessary to invloke this even when binding custom event
174+ * so that the tooltip can switch between custom and default listener
175+ */
176+ unbindBasicListener ( target ) {
177+ target . removeEventListener ( 'mouseenter' , this . showTooltip )
178+ target . removeEventListener ( 'mousemove' , this . updateTooltip )
179+ target . removeEventListener ( 'mouseleave' , this . hideTooltip )
180+ }
181+
163182 /**
164183 * When mouse enter, show the tooltip
165184 */
@@ -170,6 +189,7 @@ class ReactTooltip extends Component {
170189 const originTooltip = e . currentTarget . getAttribute ( 'data-tip' )
171190 const isMultiline = e . currentTarget . getAttribute ( 'data-multiline' ) || multiline || false
172191
192+ // Generate tootlip content
173193 let content = children
174194 if ( getContent ) {
175195 if ( Array . isArray ( getContent ) ) {
@@ -178,20 +198,29 @@ class ReactTooltip extends Component {
178198 content = getContent ( )
179199 }
180200 }
181-
182201 const placeholder = getTipContent ( originTooltip , content , isMultiline )
183202
203+ // If it is focus event, switch to `solid` effect
204+ const isFocus = e instanceof window . FocusEvent
205+
184206 this . setState ( {
185207 placeholder,
186208 place : e . currentTarget . getAttribute ( 'data-place' ) || this . props . place || 'top' ,
187209 type : e . currentTarget . getAttribute ( 'data-type' ) || this . props . type || 'dark' ,
188- effect : e . currentTarget . getAttribute ( 'data-effect' ) || this . props . effect || 'float' ,
210+ effect : isFocus && 'solid' || e . currentTarget . getAttribute ( 'data-effect' ) || this . props . effect || 'float' ,
189211 offset : e . currentTarget . getAttribute ( 'data-offset' ) || this . props . offset || { } ,
190- html : e . currentTarget . getAttribute ( 'data-html' ) === 'true' || this . props . html || false ,
212+ html : e . currentTarget . getAttribute ( 'data-html' )
213+ ? e . currentTarget . getAttribute ( 'data-html' ) === 'true'
214+ : ( this . props . html || false ) ,
191215 delayShow : e . currentTarget . getAttribute ( 'data-delay-show' ) || this . props . delayShow || 0 ,
192216 delayHide : e . currentTarget . getAttribute ( 'data-delay-hide' ) || this . props . delayHide || 0 ,
193- border : e . currentTarget . getAttribute ( 'data-border' ) === 'true' || this . props . border || false ,
194- extraClass : e . currentTarget . getAttribute ( 'data-class' ) || this . props . class || ''
217+ border : e . currentTarget . getAttribute ( 'data-border' )
218+ ? e . currentTarget . getAttribute ( 'data-border' ) === 'true'
219+ : ( this . props . border || false ) ,
220+ extraClass : e . currentTarget . getAttribute ( 'data-class' ) || this . props . class || '' ,
221+ countTransform : e . currentTarget . getAttribute ( 'data-count-transform' )
222+ ? e . currentTarget . getAttribute ( 'data-count-transform' ) === 'true'
223+ : ( this . props . countTransform != null ? this . props . countTransform : true )
195224 } , ( ) => {
196225 this . addScrollListener ( e )
197226 this . updateTooltip ( e )
@@ -243,7 +272,8 @@ class ReactTooltip extends Component {
243272 this . clearTimer ( )
244273 this . delayHideLoop = setTimeout ( ( ) => {
245274 this . setState ( {
246- show : false
275+ show : false ,
276+ place : ''
247277 } )
248278 this . removeScrollListener ( )
249279 } , parseInt ( delayHide , 10 ) )
@@ -255,7 +285,7 @@ class ReactTooltip extends Component {
255285 */
256286 addScrollListener ( e ) {
257287 const isCaptureMode = this . isCapture ( e . currentTarget )
258- window . addEventListener ( 'scroll' , :: this . hideTooltip , isCaptureMode )
288+ window . addEventListener ( 'scroll' , this . hideTooltip , isCaptureMode )
259289 }
260290
261291 removeScrollListener ( ) {
@@ -264,10 +294,10 @@ class ReactTooltip extends Component {
264294
265295 // Calculation the position
266296 updatePosition ( ) {
267- const { currentEvent, currentTarget, place, effect, offset} = this . state
297+ const { currentEvent, currentTarget, place, effect, offset, countTransform } = this . state
268298 const node = ReactDOM . findDOMNode ( this )
269299
270- const result = getPosition ( currentEvent , currentTarget , node , place , effect , offset )
300+ const result = getPosition ( currentEvent , currentTarget , node , place , effect , offset , countTransform )
271301
272302 if ( result . isNewState ) {
273303 // Switch to reverse placement
0 commit comments