Skip to content

Tooltip

When the user's mouse or focus rests on an element, a non-interactive popup is displayed near it.

A couple notes on using tooltips:

  • Do not use tooltips for information vital to task completion. The elements they are attached to should usually make sense on their own, but a tooltip can help provide a little bit more information--especially for new users of your app.
  • Keep the content minimal, they are not intended to hide critical content.
  • If you want interactive content, you can use a Dialog.

Touch Events: Touch events are currently not supported. There's not a lot of research or examples of these types of tooltips on mobile. We have some ideas but need to validate them first before implementing. Please adjust your interfaces on mobile to account for this.

Installation

npm install @reach/tooltip
# or
yarn add @reach/tooltip

And then import the components you need:

import Tooltip, { useTooltip, TooltipPopup } from "@reach/tooltip";

Usage

Sometimes the button contains information that is relevant to the user, like a badge showing the count for notifications. In these cases we want the screen reader user to know both the content in the tooltip, but also the content in the badge. For screenreader users, the only content announced to them is whatever is in the tooltip. For these cases, use the ariaLabel prop.

All props passed to Tooltip will go to the popover.

Tooltip CSS Selectors

Please see the styling guide.

[data-reach-tooltip] {
}

useTooltip, TooltipPopup

Tooltip is built on top of the useTooltip hook and TooltipPopup.

You may want to drop down to this lower level API if you need animation or you want to add the triangles to the tooltip. We've provided code for both of these use-cases below:

Triangle pointers and custom styles

Animation

Here's some code you can copy/paste to make it happen along with React Spring:

import React, { Fragment, cloneElement } from "react";
import { useTooltip, TooltipPopup } from "@reach/tooltip";
import { useTransition, animated } from "react-spring";

animated.TooltipPopup = animated(TooltipPopup);
animated.TooltipContent = animated(TooltipPopup);

function AnimatedTooltip({ children, ...rest }) {
  const [trigger, tooltip, isVisible] = useTooltip();

  const transitions = useTransition(isVisible ? tooltip : false, null, {
    from: { opacity: 0 },
    enter: { opacity: 1 },
    leave: { opacity: 0 },
    config: { mass: 1, tension: 500, friction: 40 }
  });

  return (
    <Fragment>
      {cloneElement(children, trigger)}

      {transitions.map(
        ({ item: tooltip, props: styles, key }) =>
          tooltip && (
            <animated.TooltipContent
              key={key}
              {...tooltip}
              {...rest}
              style={styles}
            />
          )
      )}
    </Fragment>
  );
}

// Now you can replace `Tooltip` with `AnimatedTooltip`
function App() {
  return (
    <AnimatedTooltip label="Compose Message">
      <button>πŸ“</button>
    </AnimatedTooltip>
  );
}