diff --git a/src/cdk/drag-drop/drop-list-ref.ts b/src/cdk/drag-drop/drop-list-ref.ts index e648c40a93db..eaf77b8967ae 100644 --- a/src/cdk/drag-drop/drop-list-ref.ts +++ b/src/cdk/drag-drop/drop-list-ref.ts @@ -146,7 +146,7 @@ export class DropListRef { private _parentPositions: ParentPositionTracker; /** Strategy being used to sort items within the list. */ - private _sortStrategy: DropListSortStrategy; + private _sortStrategy: DropListSortStrategy; /** Cached `DOMRect` of the drop list. */ private _domRect: DOMRect | undefined; @@ -187,6 +187,9 @@ export class DropListRef { /** Initial value for the element's `scroll-snap-type` style. */ private _initialScrollSnap: string; + /** Direction of the list's layout. */ + private _direction: Direction = 'ltr'; + constructor( element: ElementRef | HTMLElement, private _dragDropRegistry: DragDropRegistry, @@ -332,7 +335,10 @@ export class DropListRef { /** Sets the layout direction of the drop list. */ withDirection(direction: Direction): this { - this._sortStrategy.direction = direction; + this._direction = direction; + if (this._sortStrategy instanceof SingleAxisSortStrategy) { + this._sortStrategy.direction = direction; + } return this; } @@ -353,7 +359,7 @@ export class DropListRef { withOrientation(orientation: 'vertical' | 'horizontal'): this { // TODO(crisbeto): eventually we should be constructing the new sort strategy here based on // the new orientation. For now we can assume that it'll always be `SingleAxisSortStrategy`. - (this._sortStrategy as SingleAxisSortStrategy).orientation = orientation; + (this._sortStrategy as SingleAxisSortStrategy).orientation = orientation; return this; } @@ -455,7 +461,7 @@ export class DropListRef { [verticalScrollDirection, horizontalScrollDirection] = getElementScrollDirections( element as HTMLElement, position.clientRect, - this._sortStrategy.direction, + this._direction, pointerX, pointerY, ); diff --git a/src/cdk/drag-drop/sorting/drop-list-sort-strategy.ts b/src/cdk/drag-drop/sorting/drop-list-sort-strategy.ts index 68046ffadfc4..f6574811bfe6 100644 --- a/src/cdk/drag-drop/sorting/drop-list-sort-strategy.ts +++ b/src/cdk/drag-drop/sorting/drop-list-sort-strategy.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {Direction} from '@angular/cdk/bidi'; +import type {DragRef} from '../drag-ref'; /** * Function that is used to determine whether an item can be sorted into a particular index. @@ -14,38 +14,23 @@ import {Direction} from '@angular/cdk/bidi'; */ export type SortPredicate = (index: number, item: T) => boolean; -/** - * Item that can be sorted within `DropListSortStrategy`. This is a limited representation of - * `DragRef` used to avoid circular dependencies. It is intended to only be used within - * `DropListSortStrategy`. - * @docs-private - */ -export interface DropListSortStrategyItem { - isDragging(): boolean; - getPlaceholderElement(): HTMLElement; - getRootElement(): HTMLElement; - _sortFromLastPointerPosition(): void; - getVisibleElement(): HTMLElement; -} - /** * Strategy used to sort and position items within a drop list. * @docs-private */ -export interface DropListSortStrategy { - direction: Direction; - start(items: readonly T[]): void; +export interface DropListSortStrategy { + start(items: readonly DragRef[]): void; sort( - item: T, + item: DragRef, pointerX: number, pointerY: number, pointerDelta: {x: number; y: number}, ): {previousIndex: number; currentIndex: number} | null; - enter(item: T, pointerX: number, pointerY: number, index?: number): void; - withItems(items: readonly T[]): void; - withSortPredicate(predicate: SortPredicate): void; + enter(item: DragRef, pointerX: number, pointerY: number, index?: number): void; + withItems(items: readonly DragRef[]): void; + withSortPredicate(predicate: SortPredicate): void; reset(): void; - getActiveItemsSnapshot(): readonly T[]; - getItemIndex(item: T): number; + getActiveItemsSnapshot(): readonly DragRef[]; + getItemIndex(item: DragRef): number; updateOnScroll(topDifference: number, leftDifference: number): void; } diff --git a/src/cdk/drag-drop/sorting/single-axis-sort-strategy.ts b/src/cdk/drag-drop/sorting/single-axis-sort-strategy.ts index f7177bbf5052..7ce70419deda 100644 --- a/src/cdk/drag-drop/sorting/single-axis-sort-strategy.ts +++ b/src/cdk/drag-drop/sorting/single-axis-sort-strategy.ts @@ -13,11 +13,8 @@ import {DragDropRegistry} from '../drag-drop-registry'; import {moveItemInArray} from '../drag-utils'; import {combineTransforms} from '../dom/styling'; import {adjustDomRect, getMutableClientRect, isInsideClientRect} from '../dom/dom-rect'; -import { - DropListSortStrategy, - DropListSortStrategyItem, - SortPredicate, -} from './drop-list-sort-strategy'; +import {DropListSortStrategy, SortPredicate} from './drop-list-sort-strategy'; +import type {DragRef} from '../drag-ref'; /** * Entry in the position cache for draggable items. @@ -39,21 +36,19 @@ interface CachedItemPosition { * Items are reordered using CSS transforms which allows for sorting to be animated. * @docs-private */ -export class SingleAxisSortStrategy - implements DropListSortStrategy -{ +export class SingleAxisSortStrategy implements DropListSortStrategy { /** Function used to determine if an item can be sorted into a specific index. */ - private _sortPredicate: SortPredicate; + private _sortPredicate: SortPredicate; /** Cache of the dimensions of all the items inside the container. */ - private _itemPositions: CachedItemPosition[] = []; + private _itemPositions: CachedItemPosition[] = []; /** * Draggable items that are currently active inside the container. Includes the items * that were there at the start of the sequence, as well as any items that have been dragged * in, but haven't been dropped yet. */ - private _activeDraggables: T[]; + private _activeDraggables: DragRef[]; /** Direction in which the list is oriented. */ orientation: 'vertical' | 'horizontal' = 'vertical'; @@ -63,7 +58,7 @@ export class SingleAxisSortStrategy constructor( private _element: HTMLElement | ElementRef, - private _dragDropRegistry: DragDropRegistry, + private _dragDropRegistry: DragDropRegistry, ) {} /** @@ -72,7 +67,7 @@ export class SingleAxisSortStrategy * overlap with the swapped item after the swapping occurred. */ private _previousSwap = { - drag: null as T | null, + drag: null as DragRef | null, delta: 0, overlaps: false, }; @@ -81,7 +76,7 @@ export class SingleAxisSortStrategy * To be called when the drag sequence starts. * @param items Items that are currently in the list. */ - start(items: readonly T[]) { + start(items: readonly DragRef[]) { this.withItems(items); } @@ -92,7 +87,7 @@ export class SingleAxisSortStrategy * @param pointerY Position of the item along the Y axis. * @param pointerDelta Direction in which the pointer is moving along each axis. */ - sort(item: T, pointerX: number, pointerY: number, pointerDelta: {x: number; y: number}) { + sort(item: DragRef, pointerX: number, pointerY: number, pointerDelta: {x: number; y: number}) { const siblings = this._itemPositions; const newIndex = this._getItemIndexFromPointerPosition(item, pointerX, pointerY, pointerDelta); @@ -172,7 +167,7 @@ export class SingleAxisSortStrategy * @param index Index at which the item entered. If omitted, the container will try to figure it * out automatically. */ - enter(item: T, pointerX: number, pointerY: number, index?: number): void { + enter(item: DragRef, pointerX: number, pointerY: number, index?: number): void { const newIndex = index == null || index < 0 ? // We use the coordinates of where the item entered the drop @@ -183,7 +178,7 @@ export class SingleAxisSortStrategy const activeDraggables = this._activeDraggables; const currentIndex = activeDraggables.indexOf(item); const placeholder = item.getPlaceholderElement(); - let newPositionReference: T | undefined = activeDraggables[newIndex]; + let newPositionReference: DragRef | undefined = activeDraggables[newIndex]; // If the item at the new position is the same as the item that is being dragged, // it means that we're trying to restore the item to its initial position. In this @@ -229,13 +224,13 @@ export class SingleAxisSortStrategy } /** Sets the items that are currently part of the list. */ - withItems(items: readonly T[]): void { + withItems(items: readonly DragRef[]): void { this._activeDraggables = items.slice(); this._cacheItemPositions(); } /** Assigns a sort predicate to the strategy. */ - withSortPredicate(predicate: SortPredicate): void { + withSortPredicate(predicate: SortPredicate): void { this._sortPredicate = predicate; } @@ -262,12 +257,12 @@ export class SingleAxisSortStrategy * Gets a snapshot of items currently in the list. * Can include items that we dragged in from another list. */ - getActiveItemsSnapshot(): readonly T[] { + getActiveItemsSnapshot(): readonly DragRef[] { return this._activeDraggables; } /** Gets the index of a specific item. */ - getItemIndex(item: T): number { + getItemIndex(item: DragRef): number { // Items are sorted always by top/left in the cache, however they flow differently in RTL. // The rest of the logic still stands no matter what orientation we're in, however // we need to invert the array when determining the index. @@ -351,7 +346,7 @@ export class SingleAxisSortStrategy */ private _getSiblingOffsetPx( currentIndex: number, - siblings: CachedItemPosition[], + siblings: CachedItemPosition[], delta: 1 | -1, ) { const isHorizontal = this.orientation === 'horizontal'; @@ -410,7 +405,7 @@ export class SingleAxisSortStrategy * @param delta Direction in which the user is moving their pointer. */ private _getItemIndexFromPointerPosition( - item: T, + item: DragRef, pointerX: number, pointerY: number, delta?: {x: number; y: number},