Tooltip with Angular CDK

Nikita Poltoratsky
Feb 13, 2019 · 5 min read

A short while ago I published an article about the integration of Angular CDK in Nebular — full-featured library for Angular applications we’re developing at Akveo.

During the development, we’ve faced a bunch of interesting puzzles that Angular CDK has helped us to overcome. That’s why I decided to start a series of articles on challenges Angular CDK may aid you with.

To start with, let’s build a tooltip directive. It may sound like a simple component to build, but I believe it is a great showcase of a number of CDK features.



Table of contents

  • Angular CDK Setup
  • Building blocks
  • Make tooltip floating
  • Overlay Explained
  • Position tooltip properly
  • Results

Introduction

And here is the usage example:

<span awesomeTooltip="Tooltip text">This is an example</span>

Angular CDK Setup

npm install @angular/cdk

To use OverlayModule we have to import OverlayModule in AppModule

And include overlay styles in the global stylesheet file:

@import '~@angular/cdk/overlay-prebuilt.css';

Now we have all the required functionality set up and ready to build the tooltip directive!


Building blocks

The directive manages the tooltip state. It listens tomouseenter and mouseout events and shows and hides tooltip as a reaction to the events.

The second thing we need to create is a component that will render the passed text:

Don’t forget to add AwesomeTooltipComponent in entryComponents:

As we need to create AwesomeTooltipComponent dynamically in the runtime, we need to tell Angular compiler about that.

The next obvious step is to render AwesomeTooltipComponent with provided text input. Let’s get to it.


Make tooltip floating

Firstly, we’re injecting overlay service in tooltip directive and creating new overlay:

By callingthis.overlay.create() we’re creating somewhat called OverlayRef . You may think of it as of a remote controller, which allows us to insert some dynamically created component somewhere on top of the document tree.

During the instantiation, it creates thediv.cdk-overlay-container element that serves as a container root for all components inserted into it.

Now let’s complete show and hide methods with some CDK functions to make the magic work:

Basically, we are instantiating the AwesomeTooltipComponent component and inserting it into the overlayRef we created in the previous step.

Last thing here, we are passing the text into the newly instantiated tooltip component reference.

But what is going on in the show method? Firstly, we’re creating the tooltip portal as new ComponentPortal() . Then, we’re attaching it to the overlayRef and assigning text to the created tooltip component instance. 🤯

A bit of magic, huh? Let me explain 😅


Overlays Explained

PortalOutlet in its turn doesn’t accept any content, but only instances of Portal. Portal , per se, is a thin wrapper that let you operate with PortalOutlet .

It’s exactly what we did. We created the tooltip portal:

const tooltipPortal = new ComponentPortal(AwesomeTooltipComponent);

And attached it to the PortalOutlet instantiated previously:

const tooltipRef: ComponentRef<AwesomeTooltipComponent>
= this.overlayRef.attach(tooltipPortal);

After attaching tooltip portal to the OverlayRef we’re getting ComponentRef , which refers to the created AwesomeTooltipComponent . We may access AwesomeTooltipComponent instance еhrough that reference and pass the tooltip text into.

tooltipRef.instance.text = this.text;

The hardest part is behind now 🥳.

At this stage, we have an overlay component created dynamically when we’re moving a mouse on text and destroyed when we’re moving the mouse out.

But the tooltip is rendered somewhere misplaced. Let’s position it exactly above the host element where we need to show the tooltip.


Tooltip Positioning

The positioning of the overlay components could be implemented using OverlayPositionBuilder abstraction:

OverlayPositionBuilder is an entity that knows how to position your overlay element relatively to the host element.

We’re creating a new position strategy connected to the elementRef , which means the position of the created overlays will be connected to the elementRef the following way: center bottom point of the overlay will be connected to the center top point of the elementRef .

Literally, it means that the component will appear above the elementRef .

The last step we need to do is to connect a positioning strategy to the already created overlay:

At this stage, we have a fully functional tooltip and it is positioned properly above the host component.

Results

Also, I’ve published sources of the example tooltip at my GitHub, check it if you just need a working example.

Recap

As you may notice we could add more to the article: animations, styling, etc. But these topics are out of Angular CDK scope, and I decided to focus on Angular CDK features only.

However, there is one more important thing I haven’t mentioned — repositioning of the tooltip during the page scrolling. I hope we can get back to this part in the upcoming articles.

Stay tuned and let me know if you have any particular CDK topics you would like to hear about!

Resources

Angular In Depth

The place where advanced Angular concepts are explained

Thanks to Dmitry Nehaychik

Nikita Poltoratsky

Written by

Developer Advocate at Akveo · Tech Author · Nebular and Ngx-Admin team · Minsk, Belarus

Angular In Depth

The place where advanced Angular concepts are explained

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade