Skip to content

Commit 4bcd13d

Browse files
committed
refactor(drag-drop): expose more private apis as protected
Exposes more of the private drag&drop APIs as protected ones, in order to make it easier for people to implement their custom directives based on the CDK ones. Also moves out some of the private helper methods into functions. Fixes #14113.
1 parent 39888f3 commit 4bcd13d

File tree

3 files changed

+57
-56
lines changed

3 files changed

+57
-56
lines changed

src/cdk/drag-drop/drag.ts

+32-32
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
310310
rootElement.addEventListener('mousedown', this._pointerDown, activeEventListenerOptions);
311311
rootElement.addEventListener('touchstart', this._pointerDown, passiveEventListenerOptions);
312312
this._handles.changes.pipe(startWith(null)).subscribe(() =>
313-
toggleNativeDragInteractions(rootElement, this.getChildHandles().length > 0));
313+
toggleNativeDragInteractions(rootElement, this._getChildHandles().length > 0));
314314
});
315315
}
316316

@@ -327,7 +327,7 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
327327
if (this._isDragging()) {
328328
// Since we move out the element to the end of the body while it's being
329329
// dragged, we have to make sure that it's removed if it gets destroyed.
330-
this._removeElement(this._rootElement);
330+
removeElement(this._rootElement);
331331
}
332332
}
333333

@@ -346,13 +346,13 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
346346
}
347347

348348
/** Gets only handles that are not inside descendant `CdkDrag` instances. */
349-
private getChildHandles() {
349+
protected _getChildHandles() {
350350
return this._handles.filter(handle => handle._parentDrag === this);
351351
}
352352

353353
/** Handler for the `mousedown`/`touchstart` events. */
354354
_pointerDown = (event: MouseEvent | TouchEvent) => {
355-
const handles = this.getChildHandles();
355+
const handles = this._getChildHandles();
356356

357357
// Delegate the event based on whether it started from a handle or the element itself.
358358
if (handles.length) {
@@ -376,16 +376,16 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
376376
* @param referenceElement Element that started the drag sequence.
377377
* @param event Browser event object that started the sequence.
378378
*/
379-
private _initializeDragSequence(referenceElement: HTMLElement, event: MouseEvent | TouchEvent) {
379+
protected _initializeDragSequence(referenceElement: HTMLElement, event: MouseEvent | TouchEvent) {
380380
// Always stop propagation for the event that initializes
381381
// the dragging sequence, in order to prevent it from potentially
382382
// starting another sequence for a draggable parent somewhere up the DOM tree.
383383
event.stopPropagation();
384384

385385
const isDragging = this._isDragging();
386-
const isTouchEvent = this._isTouchEvent(event);
387-
const isAuxiliaryMouseButton = !isTouchEvent && (event as MouseEvent).button !== 0;
388-
const isSyntheticEvent = !isTouchEvent && this._lastTouchEventTime &&
386+
const wasTouchEvent = isTouchEvent(event);
387+
const isAuxiliaryMouseButton = !wasTouchEvent && (event as MouseEvent).button !== 0;
388+
const isSyntheticEvent = !wasTouchEvent && this._lastTouchEventTime &&
389389
this._lastTouchEventTime + MOUSE_EVENT_IGNORE_TIME > Date.now();
390390

391391
// If the event started from an element with the native HTML drag&drop, it'll interfere
@@ -426,11 +426,11 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
426426
}
427427

428428
/** Starts the dragging sequence. */
429-
private _startDragSequence(event: MouseEvent | TouchEvent) {
429+
protected _startDragSequence(event: MouseEvent | TouchEvent) {
430430
// Emit the event on the item before the one on the container.
431431
this.started.emit({source: this});
432432

433-
if (this._isTouchEvent(event)) {
433+
if (isTouchEvent(event)) {
434434
this._lastTouchEventTime = Date.now();
435435
}
436436

@@ -455,7 +455,7 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
455455
}
456456

457457
/** Handler that is invoked when the user moves their pointer after they've initiated a drag. */
458-
private _pointerMove = (event: MouseEvent | TouchEvent) => {
458+
protected _pointerMove = (event: MouseEvent | TouchEvent) => {
459459
const pointerPosition = this._getConstrainedPointerPosition(event);
460460

461461
if (!this._hasStartedDragging) {
@@ -509,7 +509,7 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
509509
}
510510

511511
/** Handler that is invoked when the user lifts their pointer up, after initiating a drag. */
512-
private _pointerUp = () => {
512+
protected _pointerUp = () => {
513513
if (!this._isDragging()) {
514514
return;
515515
}
@@ -672,7 +672,7 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
672672
const elementRect = this._rootElement.getBoundingClientRect();
673673
const handleElement = referenceElement === this._rootElement ? null : referenceElement;
674674
const referenceRect = handleElement ? handleElement.getBoundingClientRect() : elementRect;
675-
const point = this._isTouchEvent(event) ? event.targetTouches[0] : event;
675+
const point = isTouchEvent(event) ? event.targetTouches[0] : event;
676676
const x = point.pageX - referenceRect.left - this._scrollPosition.left;
677677
const y = point.pageY - referenceRect.top - this._scrollPosition.top;
678678

@@ -729,19 +729,9 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
729729
});
730730
}
731731

732-
/**
733-
* Helper to remove an element from the DOM and to do all the necessary null checks.
734-
* @param element Element to be removed.
735-
*/
736-
private _removeElement(element: HTMLElement | null) {
737-
if (element && element.parentNode) {
738-
element.parentNode.removeChild(element);
739-
}
740-
}
741-
742732
/** Determines the point of the page that was touched by the user. */
743733
private _getPointerPositionOnPage(event: MouseEvent | TouchEvent): Point {
744-
const point = this._isTouchEvent(event) ? event.touches[0] : event;
734+
const point = isTouchEvent(event) ? event.touches[0] : event;
745735

746736
return {
747737
x: point.pageX - this._scrollPosition.left,
@@ -763,15 +753,10 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
763753
return point;
764754
}
765755

766-
/** Determines whether an event is a touch event. */
767-
private _isTouchEvent(event: MouseEvent | TouchEvent): event is TouchEvent {
768-
return event.type.startsWith('touch');
769-
}
770-
771756
/** Destroys the preview element and its ViewRef. */
772757
private _destroyPreview() {
773758
if (this._preview) {
774-
this._removeElement(this._preview);
759+
removeElement(this._preview);
775760
}
776761

777762
if (this._previewRef) {
@@ -784,7 +769,7 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
784769
/** Destroys the placeholder element and its ViewRef. */
785770
private _destroyPlaceholder() {
786771
if (this._placeholder) {
787-
this._removeElement(this._placeholder);
772+
removeElement(this._placeholder);
788773
}
789774

790775
if (this._placeholderRef) {
@@ -822,7 +807,7 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
822807
}
823808

824809
/** Gets the root draggable element, based on the `rootElementSelector`. */
825-
private _getRootElement(): HTMLElement {
810+
protected _getRootElement(): HTMLElement {
826811
if (this.rootElementSelector) {
827812
const selector = this.rootElementSelector;
828813
let currentElement = this.element.nativeElement.parentElement as HTMLElement | null;
@@ -870,3 +855,18 @@ function deepCloneNode(node: HTMLElement): HTMLElement {
870855
clone.removeAttribute('id');
871856
return clone;
872857
}
858+
859+
/**
860+
* Helper to remove an element from the DOM and to do all the necessary null checks.
861+
* @param element Element to be removed.
862+
*/
863+
function removeElement(element: HTMLElement | null) {
864+
if (element && element.parentNode) {
865+
element.parentNode.removeChild(element);
866+
}
867+
}
868+
869+
/** Determines whether an event is a touch event. */
870+
function isTouchEvent(event: MouseEvent | TouchEvent): event is TouchEvent {
871+
return event.type.startsWith('touch');
872+
}

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

+24-24
Original file line numberDiff line numberDiff line change
@@ -179,14 +179,14 @@ export class CdkDropList<T = any> implements OnInit, OnDestroy {
179179
_dragging = false;
180180

181181
/** Cache of the dimensions of all the items and the sibling containers. */
182-
private _positionCache: PositionCache = {items: [], siblings: [], self: {} as ClientRect};
182+
protected _positionCache: PositionCache = {items: [], siblings: [], self: {} as ClientRect};
183183

184184
/**
185185
* Draggable items that are currently active inside the container. Includes the items
186186
* from `_draggables`, as well as any items that have been dragged in, but haven't
187187
* been dropped yet.
188188
*/
189-
private _activeDraggables: CdkDrag[];
189+
protected _activeDraggables: CdkDrag[];
190190

191191
/**
192192
* Keeps track of the item that was last swapped with the dragged item, as
@@ -360,10 +360,10 @@ export class CdkDropList<T = any> implements OnInit, OnDestroy {
360360
// elements may be mid-animation which will give us a wrong result.
361361
if (isHorizontal) {
362362
elementToOffset.style.transform = `translate3d(${sibling.offset}px, 0, 0)`;
363-
this._adjustClientRect(sibling.clientRect, 0, offset);
363+
adjustClientRect(sibling.clientRect, 0, offset);
364364
} else {
365365
elementToOffset.style.transform = `translate3d(0, ${sibling.offset}px, 0)`;
366-
this._adjustClientRect(sibling.clientRect, offset, 0);
366+
adjustClientRect(sibling.clientRect, offset, 0);
367367
}
368368
});
369369
}
@@ -435,7 +435,7 @@ export class CdkDropList<T = any> implements OnInit, OnDestroy {
435435
}
436436

437437
/** Resets the container to its initial state. */
438-
private _reset() {
438+
protected _reset() {
439439
this._dragging = false;
440440

441441
// TODO(crisbeto): may have to wait for the animations to finish.
@@ -447,28 +447,14 @@ export class CdkDropList<T = any> implements OnInit, OnDestroy {
447447
this._previousSwap.delta = 0;
448448
}
449449

450-
/**
451-
* Updates the top/left positions of a `ClientRect`, as well as their bottom/right counterparts.
452-
* @param clientRect `ClientRect` that should be updated.
453-
* @param top Amount to add to the `top` position.
454-
* @param left Amount to add to the `left` position.
455-
*/
456-
private _adjustClientRect(clientRect: ClientRect, top: number, left: number) {
457-
clientRect.top += top;
458-
clientRect.bottom = clientRect.top + clientRect.height;
459-
460-
clientRect.left += left;
461-
clientRect.right = clientRect.left + clientRect.width;
462-
}
463-
464450
/**
465451
* Gets the index of an item in the drop container, based on the position of the user's pointer.
466452
* @param item Item that is being sorted.
467453
* @param pointerX Position of the user's pointer along the X axis.
468454
* @param pointerY Position of the user's pointer along the Y axis.
469455
* @param delta Direction in which the user is moving their pointer.
470456
*/
471-
private _getItemIndexFromPointerPosition(item: CdkDrag, pointerX: number, pointerY: number,
457+
protected _getItemIndexFromPointerPosition(item: CdkDrag, pointerX: number, pointerY: number,
472458
delta?: {x: number, y: number}) {
473459

474460
const isHorizontal = this.orientation === 'horizontal';
@@ -503,7 +489,7 @@ export class CdkDropList<T = any> implements OnInit, OnDestroy {
503489
* @param pointerX Coordinates along the X axis.
504490
* @param pointerY Coordinates along the Y axis.
505491
*/
506-
private _isPointerNearDropContainer(pointerX: number, pointerY: number): boolean {
492+
protected _isPointerNearDropContainer(pointerX: number, pointerY: number): boolean {
507493
const {top, right, bottom, left, width, height} = this._positionCache.self;
508494
const xThreshold = width * DROP_PROXIMITY_THRESHOLD;
509495
const yThreshold = height * DROP_PROXIMITY_THRESHOLD;
@@ -518,7 +504,7 @@ export class CdkDropList<T = any> implements OnInit, OnDestroy {
518504
* @param newPosition Position of the item where the current item should be moved.
519505
* @param delta Direction in which the user is moving.
520506
*/
521-
private _getItemOffsetPx(currentPosition: ClientRect, newPosition: ClientRect, delta: 1 | -1) {
507+
protected _getItemOffsetPx(currentPosition: ClientRect, newPosition: ClientRect, delta: 1 | -1) {
522508
const isHorizontal = this.orientation === 'horizontal';
523509
let itemOffset = isHorizontal ? newPosition.left - currentPosition.left :
524510
newPosition.top - currentPosition.top;
@@ -538,7 +524,7 @@ export class CdkDropList<T = any> implements OnInit, OnDestroy {
538524
* @param siblings All of the items in the list.
539525
* @param delta Direction in which the user is moving.
540526
*/
541-
private _getSiblingOffsetPx(currentIndex: number,
527+
protected _getSiblingOffsetPx(currentIndex: number,
542528
siblings: ItemPositionCacheEntry[],
543529
delta: 1 | -1) {
544530

@@ -566,7 +552,7 @@ export class CdkDropList<T = any> implements OnInit, OnDestroy {
566552
}
567553

568554
/** Gets an array of unique drop lists that the current list is connected to. */
569-
private _getConnectedLists(): CdkDropList[] {
555+
protected _getConnectedLists(): CdkDropList[] {
570556
const siblings = coerceArray(this.connectedTo).map(drop => {
571557
return typeof drop === 'string' ? this._dragDropRegistry.getDropContainer(drop)! : drop;
572558
});
@@ -613,3 +599,17 @@ function isInsideClientRect(clientRect: ClientRect, x: number, y: number) {
613599
const {top, bottom, left, right} = clientRect;
614600
return y >= top && y <= bottom && x >= left && x <= right;
615601
}
602+
603+
/**
604+
* Updates the top/left positions of a `ClientRect`, as well as their bottom/right counterparts.
605+
* @param clientRect `ClientRect` that should be updated.
606+
* @param top Amount to add to the `top` position.
607+
* @param left Amount to add to the `left` position.
608+
*/
609+
function adjustClientRect(clientRect: ClientRect, top: number, left: number) {
610+
clientRect.top += top;
611+
clientRect.bottom = clientRect.top + clientRect.height;
612+
613+
clientRect.left += left;
614+
clientRect.right = clientRect.left + clientRect.width;
615+
}

src/cdk/drag-drop/public-api.ts

+1
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ export * from './drag-preview';
1717
export * from './drag-placeholder';
1818
export * from './drag-drop-module';
1919
export * from './drag-drop-registry';
20+
export * from './drag-parent';

0 commit comments

Comments
 (0)