Skip to content

Commit 74edb5a

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 89bb692 commit 74edb5a

File tree

3 files changed

+54
-53
lines changed

3 files changed

+54
-53
lines changed

src/cdk/drag-drop/drag.ts

+29-29
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
285285
rootElement.addEventListener('mousedown', this._pointerDown, activeEventListenerOptions);
286286
rootElement.addEventListener('touchstart', this._pointerDown, passiveEventListenerOptions);
287287
this._handles.changes.pipe(startWith(null)).subscribe(() =>
288-
toggleNativeDragInteractions(rootElement, this.getChildHandles().length > 0));
288+
toggleNativeDragInteractions(rootElement, this._getChildHandles().length > 0));
289289
});
290290
}
291291

@@ -302,7 +302,7 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
302302
if (this._isDragging()) {
303303
// Since we move out the element to the end of the body while it's being
304304
// dragged, we have to make sure that it's removed if it gets destroyed.
305-
this._removeElement(this._rootElement);
305+
removeElement(this._rootElement);
306306
}
307307
}
308308

@@ -321,13 +321,13 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
321321
}
322322

323323
/** Gets only handles that are not inside descendant `CdkDrag` instances. */
324-
private getChildHandles() {
324+
protected _getChildHandles() {
325325
return this._handles.filter(handle => handle._parentDrag === this);
326326
}
327327

328328
/** Handler for the `mousedown`/`touchstart` events. */
329329
_pointerDown = (event: MouseEvent | TouchEvent) => {
330-
const handles = this.getChildHandles();
330+
const handles = this._getChildHandles();
331331

332332
// Delegate the event based on whether it started from a handle or the element itself.
333333
if (handles.length) {
@@ -351,7 +351,7 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
351351
* @param referenceElement Element that started the drag sequence.
352352
* @param event Browser event object that started the sequence.
353353
*/
354-
private _initializeDragSequence(referenceElement: HTMLElement, event: MouseEvent | TouchEvent) {
354+
protected _initializeDragSequence(referenceElement: HTMLElement, event: MouseEvent | TouchEvent) {
355355
// Always stop propagation for the event that initializes
356356
// the dragging sequence, in order to prevent it from potentially
357357
// starting another sequence for a draggable parent somewhere up the DOM tree.
@@ -368,7 +368,7 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
368368
}
369369

370370
// Abort if the user is already dragging or is using a mouse button other than the primary one.
371-
if (this._isDragging() || (!this._isTouchEvent(event) && event.button !== 0)) {
371+
if (this._isDragging() || (!isTouchEvent(event) && event.button !== 0)) {
372372
return;
373373
}
374374

@@ -395,7 +395,7 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
395395
}
396396

397397
/** Starts the dragging sequence. */
398-
private _startDragSequence() {
398+
protected _startDragSequence() {
399399
// Emit the event on the item before the one on the container.
400400
this.started.emit({source: this});
401401

@@ -420,7 +420,7 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
420420
}
421421

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

426426
if (!this._hasStartedDragging) {
@@ -474,7 +474,7 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
474474
}
475475

476476
/** Handler that is invoked when the user lifts their pointer up, after initiating a drag. */
477-
private _pointerUp = () => {
477+
protected _pointerUp = () => {
478478
if (!this._isDragging()) {
479479
return;
480480
}
@@ -633,7 +633,7 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
633633
const elementRect = this._rootElement.getBoundingClientRect();
634634
const handleElement = referenceElement === this._rootElement ? null : referenceElement;
635635
const referenceRect = handleElement ? handleElement.getBoundingClientRect() : elementRect;
636-
const point = this._isTouchEvent(event) ? event.targetTouches[0] : event;
636+
const point = isTouchEvent(event) ? event.targetTouches[0] : event;
637637
const x = point.pageX - referenceRect.left - this._scrollPosition.left;
638638
const y = point.pageY - referenceRect.top - this._scrollPosition.top;
639639

@@ -690,19 +690,9 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
690690
});
691691
}
692692

693-
/**
694-
* Helper to remove an element from the DOM and to do all the necessary null checks.
695-
* @param element Element to be removed.
696-
*/
697-
private _removeElement(element: HTMLElement | null) {
698-
if (element && element.parentNode) {
699-
element.parentNode.removeChild(element);
700-
}
701-
}
702-
703693
/** Determines the point of the page that was touched by the user. */
704694
private _getPointerPositionOnPage(event: MouseEvent | TouchEvent): Point {
705-
const point = this._isTouchEvent(event) ? event.touches[0] : event;
695+
const point = isTouchEvent(event) ? event.touches[0] : event;
706696

707697
return {
708698
x: point.pageX - this._scrollPosition.left,
@@ -724,15 +714,10 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
724714
return point;
725715
}
726716

727-
/** Determines whether an event is a touch event. */
728-
private _isTouchEvent(event: MouseEvent | TouchEvent): event is TouchEvent {
729-
return event.type.startsWith('touch');
730-
}
731-
732717
/** Destroys the preview element and its ViewRef. */
733718
private _destroyPreview() {
734719
if (this._preview) {
735-
this._removeElement(this._preview);
720+
removeElement(this._preview);
736721
}
737722

738723
if (this._previewRef) {
@@ -745,7 +730,7 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
745730
/** Destroys the placeholder element and its ViewRef. */
746731
private _destroyPlaceholder() {
747732
if (this._placeholder) {
748-
this._removeElement(this._placeholder);
733+
removeElement(this._placeholder);
749734
}
750735

751736
if (this._placeholderRef) {
@@ -783,7 +768,7 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
783768
}
784769

785770
/** Gets the root draggable element, based on the `rootElementSelector`. */
786-
private _getRootElement(): HTMLElement {
771+
protected _getRootElement(): HTMLElement {
787772
if (this.rootElementSelector) {
788773
const selector = this.rootElementSelector;
789774
let currentElement = this.element.nativeElement.parentElement as HTMLElement | null;
@@ -831,3 +816,18 @@ function deepCloneNode(node: HTMLElement): HTMLElement {
831816
clone.removeAttribute('id');
832817
return clone;
833818
}
819+
820+
/**
821+
* Helper to remove an element from the DOM and to do all the necessary null checks.
822+
* @param element Element to be removed.
823+
*/
824+
function removeElement(element: HTMLElement | null) {
825+
if (element && element.parentNode) {
826+
element.parentNode.removeChild(element);
827+
}
828+
}
829+
830+
/** Determines whether an event is a touch event. */
831+
function isTouchEvent(event: MouseEvent | TouchEvent): event is TouchEvent {
832+
return event.type.startsWith('touch');
833+
}

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

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

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

176176
/**
177177
* Draggable items that are currently active inside the container. Includes the items
178178
* from `_draggables`, as well as any items that have been dragged in, but haven't
179179
* been dropped yet.
180180
*/
181-
private _activeDraggables: CdkDrag[];
181+
protected _activeDraggables: CdkDrag[];
182182

183183
/**
184184
* Keeps track of the item that was last swapped with the dragged item, as
@@ -352,10 +352,10 @@ export class CdkDropList<T = any> implements OnInit, OnDestroy {
352352
// elements may be mid-animation which will give us a wrong result.
353353
if (isHorizontal) {
354354
elementToOffset.style.transform = `translate3d(${sibling.offset}px, 0, 0)`;
355-
this._adjustClientRect(sibling.clientRect, 0, offset);
355+
adjustClientRect(sibling.clientRect, 0, offset);
356356
} else {
357357
elementToOffset.style.transform = `translate3d(0, ${sibling.offset}px, 0)`;
358-
this._adjustClientRect(sibling.clientRect, offset, 0);
358+
adjustClientRect(sibling.clientRect, offset, 0);
359359
}
360360
});
361361
}
@@ -427,7 +427,7 @@ export class CdkDropList<T = any> implements OnInit, OnDestroy {
427427
}
428428

429429
/** Resets the container to its initial state. */
430-
private _reset() {
430+
protected _reset() {
431431
this._dragging = false;
432432

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

442-
/**
443-
* Updates the top/left positions of a `ClientRect`, as well as their bottom/right counterparts.
444-
* @param clientRect `ClientRect` that should be updated.
445-
* @param top Amount to add to the `top` position.
446-
* @param left Amount to add to the `left` position.
447-
*/
448-
private _adjustClientRect(clientRect: ClientRect, top: number, left: number) {
449-
clientRect.top += top;
450-
clientRect.bottom = clientRect.top + clientRect.height;
451-
452-
clientRect.left += left;
453-
clientRect.right = clientRect.left + clientRect.width;
454-
}
455-
456442
/**
457443
* Gets the index of an item in the drop container, based on the position of the user's pointer.
458444
* @param item Item that is being sorted.
459445
* @param pointerX Position of the user's pointer along the X axis.
460446
* @param pointerY Position of the user's pointer along the Y axis.
461447
* @param delta Direction in which the user is moving their pointer.
462448
*/
463-
private _getItemIndexFromPointerPosition(item: CdkDrag, pointerX: number, pointerY: number,
449+
protected _getItemIndexFromPointerPosition(item: CdkDrag, pointerX: number, pointerY: number,
464450
delta?: {x: number, y: number}) {
465451

466452
const isHorizontal = this.orientation === 'horizontal';
@@ -495,7 +481,7 @@ export class CdkDropList<T = any> implements OnInit, OnDestroy {
495481
* @param pointerX Coordinates along the X axis.
496482
* @param pointerY Coordinates along the Y axis.
497483
*/
498-
private _isPointerNearDropContainer(pointerX: number, pointerY: number): boolean {
484+
protected _isPointerNearDropContainer(pointerX: number, pointerY: number): boolean {
499485
const {top, right, bottom, left, width, height} = this._positionCache.self;
500486
const xThreshold = width * DROP_PROXIMITY_THRESHOLD;
501487
const yThreshold = height * DROP_PROXIMITY_THRESHOLD;
@@ -510,7 +496,7 @@ export class CdkDropList<T = any> implements OnInit, OnDestroy {
510496
* @param newPosition Position of the item where the current item should be moved.
511497
* @param delta Direction in which the user is moving.
512498
*/
513-
private _getItemOffsetPx(currentPosition: ClientRect, newPosition: ClientRect, delta: 1 | -1) {
499+
protected _getItemOffsetPx(currentPosition: ClientRect, newPosition: ClientRect, delta: 1 | -1) {
514500
const isHorizontal = this.orientation === 'horizontal';
515501
let itemOffset = isHorizontal ? newPosition.left - currentPosition.left :
516502
newPosition.top - currentPosition.top;
@@ -530,7 +516,7 @@ export class CdkDropList<T = any> implements OnInit, OnDestroy {
530516
* @param siblings All of the items in the list.
531517
* @param delta Direction in which the user is moving.
532518
*/
533-
private _getSiblingOffsetPx(currentIndex: number,
519+
protected _getSiblingOffsetPx(currentIndex: number,
534520
siblings: ItemPositionCacheEntry[],
535521
delta: 1 | -1) {
536522

@@ -558,7 +544,7 @@ export class CdkDropList<T = any> implements OnInit, OnDestroy {
558544
}
559545

560546
/** Gets an array of unique drop lists that the current list is connected to. */
561-
private _getConnectedLists(): CdkDropList[] {
547+
protected _getConnectedLists(): CdkDropList[] {
562548
const siblings = coerceArray(this.connectedTo).map(drop => {
563549
return typeof drop === 'string' ? this._dragDropRegistry.getDropContainer(drop)! : drop;
564550
});
@@ -605,3 +591,17 @@ function isInsideClientRect(clientRect: ClientRect, x: number, y: number) {
605591
const {top, bottom, left, right} = clientRect;
606592
return y >= top && y <= bottom && x >= left && x <= right;
607593
}
594+
595+
/**
596+
* Updates the top/left positions of a `ClientRect`, as well as their bottom/right counterparts.
597+
* @param clientRect `ClientRect` that should be updated.
598+
* @param top Amount to add to the `top` position.
599+
* @param left Amount to add to the `left` position.
600+
*/
601+
function adjustClientRect(clientRect: ClientRect, top: number, left: number) {
602+
clientRect.top += top;
603+
clientRect.bottom = clientRect.top + clientRect.height;
604+
605+
clientRect.left += left;
606+
clientRect.right = clientRect.left + clientRect.width;
607+
}

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)