@@ -6,7 +6,7 @@ import { createPortal } from 'react-dom';
66import T from 'prop-types' ;
77import { Manager , Reference , Popper } from 'react-popper' ;
88import Tooltip from './Tooltip' ;
9- import { callAll } from './utils' ;
9+ import { callAll , noop } from './utils' ;
1010
1111const DEFAULT_MODIFIERS = {
1212 preventOverflow : {
@@ -35,6 +35,10 @@ export default class TooltipTrigger extends PureComponent {
3535 * use to create controlled tooltip
3636 */
3737 tooltipShown : T . bool ,
38+ /**
39+ * сalled when the visibility of the tooltip changes
40+ */
41+ onVisibilityChange : T . func ,
3842 /**
3943 * delay in showing the tooltip
4044 */
@@ -77,11 +81,32 @@ export default class TooltipTrigger extends PureComponent {
7781 defaultTooltipShown : false ,
7882 placement : 'right' ,
7983 trigger : 'hover' ,
80- closeOnOutOfBoundaries : true
84+ closeOnOutOfBoundaries : true ,
85+ onVisibilityChange : noop
8186 } ;
8287
8388 state = {
84- tooltipShown : this . props . defaultTooltipShown
89+ tooltipShown : this . _isControlled ( ) ? false : this . props . defaultTooltipShown
90+ } ;
91+
92+ _isControlled ( ) {
93+ return this . props . tooltipShown !== undefined ;
94+ }
95+
96+ _getState ( ) {
97+ return this . _isControlled ( )
98+ ? this . props . tooltipShown
99+ : this . state . tooltipShown ;
100+ }
101+
102+ _setTooltipState = state => {
103+ const cb = ( ) => this . props . onVisibilityChange ( state ) ;
104+
105+ if ( this . _isControlled ( ) ) {
106+ cb ( ) ;
107+ } else {
108+ this . setState ( { tooltipShown : state } , cb ) ;
109+ }
85110 } ;
86111
87112 _clearScheduled = ( ) => {
@@ -91,24 +116,16 @@ export default class TooltipTrigger extends PureComponent {
91116
92117 _showTooltip = ( delay = this . props . delayShow ) => {
93118 this . _clearScheduled ( ) ;
94-
95- this . _showTimeout = setTimeout (
96- ( ) => this . setState ( { tooltipShown : true } ) ,
97- delay
98- ) ;
119+ this . _showTimeout = setTimeout ( ( ) => this . _setTooltipState ( true ) , delay ) ;
99120 } ;
100121
101122 _hideTooltip = ( delay = this . props . delayHide ) => {
102123 this . _clearScheduled ( ) ;
103-
104- this . _hideTimeout = setTimeout (
105- ( ) => this . setState ( { tooltipShown : false } ) ,
106- delay
107- ) ;
124+ this . _hideTimeout = setTimeout ( ( ) => this . _setTooltipState ( false ) , delay ) ;
108125 } ;
109126
110127 _toggleTooltip = delay => {
111- const action = this . state . tooltipShown ? '_hideTooltip' : '_showTooltip' ;
128+ const action = this . _getState ( ) ? '_hideTooltip' : '_showTooltip' ;
112129 this [ action ] ( delay ) ;
113130 } ;
114131
@@ -117,11 +134,6 @@ export default class TooltipTrigger extends PureComponent {
117134 this . _toggleTooltip ( ) ;
118135 } ;
119136
120- static getDerivedStateFromProps ( props ) {
121- const { tooltipShown } = props ;
122- return tooltipShown != null ? { tooltipShown } : null ;
123- }
124-
125137 componentWillUnmount ( ) {
126138 this . _clearScheduled ( ) ;
127139 }
@@ -166,7 +178,7 @@ export default class TooltipTrigger extends PureComponent {
166178 children ( { getTriggerProps : this . getTriggerProps , triggerRef : ref } )
167179 }
168180 </ Reference >
169- { this . state . tooltipShown &&
181+ { this . _getState ( ) &&
170182 createPortal (
171183 < Popper
172184 placement = { placement }
0 commit comments