@@ -16,7 +16,13 @@ import {
1616} from '@floating-ui/react'
1717import { AnimatePresence , motion } from 'framer-motion'
1818import { 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'
2026import { SolvedTheme , solvedThemes } from '../styles'
2127import { Card , CardProps } from './Card'
2228
@@ -74,6 +80,7 @@ export type TooltipProps = {
7480 activateOnClick ?: boolean
7581 noThemeChange ?: boolean
7682 zIndex ?: number
83+ onOpenChange ?: ( open : boolean ) => void
7784} & (
7885 | {
7986 noDefaultStyles : false
@@ -133,13 +140,21 @@ export const Tooltip: React.FC<TooltipProps> = (props) => {
133140 activateOnClick = false ,
134141 noThemeChange = false ,
135142 zIndex,
143+ onOpenChange,
136144 ...cardProps
137145 } = props
138146 const [ isOpen , setIsOpen ] = useState ( false )
139147 const renderTooltip = typeof open === 'boolean' ? open : isOpen
140148
141149 const arrowRef = useRef ( null )
142150
151+ const handleOpenChange = ( open : boolean ) : void => {
152+ setIsOpen ( open )
153+ if ( onOpenChange ) {
154+ onOpenChange ( open )
155+ }
156+ }
157+
143158 const {
144159 x,
145160 y,
@@ -152,7 +167,7 @@ export const Tooltip: React.FC<TooltipProps> = (props) => {
152167 placement : place ,
153168 strategy : 'fixed' ,
154169 open : isOpen ,
155- onOpenChange : setIsOpen ,
170+ onOpenChange : handleOpenChange ,
156171 middleware : [
157172 offset ( 16 ) ,
158173 shift ( { padding : 16 } ) ,
@@ -183,8 +198,18 @@ export const Tooltip: React.FC<TooltipProps> = (props) => {
183198 ] )
184199
185200 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+ )
188213
189214 const arrowPosition =
190215 renderSide [ placement . split ( '-' ) [ 0 ] as keyof typeof renderSide ]
@@ -195,7 +220,7 @@ export const Tooltip: React.FC<TooltipProps> = (props) => {
195220 { children }
196221 </ TooltipWrapper >
197222 < FloatingPortal >
198- < ThemeProviderComponent theme = { theme || solvedThemes . dark } >
223+ < ThemeProviderComponent >
199224 < AnimatePresence >
200225 { renderTooltip && (
201226 < React . Fragment >
0 commit comments