Skip to content

Commit d0ca10b

Browse files
committed
refactor(cdk/drag-drop): simplify sort strategy interface
Simplifies the interface for sort strategies to avoid the unnecessary generics that were put in place to avoid circular imports.
1 parent b9ef786 commit d0ca10b

File tree

3 files changed

+37
-51
lines changed

3 files changed

+37
-51
lines changed

src/cdk/drag-drop/drop-list-ref.ts

+10-4
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ export class DropListRef<T = any> {
146146
private _parentPositions: ParentPositionTracker;
147147

148148
/** Strategy being used to sort items within the list. */
149-
private _sortStrategy: DropListSortStrategy<DragRef>;
149+
private _sortStrategy: DropListSortStrategy;
150150

151151
/** Cached `DOMRect` of the drop list. */
152152
private _domRect: DOMRect | undefined;
@@ -187,6 +187,9 @@ export class DropListRef<T = any> {
187187
/** Initial value for the element's `scroll-snap-type` style. */
188188
private _initialScrollSnap: string;
189189

190+
/** Direction of the list's layout. */
191+
private _direction: Direction = 'ltr';
192+
190193
constructor(
191194
element: ElementRef<HTMLElement> | HTMLElement,
192195
private _dragDropRegistry: DragDropRegistry<DragRef, DropListRef>,
@@ -332,7 +335,10 @@ export class DropListRef<T = any> {
332335

333336
/** Sets the layout direction of the drop list. */
334337
withDirection(direction: Direction): this {
335-
this._sortStrategy.direction = direction;
338+
this._direction = direction;
339+
if (this._sortStrategy instanceof SingleAxisSortStrategy) {
340+
this._sortStrategy.direction = direction;
341+
}
336342
return this;
337343
}
338344

@@ -353,7 +359,7 @@ export class DropListRef<T = any> {
353359
withOrientation(orientation: 'vertical' | 'horizontal'): this {
354360
// TODO(crisbeto): eventually we should be constructing the new sort strategy here based on
355361
// the new orientation. For now we can assume that it'll always be `SingleAxisSortStrategy`.
356-
(this._sortStrategy as SingleAxisSortStrategy<DragRef>).orientation = orientation;
362+
(this._sortStrategy as SingleAxisSortStrategy).orientation = orientation;
357363
return this;
358364
}
359365

@@ -455,7 +461,7 @@ export class DropListRef<T = any> {
455461
[verticalScrollDirection, horizontalScrollDirection] = getElementScrollDirections(
456462
element as HTMLElement,
457463
position.clientRect,
458-
this._sortStrategy.direction,
464+
this._direction,
459465
pointerX,
460466
pointerY,
461467
);

src/cdk/drag-drop/sorting/drop-list-sort-strategy.ts

+9-24
Original file line numberDiff line numberDiff line change
@@ -6,46 +6,31 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {Direction} from '@angular/cdk/bidi';
9+
import type {DragRef} from '../drag-ref';
1010

1111
/**
1212
* Function that is used to determine whether an item can be sorted into a particular index.
1313
* @docs-private
1414
*/
1515
export type SortPredicate<T> = (index: number, item: T) => boolean;
1616

17-
/**
18-
* Item that can be sorted within `DropListSortStrategy`. This is a limited representation of
19-
* `DragRef` used to avoid circular dependencies. It is intended to only be used within
20-
* `DropListSortStrategy`.
21-
* @docs-private
22-
*/
23-
export interface DropListSortStrategyItem {
24-
isDragging(): boolean;
25-
getPlaceholderElement(): HTMLElement;
26-
getRootElement(): HTMLElement;
27-
_sortFromLastPointerPosition(): void;
28-
getVisibleElement(): HTMLElement;
29-
}
30-
3117
/**
3218
* Strategy used to sort and position items within a drop list.
3319
* @docs-private
3420
*/
35-
export interface DropListSortStrategy<T extends DropListSortStrategyItem> {
36-
direction: Direction;
37-
start(items: readonly T[]): void;
21+
export interface DropListSortStrategy {
22+
start(items: readonly DragRef[]): void;
3823
sort(
39-
item: T,
24+
item: DragRef,
4025
pointerX: number,
4126
pointerY: number,
4227
pointerDelta: {x: number; y: number},
4328
): {previousIndex: number; currentIndex: number} | null;
44-
enter(item: T, pointerX: number, pointerY: number, index?: number): void;
45-
withItems(items: readonly T[]): void;
46-
withSortPredicate(predicate: SortPredicate<T>): void;
29+
enter(item: DragRef, pointerX: number, pointerY: number, index?: number): void;
30+
withItems(items: readonly DragRef[]): void;
31+
withSortPredicate(predicate: SortPredicate<DragRef>): void;
4732
reset(): void;
48-
getActiveItemsSnapshot(): readonly T[];
49-
getItemIndex(item: T): number;
33+
getActiveItemsSnapshot(): readonly DragRef[];
34+
getItemIndex(item: DragRef): number;
5035
updateOnScroll(topDifference: number, leftDifference: number): void;
5136
}

src/cdk/drag-drop/sorting/single-axis-sort-strategy.ts

+18-23
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,8 @@ import {DragDropRegistry} from '../drag-drop-registry';
1313
import {moveItemInArray} from '../drag-utils';
1414
import {combineTransforms} from '../dom/styling';
1515
import {adjustDomRect, getMutableClientRect, isInsideClientRect} from '../dom/dom-rect';
16-
import {
17-
DropListSortStrategy,
18-
DropListSortStrategyItem,
19-
SortPredicate,
20-
} from './drop-list-sort-strategy';
16+
import {DropListSortStrategy, SortPredicate} from './drop-list-sort-strategy';
17+
import type {DragRef} from '../drag-ref';
2118

2219
/**
2320
* Entry in the position cache for draggable items.
@@ -39,21 +36,19 @@ interface CachedItemPosition<T> {
3936
* Items are reordered using CSS transforms which allows for sorting to be animated.
4037
* @docs-private
4138
*/
42-
export class SingleAxisSortStrategy<T extends DropListSortStrategyItem>
43-
implements DropListSortStrategy<T>
44-
{
39+
export class SingleAxisSortStrategy implements DropListSortStrategy {
4540
/** Function used to determine if an item can be sorted into a specific index. */
46-
private _sortPredicate: SortPredicate<T>;
41+
private _sortPredicate: SortPredicate<DragRef>;
4742

4843
/** Cache of the dimensions of all the items inside the container. */
49-
private _itemPositions: CachedItemPosition<T>[] = [];
44+
private _itemPositions: CachedItemPosition<DragRef>[] = [];
5045

5146
/**
5247
* Draggable items that are currently active inside the container. Includes the items
5348
* that were there at the start of the sequence, as well as any items that have been dragged
5449
* in, but haven't been dropped yet.
5550
*/
56-
private _activeDraggables: T[];
51+
private _activeDraggables: DragRef[];
5752

5853
/** Direction in which the list is oriented. */
5954
orientation: 'vertical' | 'horizontal' = 'vertical';
@@ -63,7 +58,7 @@ export class SingleAxisSortStrategy<T extends DropListSortStrategyItem>
6358

6459
constructor(
6560
private _element: HTMLElement | ElementRef<HTMLElement>,
66-
private _dragDropRegistry: DragDropRegistry<T, unknown>,
61+
private _dragDropRegistry: DragDropRegistry<DragRef, unknown>,
6762
) {}
6863

6964
/**
@@ -72,7 +67,7 @@ export class SingleAxisSortStrategy<T extends DropListSortStrategyItem>
7267
* overlap with the swapped item after the swapping occurred.
7368
*/
7469
private _previousSwap = {
75-
drag: null as T | null,
70+
drag: null as DragRef | null,
7671
delta: 0,
7772
overlaps: false,
7873
};
@@ -81,7 +76,7 @@ export class SingleAxisSortStrategy<T extends DropListSortStrategyItem>
8176
* To be called when the drag sequence starts.
8277
* @param items Items that are currently in the list.
8378
*/
84-
start(items: readonly T[]) {
79+
start(items: readonly DragRef[]) {
8580
this.withItems(items);
8681
}
8782

@@ -92,7 +87,7 @@ export class SingleAxisSortStrategy<T extends DropListSortStrategyItem>
9287
* @param pointerY Position of the item along the Y axis.
9388
* @param pointerDelta Direction in which the pointer is moving along each axis.
9489
*/
95-
sort(item: T, pointerX: number, pointerY: number, pointerDelta: {x: number; y: number}) {
90+
sort(item: DragRef, pointerX: number, pointerY: number, pointerDelta: {x: number; y: number}) {
9691
const siblings = this._itemPositions;
9792
const newIndex = this._getItemIndexFromPointerPosition(item, pointerX, pointerY, pointerDelta);
9893

@@ -172,7 +167,7 @@ export class SingleAxisSortStrategy<T extends DropListSortStrategyItem>
172167
* @param index Index at which the item entered. If omitted, the container will try to figure it
173168
* out automatically.
174169
*/
175-
enter(item: T, pointerX: number, pointerY: number, index?: number): void {
170+
enter(item: DragRef, pointerX: number, pointerY: number, index?: number): void {
176171
const newIndex =
177172
index == null || index < 0
178173
? // We use the coordinates of where the item entered the drop
@@ -183,7 +178,7 @@ export class SingleAxisSortStrategy<T extends DropListSortStrategyItem>
183178
const activeDraggables = this._activeDraggables;
184179
const currentIndex = activeDraggables.indexOf(item);
185180
const placeholder = item.getPlaceholderElement();
186-
let newPositionReference: T | undefined = activeDraggables[newIndex];
181+
let newPositionReference: DragRef | undefined = activeDraggables[newIndex];
187182

188183
// If the item at the new position is the same as the item that is being dragged,
189184
// it means that we're trying to restore the item to its initial position. In this
@@ -229,13 +224,13 @@ export class SingleAxisSortStrategy<T extends DropListSortStrategyItem>
229224
}
230225

231226
/** Sets the items that are currently part of the list. */
232-
withItems(items: readonly T[]): void {
227+
withItems(items: readonly DragRef[]): void {
233228
this._activeDraggables = items.slice();
234229
this._cacheItemPositions();
235230
}
236231

237232
/** Assigns a sort predicate to the strategy. */
238-
withSortPredicate(predicate: SortPredicate<T>): void {
233+
withSortPredicate(predicate: SortPredicate<DragRef>): void {
239234
this._sortPredicate = predicate;
240235
}
241236

@@ -262,12 +257,12 @@ export class SingleAxisSortStrategy<T extends DropListSortStrategyItem>
262257
* Gets a snapshot of items currently in the list.
263258
* Can include items that we dragged in from another list.
264259
*/
265-
getActiveItemsSnapshot(): readonly T[] {
260+
getActiveItemsSnapshot(): readonly DragRef[] {
266261
return this._activeDraggables;
267262
}
268263

269264
/** Gets the index of a specific item. */
270-
getItemIndex(item: T): number {
265+
getItemIndex(item: DragRef): number {
271266
// Items are sorted always by top/left in the cache, however they flow differently in RTL.
272267
// The rest of the logic still stands no matter what orientation we're in, however
273268
// we need to invert the array when determining the index.
@@ -351,7 +346,7 @@ export class SingleAxisSortStrategy<T extends DropListSortStrategyItem>
351346
*/
352347
private _getSiblingOffsetPx(
353348
currentIndex: number,
354-
siblings: CachedItemPosition<T>[],
349+
siblings: CachedItemPosition<DragRef>[],
355350
delta: 1 | -1,
356351
) {
357352
const isHorizontal = this.orientation === 'horizontal';
@@ -410,7 +405,7 @@ export class SingleAxisSortStrategy<T extends DropListSortStrategyItem>
410405
* @param delta Direction in which the user is moving their pointer.
411406
*/
412407
private _getItemIndexFromPointerPosition(
413-
item: T,
408+
item: DragRef,
414409
pointerX: number,
415410
pointerY: number,
416411
delta?: {x: number; y: number},

0 commit comments

Comments
 (0)