Skip to content

Commit d2d8a1f

Browse files
nayfinmmalerba
authored andcommitted
feat(drag-utils): add utility function for cloning array items from one array to another (#13743)
* feat(drag-utils): add utility function for cloning array items from one array to another creates a utility helper for cloning an array item into the array of the drop container compliments moveItemInArray and transferArrayItem partially closes #13100 * feat(drag-utils): add utility function for cloning array items from one array to another resolves issues surfaced from code review * feat(drag-utils): add utility function for cloning array items from one array to another cuts extra space between parens * removes link in comments, and clarifies function definition as recommended in review * resolves nits
1 parent 4fbbb9d commit d2d8a1f

File tree

4 files changed

+87
-7
lines changed

4 files changed

+87
-7
lines changed

src/cdk/drag-drop/drag-utils.spec.ts

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {moveItemInArray, transferArrayItem} from './drag-utils';
1+
import {moveItemInArray, transferArrayItem, copyArrayItem} from './drag-utils';
22

33
describe('dragging utilities', () => {
44
describe('moveItemInArray', () => {
@@ -66,4 +66,45 @@ describe('dragging utilities', () => {
6666
});
6767

6868
});
69+
70+
describe('copyArrayItem', () => {
71+
it('should be able to copy an item from one array to another', () => {
72+
const a = [0, 1, 2];
73+
const b = [3, 4, 5];
74+
75+
copyArrayItem(a, b, 1, 2);
76+
expect(a).toEqual([0, 1, 2 ]);
77+
expect(b).toEqual([3, 4, 1, 5]);
78+
});
79+
80+
it('should handle an index greater than the target array length', () => {
81+
const a = [0, 1, 2];
82+
const b = [3, 4, 5];
83+
84+
copyArrayItem(a, b, 0, 7);
85+
86+
expect(a).toEqual([0, 1, 2]);
87+
expect(b).toEqual([3, 4, 5, 0]);
88+
});
89+
90+
it('should handle an index less than zero', () => {
91+
const a = [0, 1, 2];
92+
const b = [3, 4, 5];
93+
94+
copyArrayItem(a, b, 2, -1);
95+
expect(a).toEqual([0, 1, 2]);
96+
expect(b).toEqual([2, 3, 4, 5]);
97+
});
98+
99+
it('should not do anything if the source array is empty', () => {
100+
const a: number[] = [];
101+
const b = [3, 4, 5];
102+
103+
copyArrayItem(a, b, 0, 0);
104+
expect(a).toEqual([]);
105+
expect(b).toEqual([3, 4, 5]);
106+
});
107+
108+
});
109+
69110
});

src/cdk/drag-drop/drag-utils.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ export function transferArrayItem<T = any>(currentArray: T[],
4242
targetArray: T[],
4343
currentIndex: number,
4444
targetIndex: number): void {
45-
4645
const from = clamp(currentIndex, currentArray.length - 1);
4746
const to = clamp(targetIndex, targetArray.length);
4847

@@ -51,6 +50,26 @@ export function transferArrayItem<T = any>(currentArray: T[],
5150
}
5251
}
5352

53+
/**
54+
* Copies an item from one array to another, leaving it in its
55+
* original position in current array.
56+
* @param currentArray Array from which to copy the item.
57+
* @param targetArray Array into which is copy the item.
58+
* @param currentIndex Index of the item in its current array.
59+
* @param targetIndex Index at which to insert the item.
60+
*
61+
*/
62+
export function copyArrayItem<T = any>(currentArray: T[],
63+
targetArray: T[],
64+
currentIndex: number,
65+
targetIndex: number): void {
66+
const to = clamp(targetIndex, targetArray.length);
67+
68+
if (currentArray.length) {
69+
targetArray.splice(to, 0, currentArray[currentIndex]);
70+
}
71+
}
72+
5473
/** Clamps a number between zero and a maximum. */
5574
function clamp(value: number, max: number): number {
5675
return Math.max(0, Math.min(max, value));

src/demo-app/drag-drop/drag-drop-demo.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
<div>
22
<div class="demo-list">
3+
34
<h2>To do</h2>
5+
<mat-slide-toggle color="primary" [(ngModel)]="cloneMode">
6+
Clone Mode
7+
</mat-slide-toggle>
48
<div
59
cdkDropList
610
#one="cdkDropList"

src/demo-app/drag-drop/drag-drop-demo.ts

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,12 @@
99
import {Component, ViewEncapsulation} from '@angular/core';
1010
import {MatIconRegistry} from '@angular/material/icon';
1111
import {DomSanitizer} from '@angular/platform-browser';
12-
import {CdkDragDrop, moveItemInArray, transferArrayItem} from '@angular/cdk/drag-drop';
12+
import {
13+
CdkDragDrop,
14+
moveItemInArray,
15+
transferArrayItem,
16+
copyArrayItem
17+
} from '@angular/cdk/drag-drop';
1318

1419
@Component({
1520
moduleId: module.id,
@@ -19,6 +24,8 @@ import {CdkDragDrop, moveItemInArray, transferArrayItem} from '@angular/cdk/drag
1924
encapsulation: ViewEncapsulation.None,
2025
})
2126
export class DragAndDropDemo {
27+
28+
cloneMode = false;
2229
axisLock: 'x' | 'y';
2330
todo = [
2431
'Go out for Lunch',
@@ -56,10 +63,19 @@ export class DragAndDropDemo {
5663
if (event.previousContainer === event.container) {
5764
moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
5865
} else {
59-
transferArrayItem(event.previousContainer.data,
60-
event.container.data,
61-
event.previousIndex,
62-
event.currentIndex);
66+
if (this.cloneMode) {
67+
copyArrayItem(
68+
event.previousContainer.data,
69+
event.container.data,
70+
event.previousIndex,
71+
event.currentIndex);
72+
} else {
73+
transferArrayItem(
74+
event.previousContainer.data,
75+
event.container.data,
76+
event.previousIndex,
77+
event.currentIndex);
78+
}
6379
}
6480
}
6581
}

0 commit comments

Comments
 (0)