Skip to content

Commit 223b78d

Browse files
feat: forward ref to be used on render
1 parent 1015a07 commit 223b78d

File tree

4 files changed

+35
-6
lines changed

4 files changed

+35
-6
lines changed

src/components/Tooltip/Tooltip.tsx

+23-1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ const Tooltip = ({
3434
afterHide,
3535
// props handled by controller
3636
content,
37+
contentRef,
3738
isOpen,
3839
setIsOpen,
3940
activeAnchor,
@@ -425,7 +426,7 @@ const Tooltip = ({
425426
}
426427
}, [id, anchorSelect, activeAnchor])
427428

428-
useEffect(() => {
429+
const updateTooltipPosition = () => {
429430
if (position) {
430431
// if `position` is set, override regular and `float` positioning
431432
handleTooltipPosition(position)
@@ -468,8 +469,29 @@ const Tooltip = ({
468469
}
469470
setActualPlacement(computedStylesData.place as PlacesType)
470471
})
472+
}
473+
474+
useEffect(() => {
475+
updateTooltipPosition()
471476
}, [show, activeAnchor, content, externalStyles, place, offset, positionStrategy, position])
472477

478+
useEffect(() => {
479+
if (!contentRef?.current) {
480+
return () => null
481+
}
482+
const contentObserver = new MutationObserver(() => {
483+
updateTooltipPosition()
484+
})
485+
contentObserver.observe(contentRef.current, {
486+
attributes: true,
487+
childList: true,
488+
subtree: true,
489+
})
490+
return () => {
491+
contentObserver.disconnect()
492+
}
493+
}, [content, contentRef?.current])
494+
473495
useEffect(() => {
474496
const anchorById = document.querySelector<HTMLElement>(`[id='${anchorId}']`)
475497
const anchors = [...anchorsBySelect, anchorById]

src/components/Tooltip/TooltipTypes.d.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { ElementType, ReactNode, CSSProperties } from 'react'
1+
import type { ElementType, ReactNode, CSSProperties, RefObject } from 'react'
22

33
export type PlacesType = 'top' | 'right' | 'bottom' | 'left'
44

@@ -40,6 +40,7 @@ export interface ITooltip {
4040
className?: string
4141
classNameArrow?: string
4242
content?: ChildrenType
43+
contentRef?: RefObject<HTMLElement>
4344
place?: PlacesType
4445
offset?: number
4546
id?: string

src/components/TooltipController/TooltipController.tsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useEffect, useState } from 'react'
1+
import { useEffect, useRef, useState } from 'react'
22
import { Tooltip } from 'components/Tooltip'
33
import type {
44
EventsType,
@@ -205,8 +205,9 @@ const TooltipController = ({
205205
* children should be lower priority so that it can be used as the "default" content
206206
*/
207207
let renderedContent: ChildrenType = children
208+
const contentRef = useRef<HTMLElement>(null)
208209
if (render) {
209-
renderedContent = render({ content: tooltipContent ?? null, activeAnchor })
210+
renderedContent = render({ ref: contentRef, content: tooltipContent ?? null, activeAnchor })
210211
} else if (tooltipContent) {
211212
renderedContent = tooltipContent
212213
}
@@ -221,6 +222,7 @@ const TooltipController = ({
221222
className,
222223
classNameArrow,
223224
content: renderedContent,
225+
contentRef,
224226
place: tooltipPlace,
225227
variant: tooltipVariant,
226228
offset: tooltipOffset,

src/components/TooltipController/TooltipControllerTypes.d.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { CSSProperties } from 'react'
1+
import type { CSSProperties, RefObject } from 'react'
22

33
import type {
44
PlacesType,
@@ -19,7 +19,11 @@ export interface ITooltipController {
1919
* @deprecated Use `children` or `render` instead
2020
*/
2121
html?: string
22-
render?: (render: { content: string | null; activeAnchor: HTMLElement | null }) => ChildrenType
22+
render?: (render: {
23+
ref?: RefObject<HTMLElement>
24+
content: string | null
25+
activeAnchor: HTMLElement | null
26+
}) => ChildrenType
2327
place?: PlacesType
2428
offset?: number
2529
id?: string

0 commit comments

Comments
 (0)