Tom Butcher 8ac04ac0bc Implement Tooltip System and Enhance UI Components
- Introduced a new Tooltip component to standardize tooltip functionality across the application, improving consistency and usability.
- Refactored existing components to utilize the new Tooltip implementation, enhancing user interactions with clearer feedback.
- Added a CursorTooltip for dynamic tooltip positioning based on mouse movement, improving user experience.
- Updated CSS styles for tooltips and related components to enhance visual clarity and responsiveness.
- Integrated TooltipProvider to manage tooltip state and visibility, streamlining tooltip management across the application.
2026-08-20 20:14:51 +01:00

73 lines
1.6 KiB
JavaScript

import {
cloneElement,
isValidElement,
useEffect,
useId,
useRef
} from 'react'
import PropTypes from 'prop-types'
import { useTooltipContext } from '../context/TooltipContext'
const mergeHandler = (original, next) => (event) => {
next(event)
original?.(event)
}
const Tooltip = ({ children, title, content }) => {
const { showTooltip, hideTooltip } = useTooltipContext()
const id = useId()
const tooltipContent = title ?? content
const hoveringRef = useRef(false)
useEffect(() => {
return () => hideTooltip(id)
}, [hideTooltip, id])
useEffect(() => {
if (hoveringRef.current) {
showTooltip(id, tooltipContent)
}
}, [id, showTooltip, tooltipContent])
const onMouseEnter = (event) => {
hoveringRef.current = true
showTooltip(id, tooltipContent, event.clientX, event.clientY)
}
const onMouseLeave = () => {
hoveringRef.current = false
hideTooltip(id)
}
if (isValidElement(children)) {
const trigger = cloneElement(children, {
onMouseEnter: mergeHandler(children.props.onMouseEnter, onMouseEnter),
onMouseLeave: mergeHandler(children.props.onMouseLeave, onMouseLeave)
})
if (children.props.disabled) {
return (
<span onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}>
{trigger}
</span>
)
}
return trigger
}
return (
<span onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}>
{children}
</span>
)
}
Tooltip.propTypes = {
children: PropTypes.node.isRequired,
title: PropTypes.node,
content: PropTypes.node
}
export default Tooltip