import type { TooltipProps } from '@mui/material'
import { useLayoutEffect, useRef, useState, type JSX, type Ref } from 'react'
import { Tooltip } from '../tooltip/tooltip'
const EMPTY_DEPENDENCIES: unknown[] = []
/**
* An intelligent tooltip wrapper that automatically detects text overflow and displays a tooltip only when content is truncated.
*
* @remarks
* Uses a render prop pattern. The child function receives a `ref` that must be attached to the element being monitored for overflow. Use the `dependencies` array to trigger re-evaluation when content or container size changes.
*
* @example
* ```tsx
*
* {({ ref }) => (
*
* This is a long text that might get truncated
*
* )}
*
* ```
*/
export function SmartTooltip({
title,
dependencies = EMPTY_DEPENDENCIES,
timeout = 500,
TooltipProps,
children,
}: {
title: string | undefined
dependencies?: unknown[]
timeout?: number
children: (props: { ref: Ref }) => JSX.Element
TooltipProps?: Partial
}) {
const ref = useRef(null)
const [isOverflowing, setIsOverflowing] = useState(false)
// Call sites pass a fresh `dependencies={[…]}` literal each render; key by
// value so the effect does not churn ResizeObserver on referential churn.
const dependenciesKey = JSON.stringify(dependencies)
useLayoutEffect(() => {
const checkOverflow = () => {
const el = ref.current
if (!el) return
setIsOverflowing(
el.scrollWidth > el.clientWidth || el.scrollHeight > el.clientHeight,
)
}
// Initial measure after layout settles (fonts, flex collapse, …).
const timerId = setTimeout(checkOverflow, timeout)
// Re-measure when the element is resized (e.g. legend title reflows as
// hover-faded actions collapse/expand).
const el = ref.current
const resizeObserver =
el && typeof ResizeObserver !== 'undefined'
? new ResizeObserver(checkOverflow)
: null
if (el) resizeObserver?.observe(el)
return () => {
clearTimeout(timerId)
resizeObserver?.disconnect()
}
}, [dependenciesKey, timeout])
return (
{children({ ref })}
)
}