mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
feat(drag-drop): add service for attaching drag&drop to arbitrary DOM nodes (#14437)
* Adds the `DragDrop` service that simplifies the construction logic for `DragRef` and `DropListRef` and allows consumers to attach drag&drop functionality to arbitrary DOM nodes, rather than having to go through the directives. * Reworks `DragRef` and `DragDropRef` to make them easier to construct. * Normalizes some of the instances where some parameters only accept an `ElementRef`, whereas others accept `ElementRef | HTMLElement`.
This commit is contained in:
committed by
Andrew Seguin
parent
e66131744a
commit
5a18ea61e5
@@ -23,6 +23,7 @@ ng_test_library(
|
||||
name = "drag-drop_test_sources",
|
||||
srcs = glob(["**/*.spec.ts"]),
|
||||
deps = [
|
||||
"@rxjs",
|
||||
"//src/cdk/testing",
|
||||
"//src/cdk/bidi",
|
||||
":drag-drop",
|
||||
|
||||
@@ -21,6 +21,7 @@ import {
|
||||
createTouchEvent,
|
||||
} from '@angular/cdk/testing';
|
||||
import {Directionality} from '@angular/cdk/bidi';
|
||||
import {of as observableOf} from 'rxjs';
|
||||
import {CdkDrag, CDK_DRAG_CONFIG} from './drag';
|
||||
import {CdkDragDrop} from '../drag-events';
|
||||
import {moveItemInArray} from '../drag-utils';
|
||||
@@ -1140,7 +1141,7 @@ describe('CdkDrag', () => {
|
||||
it('should dispatch the correct `dropped` event in RTL horizontal drop zone', fakeAsync(() => {
|
||||
const fixture = createComponent(DraggableInHorizontalDropZone, [{
|
||||
provide: Directionality,
|
||||
useValue: ({value: 'rtl'})
|
||||
useValue: ({value: 'rtl', change: observableOf()})
|
||||
}]);
|
||||
|
||||
fixture.nativeElement.setAttribute('dir', 'rtl');
|
||||
@@ -1296,7 +1297,7 @@ describe('CdkDrag', () => {
|
||||
it('should pass the proper direction to the preview in rtl', fakeAsync(() => {
|
||||
const fixture = createComponent(DraggableInDropZone, [{
|
||||
provide: Directionality,
|
||||
useValue: ({value: 'rtl'})
|
||||
useValue: ({value: 'rtl', change: observableOf()})
|
||||
}]);
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
@@ -50,6 +50,7 @@ import {CDK_DRAG_PARENT} from '../drag-parent';
|
||||
import {DragRef, DragRefConfig} from '../drag-ref';
|
||||
import {DropListRef} from '../drop-list-ref';
|
||||
import {CdkDropListInternal as CdkDropList} from './drop-list';
|
||||
import {DragDrop} from '../drag-drop';
|
||||
|
||||
/** Injection token that can be used to configure the behavior of `CdkDrag`. */
|
||||
export const CDK_DRAG_CONFIG = new InjectionToken<DragRefConfig>('CDK_DRAG_CONFIG', {
|
||||
@@ -167,18 +168,30 @@ export class CdkDrag<T = any> implements AfterViewInit, OnChanges, OnDestroy {
|
||||
@Inject(DOCUMENT) private _document: any,
|
||||
private _ngZone: NgZone,
|
||||
private _viewContainerRef: ViewContainerRef,
|
||||
private _viewportRuler: ViewportRuler,
|
||||
private _dragDropRegistry: DragDropRegistry<DragRef, DropListRef>,
|
||||
@Inject(CDK_DRAG_CONFIG) private _config: DragRefConfig,
|
||||
@Optional() private _dir: Directionality) {
|
||||
viewportRuler: ViewportRuler,
|
||||
dragDropRegistry: DragDropRegistry<DragRef, DropListRef>,
|
||||
@Inject(CDK_DRAG_CONFIG) config: DragRefConfig,
|
||||
@Optional() private _dir: Directionality,
|
||||
|
||||
const ref = this._dragRef = new DragRef(element, this._document, this._ngZone,
|
||||
this._viewContainerRef, this._viewportRuler, this._dragDropRegistry,
|
||||
this._config, this.dropContainer ? this.dropContainer._dropListRef : undefined,
|
||||
this._dir);
|
||||
ref.data = this;
|
||||
this._syncInputs(ref);
|
||||
this._proxyEvents(ref);
|
||||
/**
|
||||
* @deprecated `viewportRuler` and `dragDropRegistry` parameters
|
||||
* to be removed. Also `dragDrop` parameter to be made required.
|
||||
* @breaking-change 8.0.0.
|
||||
*/
|
||||
dragDrop?: DragDrop) {
|
||||
|
||||
|
||||
// @breaking-change 8.0.0 Remove null check once the paramter is made required.
|
||||
if (dragDrop) {
|
||||
this._dragRef = dragDrop.createDrag(element, config);
|
||||
} else {
|
||||
this._dragRef = new DragRef(element, config, _document, _ngZone, viewportRuler,
|
||||
dragDropRegistry);
|
||||
}
|
||||
|
||||
this._dragRef.data = this;
|
||||
this._syncInputs(this._dragRef);
|
||||
this._proxyEvents(this._dragRef);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -273,15 +286,28 @@ export class CdkDrag<T = any> implements AfterViewInit, OnChanges, OnDestroy {
|
||||
private _syncInputs(ref: DragRef<CdkDrag<T>>) {
|
||||
ref.beforeStarted.subscribe(() => {
|
||||
if (!ref.isDragging()) {
|
||||
const {_placeholderTemplate: placeholder, _previewTemplate: preview} = this;
|
||||
const dir = this._dir;
|
||||
const placeholder = this._placeholderTemplate ? {
|
||||
template: this._placeholderTemplate.templateRef,
|
||||
context: this._placeholderTemplate.data,
|
||||
viewContainer: this._viewContainerRef
|
||||
} : null;
|
||||
const preview = this._previewTemplate ? {
|
||||
template: this._previewTemplate.templateRef,
|
||||
context: this._previewTemplate.data,
|
||||
viewContainer: this._viewContainerRef
|
||||
} : null;
|
||||
|
||||
ref.disabled = this.disabled;
|
||||
ref.lockAxis = this.lockAxis;
|
||||
ref.withBoundaryElement(this._getBoundaryElement());
|
||||
placeholder ? ref.withPlaceholderTemplate(placeholder.templateRef, placeholder.data) :
|
||||
ref.withPlaceholderTemplate(null);
|
||||
preview ? ref.withPreviewTemplate(preview.templateRef, preview.data) :
|
||||
ref.withPreviewTemplate(null);
|
||||
ref
|
||||
.withBoundaryElement(this._getBoundaryElement())
|
||||
.withPlaceholderTemplate(placeholder)
|
||||
.withPreviewTemplate(preview);
|
||||
|
||||
if (dir) {
|
||||
ref.withDirection(dir.value);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import {
|
||||
ChangeDetectorRef,
|
||||
SkipSelf,
|
||||
Inject,
|
||||
AfterContentInit,
|
||||
} from '@angular/core';
|
||||
import {DOCUMENT} from '@angular/common';
|
||||
import {Directionality} from '@angular/cdk/bidi';
|
||||
@@ -31,6 +32,9 @@ import {CDK_DROP_LIST_CONTAINER, CdkDropListContainer} from '../drop-list-contai
|
||||
import {CdkDropListGroup} from './drop-list-group';
|
||||
import {DropListRef} from '../drop-list-ref';
|
||||
import {DragRef} from '../drag-ref';
|
||||
import {DragDrop} from '../drag-drop';
|
||||
import {Subject} from 'rxjs';
|
||||
import {startWith, takeUntil} from 'rxjs/operators';
|
||||
|
||||
/** Counter used to generate unique ids for drop zones. */
|
||||
let _uniqueIdCounter = 0;
|
||||
@@ -62,7 +66,10 @@ export interface CdkDropListInternal extends CdkDropList {}
|
||||
'[class.cdk-drop-list-receiving]': '_dropListRef.isReceiving()',
|
||||
}
|
||||
})
|
||||
export class CdkDropList<T = any> implements CdkDropListContainer, OnDestroy {
|
||||
export class CdkDropList<T = any> implements CdkDropListContainer, AfterContentInit, OnDestroy {
|
||||
/** Emits when the list has been destroyed. */
|
||||
private _destroyed = new Subject<void>();
|
||||
|
||||
/** Keeps track of the drop lists that are currently on the page. */
|
||||
private static _dropLists: CdkDropList[] = [];
|
||||
|
||||
@@ -70,7 +77,11 @@ export class CdkDropList<T = any> implements CdkDropListContainer, OnDestroy {
|
||||
_dropListRef: DropListRef<CdkDropList<T>>;
|
||||
|
||||
/** Draggable items in the container. */
|
||||
@ContentChildren(forwardRef(() => CdkDrag)) _draggables: QueryList<CdkDrag>;
|
||||
@ContentChildren(forwardRef(() => CdkDrag), {
|
||||
// Explicitly set to false since some of the logic below makes assumptions about it.
|
||||
// The `.withItems` call below should be updated if we ever need to switch this to `true`.
|
||||
descendants: false
|
||||
}) _draggables: QueryList<CdkDrag>;
|
||||
|
||||
/**
|
||||
* Other draggable containers that this container is connected to and into which the
|
||||
@@ -134,24 +145,35 @@ export class CdkDropList<T = any> implements CdkDropListContainer, OnDestroy {
|
||||
sorted: EventEmitter<CdkDragSortEvent<T>> = new EventEmitter<CdkDragSortEvent<T>>();
|
||||
|
||||
constructor(
|
||||
/** Element that the drop list is attached to. */
|
||||
public element: ElementRef<HTMLElement>,
|
||||
dragDropRegistry: DragDropRegistry<DragRef, DropListRef>,
|
||||
private _changeDetectorRef: ChangeDetectorRef,
|
||||
@Optional() dir?: Directionality,
|
||||
@Optional() private _dir?: Directionality,
|
||||
@Optional() @SkipSelf() private _group?: CdkDropListGroup<CdkDropList>,
|
||||
// @breaking-change 8.0.0 `_document` parameter to be made required.
|
||||
@Optional() @Inject(DOCUMENT) _document?: any) {
|
||||
@Optional() @Inject(DOCUMENT) _document?: any,
|
||||
|
||||
/**
|
||||
* @deprecated `dragDropRegistry` and `_document` parameters to be removed.
|
||||
* Also `dragDrop` parameter to be made required.
|
||||
* @breaking-change 8.0.0.
|
||||
*/
|
||||
dragDrop?: DragDrop) {
|
||||
|
||||
// @breaking-change 8.0.0 Remove || once `_document` parameter is required.
|
||||
const ref = this._dropListRef = new DropListRef(element, dragDropRegistry,
|
||||
_document || document, dir);
|
||||
ref.data = this;
|
||||
ref.enterPredicate = (drag: DragRef<CdkDrag>, drop: DropListRef<CdkDropList>) => {
|
||||
// @breaking-change 8.0.0 Remove null check once `dragDrop` parameter is made required.
|
||||
if (dragDrop) {
|
||||
this._dropListRef = dragDrop.createDropList(element);
|
||||
} else {
|
||||
this._dropListRef = new DropListRef(element, dragDropRegistry, _document || document);
|
||||
}
|
||||
|
||||
this._dropListRef.data = this;
|
||||
this._dropListRef.enterPredicate = (drag: DragRef<CdkDrag>, drop: DropListRef<CdkDropList>) => {
|
||||
return this.enterPredicate(drag.data, drop.data);
|
||||
};
|
||||
this._syncInputs(ref);
|
||||
this._handleEvents(ref);
|
||||
|
||||
this._syncInputs(this._dropListRef);
|
||||
this._handleEvents(this._dropListRef);
|
||||
CdkDropList._dropLists.push(this);
|
||||
|
||||
if (_group) {
|
||||
@@ -159,9 +181,16 @@ export class CdkDropList<T = any> implements CdkDropListContainer, OnDestroy {
|
||||
}
|
||||
}
|
||||
|
||||
ngAfterContentInit() {
|
||||
this._draggables.changes
|
||||
.pipe(startWith(this._draggables), takeUntil(this._destroyed))
|
||||
.subscribe((items: QueryList<CdkDrag>) => {
|
||||
this._dropListRef.withItems(items.map(drag => drag._dragRef));
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
const index = CdkDropList._dropLists.indexOf(this);
|
||||
this._dropListRef.dispose();
|
||||
|
||||
if (index > -1) {
|
||||
CdkDropList._dropLists.splice(index, 1);
|
||||
@@ -170,6 +199,10 @@ export class CdkDropList<T = any> implements CdkDropListContainer, OnDestroy {
|
||||
if (this._group) {
|
||||
this._group._items.delete(this);
|
||||
}
|
||||
|
||||
this._dropListRef.dispose();
|
||||
this._destroyed.next();
|
||||
this._destroyed.complete();
|
||||
}
|
||||
|
||||
/** Starts dragging an item. */
|
||||
@@ -253,6 +286,12 @@ export class CdkDropList<T = any> implements CdkDropListContainer, OnDestroy {
|
||||
|
||||
/** Syncs the inputs of the CdkDropList with the options of the underlying DropListRef. */
|
||||
private _syncInputs(ref: DropListRef<CdkDropList>) {
|
||||
if (this._dir) {
|
||||
this._dir.change
|
||||
.pipe(startWith(this._dir.value), takeUntil(this._destroyed))
|
||||
.subscribe(value => ref.withDirection(value));
|
||||
}
|
||||
|
||||
ref.beforeStarted.subscribe(() => {
|
||||
const siblings = coerceArray(this.connectedTo).map(drop => {
|
||||
return typeof drop === 'string' ?
|
||||
@@ -270,8 +309,7 @@ export class CdkDropList<T = any> implements CdkDropListContainer, OnDestroy {
|
||||
ref.lockAxis = this.lockAxis;
|
||||
ref
|
||||
.connectedTo(siblings.filter(drop => drop && drop !== this).map(list => list._dropListRef))
|
||||
.withOrientation(this.orientation)
|
||||
.withItems(this._draggables.map(drag => drag._dragRef));
|
||||
.withOrientation(this.orientation);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import {CdkDrag} from './directives/drag';
|
||||
import {CdkDragHandle} from './directives/drag-handle';
|
||||
import {CdkDragPreview} from './directives/drag-preview';
|
||||
import {CdkDragPlaceholder} from './directives/drag-placeholder';
|
||||
import {DragDrop} from './drag-drop';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
@@ -31,5 +32,8 @@ import {CdkDragPlaceholder} from './directives/drag-placeholder';
|
||||
CdkDragPreview,
|
||||
CdkDragPlaceholder,
|
||||
],
|
||||
providers: [
|
||||
DragDrop,
|
||||
]
|
||||
})
|
||||
export class DragDropModule {}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
import {Component, ElementRef} from '@angular/core';
|
||||
import {fakeAsync, TestBed, inject} from '@angular/core/testing';
|
||||
import {DragDropModule} from './drag-drop-module';
|
||||
import {DragDrop} from './drag-drop';
|
||||
import {DragRef} from './drag-ref';
|
||||
import {DropListRef} from './drop-list-ref';
|
||||
|
||||
describe('DragDrop', () => {
|
||||
let service: DragDrop;
|
||||
|
||||
beforeEach(fakeAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [TestComponent],
|
||||
imports: [DragDropModule],
|
||||
});
|
||||
|
||||
TestBed.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(inject([DragDrop], (d: DragDrop) => {
|
||||
service = d;
|
||||
}));
|
||||
|
||||
it('should be able to attach a DragRef to a DOM node', () => {
|
||||
const fixture = TestBed.createComponent(TestComponent);
|
||||
fixture.detectChanges();
|
||||
const ref = service.createDrag(fixture.componentInstance.elementRef);
|
||||
|
||||
expect(ref instanceof DragRef).toBe(true);
|
||||
});
|
||||
|
||||
it('should be able to attach a DropListRef to a DOM node', () => {
|
||||
const fixture = TestBed.createComponent(TestComponent);
|
||||
fixture.detectChanges();
|
||||
const ref = service.createDropList(fixture.componentInstance.elementRef);
|
||||
|
||||
expect(ref instanceof DropListRef).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@Component({
|
||||
template: '<div></div>'
|
||||
})
|
||||
class TestComponent {
|
||||
constructor(public elementRef: ElementRef<HTMLElement>) {}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Injectable, Inject, NgZone, ElementRef} from '@angular/core';
|
||||
import {DOCUMENT} from '@angular/common';
|
||||
import {ViewportRuler} from '@angular/cdk/scrolling';
|
||||
import {DragRef, DragRefConfig} from './drag-ref';
|
||||
import {DropListRef} from './drop-list-ref';
|
||||
import {DragDropRegistry} from './drag-drop-registry';
|
||||
|
||||
/** Default configuration to be used when creating a `DragRef`. */
|
||||
const DEFAULT_CONFIG = {
|
||||
dragStartThreshold: 5,
|
||||
pointerDirectionChangeThreshold: 5
|
||||
};
|
||||
|
||||
/**
|
||||
* Service that allows for drag-and-drop functionality to be attached to DOM elements.
|
||||
*/
|
||||
@Injectable({providedIn: 'root'})
|
||||
export class DragDrop {
|
||||
constructor(
|
||||
@Inject(DOCUMENT) private _document: any,
|
||||
private _ngZone: NgZone,
|
||||
private _viewportRuler: ViewportRuler,
|
||||
private _dragDropRegistry: DragDropRegistry<DragRef, DropListRef>) {}
|
||||
|
||||
/**
|
||||
* Turns an element into a draggable item.
|
||||
* @param element Element to which to attach the dragging functionality.
|
||||
* @param config Object used to configure the dragging behavior.
|
||||
*/
|
||||
createDrag<T = any>(element: ElementRef<HTMLElement> | HTMLElement,
|
||||
config: DragRefConfig = DEFAULT_CONFIG): DragRef<T> {
|
||||
|
||||
return new DragRef<T>(element, config, this._document, this._ngZone, this._viewportRuler,
|
||||
this._dragDropRegistry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns an element into a drop list.
|
||||
* @param element Element to which to attach the drop list functionality.
|
||||
*/
|
||||
createDropList<T = any>(element: ElementRef<HTMLElement> | HTMLElement): DropListRef<T> {
|
||||
return new DropListRef<T>(element, this._dragDropRegistry, this._document);
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
import {EmbeddedViewRef, ElementRef, NgZone, ViewContainerRef, TemplateRef} from '@angular/core';
|
||||
import {ViewportRuler} from '@angular/cdk/scrolling';
|
||||
import {Directionality} from '@angular/cdk/bidi';
|
||||
import {Direction} from '@angular/cdk/bidi';
|
||||
import {normalizePassiveListenerOptions} from '@angular/cdk/platform';
|
||||
import {coerceBooleanProperty, coerceElement} from '@angular/cdk/coercion';
|
||||
import {Subscription, Subject, Observable, Observer} from 'rxjs';
|
||||
@@ -57,6 +57,13 @@ const MOUSE_EVENT_IGNORE_TIME = 800;
|
||||
*/
|
||||
export interface DragRefInternal extends DragRef {}
|
||||
|
||||
/** Template that can be used to create a drag helper element (e.g. a preview or a placeholder). */
|
||||
interface DragHelperTemplate<T = any> {
|
||||
template: TemplateRef<T> | null;
|
||||
viewContainer: ViewContainerRef;
|
||||
context: T;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reference to a draggable item. Used to manipulate or dispose of the item.
|
||||
* @docs-private
|
||||
@@ -173,10 +180,10 @@ export class DragRef<T = any> {
|
||||
private _boundaryRect?: ClientRect;
|
||||
|
||||
/** Element that will be used as a template to create the draggable item's preview. */
|
||||
private _previewTemplate?: {template: TemplateRef<any> | null, context?: any};
|
||||
private _previewTemplate?: DragHelperTemplate | null;
|
||||
|
||||
/** Template for placeholder element rendered to show where a draggable would be dropped. */
|
||||
private _placeholderTemplate?: {template: TemplateRef<any> | null, context?: any};
|
||||
private _placeholderTemplate?: DragHelperTemplate | null;
|
||||
|
||||
/** Elements that can be used to drag the draggable item. */
|
||||
private _handles: HTMLElement[] = [];
|
||||
@@ -184,12 +191,18 @@ export class DragRef<T = any> {
|
||||
/** Registered handles that are currently disabled. */
|
||||
private _disabledHandles = new Set<HTMLElement>();
|
||||
|
||||
/** Droppable container that the draggable is a part of. */
|
||||
private _dropContainer?: DropListRef;
|
||||
|
||||
/** Layout direction of the item. */
|
||||
private _direction: Direction = 'ltr';
|
||||
|
||||
/** Axis along which dragging is locked. */
|
||||
lockAxis: 'x' | 'y';
|
||||
|
||||
/** Whether starting to drag this element is disabled. */
|
||||
get disabled(): boolean {
|
||||
return this._disabled || !!(this.dropContainer && this.dropContainer.disabled);
|
||||
return this._disabled || !!(this._dropContainer && this._dropContainer.disabled);
|
||||
}
|
||||
set disabled(value: boolean) {
|
||||
const newValue = coerceBooleanProperty(value);
|
||||
@@ -253,15 +266,11 @@ export class DragRef<T = any> {
|
||||
|
||||
constructor(
|
||||
element: ElementRef<HTMLElement> | HTMLElement,
|
||||
private _config: DragRefConfig,
|
||||
private _document: Document,
|
||||
private _ngZone: NgZone,
|
||||
private _viewContainerRef: ViewContainerRef,
|
||||
private _viewportRuler: ViewportRuler,
|
||||
private _dragDropRegistry: DragDropRegistry<DragRef, DropListRef>,
|
||||
private _config: DragRefConfig,
|
||||
/** Droppable container that the draggable is a part of. */
|
||||
public dropContainer?: DropListRef,
|
||||
private _dir?: Directionality) {
|
||||
private _dragDropRegistry: DragDropRegistry<DragRef, DropListRef>) {
|
||||
|
||||
this.withRootElement(element);
|
||||
_dragDropRegistry.registerDragItem(this);
|
||||
@@ -291,20 +300,18 @@ export class DragRef<T = any> {
|
||||
/**
|
||||
* Registers the template that should be used for the drag preview.
|
||||
* @param template Template that from which to stamp out the preview.
|
||||
* @param context Variables to add to the template's context.
|
||||
*/
|
||||
withPreviewTemplate(template: TemplateRef<any> | null, context?: any): this {
|
||||
this._previewTemplate = {template, context};
|
||||
withPreviewTemplate(template: DragHelperTemplate | null): this {
|
||||
this._previewTemplate = template;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the template that should be used for the drag placeholder.
|
||||
* @param template Template that from which to stamp out the placeholder.
|
||||
* @param context Variables to add to the template's context.
|
||||
*/
|
||||
withPlaceholderTemplate(template: TemplateRef<any> | null, context?: any): this {
|
||||
this._placeholderTemplate = {template, context};
|
||||
withPlaceholderTemplate(template: DragHelperTemplate | null): this {
|
||||
this._placeholderTemplate = template;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -364,6 +371,7 @@ export class DragRef<T = any> {
|
||||
this._moveEvents.complete();
|
||||
this._handles = [];
|
||||
this._disabledHandles.clear();
|
||||
this._dropContainer = undefined;
|
||||
this._boundaryElement = this._rootElement = this._placeholderTemplate =
|
||||
this._previewTemplate = this._nextSibling = null!;
|
||||
}
|
||||
@@ -398,6 +406,17 @@ export class DragRef<T = any> {
|
||||
this._disabledHandles.delete(handle);
|
||||
}
|
||||
|
||||
/** Sets the layout direction of the draggable item. */
|
||||
withDirection(direction: Direction): this {
|
||||
this._direction = direction;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets the container that the item is part of. */
|
||||
_withDropContainer(container: DropListRef) {
|
||||
this._dropContainer = container;
|
||||
}
|
||||
|
||||
/** Unsubscribes from the global subscriptions. */
|
||||
private _removeSubscriptions() {
|
||||
this._pointerMoveSubscription.unsubscribe();
|
||||
@@ -482,7 +501,7 @@ export class DragRef<T = any> {
|
||||
event.preventDefault();
|
||||
this._updatePointerDirectionDelta(constrainedPointerPosition);
|
||||
|
||||
if (this.dropContainer) {
|
||||
if (this._dropContainer) {
|
||||
this._updateActiveDropContainer(constrainedPointerPosition);
|
||||
} else {
|
||||
const activeTransform = this._activeTransform;
|
||||
@@ -543,7 +562,7 @@ export class DragRef<T = any> {
|
||||
|
||||
this.released.next({source: this});
|
||||
|
||||
if (!this.dropContainer) {
|
||||
if (!this._dropContainer) {
|
||||
// Convert the active transform into a passive one. This means that next time
|
||||
// the user starts dragging the item, its position will be calculated relatively
|
||||
// to the new passive transform.
|
||||
@@ -569,7 +588,7 @@ export class DragRef<T = any> {
|
||||
this._lastTouchEventTime = Date.now();
|
||||
}
|
||||
|
||||
if (this.dropContainer) {
|
||||
if (this._dropContainer) {
|
||||
const element = this._rootElement;
|
||||
|
||||
// Grab the `nextSibling` before the preview and placeholder
|
||||
@@ -585,7 +604,7 @@ export class DragRef<T = any> {
|
||||
element.style.display = 'none';
|
||||
this._document.body.appendChild(element.parentNode!.replaceChild(placeholder, element));
|
||||
this._document.body.appendChild(preview);
|
||||
this.dropContainer.start();
|
||||
this._dropContainer.start();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -639,7 +658,7 @@ export class DragRef<T = any> {
|
||||
|
||||
this._toggleNativeDragInteractions();
|
||||
this._hasStartedDragging = this._hasMoved = false;
|
||||
this._initialContainer = this.dropContainer!;
|
||||
this._initialContainer = this._dropContainer!;
|
||||
this._pointerMoveSubscription = this._dragDropRegistry.pointerMove.subscribe(this._pointerMove);
|
||||
this._pointerUpSubscription = this._dragDropRegistry.pointerUp.subscribe(this._pointerUp);
|
||||
this._scrollPosition = this._viewportRuler.getViewportScrollPosition();
|
||||
@@ -670,7 +689,7 @@ export class DragRef<T = any> {
|
||||
if (this._nextSibling) {
|
||||
this._nextSibling.parentNode!.insertBefore(this._rootElement, this._nextSibling);
|
||||
} else {
|
||||
this._initialContainer.element.nativeElement.appendChild(this._rootElement);
|
||||
this._initialContainer.element.appendChild(this._rootElement);
|
||||
}
|
||||
|
||||
this._destroyPreview();
|
||||
@@ -679,7 +698,7 @@ export class DragRef<T = any> {
|
||||
|
||||
// Re-enter the NgZone since we bound `document` events on the outside.
|
||||
this._ngZone.run(() => {
|
||||
const container = this.dropContainer!;
|
||||
const container = this._dropContainer!;
|
||||
const currentIndex = container.getItemIndex(this);
|
||||
const {x, y} = this._getPointerPositionOnPage(event);
|
||||
const isPointerOverContainer = container._isOverContainer(x, y);
|
||||
@@ -694,7 +713,7 @@ export class DragRef<T = any> {
|
||||
isPointerOverContainer
|
||||
});
|
||||
container.drop(this, currentIndex, this._initialContainer, isPointerOverContainer);
|
||||
this.dropContainer = this._initialContainer;
|
||||
this._dropContainer = this._initialContainer;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -704,31 +723,31 @@ export class DragRef<T = any> {
|
||||
*/
|
||||
private _updateActiveDropContainer({x, y}: Point) {
|
||||
// Drop container that draggable has been moved into.
|
||||
let newContainer = this.dropContainer!._getSiblingContainerFromPosition(this, x, y) ||
|
||||
let newContainer = this._dropContainer!._getSiblingContainerFromPosition(this, x, y) ||
|
||||
this._initialContainer._getSiblingContainerFromPosition(this, x, y);
|
||||
|
||||
// If we couldn't find a new container to move the item into, and the item has left it's
|
||||
// initial container, check whether the it's over the initial container. This handles the
|
||||
// case where two containers are connected one way and the user tries to undo dragging an
|
||||
// item into a new container.
|
||||
if (!newContainer && this.dropContainer !== this._initialContainer &&
|
||||
if (!newContainer && this._dropContainer !== this._initialContainer &&
|
||||
this._initialContainer._isOverContainer(x, y)) {
|
||||
newContainer = this._initialContainer;
|
||||
}
|
||||
|
||||
if (newContainer && newContainer !== this.dropContainer) {
|
||||
if (newContainer && newContainer !== this._dropContainer) {
|
||||
this._ngZone.run(() => {
|
||||
// Notify the old container that the item has left.
|
||||
this.exited.next({item: this, container: this.dropContainer!});
|
||||
this.dropContainer!.exit(this);
|
||||
this.exited.next({item: this, container: this._dropContainer!});
|
||||
this._dropContainer!.exit(this);
|
||||
// Notify the new container that the item has entered.
|
||||
this.entered.next({item: this, container: newContainer!});
|
||||
this.dropContainer = newContainer!;
|
||||
this.dropContainer.enter(this, x, y);
|
||||
this._dropContainer = newContainer!;
|
||||
this._dropContainer.enter(this, x, y);
|
||||
});
|
||||
}
|
||||
|
||||
this.dropContainer!._sortItem(this, x, y, this._pointerDirectionDelta);
|
||||
this._dropContainer!._sortItem(this, x, y, this._pointerDirectionDelta);
|
||||
this._preview.style.transform =
|
||||
getTransform(x - this._pickupPositionInElement.x, y - this._pickupPositionInElement.y);
|
||||
}
|
||||
@@ -738,12 +757,13 @@ export class DragRef<T = any> {
|
||||
* and will be used as a preview of the element that is being dragged.
|
||||
*/
|
||||
private _createPreviewElement(): HTMLElement {
|
||||
const previewTemplate = this._previewTemplate;
|
||||
const previewConfig = this._previewTemplate;
|
||||
const previewTemplate = previewConfig ? previewConfig.template : null;
|
||||
let preview: HTMLElement;
|
||||
|
||||
if (previewTemplate && previewTemplate.template) {
|
||||
const viewRef = this._viewContainerRef.createEmbeddedView(previewTemplate.template,
|
||||
previewTemplate.context);
|
||||
if (previewTemplate) {
|
||||
const viewRef = previewConfig!.viewContainer.createEmbeddedView(previewTemplate,
|
||||
previewConfig!.context);
|
||||
preview = viewRef.rootNodes[0];
|
||||
this._previewRef = viewRef;
|
||||
preview.style.transform =
|
||||
@@ -771,7 +791,7 @@ export class DragRef<T = any> {
|
||||
toggleNativeDragInteractions(preview, false);
|
||||
|
||||
preview.classList.add('cdk-drag-preview');
|
||||
preview.setAttribute('dir', this._dir ? this._dir.value : 'ltr');
|
||||
preview.setAttribute('dir', this._direction);
|
||||
|
||||
return preview;
|
||||
}
|
||||
@@ -825,13 +845,14 @@ export class DragRef<T = any> {
|
||||
|
||||
/** Creates an element that will be shown instead of the current element while dragging. */
|
||||
private _createPlaceholderElement(): HTMLElement {
|
||||
const placeholderTemplate = this._placeholderTemplate;
|
||||
const placeholderConfig = this._placeholderTemplate;
|
||||
const placeholderTemplate = placeholderConfig ? placeholderConfig.template : null;
|
||||
let placeholder: HTMLElement;
|
||||
|
||||
if (placeholderTemplate && placeholderTemplate.template) {
|
||||
this._placeholderRef = this._viewContainerRef.createEmbeddedView(
|
||||
placeholderTemplate.template,
|
||||
placeholderTemplate.context
|
||||
if (placeholderTemplate) {
|
||||
this._placeholderRef = placeholderConfig!.viewContainer.createEmbeddedView(
|
||||
placeholderTemplate,
|
||||
placeholderConfig!.context
|
||||
);
|
||||
placeholder = this._placeholderRef.rootNodes[0];
|
||||
} else {
|
||||
@@ -877,7 +898,7 @@ export class DragRef<T = any> {
|
||||
/** Gets the pointer position on the page, accounting for any position constraints. */
|
||||
private _getConstrainedPointerPosition(event: MouseEvent | TouchEvent): Point {
|
||||
const point = this._getPointerPositionOnPage(event);
|
||||
const dropContainerLock = this.dropContainer ? this.dropContainer.lockAxis : null;
|
||||
const dropContainerLock = this._dropContainer ? this._dropContainer.lockAxis : null;
|
||||
|
||||
if (this.lockAxis === 'x' || dropContainerLock === 'x') {
|
||||
point.y = this._pickupPositionOnPage.y;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
import {ElementRef} from '@angular/core';
|
||||
import {DragDropRegistry} from './drag-drop-registry';
|
||||
import {Directionality} from '@angular/cdk/bidi';
|
||||
import {Direction} from '@angular/cdk/bidi';
|
||||
import {Subject} from 'rxjs';
|
||||
import {moveItemInArray} from './drag-utils';
|
||||
import {DragRefInternal as DragRef} from './drag-ref';
|
||||
@@ -50,6 +50,9 @@ export interface DropListRefInternal extends DropListRef {}
|
||||
export class DropListRef<T = any> {
|
||||
private _document: Document;
|
||||
|
||||
/** Element that the drop list is attached to. */
|
||||
readonly element: HTMLElement;
|
||||
|
||||
/**
|
||||
* Unique ID for the drop list.
|
||||
* @deprecated No longer being used. To be removed.
|
||||
@@ -138,13 +141,16 @@ export class DropListRef<T = any> {
|
||||
/** Connected siblings that currently have a dragged item. */
|
||||
private _activeSiblings = new Set<DropListRef>();
|
||||
|
||||
/** Layout direction of the drop list. */
|
||||
private _direction: Direction = 'ltr';
|
||||
|
||||
constructor(
|
||||
public element: ElementRef<HTMLElement>,
|
||||
element: ElementRef<HTMLElement> | HTMLElement,
|
||||
private _dragDropRegistry: DragDropRegistry<DragRef, DropListRef>,
|
||||
_document: any,
|
||||
private _dir?: Directionality) {
|
||||
_document: any) {
|
||||
_dragDropRegistry.registerDropContainer(this);
|
||||
this._document = _document;
|
||||
this.element = element instanceof ElementRef ? element.nativeElement : element;
|
||||
}
|
||||
|
||||
/** Removes the drop list functionality from the DOM element. */
|
||||
@@ -203,7 +209,7 @@ export class DropListRef<T = any> {
|
||||
element.parentElement!.insertBefore(placeholder, element);
|
||||
this._activeDraggables.splice(newIndex, 0, item);
|
||||
} else {
|
||||
this.element.nativeElement.appendChild(placeholder);
|
||||
this.element.appendChild(placeholder);
|
||||
this._activeDraggables.push(item);
|
||||
}
|
||||
|
||||
@@ -251,6 +257,13 @@ export class DropListRef<T = any> {
|
||||
*/
|
||||
withItems(items: DragRef[]): this {
|
||||
this._draggables = items.slice();
|
||||
items.forEach(item => item._withDropContainer(this));
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Sets the layout direction of the drop list. */
|
||||
withDirection(direction: Direction): this {
|
||||
this._direction = direction;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -285,7 +298,7 @@ export class DropListRef<T = any> {
|
||||
// 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.
|
||||
const items = this._orientation === 'horizontal' && this._dir && this._dir.value === 'rtl' ?
|
||||
const items = this._orientation === 'horizontal' && this._direction === 'rtl' ?
|
||||
this._itemPositions.slice().reverse() : this._itemPositions;
|
||||
|
||||
return findIndex(items, currentItem => currentItem.drag === item);
|
||||
@@ -382,7 +395,7 @@ export class DropListRef<T = any> {
|
||||
|
||||
/** Caches the position of the drop list. */
|
||||
private _cacheOwnPosition() {
|
||||
this._clientRect = this.element.nativeElement.getBoundingClientRect();
|
||||
this._clientRect = this.element.getBoundingClientRect();
|
||||
}
|
||||
|
||||
/** Refreshes the position cache of the items and sibling containers. */
|
||||
@@ -574,15 +587,13 @@ export class DropListRef<T = any> {
|
||||
return false;
|
||||
}
|
||||
|
||||
const element = this.element.nativeElement;
|
||||
|
||||
// The `ClientRect`, that we're using to find the container over which the user is
|
||||
// hovering, doesn't give us any information on whether the element has been scrolled
|
||||
// out of the view or whether it's overlapping with other containers. This means that
|
||||
// we could end up transferring the item into a container that's invisible or is positioned
|
||||
// below another one. We use the result from `elementFromPoint` to get the top-most element
|
||||
// at the pointer position and to find whether it's one of the intersecting drop containers.
|
||||
return elementFromPoint === element || element.contains(elementFromPoint);
|
||||
return elementFromPoint === this.element || this.element.contains(elementFromPoint);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
// TODO(crisbeto): export once API is finalized
|
||||
// export * from './drag-ref';
|
||||
// export * from './drop-list-ref';
|
||||
export {DragDrop} from './drag-drop';
|
||||
export {DragRef, DragRefConfig} from './drag-ref';
|
||||
export {DropListRef} from './drop-list-ref';
|
||||
|
||||
export * from './drop-list-container';
|
||||
export * from './drag-events';
|
||||
@@ -16,7 +16,7 @@ export * from './drag-utils';
|
||||
export * from './drag-drop-module';
|
||||
export * from './drag-drop-registry';
|
||||
|
||||
export * from './directives/drop-list';
|
||||
export {CdkDropList} from './directives/drop-list';
|
||||
export * from './directives/drop-list-group';
|
||||
export * from './directives/drag';
|
||||
export * from './directives/drag-handle';
|
||||
|
||||
+131
-6
@@ -27,7 +27,8 @@ export declare class CdkDrag<T = any> implements AfterViewInit, OnChanges, OnDes
|
||||
started: EventEmitter<CdkDragStart>;
|
||||
constructor(
|
||||
element: ElementRef<HTMLElement>,
|
||||
dropContainer: CdkDropList, _document: any, _ngZone: NgZone, _viewContainerRef: ViewContainerRef, _viewportRuler: ViewportRuler, _dragDropRegistry: DragDropRegistry<DragRef, DropListRef>, _config: DragRefConfig, _dir: Directionality);
|
||||
dropContainer: CdkDropList, _document: any, _ngZone: NgZone, _viewContainerRef: ViewContainerRef, viewportRuler: ViewportRuler, dragDropRegistry: DragDropRegistry<DragRef, DropListRef>, config: DragRefConfig, _dir: Directionality,
|
||||
dragDrop?: DragDrop);
|
||||
getPlaceholderElement(): HTMLElement;
|
||||
getRootElement(): HTMLElement;
|
||||
ngAfterViewInit(): void;
|
||||
@@ -111,7 +112,7 @@ export interface CdkDragStart<T = any> {
|
||||
source: CdkDrag<T>;
|
||||
}
|
||||
|
||||
export declare class CdkDropList<T = any> implements CdkDropListContainer, OnDestroy {
|
||||
export declare class CdkDropList<T = any> implements CdkDropListContainer, AfterContentInit, OnDestroy {
|
||||
_draggables: QueryList<CdkDrag>;
|
||||
_dropListRef: DropListRef<CdkDropList<T>>;
|
||||
connectedTo: (CdkDropList | string)[] | CdkDropList | string;
|
||||
@@ -126,7 +127,9 @@ export declare class CdkDropList<T = any> implements CdkDropListContainer, OnDes
|
||||
lockAxis: 'x' | 'y';
|
||||
orientation: 'horizontal' | 'vertical';
|
||||
sorted: EventEmitter<CdkDragSortEvent<T>>;
|
||||
constructor(element: ElementRef<HTMLElement>, dragDropRegistry: DragDropRegistry<DragRef, DropListRef>, _changeDetectorRef: ChangeDetectorRef, dir?: Directionality, _group?: CdkDropListGroup<CdkDropList<any>> | undefined, _document?: any);
|
||||
constructor(
|
||||
element: ElementRef<HTMLElement>, dragDropRegistry: DragDropRegistry<DragRef, DropListRef>, _changeDetectorRef: ChangeDetectorRef, _dir?: Directionality | undefined, _group?: CdkDropListGroup<CdkDropList<any>> | undefined, _document?: any,
|
||||
dragDrop?: DragDrop);
|
||||
_getSiblingContainerFromPosition(item: CdkDrag, x: number, y: number): CdkDropListContainer | null;
|
||||
_isOverContainer(x: number, y: number): boolean;
|
||||
_sortItem(item: CdkDrag, pointerX: number, pointerY: number, pointerDelta: {
|
||||
@@ -137,6 +140,7 @@ export declare class CdkDropList<T = any> implements CdkDropListContainer, OnDes
|
||||
enter(item: CdkDrag, pointerX: number, pointerY: number): void;
|
||||
exit(item: CdkDrag): void;
|
||||
getItemIndex(item: CdkDrag): number;
|
||||
ngAfterContentInit(): void;
|
||||
ngOnDestroy(): void;
|
||||
start(): void;
|
||||
}
|
||||
@@ -168,11 +172,14 @@ export declare class CdkDropListGroup<T> implements OnDestroy {
|
||||
ngOnDestroy(): void;
|
||||
}
|
||||
|
||||
export interface CdkDropListInternal extends CdkDropList {
|
||||
}
|
||||
|
||||
export declare function copyArrayItem<T = any>(currentArray: T[], targetArray: T[], currentIndex: number, targetIndex: number): void;
|
||||
|
||||
export declare class DragDrop {
|
||||
constructor(_document: any, _ngZone: NgZone, _viewportRuler: ViewportRuler, _dragDropRegistry: DragDropRegistry<DragRef, DropListRef>);
|
||||
createDrag<T = any>(element: ElementRef<HTMLElement> | HTMLElement, config?: DragRefConfig): DragRef<T>;
|
||||
createDropList<T = any>(element: ElementRef<HTMLElement> | HTMLElement): DropListRef<T>;
|
||||
}
|
||||
|
||||
export declare class DragDropModule {
|
||||
}
|
||||
|
||||
@@ -193,6 +200,124 @@ export declare class DragDropRegistry<I, C extends {
|
||||
stopDragging(drag: I): void;
|
||||
}
|
||||
|
||||
export declare class DragRef<T = any> {
|
||||
beforeStarted: Subject<void>;
|
||||
data: T;
|
||||
disabled: boolean;
|
||||
dropped: Subject<{
|
||||
previousIndex: number;
|
||||
currentIndex: number;
|
||||
item: DragRef<any>;
|
||||
container: DropListRef;
|
||||
previousContainer: DropListRef;
|
||||
isPointerOverContainer: boolean;
|
||||
}>;
|
||||
ended: Subject<{
|
||||
source: DragRef<any>;
|
||||
}>;
|
||||
entered: Subject<{
|
||||
container: DropListRef;
|
||||
item: DragRef<any>;
|
||||
}>;
|
||||
exited: Subject<{
|
||||
container: DropListRef;
|
||||
item: DragRef<any>;
|
||||
}>;
|
||||
lockAxis: 'x' | 'y';
|
||||
moved: Observable<{
|
||||
source: DragRef;
|
||||
pointerPosition: {
|
||||
x: number;
|
||||
y: number;
|
||||
};
|
||||
event: MouseEvent | TouchEvent;
|
||||
delta: {
|
||||
x: -1 | 0 | 1;
|
||||
y: -1 | 0 | 1;
|
||||
};
|
||||
}>;
|
||||
released: Subject<{
|
||||
source: DragRef<any>;
|
||||
}>;
|
||||
started: Subject<{
|
||||
source: DragRef<any>;
|
||||
}>;
|
||||
constructor(element: ElementRef<HTMLElement> | HTMLElement, _config: DragRefConfig, _document: Document, _ngZone: NgZone, _viewportRuler: ViewportRuler, _dragDropRegistry: DragDropRegistry<DragRef, DropListRef>);
|
||||
_withDropContainer(container: DropListRef): void;
|
||||
disableHandle(handle: HTMLElement): void;
|
||||
dispose(): void;
|
||||
enableHandle(handle: HTMLElement): void;
|
||||
getPlaceholderElement(): HTMLElement;
|
||||
getRootElement(): HTMLElement;
|
||||
isDragging(): boolean;
|
||||
reset(): void;
|
||||
withBoundaryElement(boundaryElement: ElementRef<HTMLElement> | HTMLElement | null): this;
|
||||
withDirection(direction: Direction): this;
|
||||
withHandles(handles: (HTMLElement | ElementRef<HTMLElement>)[]): this;
|
||||
withPlaceholderTemplate(template: DragHelperTemplate | null): this;
|
||||
withPreviewTemplate(template: DragHelperTemplate | null): this;
|
||||
withRootElement(rootElement: ElementRef<HTMLElement> | HTMLElement): this;
|
||||
}
|
||||
|
||||
export interface DragRefConfig {
|
||||
dragStartThreshold: number;
|
||||
pointerDirectionChangeThreshold: number;
|
||||
}
|
||||
|
||||
export declare class DropListRef<T = any> {
|
||||
beforeStarted: Subject<void>;
|
||||
data: T;
|
||||
disabled: boolean;
|
||||
dropped: Subject<{
|
||||
item: DragRef;
|
||||
currentIndex: number;
|
||||
previousIndex: number;
|
||||
container: DropListRef<any>;
|
||||
previousContainer: DropListRef<any>;
|
||||
isPointerOverContainer: boolean;
|
||||
}>;
|
||||
readonly element: HTMLElement;
|
||||
enterPredicate: (drag: DragRef, drop: DropListRef) => boolean;
|
||||
entered: Subject<{
|
||||
item: DragRef;
|
||||
container: DropListRef<any>;
|
||||
}>;
|
||||
exited: Subject<{
|
||||
item: DragRef;
|
||||
container: DropListRef<any>;
|
||||
}>;
|
||||
id: string;
|
||||
lockAxis: 'x' | 'y';
|
||||
sorted: Subject<{
|
||||
previousIndex: number;
|
||||
currentIndex: number;
|
||||
container: DropListRef<any>;
|
||||
item: DragRef;
|
||||
}>;
|
||||
constructor(element: ElementRef<HTMLElement> | HTMLElement, _dragDropRegistry: DragDropRegistry<DragRef, DropListRef>, _document: any);
|
||||
_canReceive(item: DragRef, x: number, y: number): boolean;
|
||||
_getSiblingContainerFromPosition(item: DragRef, x: number, y: number): DropListRef | undefined;
|
||||
_isOverContainer(x: number, y: number): boolean;
|
||||
_sortItem(item: DragRef, pointerX: number, pointerY: number, pointerDelta: {
|
||||
x: number;
|
||||
y: number;
|
||||
}): void;
|
||||
_startReceiving(sibling: DropListRef): void;
|
||||
_stopReceiving(sibling: DropListRef): void;
|
||||
connectedTo(connectedTo: DropListRef[]): this;
|
||||
dispose(): void;
|
||||
drop(item: DragRef, currentIndex: number, previousContainer: DropListRef, isPointerOverContainer: boolean): void;
|
||||
enter(item: DragRef, pointerX: number, pointerY: number): void;
|
||||
exit(item: DragRef): void;
|
||||
getItemIndex(item: DragRef): number;
|
||||
isDragging(): boolean;
|
||||
isReceiving(): boolean;
|
||||
start(): void;
|
||||
withDirection(direction: Direction): this;
|
||||
withItems(items: DragRef[]): this;
|
||||
withOrientation(orientation: 'vertical' | 'horizontal'): this;
|
||||
}
|
||||
|
||||
export declare function moveItemInArray<T = any>(array: T[], fromIndex: number, toIndex: number): void;
|
||||
|
||||
export declare function transferArrayItem<T = any>(currentArray: T[], targetArray: T[], currentIndex: number, targetIndex: number): void;
|
||||
|
||||
Reference in New Issue
Block a user