All files / src/components Tooltip.jsx

0% Statements 0/19
0% Branches 0/10
0% Functions 0/6
0% Lines 0/17

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72                                                                                                                                               
/**
 * @fileoverview Custom Tooltip Component
 * @description Styled tooltips to replace native title attributes
 * @module components/Tooltip
 */
 
import { useState, useRef, useEffect } from 'react';
import './Tooltip.css';
 
/**
 * Tooltip Component
 */
function Tooltip({ children, content, position = 'top', delay = 300 }) {
  const [isVisible, setIsVisible] = useState(false);
  const [coords, setCoords] = useState({ x: 0, y: 0 });
  const timeoutRef = useRef(null);
  const triggerRef = useRef(null);
 
  const showTooltip = () => {
    timeoutRef.current = setTimeout(() => {
      if (triggerRef.current) {
        const rect = triggerRef.current.getBoundingClientRect();
        setCoords({
          x: rect.left + rect.width / 2,
          y: position === 'top' ? rect.top : rect.bottom
        });
        setIsVisible(true);
      }
    }, delay);
  };
 
  const hideTooltip = () => {
    clearTimeout(timeoutRef.current);
    setIsVisible(false);
  };
 
  useEffect(() => {
    return () => clearTimeout(timeoutRef.current);
  }, []);
 
  if (!content) return children;
 
  return (
    <>
      <span 
        ref={triggerRef}
        className="tooltip-trigger"
        onMouseEnter={showTooltip}
        onMouseLeave={hideTooltip}
        onFocus={showTooltip}
        onBlur={hideTooltip}
      >
        {children}
      </span>
      {isVisible && (
        <div 
          className={`tooltip tooltip-${position}`}
          style={{
            left: coords.x,
            top: coords.y
          }}
        >
          {content}
          <div className="tooltip-arrow" />
        </div>
      )}
    </>
  );
}
 
export default Tooltip;