11
11
*/
12
12
13
13
import { AriaLabelingProps , FocusableElement } from '@react-types/shared' ;
14
+ import { AriaPositionProps , mergeProps , OverlayContainer , PlacementAxis , PositionProps , useOverlayPosition , useTooltip , useTooltipTrigger } from 'react-aria' ;
14
15
import { ContextValue , forwardRefType , Provider , RenderProps , useContextProps , useEnterAnimation , useExitAnimation , useRenderProps } from './utils' ;
15
16
import { FocusableProvider } from '@react-aria/focus' ;
16
- import { mergeProps , OverlayContainer , PlacementAxis , PositionProps , useOverlayPosition , useTooltip , useTooltipTrigger } from 'react-aria' ;
17
17
import { OverlayArrowContext } from './OverlayArrow' ;
18
18
import { OverlayTriggerProps , TooltipTriggerProps , TooltipTriggerState , useTooltipTriggerState } from 'react-stately' ;
19
- import React , { createContext , ForwardedRef , forwardRef , ReactNode , RefObject , useContext , useRef } from 'react' ;
19
+ import React , { createContext , ForwardedRef , forwardRef , ReactNode , RefObject , useContext , useRef , useState } from 'react' ;
20
+ import { useLayoutEffect } from '@react-aria/utils' ;
20
21
21
22
export interface TooltipTriggerComponentProps extends TooltipTriggerProps {
22
23
children : ReactNode
23
24
}
24
25
25
- export interface TooltipProps extends PositionProps , OverlayTriggerProps , AriaLabelingProps , RenderProps < TooltipRenderProps > {
26
+ export interface TooltipProps extends PositionProps , Pick < AriaPositionProps , 'arrowBoundaryOffset' > , OverlayTriggerProps , AriaLabelingProps , RenderProps < TooltipRenderProps > {
26
27
/**
27
28
* The ref for the element which the tooltip positions itself with respect to.
28
29
*
@@ -118,13 +119,25 @@ export {_Tooltip as Tooltip};
118
119
function TooltipInner ( props : TooltipProps & { isExiting : boolean , tooltipRef : RefObject < HTMLDivElement > } ) {
119
120
let state = useContext ( TooltipTriggerStateContext ) ! ;
120
121
122
+ // Calculate the arrow size internally
123
+ // Referenced from: packages/@react -spectrum/tooltip/src/TooltipTrigger.tsx
124
+ let arrowRef = useRef < HTMLDivElement > ( null ) ;
125
+ let [ arrowWidth , setArrowWidth ] = useState ( 0 ) ;
126
+ useLayoutEffect ( ( ) => {
127
+ if ( arrowRef . current && state . isOpen ) {
128
+ setArrowWidth ( arrowRef . current . getBoundingClientRect ( ) . width ) ;
129
+ }
130
+ } , [ state . isOpen , arrowRef ] ) ;
131
+
121
132
let { overlayProps, arrowProps, placement} = useOverlayPosition ( {
122
133
placement : props . placement || 'top' ,
123
134
targetRef : props . triggerRef ! ,
124
135
overlayRef : props . tooltipRef ,
125
136
offset : props . offset ,
126
137
crossOffset : props . crossOffset ,
127
- isOpen : state . isOpen
138
+ isOpen : state . isOpen ,
139
+ arrowSize : arrowWidth ,
140
+ arrowBoundaryOffset : props . arrowBoundaryOffset
128
141
} ) ;
129
142
130
143
let isEntering = useEnterAnimation ( props . tooltipRef , ! ! placement ) || props . isEntering || false ;
@@ -151,7 +164,7 @@ function TooltipInner(props: TooltipProps & {isExiting: boolean, tooltipRef: Ref
151
164
data-placement = { placement }
152
165
data-entering = { isEntering || undefined }
153
166
data-exiting = { props . isExiting || undefined } >
154
- < OverlayArrowContext . Provider value = { { ...arrowProps , placement} } >
167
+ < OverlayArrowContext . Provider value = { { ...arrowProps , placement, ref : arrowRef } } >
155
168
{ renderProps . children }
156
169
</ OverlayArrowContext . Provider >
157
170
</ div >
0 commit comments