# All files / src/tooltip useOverflowTooltip.ts

100% Statements 93/93
100% Branches 3/3
100% Functions 1/1
100% Lines 93/93

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
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    941x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    6x
    6x
    6x
    6x
    6x
    6x
    6x
    6x
    3x
    3x
    6x
    6x
    6x
    6x
    6x
    6x
    6x
    6x
    6x
    6x
    6x
    6x
    6x
     "use client";
    import { useCallback, useState, type Ref, type RefCallback } from "react";
    import { useResizeObserver } from "../useResizeObserver.js";
    import {
      useTooltip,
      type TooltipImplementation,
      type TooltipOptions,
    } from "./useTooltip.js";

    /**
     * @remarks \@since 6.0.0
     */
    export interface OverflowTooltipOptions extends TooltipOptions {
      elementRef?: Ref<HTMLElement>;
    }

    /**
     * @remarks \@since 6.0.0
     */
    export interface OverflowTooltipImplementation extends TooltipImplementation {
      nodeRef: RefCallback<HTMLElement>;
    }

    /**
     * This hook will ensure that a tooltip will only appear when text has
     * overflown by checking the size with the {@link useResizeObserver}.
     *
     * @example
     * ```tsx
     * import {
     *   cssUtils,
     *   Link,
     *   Tooltip,
     *   useOverflowTooltip,
     *   type LinkProps,
     * } from "@react-md/core";
     * import { type ReactElement } from "react";
     *
     * function NavigationLink(props: LinkProps): ReactElement {
     *   const { children, ...remaining } = props;
     *   const { nodeRef, elementProps, tooltipProps } = useOverflowTooltip(remaining);
     *
     *   return (
     *     <Link {...remaining} {...elementProps} style={{ width: "100%" }}>
     *       <span ref={nodeRef} className={cssUtils({ textOverflow: "ellipsis" })}>
     *         {children}
     *       </span>
     *       <Tooltip {...tooltipProps}>
     *         {children}
     *       </Tooltip>
     *     </Link>
     *   );
     * }
     *
     * function Example(): ReactElement {
     *   return (
     *     <div style={{ width: "10rem", overflow: "auto" }}>
     *       <NavigationLink href="/">Home</NavigationLink>
     *       <NavigationLink href="/some-path">
     *         Super long text that will be truncated with ellipsis and
     *         have a tooltip appear
     *       </NavigationLink>
     *     </div>
     *   );
     * }
     * ```
     *
     * @remarks \@since 6.0.0
     */
    export function useOverflowTooltip(
      options: OverflowTooltipOptions = {}
    ): OverflowTooltipImplementation {
      const { disabled, elementRef, ...tooltipOptions } = options;
      const [overflown, setOverflown] = useState(false);
      const nodeRef = useResizeObserver({
        ref: elementRef,
        disableHeight: true,
        onUpdate: useCallback((entry) => {
          const target = entry.target as HTMLElement;
          setOverflown(target.offsetWidth < target.scrollWidth);
        }, []),
      });

      const implementation = useTooltip({
        ...tooltipOptions,
        disabled: !overflown || disabled,
      });

      return {
        nodeRef,
        ...implementation,
      };
    }