Skip to content

Commit 4a40f9a

Browse files
committed
feat: add experimental drag-drop package
Adds an initial version of the `drag-drop` module to `cdk-experimental` with support for the following: * Dragging an element on its own. * Dragging an element using a handle. * Sorting an element within a drop zone. * Moving an element between drop zones. * Touch and mouse support. * Custom template for the preview element. * Custom template for the placeholder element. * Animation support for the preview. Demo: https://material-cb7ec.firebaseapp.com/drag-drop Relates to #8963.
1 parent c276e26 commit 4a40f9a

32 files changed

+1839
-3
lines changed

.github/CODEOWNERS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
/src/cdk-experimental/** @jelbourn
8888
/src/cdk-experimental/dialog/** @jelbourn @josephperrott @crisbeto
8989
/src/cdk-experimental/scrolling/** @mmalerba
90+
/src/cdk-experimental/drag-drop/** @crisbeto
9091

9192
# Docs examples & guides
9293
/guides/** @amcdnl @jelbourn
@@ -110,6 +111,7 @@
110111
/src/demo-app/demo-app/** @jelbourn
111112
/src/demo-app/dialog/** @jelbourn @crisbeto
112113
/src/demo-app/drawer/** @mmalerba
114+
/src/demo-app/drag-drop/** @crisbeto
113115
/src/demo-app/example/** @andrewseguin
114116
/src/demo-app/examples-page/** @andrewseguin
115117
/src/demo-app/expansion/** @josephperrott

packages.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ CDK_TARGETS = ["//src/cdk"] + ["//src/cdk/%s" % p for p in CDK_PACKAGES]
2424
CDK_EXPERIMENTAL_PACKAGES = [
2525
"dialog",
2626
"scrolling",
27+
"drag-drop",
2728
]
2829

2930
CDK_EXPERIMENTAL_TARGETS = ["//src/cdk-experimental"] + [
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package(default_visibility=["//visibility:public"])
2+
load("@angular//:index.bzl", "ng_module")
3+
load("@build_bazel_rules_typescript//:defs.bzl", "ts_library", "ts_web_test")
4+
load("@io_bazel_rules_sass//sass:sass.bzl", "sass_binary")
5+
6+
7+
ng_module(
8+
name = "drag-drop",
9+
srcs = glob(["**/*.ts"], exclude=["**/*.spec.ts"]),
10+
module_name = "@angular/cdk-experimental/drag-drop",
11+
assets = [":drop.css"],
12+
deps = [
13+
"@rxjs",
14+
"//src/cdk/platform",
15+
],
16+
tsconfig = "//src/cdk-experimental:tsconfig-build.json",
17+
)
18+
19+
20+
ts_library(
21+
name = "drag_and_drop_test_sources",
22+
testonly = 1,
23+
srcs = glob(["**/*.spec.ts"]),
24+
deps = [
25+
":drag-drop",
26+
"//src/cdk/testing",
27+
],
28+
tsconfig = "//src/cdk-experimental:tsconfig-build.json",
29+
)
30+
31+
sass_binary(
32+
name = "drop_scss",
33+
src = "drop.scss",
34+
)
35+
36+
ts_web_test(
37+
name = "unit_tests",
38+
bootstrap = [
39+
"//:web_test_bootstrap_scripts",
40+
],
41+
tags = ["manual"],
42+
43+
# Do not sort
44+
deps = [
45+
"//:tslib_bundle",
46+
"//:angular_bundles",
47+
"//:angular_test_bundles",
48+
"//test:angular_test_init",
49+
":drag_and_drop_test_sources",
50+
],
51+
)
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import {NgModule} from '@angular/core';
10+
import {CdkDrop} from './drop';
11+
import {CdkDrag} from './drag';
12+
import {CdkDragHandle} from './drag-handle';
13+
import {CdkDragPreview} from './drag-preview';
14+
import {CdkDragPlaceholder} from './drag-placeholder';
15+
16+
@NgModule({
17+
declarations: [
18+
CdkDrop,
19+
CdkDrag,
20+
CdkDragHandle,
21+
CdkDragPreview,
22+
CdkDragPlaceholder,
23+
],
24+
exports: [
25+
CdkDrop,
26+
CdkDrag,
27+
CdkDragHandle,
28+
CdkDragPreview,
29+
CdkDragPlaceholder,
30+
],
31+
})
32+
export class CdkDragDropModule {}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# TODO
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import {CdkDrag} from './drag';
10+
import {CdkDropContainer} from './drop-container';
11+
12+
/** Event emitted when the user starts dragging a draggable. */
13+
export interface CdkDragStart {
14+
/** Draggable that emitted the event. */
15+
source: CdkDrag;
16+
}
17+
18+
19+
/** Event emitted when the user stops dragging a draggable. */
20+
export interface CdkDragEnd {
21+
/** Draggable that emitted the event. */
22+
source: CdkDrag;
23+
}
24+
25+
/** Event emitted when the user moves an item into a new drop container. */
26+
export interface CdkDragEnter<T> {
27+
/** Container into which the user has moved the item. */
28+
container: CdkDropContainer<T>;
29+
/** Item that was removed from the container. */
30+
item: CdkDrag;
31+
}
32+
33+
/**
34+
* Event emitted when the user removes an item from a
35+
* drop container by moving it into another one.
36+
*/
37+
export interface CdkDragExit<T> {
38+
/** Container from which the user has a removed an item. */
39+
container: CdkDropContainer<T>;
40+
/** Item that was removed from the container. */
41+
item: CdkDrag;
42+
}
43+
44+
45+
/** Event emitted when the user drops a draggable item inside a drop container. */
46+
export interface CdkDragDrop<T, O = T> {
47+
/** Index of the item when it was picked up. */
48+
previousIndex: number;
49+
/** Current index of the item. */
50+
currentIndex: number;
51+
/** Item that is being dropped. */
52+
item: CdkDrag;
53+
/** Container in which the item was dropped. */
54+
container: CdkDropContainer<T>;
55+
/** Container from which the item was picked up. Can be the same as the `container`. */
56+
previousContainer: CdkDropContainer<O>;
57+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import {Directive, ElementRef} from '@angular/core';
10+
11+
/** Handle that can be used to drag and CdkDrag instance. */
12+
@Directive({
13+
selector: '[cdkDragHandle]',
14+
host: {
15+
'class': 'cdk-drag-handle'
16+
}
17+
})
18+
export class CdkDragHandle {
19+
constructor(public element: ElementRef<HTMLElement>) {}
20+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import {Directive, TemplateRef, Input} from '@angular/core';
10+
11+
/**
12+
* Element that will be used as a template for the placeholder of a CdkDrag when
13+
* it is being dragged. The placeholder is displayed in place of the element being dragged.
14+
*/
15+
@Directive({
16+
selector: 'ng-template[cdkDragPlaceholder]'
17+
})
18+
export class CdkDragPlaceholder<T = any> {
19+
/** Context data to be added to the placeholder template instance. */
20+
@Input() data: T;
21+
constructor(public templateRef: TemplateRef<T>) {}
22+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import {Directive, TemplateRef, Input} from '@angular/core';
10+
11+
/**
12+
* Element that will be used as a template for the preview
13+
* of a CdkDrag when it is being dragged.
14+
*/
15+
@Directive({
16+
selector: 'ng-template[cdkDragPreview]'
17+
})
18+
export class CdkDragPreview<T = any> {
19+
/** Context data to be added to the preview template instance. */
20+
@Input() data: T;
21+
constructor(public templateRef: TemplateRef<T>) {}
22+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
/**
10+
* Moves an item one index in an array to another.
11+
* @param array Array in which to move the item.
12+
* @param fromIndex Starting index of the item.
13+
* @param toIndex Index to which the item should be moved.
14+
*/
15+
export function moveItemInArray<T = any>(array: T[], fromIndex: number, toIndex: number): void {
16+
if (fromIndex === toIndex) {
17+
return;
18+
}
19+
20+
const target = array[fromIndex];
21+
const delta = toIndex < fromIndex ? -1 : 1;
22+
23+
for (let i = fromIndex; i !== toIndex; i += delta) {
24+
array[i] = array[i + delta];
25+
}
26+
27+
array[toIndex] = target;
28+
}
29+
30+
31+
/**
32+
* Moves an item from one array to another.
33+
* @param currentArray Array from which to transfer the item.
34+
* @param targetArray Array into which to put the item.
35+
* @param currentIndex Index of the item in its current array.
36+
* @param targetIndex Index at which to insert the item.
37+
*/
38+
export function transferArrayItem<T = any>(currentArray: T[],
39+
targetArray: T[],
40+
currentIndex: number,
41+
targetIndex: number): void {
42+
targetArray.splice(targetIndex, 0, currentArray.splice(currentIndex, 1)[0]);
43+
}

0 commit comments

Comments
 (0)