1- import React , { useCallback , useEffect , useImperativeHandle , useRef , useState } from 'react' ;
1+ import React , { useCallback , useEffect , useImperativeHandle , useMemo , useRef , useState } from 'react' ;
22import { Popper , POPPER_HORIZONTAL , POPPER_VERTICAL , PopperHorizontal , PopperVertical } from './Popper' ;
33import type { JSX } from 'react/jsx-runtime' ;
44import { TooltipTitleContent } from './TooltipTitleContent' ;
5- import { useOnClickOutside } from '@/hooks' ;
5+ import { useOnClickOutside , useStateToRef } from '@/hooks' ;
66
77import cn from 'classnames' ;
88import css from './style.module.css' ;
@@ -27,6 +27,7 @@ export type TooltipProps<T extends keyof JSX.IntrinsicElements> = {
2727 delay ?: number ;
2828 delayClose ?: number ;
2929 onClickOuter ?: ( ) => void ;
30+ noStyle ?: boolean ;
3031} & Omit < JSX . IntrinsicElements [ T ] , 'title' > ;
3132
3233declare function _TooltipFn < T extends keyof JSX . IntrinsicElements > ( props : TooltipProps < T > ) : JSX . Element ;
@@ -52,32 +53,36 @@ export const Tooltip = React.forwardRef<Element, TooltipProps<'div'>>(function T
5253 onMouseOut,
5354 onMouseMove,
5455 onClick,
56+ noStyle,
5557 ...props
5658 } ,
5759 ref
5860) {
5961 const timeoutDelayRef = useRef < NodeJS . Timeout | null > ( null ) ;
6062 const [ localRef , setLocalRef ] = useState < Element | null > ( null ) ;
63+ const [ open , setOpen ] = useState ( false ) ;
6164
62- const targetRef = useRef < Element | null > ( null ) ;
65+ const openRef = useStateToRef ( open ) ;
66+ const targetRef = useStateToRef ( localRef ) ;
6367
6468 useImperativeHandle < Element | null , Element | null > ( ref , ( ) => localRef , [ localRef ] ) ;
6569
6670 const portalRef = useRef ( null ) ;
67- useOnClickOutside ( portalRef , ( ) => {
68- if ( outerOpen == null ) {
69- timeoutDelayRef . current = setTimeout ( ( ) => {
70- setOpen ( false ) ;
71- } , delayClose ) ;
72- }
73- onClickOuter ?.( ) ;
74- } ) ;
71+ const innerRef = useMemo ( ( ) => [ portalRef , targetRef ] , [ targetRef ] ) ;
7572
76- useEffect ( ( ) => {
77- targetRef . current = localRef ;
78- } , [ localRef ] ) ;
79-
80- const [ open , setOpen ] = useState ( false ) ;
73+ useOnClickOutside (
74+ innerRef ,
75+ useCallback ( ( ) => {
76+ if ( outerOpen == null ) {
77+ timeoutDelayRef . current = setTimeout ( ( ) => {
78+ setOpen ( false ) ;
79+ } , delayClose ) ;
80+ }
81+ if ( openRef . current ) {
82+ onClickOuter ?.( ) ;
83+ }
84+ } , [ delayClose , onClickOuter , openRef , outerOpen ] )
85+ ) ;
8186
8287 useEffect ( ( ) => {
8388 if ( outerOpen != null ) {
@@ -163,8 +168,12 @@ export const Tooltip = React.forwardRef<Element, TooltipProps<'div'>>(function T
163168 vertical = { vertical }
164169 show = { open }
165170 >
166- < div ref = { portalRef } className = { cn ( titleClassName , 'card overflow-auto' ) } onClick = { stopPropagation } >
167- < div className = "card-body p-1" style = { { minHeight, minWidth, maxHeight, maxWidth } } >
171+ < div
172+ ref = { portalRef }
173+ className = { cn ( titleClassName , ! noStyle && 'card overflow-auto' ) }
174+ onClick = { stopPropagation }
175+ >
176+ < div className = { cn ( ! noStyle && 'card-body p-1' ) } style = { { minHeight, minWidth, maxHeight, maxWidth } } >
168177 < TooltipTitleContent > { title } </ TooltipTitleContent >
169178 </ div >
170179 </ div >
0 commit comments