@@ -16,7 +16,13 @@ import {
16
16
} from '@floating-ui/react'
17
17
import { AnimatePresence , motion } from 'framer-motion'
18
18
import { transparentize } from 'polished'
19
- import React , { CSSProperties , ReactNode , useRef , useState } from 'react'
19
+ import React , {
20
+ CSSProperties ,
21
+ ReactNode ,
22
+ useRef ,
23
+ useState ,
24
+ useMemo ,
25
+ } from 'react'
20
26
import { SolvedTheme , solvedThemes } from '../styles'
21
27
import { Card , CardProps } from './Card'
22
28
@@ -74,6 +80,7 @@ export type TooltipProps = {
74
80
activateOnClick ?: boolean
75
81
noThemeChange ?: boolean
76
82
zIndex ?: number
83
+ onOpenChange ?: ( open : boolean ) => void
77
84
} & (
78
85
| {
79
86
noDefaultStyles : false
@@ -133,13 +140,21 @@ export const Tooltip: React.FC<TooltipProps> = (props) => {
133
140
activateOnClick = false ,
134
141
noThemeChange = false ,
135
142
zIndex,
143
+ onOpenChange,
136
144
...cardProps
137
145
} = props
138
146
const [ isOpen , setIsOpen ] = useState ( false )
139
147
const renderTooltip = typeof open === 'boolean' ? open : isOpen
140
148
141
149
const arrowRef = useRef ( null )
142
150
151
+ const handleOpenChange = ( open : boolean ) : void => {
152
+ setIsOpen ( open )
153
+ if ( onOpenChange ) {
154
+ onOpenChange ( open )
155
+ }
156
+ }
157
+
143
158
const {
144
159
x,
145
160
y,
@@ -152,7 +167,7 @@ export const Tooltip: React.FC<TooltipProps> = (props) => {
152
167
placement : place ,
153
168
strategy : 'fixed' ,
154
169
open : isOpen ,
155
- onOpenChange : setIsOpen ,
170
+ onOpenChange : handleOpenChange ,
156
171
middleware : [
157
172
offset ( 16 ) ,
158
173
shift ( { padding : 16 } ) ,
@@ -183,8 +198,18 @@ export const Tooltip: React.FC<TooltipProps> = (props) => {
183
198
] )
184
199
185
200
const RenderComponent = noBackground ? motion . div : TooltipContainer
186
- const ThemeProviderComponent =
187
- noThemeChange || noBackground ? React . Fragment : ThemeProvider
201
+ const ThemeProviderComponent = useMemo (
202
+ ( ) =>
203
+ noThemeChange || noBackground
204
+ ? React . Fragment
205
+ : ( { children } : { children ?: ReactNode } ) => (
206
+ // eslint-disable-next-line react/jsx-indent
207
+ < ThemeProvider theme = { theme || solvedThemes . dark } >
208
+ { children }
209
+ </ ThemeProvider >
210
+ ) ,
211
+ [ noThemeChange , noBackground , theme ]
212
+ )
188
213
189
214
const arrowPosition =
190
215
renderSide [ placement . split ( '-' ) [ 0 ] as keyof typeof renderSide ]
@@ -195,7 +220,7 @@ export const Tooltip: React.FC<TooltipProps> = (props) => {
195
220
{ children }
196
221
</ TooltipWrapper >
197
222
< FloatingPortal >
198
- < ThemeProviderComponent theme = { theme || solvedThemes . dark } >
223
+ < ThemeProviderComponent >
199
224
< AnimatePresence >
200
225
{ renderTooltip && (
201
226
< React . Fragment >
0 commit comments