import type { CSSProperties, MouseEvent } from 'react' import { useState } from 'react' import isUndefined from 'lodash/isUndefined' import { useToggle } from './useToggle' type TooltipParams = { anchorId?: string, horizontalPosition?: 'left' | 'center' | 'right', indent?: number, tooltipText: string, verticalPosition?: 'top' | 'bottom', } export const useTooltip = () => { const [stateTooltipStyle, setTooltipStyle] = useState({}) const [stateAnchorId, setAnchorId] = useState(null) const [stateTooltipText, setTooltipText] = useState('') const { close: hideTooltip, isOpen: isTooltipShown, open: showTooltip, } = useToggle() const onMouseOver = ({ anchorId, horizontalPosition = 'center', indent = 10, tooltipText, verticalPosition = 'bottom', }: TooltipParams) => (e: MouseEvent) => { const target = e.target as HTMLElement if (anchorId && target.id !== anchorId) return const { left, right, top, } = target.getBoundingClientRect() const coords: Partial = { top: verticalPosition === 'bottom' ? top + target.clientHeight + indent : top - target.clientHeight - indent, ...(horizontalPosition === 'center' && { left: left + target.clientWidth / 2 }), ...(horizontalPosition === 'left' && { left }), ...(horizontalPosition === 'right' && { right }), } const tooltipStyle: CSSProperties = { left: !isUndefined(coords.left) ? `${coords.left}px` : 'auto', position: 'fixed', right: !isUndefined(coords.right) ? `${window.innerWidth - coords.right}px` : 'auto', top: `${coords.top}px`, zIndex: 999, ...(horizontalPosition === 'center' && { transform: 'translateX: (-50%)' }), ...(verticalPosition === 'top' && { transform: 'translateY: (-50%)' }), ...(horizontalPosition === 'center' && verticalPosition === 'top' && { transform: 'translate: (-50%, -50%)' }), } if (anchorId) { setAnchorId(anchorId) } setTooltipStyle(tooltipStyle) showTooltip() setTooltipText(tooltipText) } const onMouseLeave = () => { hideTooltip() setAnchorId(null) setTooltipStyle({}) } return { anchorId: stateAnchorId, isTooltipShown, onMouseLeave, onMouseOver, tooltipStyle: stateTooltipStyle, tooltipText: stateTooltipText, } }