UNPKG

@swimlane/ngx-dnd

Version:

Drag and Drop for Angular2 and beyond!

145 lines (144 loc) 15.3 kB
import { Directive, ElementRef, HostListener, Input, Output, EventEmitter } from '@angular/core'; import { DroppableDirective } from './ngx-droppable.directive'; import { DrakeStoreService } from '../services/drake-store.service'; import * as i0 from "@angular/core"; import * as i1 from "../services/drake-store.service"; import * as i2 from "./ngx-droppable.directive"; /** * Adds properties and events to draggable elements * * @export */ export class DraggableDirective { el; drakesService; droppableDirective; ngxDraggable; model; get dropZones() { return this._dropZones || this.ngxDraggable || this._parentDropzones; } set dropZones(val) { this._dropZones = val; } _moves = true; /* ContentChildren doesn't get children created with NgTemplateOutlet See https://github.com/angular/angular/issues/14842 Implemented via updateElements method @ContentChildren(DragHandleDirective, {descendants: true}) handlesList: QueryList<DragHandleDirective>; */ handles = []; get hasHandle() { return !!this.handles.length; } drag = new EventEmitter(); dragDelay = 200; // milliseconds dragDelayed = true; touchTimeout; get element() { return this.el.nativeElement; } _dropZones; _parentDropzones; constructor(el, drakesService, droppableDirective) { this.el = el; this.drakesService = drakesService; this.droppableDirective = droppableDirective; } // From: https://github.com/bevacqua/dragula/issues/289#issuecomment-277143172 onMove(e) { if (!this._moves || this.dragDelayed) { e.stopPropagation(); clearTimeout(this.touchTimeout); } } onDown() { if (this._moves) { this.touchTimeout = setTimeout(() => { this.dragDelayed = false; }, this.dragDelay); } } onUp() { if (this._moves) { clearTimeout(this.touchTimeout); this.dragDelayed = true; } } ngOnInit() { this.update(); } update() { this._parentDropzones = [this.droppableDirective.dropZone]; this.drakesService.registerDraggable(this); this.updateElements(); } ngOnDestroy() { this.drakesService.removeDraggable(this); } updateElements() { const nativeElement = this.el.nativeElement; const handles = nativeElement.querySelectorAll('[ngxdraghandle]'); this.handles = Array.from(handles).filter((h) => findFirstDraggableParent(h) === nativeElement); function findFirstDraggableParent(c) { while (c.parentNode) { c = c.parentNode; if (c.hasAttribute && c.hasAttribute('ngxdraggable')) { return c; } } } } canMove(source, handle, sibling) { if (typeof this._moves === 'boolean') return this._moves; if (typeof this._moves === 'function') return this._moves(this.model, source, handle, sibling); return true; } moves(source, handle, sibling) { if (!this.canMove(source, handle, sibling)) return false; return this.hasHandle ? this.handles.some(h => handelFor(handle, h)) : true; function handelFor(c, p) { if (c === p) return true; while ((c = c.parentNode) && c !== p) ; // tslint:disable-line return !!c; } } ngDoCheck() { this.updateElements(); } static ɵfac = function DraggableDirective_Factory(t) { return new (t || DraggableDirective)(i0.ɵɵdirectiveInject(i0.ElementRef), i0.ɵɵdirectiveInject(i1.DrakeStoreService), i0.ɵɵdirectiveInject(i2.DroppableDirective)); }; static ɵdir = /*@__PURE__*/ i0.ɵɵdefineDirective({ type: DraggableDirective, selectors: [["", "ngxDraggable", ""]], hostBindings: function DraggableDirective_HostBindings(rf, ctx) { if (rf & 1) { i0.ɵɵlistener("touchmove", function DraggableDirective_touchmove_HostBindingHandler($event) { return ctx.onMove($event); })("touchstart", function DraggableDirective_touchstart_HostBindingHandler() { return ctx.onDown(); })("touchend", function DraggableDirective_touchend_HostBindingHandler() { return ctx.onUp(); }); } }, inputs: { ngxDraggable: "ngxDraggable", model: "model", dropZones: "dropZones", _moves: [0, "moves", "_moves"] }, outputs: { drag: "drag" } }); } (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(DraggableDirective, [{ type: Directive, args: [{ selector: '[ngxDraggable]' }] }], () => [{ type: i0.ElementRef }, { type: i1.DrakeStoreService }, { type: i2.DroppableDirective }], { ngxDraggable: [{ type: Input }], model: [{ type: Input }], dropZones: [{ type: Input }], _moves: [{ type: Input, args: ['moves'] }], drag: [{ type: Output }], onMove: [{ type: HostListener, args: ['touchmove', ['$event']] }], onDown: [{ type: HostListener, args: ['touchstart'] }], onUp: [{ type: HostListener, args: ['touchend'] }] }); })(); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWRyYWdnYWJsZS5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zd2ltbGFuZS9uZ3gtZG5kL3NyYy9saWIvZGlyZWN0aXZlcy9uZ3gtZHJhZ2dhYmxlLmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQXFCLE1BQU0sZUFBZSxDQUFDO0FBRXBILE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQy9ELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGlDQUFpQyxDQUFDOzs7O0FBRXBFOzs7O0dBSUc7QUFFSCxNQUFNLE9BQU8sa0JBQWtCO0lBMkNuQjtJQUNBO0lBQ0E7SUE1Q0QsWUFBWSxDQUFXO0lBQ3ZCLEtBQUssQ0FBTTtJQUVwQixJQUNJLFNBQVM7UUFDWCxPQUFPLElBQUksQ0FBQyxVQUFVLElBQUksSUFBSSxDQUFDLFlBQVksSUFBSSxJQUFJLENBQUMsZ0JBQWdCLENBQUM7SUFDdkUsQ0FBQztJQUNELElBQUksU0FBUyxDQUFDLEdBQVE7UUFDcEIsSUFBSSxDQUFDLFVBQVUsR0FBRyxHQUFHLENBQUM7SUFDeEIsQ0FBQztJQUVlLE1BQU0sR0FBd0MsSUFBSSxDQUFDO0lBRW5FOzs7Ozs7bURBTStDO0lBRS9DLE9BQU8sR0FBVSxFQUFFLENBQUM7SUFFcEIsSUFBSSxTQUFTO1FBQ1gsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUM7SUFDL0IsQ0FBQztJQUVTLElBQUksR0FBc0IsSUFBSSxZQUFZLEVBQU8sQ0FBQztJQUU1RCxTQUFTLEdBQVcsR0FBRyxDQUFDLENBQUMsZUFBZTtJQUN4QyxXQUFXLEdBQVksSUFBSSxDQUFDO0lBRTVCLFlBQVksQ0FBTTtJQUVsQixJ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QUMsWUFBWTtZQVUxQixJQUFJO2tCQURILFlBQVk7bUJBQUMsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERpcmVjdGl2ZSwgRWxlbWVudFJlZiwgSG9zdExpc3RlbmVyLCBJbnB1dCwgT3V0cHV0LCBFdmVudEVtaXR0ZXIsIE9uRGVzdHJveSwgT25Jbml0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IERyb3BwYWJsZURpcmVjdGl2ZSB9IGZyb20gJy4vbmd4LWRyb3BwYWJsZS5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgRHJha2VTdG9yZVNlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy9kcmFrZS1zdG9yZS5zZXJ2aWNlJztcblxuLyoqXG4gKiBBZGRzIHByb3BlcnRpZXMgYW5kIGV2ZW50cyB0byBkcmFnZ2FibGUgZWxlbWVudHNcbiAqXG4gKiBAZXhwb3J0XG4gKi9cbkBEaXJlY3RpdmUoeyBzZWxlY3RvcjogJ1tuZ3hEcmFnZ2FibGVdJyB9KVxuZXhwb3J0IGNsYXNzIERyYWdnYWJsZURpcmVjdGl2ZSBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgQElucHV0KCkgbmd4RHJhZ2dhYmxlOiBzdHJpbmdbXTtcbiAgQElucHV0KCkgbW9kZWw6IGFueTtcblxuICBASW5wdXQoKVxuICBnZXQgZHJvcFpvbmVzKCk6IGFueSB7XG4gICAgcmV0dXJuIHRoaXMuX2Ryb3Bab25lcyB8fCB0aGlzLm5neERyYWdnYWJsZSB8fCB0aGlzLl9wYXJlbnREcm9wem9uZXM7XG4gIH1cbiAgc2V0IGRyb3Bab25lcyh2YWw6IGFueSkge1xuICAgIHRoaXMuX2Ryb3Bab25lcyA9IHZhbDtcbiAgfVxuXG4gIEBJbnB1dCgnbW92ZXMnKSBfbW92ZXM6IGJvb2xlYW4gfCAoKC4uLmFyZ3M6IGFueVtdKSA9PiBhbnkpID0gdHJ1ZTtcblxuICAvKlxuICBDb250ZW50Q2hpbGRyZW4gZG9lc24ndCBnZXQgY2hpbGRyZW4gY3JlYXRlZCB3aXRoIE5nVGVtcGxhdGVPdXRsZXRcbiAgU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9hbmd1bGFyL2FuZ3VsYXIvaXNzdWVzLzE0ODQyXG4gIEltcGxlbWVudGVkIHZpYSB1cGRhdGVFbGVtZW50cyBtZXRob2RcblxuICBAQ29udGVudENoaWxkcmVuKERyYWdIYW5kbGVEaXJlY3RpdmUsIHtkZXNjZW5kYW50czogdHJ1ZX0pXG4gIGhhbmRsZXNMaXN0OiBRdWVyeUxpc3Q8RHJhZ0hhbmRsZURpcmVjdGl2ZT47ICovXG5cbiAgaGFuZGxlczogYW55W10gPSBbXTtcblxuICBnZXQgaGFzSGFuZGxlKCkge1xuICAgIHJldHVybiAhIXRoaXMuaGFuZGxlcy5sZW5ndGg7XG4gIH1cblxuICBAT3V0cHV0KCkgZHJhZzogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcblxuICBkcmFnRGVsYXk6IG51bWJlciA9IDIwMDsgLy8gbWlsbGlzZWNvbmRzXG4gIGRyYWdEZWxheWVkOiBib29sZWFuID0gdHJ1ZTtcblxuICB0b3VjaFRpbWVvdXQ6IGFueTtcblxuICBnZXQgZWxlbWVudCgpOiBhbnkge1xuICAgIHJldHVybiB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQ7XG4gIH1cblxuICBfZHJvcFpvbmVzOiBzdHJpbmdbXTtcbiAgX3BhcmVudERyb3B6b25lczogc3RyaW5nW107XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBlbDogRWxlbWVudFJlZixcbiAgICBwcml2YXRlIGRyYWtlc1NlcnZpY2U6IERyYWtlU3RvcmVTZXJ2aWNlLFxuICAgIHByaXZhdGUgZHJvcHBhYmxlRGlyZWN0aXZlOiBEcm9wcGFibGVEaXJlY3RpdmVcbiAgKSB7fVxuXG4gIC8vIEZyb206IGh0dHBzOi8vZ2l0aHViLmNvbS9iZXZhY3F1YS9kcmFndWxhL2lzc3Vlcy8yODkjaXNzdWVjb21tZW50LTI3NzE0MzE3MlxuICBASG9zdExpc3RlbmVyKCd0b3VjaG1vdmUnLCBbJyRldmVudCddKVxuICBvbk1vdmUoZTogRXZlbnQpIHtcbiAgICBpZiAoIXRoaXMuX21vdmVzIHx8IHRoaXMuZHJhZ0RlbGF5ZWQpIHtcbiAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICBjbGVhclRpbWVvdXQodGhpcy50b3VjaFRpbWVvdXQpO1xuICAgIH1cbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ3RvdWNoc3RhcnQnKVxuICBvbkRvd24oKSB7XG4gICAgaWYgKHRoaXMuX21vdmVzKSB7XG4gICAgICB0aGlzLnRvdWNoVGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB0aGlzLmRyYWdEZWxheWVkID0gZmFsc2U7XG4gICAgICB9LCB0aGlzLmRyYWdEZWxheSk7XG4gICAgfVxuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcigndG91Y2hlbmQnKVxuICBvblVwKCkge1xuICAgIGlmICh0aGlzLl9tb3Zlcykge1xuICAgICAgY2xlYXJUaW1lb3V0KDxudW1iZXI+dGhpcy50b3VjaFRpbWVvdXQpO1xuICAgICAgdGhpcy5kcmFnRGVsYXllZCA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy51cGRhdGUoKTtcbiAgfVxuXG4gIHVwZGF0ZSgpOiB2b2lkIHtcbiAgICB0aGlzLl9wYXJlbnREcm9wem9uZXMgPSBbdGhpcy5kcm9wcGFibGVEaXJlY3RpdmUuZHJvcFpvbmVdO1xuICAgIHRoaXMuZHJha2VzU2VydmljZS5yZWdpc3RlckRyYWdnYWJsZSh0aGlzKTtcbiAgICB0aGlzLnVwZGF0ZUVsZW1lbnRzKCk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLmRyYWtlc1NlcnZpY2UucmVtb3ZlRHJhZ2dhYmxlKHRoaXMpO1xuICB9XG5cbiAgdXBkYXRlRWxlbWVudHMoKTogdm9pZCB7XG4gICAgY29uc3QgbmF0aXZlRWxlbWVudCA9IHRoaXMuZWwubmF0aXZlRWxlbWVudDtcbiAgICBjb25zdCBoYW5kbGVzOiBOb2RlTGlzdCA9IG5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvckFsbCgnW25neGRyYWdoYW5kbGVdJyk7XG4gICAgdGhpcy5oYW5kbGVzID0gQXJyYXkuZnJvbShoYW5kbGVzKS5maWx0ZXIoKGg6IGFueSkgPT4gZmluZEZpcnN0RHJhZ2dhYmxlUGFyZW50KGgpID09PSBuYXRpdmVFbGVtZW50KTtcblxuICAgIGZ1bmN0aW9uIGZpbmRGaXJzdERyYWdnYWJsZVBhcmVudChjOiBhbnkpIHtcbiAgICAgIHdoaWxlIChjLnBhcmVudE5vZGUpIHtcbiAgICAgICAgYyA9IGMucGFyZW50Tm9kZTtcbiAgICAgICAgaWYgKGMuaGFzQXR0cmlidXRlICYmIGMuaGFzQXR0cmlidXRlKCduZ3hkcmFnZ2FibGUnKSkge1xuICAgICAgICAgIHJldHVybiBjO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgY2FuTW92ZShzb3VyY2U/OiBhbnksIGhhbmRsZT86IGFueSwgc2libGluZz86IGFueSk6IGJvb2xlYW4ge1xuICAgIGlmICh0eXBlb2YgdGhpcy5fbW92ZXMgPT09ICdib29sZWFuJykgcmV0dXJuIHRoaXMuX21vdmVzO1xuICAgIGlmICh0eXBlb2YgdGhpcy5fbW92ZXMgPT09ICdmdW5jdGlvbicpIHJldHVybiB0aGlzLl9tb3Zlcyh0aGlzLm1vZGVsLCBzb3VyY2UsIGhhbmRsZSwgc2libGluZyk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBtb3Zlcyhzb3VyY2U6IGFueSwgaGFuZGxlOiBhbnksIHNpYmxpbmc6IGFueSk6IGJvb2xlYW4ge1xuICAgIGlmICghdGhpcy5jYW5Nb3ZlKHNvdXJjZSwgaGFuZGxlLCBzaWJsaW5nKSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgcmV0dXJuIHRoaXMuaGFzSGFuZGxlID8gdGhpcy5oYW5kbGVzLnNvbWUoaCA9PiBoYW5kZWxGb3IoaGFuZGxlLCBoKSkgOiB0cnVlO1xuXG4gICAgZnVuY3Rpb24gaGFuZGVsRm9yKGM6IGFueSwgcDogYW55KSB7XG4gICAgICBpZiAoYyA9PT0gcCkgcmV0dXJuIHRydWU7XG4gICAgICB3aGlsZSAoKGMgPSBjLnBhcmVudE5vZGUpICYmIGMgIT09IHApOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lXG4gICAgICByZXR1cm4gISFjO1xuICAgIH1cbiAgfVxuXG4gIG5nRG9DaGVjaygpOiB2b2lkIHtcbiAgICB0aGlzLnVwZGF0ZUVsZW1lbnRzKCk7XG4gIH1cbn1cbiJdfQ==