DEV Community

Cover image for How To Create A Tooltip With Floating UI

How To Create A Tooltip With Floating UI

In software development, good user experience is usually one of the most important things to consider when building software. You don't have to make your users guess how to use your software application; this might affect the usability of your application, which is not what you want.

Most users are impatient, they might not be patient enough to explore and see how your app works, but with a tooltip, you can easily guide them through your application like a tour guide.

Today, we will be discussing how to build a tooltip easily with Floating UI.

Tooltip

Tooltips are small but informative popups that appear when a user hovers over, clicks on, or focuses on an element. Some tooltips might not require a user to trigger them; instead, they can serve as guides when a user visits your application for the first time, providing context and instructions automatically.

Floating UI

Floating UI is an amazing library that will enable you to create awesome tooltips that can easily adjust their positions based on the screen size. You don`t have to worry about responsiveness, Floating UI will handle that for you.

Sometimes, creating efficient tooltips can be time consuming, it involves some steps that you might find boring to take, that`s why you have to use libraries like Floating UI.

Prerequisites you need to understand this article

  1. Basic knowledge of React js.
  2. Basic understanding of javascript.
  3. You must have Node js installed on your computer (for your React application to run)
  4. And finally, a web browser like Google Chrome.

Let`s install Floating UI

We have to install Floating UI in our React js application. And we can do that by running this command.

npm install @floating-ui/react

We need to import lots of functions from the Floating UI library, these functions will enable us to create a tooltip effortlessly.

`
import {
useClick,
useFloating,
useInteractions,
flip,
offset,
useDismiss,
} from '@floating-ui/react';

`

Destructure useFloating

`
const {
refs: calendar1Refs,
floatingStyles: calendar1FloatingStyles,
context: calendar1Context,
} = useFloating({
open: isOpen1,
onOpenChange: setIsOpen1,
placement: 'bottom-end',
middleware: [
flip({
fallbackPlacements: ['right'],
}),

offset({ mainAxis: 20, crossAxis: 70 }),
],
});
`

Refs

This enables us to connect our tooltip with it`s reference effortlessly. Our reference should look like this.

<i
      className="fa-light fa-calendar cursor-pointer text-gray-500"
            ref={calendar1Refs.setReference}
           ></i>
Enter fullscreen mode Exit fullscreen mode

While our tooltip should look like this.

{isOpen1 && (
            <div
             className="absolute z-10 bg-white"
             ref={calendar1Refs.setFloating}

            >
             <Calendar onChange={handleSelectDate1} />
            </div>
           )}The difference here is that our tooltip reference has “setReference” while our tooltip has “setFloating”. This will enable them to be connect, making sure that the tooltip floats around it`s reference.
Enter fullscreen mode Exit fullscreen mode

FloatingStyles

The floatingStyles is an object that contains CSS styles which determine the exact position and dimensions of your floating element (like a tooltip) in relation to its reference element.

{isOpen2 && (
          <div
           className="z-[9999]"
           ref={calendar1Refs.setFloating}
           style={calendar1FloatingStyles}
           {...calendar1TooltipFloatingProps()}
          >
           <Calendar
            onChange={(date) => hanledSelectDate2(date)}
           />
          </div>
         )}
Enter fullscreen mode Exit fullscreen mode

Context

In Floating UI, context (like calendar1Context in this case) provides a way to manage and share state and interactions across multiple hooks. This helps us to share events like click, hover etc. It also helps to dismiss the interactions seamlessly, ensuring that each tooltip or floating element behaves consistently.

const click1 = useClick(calendar1Context);
 const dismissCalendar1ToolTip = useDismiss(calendar1Context);
Enter fullscreen mode Exit fullscreen mode

Open

The open prop is very important for the visibility of our tooltip. It helps us to manage the visibility of our tooltip based on a component’s internal state.

We first create a useState with a default value of false so that we can hide the tooltip until a user clicks on it. This useState tracks whether the tooltip is currently open or not.

const [isOpen, setIsOpen] = useState(false);
Enter fullscreen mode Exit fullscreen mode

onOpenChange

This callback helps us to update the setIsOpen value. So whenever a user clicks or trigger an event, we will set the false value in the isOpen to true, vice versa.

Placement

This helps to determine where to place our tooltip in relation to it`s reference. We can decide to place our tooltip in any of these positions;

  1. bottom
  2. bottom-end
  3. bottom-start
  4. left
  5. left-end
  6. left-start
  7. right
  8. right-end
  9. right-start
  10. top
  11. top-end
  12. top-start

Flip

The flip middleware that is inside the middleware array automatically adjusts the floating element’s position if there isn`t enough space in the specified direction. Here, if there’s not enough space below, it will attempt to position it using the fallback placements (['bottom-end']). We can choose any position we want based on available space.

middleware: [
   flip({
    fallbackPlacements: ['bottom-end'],
   }),

    ],
Enter fullscreen mode Exit fullscreen mode

Offset

This middleware creates spacing between the reference and the floating element. mainAxis: 20 creates a 20px gap in the primary direction (below the reference, in this case), while crossAxis: 50 creates a 50px offset along the perpendicular axis.

middleware: [
   offset({ mainAxis: 20, crossAxis: 50 }),
  ],
Enter fullscreen mode Exit fullscreen mode

This is how the configuration should look like

const [isOpen, setIsOpen] = useState(false);
 const {
  refs: calendar1Refs,
  floatingStyles: calendar1FloatingStyles,
  context: calendar1Context,
 } = useFloating({
  open: isOpen,
  onOpenChange: setIsOpen,
  placement: 'bottom-end',

  middleware: [
   flip({
    fallbackPlacements: ['bottom-end'],
   }),

   offset({ mainAxis: 20, crossAxis: 50 }),
  ],
 });

 const click = useClick(calendar1Context);
 const dismissImageToolTip = useDismiss(calendar1Context);

 const {
  getReferenceProps: calendar1TooltipReference,
  getFloatingProps: calendar1TooltipFloatingProps,
 } = useInteractions([click, dismissImageToolTip]);
Enter fullscreen mode Exit fullscreen mode

The demo

Click this link to watch the demo video.

From the video, you can clearly see that our tooltip adjusts its position if the space isnt enough to contain it. It uses the position of the fallbackPlacements we defined.

Conclusion

Floating UI provides a powerful and flexible way to implement tooltips in React applications. With its automatic positioning and rich customization options, you can create tooltips that enhance your application’s user experience while maintaining reliable functionality across different devices and screen sizes.

It involves so many functions and objects like; refs, floatingStyles, context, useState for state management, onOpenChange, placement, flip and offset.

By following this guide, you now have the knowledge to implement responsive and user-friendly tooltips in your React applications. Experiment with different configurations and middleware to create the perfect tooltip experience for your users.

Happy coding 😊

Top comments (0)