Exploring Angular CDK: Creating Context Menu & Text Popover

In this article, I will showcase context-menu & text-popover built using Angular CDK Overlay.

10th June, 2024 — 4 min read

## Angular CDK `@angular/cdk`, also known as the Angular Component Dev Kit, is a library that provides a set of building blocks for creating UI components in Angular applications. It offers functionalities that are not directly visual components themselves, but rather assist in building those components. Here are some of the key features of `@angular/cdk`: - **Accessibility**: It includes utilities to help developers create components that are accessible to users with disabilities, such as screen reader support and focus management - **Layout**: Provides tools for managing layout based on factors like viewport size and direction (RTL/LTR) - **Behavior**: Offers functionalities like working with the clipboard, managing collections, and creating step-through processes - **Portal**: The portals package provides a flexible system for rendering dynamic content into an application - **Overlay**: The overlay package provides a way to open floating panels on the screen - and many more. For this article, we will focus on `overlay` package, and we will see that it's possible to create context-menus and text-popovers using the same. ## TL;DR If you're simple interested in Demo and code, jump to [that section](#demos-and-codes). ## Overlay package The `overlay` package provides a set-of very useful directives, which helps to create floating panels easily without much code. To see a simple demo, take a look at the [examples at the official docs](https://material.angular.io/cdk/overlay/examples). ![embedded video](/assets/angular-material.dev/Exploring%20Angular%20CDK_%20Creating%20Context%20Menu%20Text%20Popover/overlay_basic_vekgay.mp4=x300 "overlay package demo") As you can see, with a very few lines of code, we can achieve a simple floating panel, which is shown with respect to a trigger button. ## Context menu Context menus are the floating panels which can be shown when user right-clicks. So, instead of default browser menu on bigger screens, we can show a custom menu with useful actions. For example, you would have seen context menus when you right click anywhere in Google drive or in Figma. ![embedded video](/assets/angular-material.dev/Exploring%20Angular%20CDK_%20Creating%20Context%20Menu%20Text%20Popover/google_drive_context_menu_coxynw.mp4=x500) ![embedded video](/assets/angular-material.dev/Exploring%20Angular%20CDK_%20Creating%20Context%20Menu%20Text%20Popover/figma_context_menu_n56irr.mp4=x300) We can create such context-menu thanks to the `overlay` package. For this article, we want to create a context-menu using [``](https://material.angular.io/components/menu/overview) (is a floating panel containing list of options). The reason behind using `` is because it already has the Material styles applied to it, closing and opening animations are built-in and it also has a [wide verity of API support](https://material.angular.io/components/menu/api) available. > Now, there is a separate package called [`@angular/cdk/menu`](https://material.angular.io/cdk/menu/overview), which has a special directive to handle context menus called [`cdkContextMenuTriggerFor`](https://material.angular.io/cdk/menu/overview#context-menus). But, it is not possible to open the official [Angular Material Menu](https://material.angular.io/components/menu/overview) component through that directive yet. Hence, we need to follow a more controlled way through `overlay` package. So, to open `` on right-click, we need to follow below approach: 1. Create a desired menu using `` 2. Create a `` trigger using [`[matMenuTriggerFor]`](https://material.angular.io/components/menu/api#MatMenuTrigger), which will open that `` 3. Figure out the position where user have right-clicked and create a [`cdkOverlayOrigin`](https://material.angular.io/cdk/overlay/api#CdkOverlayOrigin) at that position 4. Attach trigger button dynamically at above origin using [`cdkConnectedOverlay`](https://material.angular.io/cdk/overlay/api#CdkConnectedOverlay) 5. Open the `` once the trigger is attached using [`MatMenuTrigger.openMenu`](https://material.angular.io/components/menu/api#MatMenuTrigger:~:text=FocusOptions-,openMenu,-Opens%20the%20menu) Once you have followed above steps, you can easily open the Material menu on right click. Try it out your-self in below demo: You can also control in which area user clicks, and perform various actions. For example, play around with below sample google drive like card. Observe that it only opens up the menu when you right click anywhere inside the card, and when the context-menu is opened, it adds a highlighting style to the card. ## Text popover The next feature we are going to look at, is text popover. It is a popover which should be visible once use selects the text. For example, you would have seen text popover when you select any text in Medium. ![embedded video](/assets/angular-material.dev/Exploring%20Angular%20CDK_%20Creating%20Context%20Menu%20Text%20Popover/medium_text_popover_demo_ecxgri.mp4=x300) We want to create such popovers using the `overlay` package. We can follow below approach: 1. Create a desired popover layout and content 2. Figure out a way to identify when user selects any text 3. Find out a suitable position, preferably center of the selected text's [`DOMRect`](https://developer.mozilla.org/en-US/docs/Web/API/DOMRect) 4. Create a [`cdkOverlayOrigin`](https://material.angular.io/cdk/overlay/api#CdkOverlayOrigin) at that position 5. Attach popover dynamically with above origin, using [`cdkConnectedOverlay`](https://material.angular.io/cdk/overlay/api#CdkConnectedOverlay) As a result after all those steps, you can easily create a popover like below. Once you have the core logic, you can create any type of popover, for example with a [``](https://material.angular.io/components/button-toggle/overview) like below: Or, even a medium like popover: ## Demos and Codes The demos are available at below links: | Index | Angular/Angular Material version | Demo Link | | ----- | -------------------------------- | ----------------------------------------------------------------------- | | 1 | 17 | [Link](https://ng-17--tubular-sunshine-acc5c7.netlify.app/context-menu) | | 2 | 18 | [Link](https://tubular-sunshine-acc5c7.netlify.app/) | The code is available for a nominal price on our [storefront on lemonsqueezy](https://angular-material-dev.lemonsqueezy.com/).
Dharmen Shah
Written by Dharmen Shah

I have around 8+ years of experience in IT industry. I have got opportunity to work at different companies with different technologies, mostly focused on Front-end, like Angular, React, Next, vanilla web stack (HTML, CSS, JavaScript).

You can find me on Twitter, Linkedin and Github.

Discuss online

Share this article

Read more

View all articles

Learn more

View courses page

Envelop
Don't miss any update

Stay up to date

Subscribe to the newsletter to stay up to date with articles, courses and much more!

Angular Material Dev

Angular Material Dev is one place stop for developers to learn about integrating Material Design in Angular applications like a pro.

Find us on X (Twitter) and LinkedIn