Skip to content

Modus-Logo-Long-BlackCreated with Sketch.

  • Services
  • Work
  • Blog
  • Resources

    OUR RESOURCES

    Innovation Podcast

    Explore transformative innovation with industry leaders.

    Guides & Playbooks

    Implement leading digital innovation with our strategic guides.

    Practical guide to building an effective AI strategy
  • Who we are

    Our story

    Learn about our values, vision, and commitment to client success.

    Open Source

    Discover how we contribute to and benefit from the global open source ecosystem.

    Careers

    Join our dynamic team and shape the future of digital transformation.

    How we built our unique culture
  • Let's talk
  • EN
  • FR

Angular CDK brings Drag & Drop in Beta 7

Published on September 7, 2018
Last Updated on April 8, 2021
Application Development

In this article we’ll go through one of the most anticipated features that all Angular developers have been waiting for  – Drag & Drop.


NEW RESEARCH: LEARN HOW DECISION-MAKERS ARE PRIORITIZING DIGITAL INITIATIVES IN 2024.

Get Report


We’ll go through some example use cases of the feature with the API that the Angular Component Developer Kit (CDK) exposes. To begin, add or update the @angular/cdk package in your project.

npm install @angular/cdk@7.0.0-beta.0
OR
yarn add @angular/cdk@7.0.0-beta.0

Then include the package in your app.module.ts

import { DragDropModule } from '@angular/cdk/drag-drop';
@NgModule({
 imports: [BrowserModule, FormsModule, DragDropModule],
 declarations: [AppComponent],
 bootstrap: [AppComponent]
})
export class AppModule { }

Basic Drag & Drop

To make an element draggable, all you have to do is to add the cdkDrag directive on the element. And boom!

cdkDrag example
cdkDrag example

If we just apply cdkDrag to an element and move it around, the element is free to be dropped anywhere on the screen. However, in real apps, you may want to have some specific drop-zones where the element(s) would be dropped.

You can createcdk-drop elements that will tell the CDK that the draggable item is only allowed to drop inside this drop-zone. See the below example.

<cdk-drop> example
example
You can see that the element isn’t droppable outside of the cdk-drop element. You may also notice that while the element is being dragged, the original element still stays in its original position. This looks a bit clumsy and not what we usually see when we drag drop elements in everyday apps. We’re going to use some of the the classes that the Angular CDK provides to make this a little better. Hold your horses.

First off, we will make sure that when we drag the element, the placeholder (at the original position of the element) gets hidden so we only see the drag-preview. To do that, we’ll give the following styles in our styles.css file:

.cdk-drag-placeholder {
  opacity: 0;
}

.cdk-drag-placeholder style example
.cdk-drag-placeholder style example

You can see that now when we’re dragging the element, there’s no placeholder present at the original position.

There’s still room for improvement because:

  • The drag preview looks larger than the original element which is weird.
  • When we leave the dragged element, the dragged elements quickly hides in a snap and the original element shows. There’s no transition involved.

To solve issue 1, we’ll be adding the following css to our component:

.cdk-drag-preview {
   box-sizing: border-box;
   box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2),
               0 8px 10px 1px rgba(0, 0, 0, 0.14),
               0 3px 14px 2px rgba(0, 0, 0, 0.12);
}

The box-sizing: border-box; does the trick and keeps the size of the preview same as the original element. The box-shadow is just added sugar.

.cdk-drag-preview style example
.cdk-drag-preview style example

For issue 2, we’ll add a transition to the dragged element using the following css:

.cdk-drag-animating {
  transition: transform 450ms cubic-bezier(0, 0, 0.2, 1);
}

.cdk-drag-animating style example
.cdk-drag-animating style example

Items Reordering

One common use-case of Drag & Drop is sorting or reordering lists. Angular CDK provides a clean way of doing this. Just apply cdkDrag directive to the list items and enclose the list within the cdk-drop element and that’s it.

See the below example:

 

{{user.name.first}} {{user.name.last}}

 

{{user.email}}

 

 

 

Notice we have a drop zone enclosing all the draggable elements. Each element has the cdkDrag attribute which makes it draggable and the elements automatically move their position for the dragged element to be dropped at a desired position. See the preview below:

items reorder preview
items reorder preview

One important thing to note while implementing Drag & Drop with complex elements like in the above preview (having display: flex and a bunch of nested elements), is that the dragged preview may look weird. That is because Angular CDK currently does not copy the styles of the dragged elements. Instead it clones the markup of the dragged element. So to make sure that your dragged preview looks normal, do style the drag preview (.cdk-drag-preview) as well. You can see how we have handled this issue in this file:

.items-container .item,
.cdk-drag-preview {
  display: flex;
  align-items: center;
  border: 1px solid #eee;
  padding: 8px 10px;
}
.items-container .item .item-image,
.cdk-drag-preview .item-image {
  margin-right: 16px;
}
.items-container .item .item-content p,
.cdk-drag-preview .item-content p {
  font-size: 12px;
}
.items-container .item .item-content .item-content-primary,
.cdk-drag-preview .item-content .item-content-primary {
  font-size: 14px;
}
.items-container .item .item-content .item-content-primary,
.items-container .item .item-content p,
.cdk-drag-preview .item-content .item-content-primary,
.cdk-drag-preview .item-content p {
  margin: 0;
}

Applying the same styles as the list item to the .cdk-drag-preview element as shown above, we made sure that the preview looks exactly like the item.

You may have noticed that after dropping the item, the list remains unchanged. That is because Angular CDK just drops the item and the list (data array) remains unchanged until you handle the drop event and use Angular CDK’s moveItemInArray method to update the list array.

So first, in the template:


Then in the component file:

import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
...
drop($event: CdkDragDrop) {
 moveItemInArray(
   this.users,
   $event.previousIndex,
   $event.currentIndex
 );
}

The example above for sorting uses a vertical list.
The example above for sorting uses a vertical list. However, if you had a horizontal list, the cdk-drop element will still assume that the list is vertical by default. You can change this by setting the orientation property of the cdk-drop element to horizontal.

Locking the drag axis

You can also lock the axis of the drag movement to either horizontal or vertical. To do so, just add cdkDragLockAxis="y" or cdkDragLockAxis="x" to the cdkDrag element.

Locking drag axis example
Locking drag axis example

Dragging using a cdkDragHandle

You can specify a custom area within the draggable element as a drag-handle by adding the cdkDragHandle attribute to the handle element. The whole draggable element will now be dragged only using this drag-handle.

+

 

You can specify a custom area within the draggable element as a drag-handle

Transferring items between drop-zones

If you had two sets of data and wanted to be able to drag an item from one set/list to another, you can do that by connecting the drop-zones (cdk-drop elements) using connectedTo attribute. The value of this attribute can be either a template variable or the id of the cdk-drop element to connect to.
See an example in the below template:

  ...


  ...

Notice that the first cdk-drop is connected to zone2 which is a template variable of the second cdk-drop element and vice versa.

The drop method for this scenario will be a bit different in our component class as it handles both cases when the item is dropped within the same zone, and when the item is dropped in the other zone. See the implementation in this file:

drop($event: CdkDragDrop) {
 if ($event.previousContainer === $event.container) {
   moveItemInArray(
     $event.container.data,
     $event.previousIndex,
     $event.currentIndex
   );
 } else {
   transferArrayItem(
     $event.previousContainer.data,
     $event.container.data,
     $event.previousIndex,
     $event.currentIndex
   );
 }
}

connectedTo example for transferring items between drop zones
connectedTo example for transferring items between drop zones

That is not it

This feature is still a work in progress and I have only focused on some of the main sub-features and use cases of the Drag & Drop. However, there is a lot more in the docs. Feel free to give Drag & Drop a try and let me know what you build using this amazing new feature in the comments. All of the examples and their code can be seen here.

Posted in Application Development
Share this

Ahsan Ayaz

Ahsan Ayaz is a Google Developer Expert in Angular. During his time at Modus, Ahsan worked as a Software Architect. Apart from building web and hybird-mobile apps based on Angular, Ionic & MEAN Stack, Ahsan contributes to open-source projects, speaks at events, writes articles and makes video tutorials.
Follow

Related Posts

  • How to Add Keyboard Navigation to Angular Lists
    How to Add Keyboard Navigation to Angular Lists

    Originally published on NG-Conf Programming is fun, especially when you love the technology you’re working…

  • Ext JS to React: Drag and Drop
    Ext JS to React: Drag and Drop

    This is part of the Ext JS to React blog series. You can review the…

Want more insights to fuel your innovation efforts?

Sign up to receive our monthly newsletter and exclusive content about digital transformation and product development.

What we do

Our services
AI and data
Product development
Design and UX
IT modernization
Platform and MLOps
Developer experience
Security

Our partners
Atlassian
AWS
GitHub
Other partners

Who we are

Our story
Careers
Open source

Our work

Our case studies

Our resources

Blog
Innovation podcast
Guides & playbooks

Connect with us

Get monthly insights on AI adoption

© 2025 Modus Create, LLC

Privacy PolicySitemap
Scroll To Top
  • Services
  • Work
  • Blog
  • Resources
    • Innovation Podcast
    • Guides & Playbooks
  • Who we are
    • Our story
    • Careers
  • Let’s talk
  • EN
  • FR