refactor(drag-drop): convert cdk-drop into a directive (#13441)

Converts `cdk-drop` into a directive and moves the handful of structural styles into JS.

Fixes #13341.
This commit is contained in:
Kristiyan Kostadinov
2018-10-09 01:59:44 +03:00
committed by vivian-hu
parent 4b15b78a44
commit f3555f164e
16 changed files with 201 additions and 151 deletions
-6
View File
@@ -8,7 +8,6 @@ ng_module(
name = "drag-drop",
srcs = glob(["**/*.ts"], exclude=["**/*.spec.ts"]),
module_name = "@angular/cdk/drag-drop",
assets = [":drop.css"],
deps = [
"@rxjs",
"//src/cdk/platform",
@@ -32,11 +31,6 @@ ts_library(
tsconfig = "//src/cdk:tsconfig-build.json",
)
sass_binary(
name = "drop_scss",
src = "drop.scss",
)
ts_web_test(
name = "unit_tests",
bootstrap = [
+3 -13
View File
@@ -155,25 +155,15 @@ describe('DragDropRegistry', () => {
expect(dispatchTouchEvent(document, 'touchmove').defaultPrevented).toBe(true);
});
it('should disable the native interactions on the body while dragging', () => {
const firstItem = testComponent.dragItems.first;
registry.startDragging(firstItem, createMouseEvent('mousedown'));
expect(document.body.classList).toContain('cdk-drag-drop-disable-native-interactions');
registry.stopDragging(firstItem);
expect(document.body.classList).not.toContain('cdk-drag-drop-disable-native-interactions');
});
});
@Component({
template: `
<cdk-drop id="items" [data]="items">
<div cdkDrop id="items" [cdkDropData]="items">
<div *ngFor="let item of items" cdkDrag>{{item}}</div>
</cdk-drop>
</div>
<cdk-drop id="items" *ngIf="showDuplicateContainer"></cdk-drop>
<div cdkDrop id="items" *ngIf="showDuplicateContainer"></div>
`
})
class SimpleDropZone {
+3 -2
View File
@@ -10,6 +10,7 @@ import {Injectable, NgZone, OnDestroy, Inject} from '@angular/core';
import {DOCUMENT} from '@angular/common';
import {supportsPassiveEventListeners} from '@angular/cdk/platform';
import {Subject} from 'rxjs';
import {toggleNativeDragInteractions} from './drag-styling';
/** Event options that can be used to bind an active event. */
const activeEventOptions = supportsPassiveEventListeners() ? {passive: false} : false;
@@ -118,7 +119,7 @@ export class DragDropRegistry<I, C extends {id: string}> implements OnDestroy {
// We need to disable the native interactions on the entire body, because
// the user can start marking text if they drag too far in Safari.
this._document.body.classList.add('cdk-drag-drop-disable-native-interactions');
toggleNativeDragInteractions(this._document.body, false);
// We explicitly bind __active__ listeners here, because newer browsers will default to
// passive ones for `mousemove` and `touchmove`. The events need to be active, because we
@@ -140,7 +141,7 @@ export class DragDropRegistry<I, C extends {id: string}> implements OnDestroy {
if (this._activeDragInstances.size === 0) {
this._clearGlobalListeners();
this._document.body.classList.remove('cdk-drag-drop-disable-native-interactions');
toggleNativeDragInteractions(this._document.body, true);
}
}
+23 -23
View File
@@ -6,62 +6,62 @@ in addition to horizontal lists and locking along an axis.
### Getting started
Start by importing `DragDropModule` into the `NgModule` where you want to use drag-and-drop
features. You can now add the `cdkDrag` directive to elements to make them draggable. When
outside of a `<cdk-drop>` element, draggable elements can be freely moved around the page.
You can add `<cdk-drop>` elements to constrain where elements may be dropped.
outside of a `cdkDrop` element, draggable elements can be freely moved around the page.
You can add `cdkDrop` elements to constrain where elements may be dropped.
<!-- example(cdk-drag-drop-overview) -->
### Reordering lists
Adding `<cdk-drop>` around a set of `cdkDrag` elements groups the draggables into a
Adding `cdkDrop` around a set of `cdkDrag` elements groups the draggables into a
reorderable collection. Items will automatically rearrange as an element moves. Note
that this will *not* update your data model; you can listen to the `dropped` event to
that this will *not* update your data model; you can listen to the `cdkDropDropped` event to
update the data model once the user finishes dragging.
<!-- example(cdk-drag-drop-sorting) -->
### Transferring items between lists
The `<cdk-drop>` component supports transferring dragged items between connected drop zones.
You can connect one or more `<cdk-drop>` instances together by setting the `connectedTo`
The `cdkDrop` directive supports transferring dragged items between connected drop zones.
You can connect one or more `cdkDrop` instances together by setting the `cdkDropConnectedTo`
property.
<!-- example(cdk-drag-drop-connected-sorting) -->
Note that `connectedTo` works both with a direct reference to another `<cdk-drop>`, or by
Note that `cdkDropConnectedTo` works both with a direct reference to another `cdkDrop`, or by
referencing the `id` of another drop container:
```html
<!-- This is valid -->
<cdk-drop #listOne [connectedTo]="[listTwo]"></cdk-drop>
<cdk-drop #listTwo [connectedTo]="[listOne]"></cdk-drop>
<div cdkDrop #listOne="cdkDrop" [cdkDropConnectedTo]="[listTwo]"></div>
<div cdkDrop #listTwo="cdkDrop" [cdkDropConnectedTo]="[listOne]"></div>
<!-- This is valid as well -->
<cdk-drop id="list-one" [connectedTo]="['list-two']"></cdk-drop>
<cdk-drop id="list-two" [connectedTo]="['list-one']"></cdk-drop>
<div cdkDrop id="list-one" [cdkDropConnectedTo]="['list-two']"></div>
<div cdkDrop id="list-two" [cdkDropConnectedTo]="['list-one']"></div>
```
### Attaching data
You can associate some arbitrary data with both `cdkDrag` and `<cdk-drop>` by setting
`cdkDragData` or `data`, respectively. Events fired from both directives include this data,
allowing you to easily identify the origin of the drag or drop interaction.
You can associate some arbitrary data with both `cdkDrag` and `cdkDrop` by setting `cdkDragData`
or `cdkDropData`, respectively. Events fired from both directives include this data, allowing
you to easily identify the origin of the drag or drop interaction.
```html
<cdk-drop [data]="list" *ngFor="let list of lists" (dropped)="drop($event)">
<div cdkDrop [cdkDropData]="list" *ngFor="let list of lists" (cdkDropDropped)="drop($event)">
<div cdkDrag [cdkDragData]="item" *ngFor="let item of list"></div>
</cdk-drop>
</div>
```
### Styling
The `cdkDrag` and `<cdk-drop>` directive include only those styles strictly necessary for
The `cdkDrag` and `cdkDrop` directive include only those styles strictly necessary for
functionality. The application can then customize the elements by styling CSS classes added
by the directives:
| Selector | Description |
|---------------------|--------------------------------------------------------------------------|
| `.cdk-drop` | Corresponds to the `<cdk-drop>` container. |
| `.cdk-drop` | Corresponds to the `cdkDrop` container. |
| `.cdk-drag` | Corresponds to a `cdkDrag` instance. |
| `.cdk-drag-preview` | This is the element that will be rendered next to the user's cursor as they're dragging an item in a sortable list. By default the element looks exactly like the element that is being dragged. |
| `.cdk-drag-placeholder` | This is element that will be shown instead of the real element as it's being dragged inside a `<cdk-drop>`. By default this will look exactly like the element that is being sorted. |
| `.cdk-drop-dragging` | A class that is added to `<cdk-drop>` while the user is dragging an item. |
| `.cdk-drag-placeholder` | This is element that will be shown instead of the real element as it's being dragged inside a `cdkDrop`. By default this will look exactly like the element that is being sorted. |
| `.cdk-drop-dragging` | A class that is added to `cdkDrop` while the user is dragging an item. |
### Animations
The drag-and-drop module supports animations both while sorting an element inside a list, as well as
@@ -73,7 +73,7 @@ following classes can be used for animations:
through a list.
* `.cdk-drag-animating` - This class is added to a `cdkDrag` when the user has stopped dragging.
If you add a `transition` to it, the CDK will animate the element from its drop position to
the final position inside the `<cdk-drop>` container.
the final position inside the `cdkDrop` container.
Example animations:
@@ -105,14 +105,14 @@ This preview can be customized, though, by providing a custom template via `*cdk
<!-- example(cdk-drag-drop-custom-preview) -->
### List orientation
The `cdk-drop` component assumes that lists are vertical by default. This can be
The `cdkDrop` directive assumes that lists are vertical by default. This can be
changed by setting the `orientation` property to `"horizontal".
<!-- example(cdk-drag-drop-horizontal-sorting) -->
### Restricting movement along an axis
By default, `cdkDrag` allows free movement in all directions. To restrict dragging to a
specific axis, you can set `cdkDragLockAxis` on `cdkDrag` or `lockAxis` on `<cdk-drop>`
specific axis, you can set `cdkDragLockAxis` on `cdkDrag` or `lockAxis` on `cdkDrop`
to either `"x"` or `"y"`.
<!-- example(cdk-drag-drop-axis-lock) -->
+4 -1
View File
@@ -7,6 +7,7 @@
*/
import {Directive, ElementRef} from '@angular/core';
import {toggleNativeDragInteractions} from './drag-styling';
/** Handle that can be used to drag and CdkDrag instance. */
@Directive({
@@ -16,5 +17,7 @@ import {Directive, ElementRef} from '@angular/core';
}
})
export class CdkDragHandle {
constructor(public element: ElementRef<HTMLElement>) {}
constructor(public element: ElementRef<HTMLElement>) {
toggleNativeDragInteractions(element.nativeElement, false);
}
}
+51
View File
@@ -0,0 +1,51 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* Extended CSSStyleDeclaration that includes a couple of drag-related
* properties that aren't in the built-in TS typings.
*/
interface DragCSSStyleDeclaration extends CSSStyleDeclaration {
webkitUserDrag: string;
MozUserSelect: string; // For some reason the Firefox property is in PascalCase.
}
/**
* Shallow-extends a stylesheet object with another stylesheet object.
* @docs-private
*/
export function extendStyles(dest: CSSStyleDeclaration, source: Partial<DragCSSStyleDeclaration>) {
for (let key in source) {
if (source.hasOwnProperty(key)) {
dest[key!] = source[key];
}
}
return dest;
}
/**
* Toggles whether the native drag interactions should be enabled for an element.
* @param element Element on which to toggle the drag interactions.
* @param enable Whether the drag interactions should be enabled.
* @docs-private
*/
export function toggleNativeDragInteractions(element: HTMLElement, enable: boolean) {
const userSelect = enable ? '' : 'none';
extendStyles(element.style, {
touchAction: enable ? '' : 'none',
webkitUserDrag: enable ? '' : 'none',
webkitTapHighlightColor: enable ? '' : 'transparent',
userSelect: userSelect,
msUserSelect: userSelect,
webkitUserSelect: userSelect,
MozUserSelect: userSelect
});
}
+42 -30
View File
@@ -1726,17 +1726,18 @@ class StandaloneDraggableWithMultipleHandles {
@Component({
template: `
<cdk-drop
style="display: block; width: 100px; background: pink;"
<div
cdkDrop
style="width: 100px; background: pink;"
[id]="dropZoneId"
[data]="items"
(dropped)="droppedSpy($event)">
[cdkDropData]="items"
(cdkDropDropped)="droppedSpy($event)">
<div
*ngFor="let item of items"
cdkDrag
[cdkDragData]="item"
style="width: 100%; height: ${ITEM_HEIGHT}px; background: red;">{{item}}</div>
</cdk-drop>
</div>
`
})
class DraggableInDropZone {
@@ -1770,12 +1771,13 @@ class DraggableInDropZone {
}
`],
template: `
<cdk-drop
orientation="horizontal"
[data]="items"
(dropped)="droppedSpy($event)">
<div
cdkDrop
cdkDropOrientation="horizontal"
[cdkDropData]="items"
(cdkDropDropped)="droppedSpy($event)">
<div *ngFor="let item of items" cdkDrag>{{item}}</div>
</cdk-drop>
</div>
`
})
class DraggableInHorizontalDropZone {
@@ -1789,13 +1791,13 @@ class DraggableInHorizontalDropZone {
@Component({
template: `
<cdk-drop style="display: block; width: 100px; background: pink;">
<div cdkDrop style="width: 100px; background: pink;">
<div *ngFor="let item of items" cdkDrag
style="width: 100%; height: ${ITEM_HEIGHT}px; background: red;">
{{item}}
<div class="custom-preview" *cdkDragPreview>Custom preview</div>
</div>
</cdk-drop>
</div>
`
})
class DraggableInDropZoneWithCustomPreview {
@@ -1807,13 +1809,13 @@ class DraggableInDropZoneWithCustomPreview {
@Component({
template: `
<cdk-drop style="display: block; width: 100px; background: pink;">
<div cdkDrop style="width: 100px; background: pink;">
<div *ngFor="let item of items" cdkDrag
style="width: 100%; height: ${ITEM_HEIGHT}px; background: red;">
{{item}}
<div class="custom-placeholder" *cdkDragPlaceholder>Custom placeholder</div>
</div>
</cdk-drop>
</div>
`
})
class DraggableInDropZoneWithCustomPlaceholder {
@@ -1839,21 +1841,23 @@ class DraggableInDropZoneWithCustomPlaceholder {
}
`],
template: `
<cdk-drop
#todoZone
[data]="todo"
[connectedTo]="[doneZone]"
(dropped)="droppedSpy($event)">
<div
cdkDrop
#todoZone="cdkDrop"
[cdkDropData]="todo"
[cdkDropConnectedTo]="[doneZone]"
(cdkDropDropped)="droppedSpy($event)">
<div [cdkDragData]="item" *ngFor="let item of todo" cdkDrag>{{item}}</div>
</cdk-drop>
</div>
<cdk-drop
#doneZone
[data]="done"
[connectedTo]="[todoZone]"
(dropped)="droppedSpy($event)">
<div
cdkDrop
#doneZone="cdkDrop"
[cdkDropData]="done"
[cdkDropConnectedTo]="[todoZone]"
(cdkDropDropped)="droppedSpy($event)">
<div [cdkDragData]="item" *ngFor="let item of done" cdkDrag>{{item}}</div>
</cdk-drop>
</div>
`
})
class ConnectedDropZones implements AfterViewInit {
@@ -1912,13 +1916,21 @@ class DraggableWithAlternateRoot {
}
`],
template: `
<cdk-drop #todoZone [connectedTo]="[doneZone]" (dropped)="droppedSpy($event)">
<div
cdkDrop
#todoZone="cdkDrop"
[cdkDropConnectedTo]="[doneZone]"
(cdkDropDropped)="droppedSpy($event)">
<div cdkDrag>One</div>
</cdk-drop>
</div>
<cdk-drop #doneZone [connectedTo]="[todoZone]" (dropped)="droppedSpy($event)">
<div
cdkDrop
#doneZone="cdkDrop"
[cdkDropConnectedTo]="[todoZone]"
(cdkDropDropped)="droppedSpy($event)">
<div cdkDrag>Two</div>
</cdk-drop>
</div>
`
})
class ConnectedDropZonesWithSingleItems {
+9
View File
@@ -44,6 +44,7 @@ import {CdkDragPlaceholder} from './drag-placeholder';
import {CdkDragPreview} from './drag-preview';
import {CDK_DROP_CONTAINER, CdkDropContainer} from './drop-container';
import {getTransformTransitionDurationInMs} from './transition-duration';
import {extendStyles, toggleNativeDragInteractions} from './drag-styling';
// TODO(crisbeto): add auto-scrolling functionality.
@@ -255,6 +256,7 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
const rootElement = this._rootElement = this._getRootElement();
rootElement.addEventListener('mousedown', this._pointerDown);
rootElement.addEventListener('touchstart', this._pointerDown);
toggleNativeDragInteractions(rootElement , false);
});
}
@@ -526,6 +528,13 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
this._setTransform(preview, elementRect.left, elementRect.top);
}
extendStyles(preview.style, {
position: 'fixed',
top: '0',
left: '0',
zIndex: '1000'
});
preview.classList.add('cdk-drag-preview');
preview.setAttribute('dir', this._dir ? this._dir.value : 'ltr');
-24
View File
@@ -1,24 +0,0 @@
$cdk-z-index-drag-preview: 1000;
.cdk-drag-preview {
position: fixed;
top: 0;
left: 0;
z-index: $cdk-z-index-drag-preview;
}
.cdk-drag,
.cdk-drag-handle,
.cdk-drag-drop-disable-native-interactions {
touch-action: none;
-webkit-user-drag: none;
-webkit-tap-highlight-color: transparent;
// stylelint-disable material/no-prefixes
// normally we have a mixin for these, but it's in material/core.
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
// stylelint-enable material/no-prefixes
}
+15 -18
View File
@@ -8,8 +8,6 @@
import {coerceArray} from '@angular/cdk/coercion';
import {
ChangeDetectionStrategy,
Component,
ContentChildren,
ElementRef,
EventEmitter,
@@ -19,8 +17,8 @@ import {
OnInit,
Output,
QueryList,
ViewEncapsulation,
Optional,
Directive,
} from '@angular/core';
import {Directionality} from '@angular/cdk/bidi';
import {CdkDrag} from './drag';
@@ -40,14 +38,9 @@ let _uniqueIdCounter = 0;
const DROP_PROXIMITY_THRESHOLD = 0.05;
/** Container that wraps a set of draggable items. */
@Component({
moduleId: module.id,
selector: 'cdk-drop',
@Directive({
selector: '[cdkDrop], cdk-drop',
exportAs: 'cdkDrop',
template: '<ng-content></ng-content>',
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
styleUrls: ['drop.css'],
providers: [
{provide: CDK_DROP_CONTAINER, useExisting: CdkDrop},
],
@@ -66,13 +59,13 @@ export class CdkDrop<T = any> implements OnInit, OnDestroy {
* container's items can be transferred. Can either be references to other drop containers,
* or their unique IDs.
*/
@Input() connectedTo: (CdkDrop | string)[] | CdkDrop | string = [];
@Input('cdkDropConnectedTo') connectedTo: (CdkDrop | string)[] | CdkDrop | string = [];
/** Arbitrary data to attach to this container. */
@Input() data: T;
@Input('cdkDropData') data: T;
/** Direction in which the list is oriented. */
@Input() orientation: 'horizontal' | 'vertical' = 'vertical';
@Input('cdkDropOrientation') orientation: 'horizontal' | 'vertical' = 'vertical';
/**
* Unique ID for the drop zone. Can be used as a reference
@@ -81,27 +74,31 @@ export class CdkDrop<T = any> implements OnInit, OnDestroy {
@Input() id: string = `cdk-drop-${_uniqueIdCounter++}`;
/** Locks the position of the draggable elements inside the container along the specified axis. */
@Input() lockAxis: 'x' | 'y';
@Input('cdkDropLockAxis') lockAxis: 'x' | 'y';
/**
* Function that is used to determine whether an item
* is allowed to be moved into a drop container.
*/
@Input() enterPredicate: (drag?: CdkDrag, drop?: CdkDrop) => boolean = () => true;
@Input('cdkDropEnterPredication')
enterPredicate: (drag?: CdkDrag, drop?: CdkDrop) => boolean = () => true
/** Emits when the user drops an item inside the container. */
@Output() dropped: EventEmitter<CdkDragDrop<T, any>> = new EventEmitter<CdkDragDrop<T, any>>();
@Output('cdkDropDropped')
dropped: EventEmitter<CdkDragDrop<T, any>> = new EventEmitter<CdkDragDrop<T, any>>();
/**
* Emits when the user has moved a new drag item into this container.
*/
@Output() entered: EventEmitter<CdkDragEnter<T>> = new EventEmitter<CdkDragEnter<T>>();
@Output('cdkDropEntered')
entered: EventEmitter<CdkDragEnter<T>> = new EventEmitter<CdkDragEnter<T>>();
/**
* Emits when the user removes an item from the container
* by dragging it into another container.
*/
@Output() exited: EventEmitter<CdkDragExit<T>> = new EventEmitter<CdkDragExit<T>>();
@Output('cdkDropExited')
exited: EventEmitter<CdkDragExit<T>> = new EventEmitter<CdkDragExit<T>>();
constructor(
public element: ElementRef<HTMLElement>,
@@ -1,15 +1,17 @@
<div class="container">
<h2>To do</h2>
<cdk-drop #todoList [data]="todo" [connectedTo]="doneList" class="list" (dropped)="drop($event)">
<div cdkDrop #todoList="cdkDrop" [cdkDropData]="todo" [cdkDropConnectedTo]="doneList" class="list"
(cdkDropDropped)="drop($event)">
<div class="list-item" *ngFor="let item of todo" cdkDrag>{{item}}</div>
</cdk-drop>
</div>
</div>
<div class="container">
<h2>Done</h2>
<cdk-drop #doneList [data]="done" [connectedTo]="todoList" class="list" (dropped)="drop($event)">
<div cdkDrop #doneList="cdkDrop" [cdkDropData]="done" [cdkDropConnectedTo]="todoList" class="list"
(cdkDropDropped)="drop($event)">
<div class="list-item" *ngFor="let item of done" cdkDrag>{{item}}</div>
</cdk-drop>
</div>
</div>
+23 -20
View File
@@ -1,48 +1,51 @@
<div>
<div class="list">
<h2>To do</h2>
<cdk-drop
#one
(dropped)="drop($event)"
[lockAxis]="axisLock"
[data]="todo"
[connectedTo]="[two]">
<div
cdkDrop
#one="cdkDrop"
(cdkDropDropped)="drop($event)"
[cdkDropLockAxis]="axisLock"
[cdkDropData]="todo"
[cdkDropConnectedTo]="[two]">
<div *ngFor="let item of todo" cdkDrag>
{{item}}
<mat-icon cdkDragHandle svgIcon="dnd-move"></mat-icon>
</div>
</cdk-drop>
</div>
</div>
<div class="list">
<h2>Done</h2>
<cdk-drop
#two
(dropped)="drop($event)"
[lockAxis]="axisLock"
[data]="done"
[connectedTo]="[one]">
<div
cdkDrop
#two="cdkDrop"
(cdkDropDropped)="drop($event)"
[cdkDropLockAxis]="axisLock"
[cdkDropData]="done"
[cdkDropConnectedTo]="[one]">
<div *ngFor="let item of done" cdkDrag>
{{item}}
<mat-icon cdkDragHandle svgIcon="dnd-move"></mat-icon>
</div>
</cdk-drop>
</div>
</div>
</div>
<div>
<div class="list horizontal">
<h2>Horizontal list</h2>
<cdk-drop
orientation="horizontal"
(dropped)="drop($event)"
[lockAxis]="axisLock"
[data]="horizontalData">
<div
cdkDrop
cdkDropOrientation="horizontal"
(cdkDropDropped)="drop($event)"
[cdkDropLockAxis]="axisLock"
[cdkDropData]="horizontalData">
<div *ngFor="let item of horizontalData" cdkDrag>
{{item}}
<mat-icon cdkDragHandle svgIcon="dnd-move"></mat-icon>
</div>
</cdk-drop>
</div>
</div>
</div>
@@ -1,16 +1,28 @@
<div class="container">
<h2>To do</h2>
<cdk-drop #todoList [data]="todo" [connectedTo]="[doneList]" class="list" (dropped)="drop($event)">
<div
cdkDrop
#todoList="cdkDrop"
[cdkDropData]="todo"
[cdkDropConnectedTo]="[doneList]"
class="list"
(cdkDropDropped)="drop($event)">
<div class="box" *ngFor="let item of todo" cdkDrag>{{item}}</div>
</cdk-drop>
</div>
</div>
<div class="container">
<h2>Done</h2>
<cdk-drop #doneList [data]="done" [connectedTo]="[todoList]" class="list" (dropped)="drop($event)">
<div
cdkDrop
#doneList="cdkDrop"
[cdkDropData]="done"
[cdkDropConnectedTo]="[todoList]"
class="list"
(cdkDropDropped)="drop($event)">
<div class="box" *ngFor="let item of done" cdkDrag>{{item}}</div>
</cdk-drop>
</div>
</div>
@@ -1,6 +1,6 @@
<cdk-drop class="list" (dropped)="drop($event)">
<div cdkDrop class="list" (cdkDropDropped)="drop($event)">
<div class="box" *ngFor="let movie of movies" cdkDrag>
{{movie.title}}
<img *cdkDragPreview [src]="movie.poster" [alt]="movie.title">
</div>
</cdk-drop>
</div>
@@ -1,3 +1,3 @@
<cdk-drop orientation="horizontal" class="list" (dropped)="drop($event)">
<div cdkDrop cdkDropOrientation="horizontal" class="list" (cdkDropDropped)="drop($event)">
<div class="box" *ngFor="let timePeriod of timePeriods" cdkDrag>{{timePeriod}}</div>
</cdk-drop>
</div>
@@ -1,3 +1,3 @@
<cdk-drop class="list" (dropped)="drop($event)">
<div cdkDrop class="list" (cdkDropDropped)="drop($event)">
<div class="box" *ngFor="let movie of movies" cdkDrag>{{movie}}</div>
</cdk-drop>
</div>