UNPKG

angular-draggable-droppable

Version:
575 lines 84.3 kB
import { Directive, Output, EventEmitter, Input, Inject, Optional, } from '@angular/core'; import { Subject, Observable, merge, ReplaySubject, combineLatest, fromEvent, } from 'rxjs'; import { map, mergeMap, takeUntil, take, takeLast, pairwise, share, filter, count, startWith, } from 'rxjs/operators'; import { DOCUMENT } from '@angular/common'; import autoScroll from '@mattlewis92/dom-autoscroller'; import { addClass, removeClass } from './util'; import * as i0 from "@angular/core"; import * as i1 from "./draggable-helper.provider"; import * as i2 from "./draggable-scroll-container.directive"; export class DraggableDirective { /** * @hidden */ constructor(element, renderer, draggableHelper, zone, vcr, scrollContainer, document) { this.element = element; this.renderer = renderer; this.draggableHelper = draggableHelper; this.zone = zone; this.vcr = vcr; this.scrollContainer = scrollContainer; this.document = document; /** * The axis along which the element is draggable */ this.dragAxis = { x: true, y: true }; /** * Snap all drags to an x / y grid */ this.dragSnapGrid = {}; /** * Show a ghost element that shows the drag when dragging */ this.ghostDragEnabled = true; /** * Show the original element when ghostDragEnabled is true */ this.showOriginalElementWhileDragging = false; /** * The cursor to use when hovering over a draggable element */ this.dragCursor = ''; /* * Options used to control the behaviour of auto scrolling: https://www.npmjs.com/package/dom-autoscroller */ this.autoScroll = { margin: 20, }; /** * Called when the element can be dragged along one axis and has the mouse or pointer device pressed on it */ this.dragPointerDown = new EventEmitter(); /** * Called when the element has started to be dragged. * Only called after at least one mouse or touch move event. * If you call $event.cancelDrag$.emit() it will cancel the current drag */ this.dragStart = new EventEmitter(); /** * Called after the ghost element has been created */ this.ghostElementCreated = new EventEmitter(); /** * Called when the element is being dragged */ this.dragging = new EventEmitter(); /** * Called after the element is dragged */ this.dragEnd = new EventEmitter(); /** * @hidden */ this.pointerDown$ = new Subject(); /** * @hidden */ this.pointerMove$ = new Subject(); /** * @hidden */ this.pointerUp$ = new Subject(); this.eventListenerSubscriptions = {}; this.destroy$ = new Subject(); this.timeLongPress = { timerBegin: 0, timerEnd: 0 }; } ngOnInit() { this.checkEventListeners(); const pointerDragged$ = this.pointerDown$.pipe(filter(() => this.canDrag()), mergeMap((pointerDownEvent) => { // fix for https://github.com/mattlewis92/angular-draggable-droppable/issues/61 // stop mouse events propagating up the chain if (pointerDownEvent.event.stopPropagation && !this.scrollContainer) { pointerDownEvent.event.stopPropagation(); } // hack to prevent text getting selected in safari while dragging const globalDragStyle = this.renderer.createElement('style'); this.renderer.setAttribute(globalDragStyle, 'type', 'text/css'); this.renderer.appendChild(globalDragStyle, this.renderer.createText(` body * { -moz-user-select: none; -ms-user-select: none; -webkit-user-select: none; user-select: none; } `)); requestAnimationFrame(() => { this.document.head.appendChild(globalDragStyle); }); const startScrollPosition = this.getScrollPosition(); const scrollContainerScroll$ = new Observable((observer) => { const scrollContainer = this.scrollContainer ? this.scrollContainer.elementRef.nativeElement : 'window'; return this.renderer.listen(scrollContainer, 'scroll', (e) => observer.next(e)); }).pipe(startWith(startScrollPosition), map(() => this.getScrollPosition())); const currentDrag$ = new Subject(); const cancelDrag$ = new ReplaySubject(); if (this.dragPointerDown.observers.length > 0) { this.zone.run(() => { this.dragPointerDown.next({ x: 0, y: 0 }); }); } const dragComplete$ = merge(this.pointerUp$, this.pointerDown$, cancelDrag$, this.destroy$).pipe(share()); const pointerMove = combineLatest([ this.pointerMove$, scrollContainerScroll$, ]).pipe(map(([pointerMoveEvent, scroll]) => { return { currentDrag$, transformX: pointerMoveEvent.clientX - pointerDownEvent.clientX, transformY: pointerMoveEvent.clientY - pointerDownEvent.clientY, clientX: pointerMoveEvent.clientX, clientY: pointerMoveEvent.clientY, scrollLeft: scroll.left, scrollTop: scroll.top, target: pointerMoveEvent.event.target, }; }), map((moveData) => { if (this.dragSnapGrid.x) { moveData.transformX = Math.round(moveData.transformX / this.dragSnapGrid.x) * this.dragSnapGrid.x; } if (this.dragSnapGrid.y) { moveData.transformY = Math.round(moveData.transformY / this.dragSnapGrid.y) * this.dragSnapGrid.y; } return moveData; }), map((moveData) => { if (!this.dragAxis.x) { moveData.transformX = 0; } if (!this.dragAxis.y) { moveData.transformY = 0; } return moveData; }), map((moveData) => { const scrollX = moveData.scrollLeft - startScrollPosition.left; const scrollY = moveData.scrollTop - startScrollPosition.top; return { ...moveData, x: moveData.transformX + scrollX, y: moveData.transformY + scrollY, }; }), filter(({ x, y, transformX, transformY }) => !this.validateDrag || this.validateDrag({ x, y, transform: { x: transformX, y: transformY }, })), takeUntil(dragComplete$), share()); const dragStarted$ = pointerMove.pipe(take(1), share()); const dragEnded$ = pointerMove.pipe(takeLast(1), share()); dragStarted$.subscribe(({ clientX, clientY, x, y }) => { if (this.dragStart.observers.length > 0) { this.zone.run(() => { this.dragStart.next({ cancelDrag$ }); }); } this.scroller = autoScroll([ this.scrollContainer ? this.scrollContainer.elementRef.nativeElement : this.document.defaultView, ], { ...this.autoScroll, autoScroll() { return true; }, }); addClass(this.renderer, this.element, this.dragActiveClass); if (this.ghostDragEnabled) { const rect = this.element.nativeElement.getBoundingClientRect(); const clone = this.element.nativeElement.cloneNode(true); if (!this.showOriginalElementWhileDragging) { this.renderer.setStyle(this.element.nativeElement, 'visibility', 'hidden'); } if (this.ghostElementAppendTo) { this.ghostElementAppendTo.appendChild(clone); } else { this.element.nativeElement.parentNode.insertBefore(clone, this.element.nativeElement.nextSibling); } this.ghostElement = clone; this.document.body.style.cursor = this.dragCursor; this.setElementStyles(clone, { position: 'fixed', top: `${rect.top}px`, left: `${rect.left}px`, width: `${rect.width}px`, height: `${rect.height}px`, cursor: this.dragCursor, margin: '0', willChange: 'transform', pointerEvents: 'none', }); if (this.ghostElementTemplate) { const viewRef = this.vcr.createEmbeddedView(this.ghostElementTemplate); clone.innerHTML = ''; viewRef.rootNodes .filter((node) => node instanceof Node) .forEach((node) => { clone.appendChild(node); }); dragEnded$.subscribe(() => { this.vcr.remove(this.vcr.indexOf(viewRef)); }); } if (this.ghostElementCreated.observers.length > 0) { this.zone.run(() => { this.ghostElementCreated.emit({ clientX: clientX - x, clientY: clientY - y, element: clone, }); }); } dragEnded$.subscribe(() => { clone.parentElement.removeChild(clone); this.ghostElement = null; this.renderer.setStyle(this.element.nativeElement, 'visibility', ''); }); } this.draggableHelper.currentDrag.next(currentDrag$); }); dragEnded$ .pipe(mergeMap((dragEndData) => { const dragEndData$ = cancelDrag$.pipe(count(), take(1), map((calledCount) => ({ ...dragEndData, dragCancelled: calledCount > 0, }))); cancelDrag$.complete(); return dragEndData$; })) .subscribe(({ x, y, dragCancelled }) => { this.scroller.destroy(); if (this.dragEnd.observers.length > 0) { this.zone.run(() => { this.dragEnd.next({ x, y, dragCancelled }); }); } removeClass(this.renderer, this.element, this.dragActiveClass); currentDrag$.complete(); }); merge(dragComplete$, dragEnded$) .pipe(take(1)) .subscribe(() => { requestAnimationFrame(() => { this.document.head.removeChild(globalDragStyle); }); }); return pointerMove; }), share()); merge(pointerDragged$.pipe(take(1), map((value) => [, value])), pointerDragged$.pipe(pairwise())) .pipe(filter(([previous, next]) => { if (!previous) { return true; } return previous.x !== next.x || previous.y !== next.y; }), map(([previous, next]) => next)) .subscribe(({ x, y, currentDrag$, clientX, clientY, transformX, transformY, target, }) => { if (this.dragging.observers.length > 0) { this.zone.run(() => { this.dragging.next({ x, y }); }); } requestAnimationFrame(() => { if (this.ghostElement) { const transform = `translate3d(${transformX}px, ${transformY}px, 0px)`; this.setElementStyles(this.ghostElement, { transform, '-webkit-transform': transform, '-ms-transform': transform, '-moz-transform': transform, '-o-transform': transform, }); } }); currentDrag$.next({ clientX, clientY, dropData: this.dropData, target, }); }); } ngOnChanges(changes) { if (changes.dragAxis) { this.checkEventListeners(); } } ngOnDestroy() { this.unsubscribeEventListeners(); this.pointerDown$.complete(); this.pointerMove$.complete(); this.pointerUp$.complete(); this.destroy$.next(); } checkEventListeners() { const canDrag = this.canDrag(); const hasEventListeners = Object.keys(this.eventListenerSubscriptions).length > 0; if (canDrag && !hasEventListeners) { this.zone.runOutsideAngular(() => { this.eventListenerSubscriptions.mousedown = this.renderer.listen(this.element.nativeElement, 'mousedown', (event) => { this.onMouseDown(event); }); this.eventListenerSubscriptions.mouseup = this.renderer.listen('document', 'mouseup', (event) => { this.onMouseUp(event); }); this.eventListenerSubscriptions.touchstart = this.renderer.listen(this.element.nativeElement, 'touchstart', (event) => { this.onTouchStart(event); }); this.eventListenerSubscriptions.touchend = this.renderer.listen('document', 'touchend', (event) => { this.onTouchEnd(event); }); this.eventListenerSubscriptions.touchcancel = this.renderer.listen('document', 'touchcancel', (event) => { this.onTouchEnd(event); }); this.eventListenerSubscriptions.mouseenter = this.renderer.listen(this.element.nativeElement, 'mouseenter', () => { this.onMouseEnter(); }); this.eventListenerSubscriptions.mouseleave = this.renderer.listen(this.element.nativeElement, 'mouseleave', () => { this.onMouseLeave(); }); }); } else if (!canDrag && hasEventListeners) { this.unsubscribeEventListeners(); } } onMouseDown(event) { if (event.button === 0) { if (!this.eventListenerSubscriptions.mousemove) { this.eventListenerSubscriptions.mousemove = this.renderer.listen('document', 'mousemove', (mouseMoveEvent) => { this.pointerMove$.next({ event: mouseMoveEvent, clientX: mouseMoveEvent.clientX, clientY: mouseMoveEvent.clientY, }); }); } this.pointerDown$.next({ event, clientX: event.clientX, clientY: event.clientY, }); } } onMouseUp(event) { if (event.button === 0) { if (this.eventListenerSubscriptions.mousemove) { this.eventListenerSubscriptions.mousemove(); delete this.eventListenerSubscriptions.mousemove; } this.pointerUp$.next({ event, clientX: event.clientX, clientY: event.clientY, }); } } onTouchStart(event) { let startScrollPosition; let isDragActivated; let hasContainerScrollbar; if (this.touchStartLongPress) { this.timeLongPress.timerBegin = Date.now(); isDragActivated = false; hasContainerScrollbar = this.hasScrollbar(); startScrollPosition = this.getScrollPosition(); } if (!this.eventListenerSubscriptions.touchmove) { const contextMenuListener = fromEvent(this.document, 'contextmenu').subscribe((e) => { e.preventDefault(); }); const touchMoveListener = fromEvent(this.document, 'touchmove', { passive: false, }).subscribe((touchMoveEvent) => { if (this.touchStartLongPress && !isDragActivated && hasContainerScrollbar) { isDragActivated = this.shouldBeginDrag(event, touchMoveEvent, startScrollPosition); } if (!this.touchStartLongPress || !hasContainerScrollbar || isDragActivated) { touchMoveEvent.preventDefault(); this.pointerMove$.next({ event: touchMoveEvent, clientX: touchMoveEvent.targetTouches[0].clientX, clientY: touchMoveEvent.targetTouches[0].clientY, }); } }); this.eventListenerSubscriptions.touchmove = () => { contextMenuListener.unsubscribe(); touchMoveListener.unsubscribe(); }; } this.pointerDown$.next({ event, clientX: event.touches[0].clientX, clientY: event.touches[0].clientY, }); } onTouchEnd(event) { if (this.eventListenerSubscriptions.touchmove) { this.eventListenerSubscriptions.touchmove(); delete this.eventListenerSubscriptions.touchmove; if (this.touchStartLongPress) { this.enableScroll(); } } this.pointerUp$.next({ event, clientX: event.changedTouches[0].clientX, clientY: event.changedTouches[0].clientY, }); } onMouseEnter() { this.setCursor(this.dragCursor); } onMouseLeave() { this.setCursor(''); } canDrag() { return this.dragAxis.x || this.dragAxis.y; } setCursor(value) { if (!this.eventListenerSubscriptions.mousemove) { this.renderer.setStyle(this.element.nativeElement, 'cursor', value); } } unsubscribeEventListeners() { Object.keys(this.eventListenerSubscriptions).forEach((type) => { this.eventListenerSubscriptions[type](); delete this.eventListenerSubscriptions[type]; }); } setElementStyles(element, styles) { Object.keys(styles).forEach((key) => { this.renderer.setStyle(element, key, styles[key]); }); } getScrollElement() { if (this.scrollContainer) { return this.scrollContainer.elementRef.nativeElement; } else { return this.document.body; } } getScrollPosition() { if (this.scrollContainer) { return { top: this.scrollContainer.elementRef.nativeElement.scrollTop, left: this.scrollContainer.elementRef.nativeElement.scrollLeft, }; } else { return { top: window.pageYOffset || this.document.documentElement.scrollTop, left: window.pageXOffset || this.document.documentElement.scrollLeft, }; } } shouldBeginDrag(event, touchMoveEvent, startScrollPosition) { const moveScrollPosition = this.getScrollPosition(); const deltaScroll = { top: Math.abs(moveScrollPosition.top - startScrollPosition.top), left: Math.abs(moveScrollPosition.left - startScrollPosition.left), }; const deltaX = Math.abs(touchMoveEvent.targetTouches[0].clientX - event.touches[0].clientX) - deltaScroll.left; const deltaY = Math.abs(touchMoveEvent.targetTouches[0].clientY - event.touches[0].clientY) - deltaScroll.top; const deltaTotal = deltaX + deltaY; const longPressConfig = this.touchStartLongPress; if (deltaTotal > longPressConfig.delta || deltaScroll.top > 0 || deltaScroll.left > 0) { this.timeLongPress.timerBegin = Date.now(); } this.timeLongPress.timerEnd = Date.now(); const duration = this.timeLongPress.timerEnd - this.timeLongPress.timerBegin; if (duration >= longPressConfig.delay) { this.disableScroll(); return true; } return false; } enableScroll() { if (this.scrollContainer) { this.renderer.setStyle(this.scrollContainer.elementRef.nativeElement, 'overflow', ''); } this.renderer.setStyle(this.document.body, 'overflow', ''); } disableScroll() { /* istanbul ignore next */ if (this.scrollContainer) { this.renderer.setStyle(this.scrollContainer.elementRef.nativeElement, 'overflow', 'hidden'); } this.renderer.setStyle(this.document.body, 'overflow', 'hidden'); } hasScrollbar() { const scrollContainer = this.getScrollElement(); const containerHasHorizontalScroll = scrollContainer.scrollWidth > scrollContainer.clientWidth; const containerHasVerticalScroll = scrollContainer.scrollHeight > scrollContainer.clientHeight; return containerHasHorizontalScroll || containerHasVerticalScroll; } } DraggableDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.3", ngImport: i0, type: DraggableDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i1.DraggableHelper }, { token: i0.NgZone }, { token: i0.ViewContainerRef }, { token: i2.DraggableScrollContainerDirective, optional: true }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Directive }); DraggableDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.0.3", type: DraggableDirective, selector: "[mwlDraggable]", inputs: { dropData: "dropData", dragAxis: "dragAxis", dragSnapGrid: "dragSnapGrid", ghostDragEnabled: "ghostDragEnabled", showOriginalElementWhileDragging: "showOriginalElementWhileDragging", validateDrag: "validateDrag", dragCursor: "dragCursor", dragActiveClass: "dragActiveClass", ghostElementAppendTo: "ghostElementAppendTo", ghostElementTemplate: "ghostElementTemplate", touchStartLongPress: "touchStartLongPress", autoScroll: "autoScroll" }, outputs: { dragPointerDown: "dragPointerDown", dragStart: "dragStart", ghostElementCreated: "ghostElementCreated", dragging: "dragging", dragEnd: "dragEnd" }, usesOnChanges: true, ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.3", ngImport: i0, type: DraggableDirective, decorators: [{ type: Directive, args: [{ selector: '[mwlDraggable]', }] }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i1.DraggableHelper }, { type: i0.NgZone }, { type: i0.ViewContainerRef }, { type: i2.DraggableScrollContainerDirective, decorators: [{ type: Optional }] }, { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT] }] }]; }, propDecorators: { dropData: [{ type: Input }], dragAxis: [{ type: Input }], dragSnapGrid: [{ type: Input }], ghostDragEnabled: [{ type: Input }], showOriginalElementWhileDragging: [{ type: Input }], validateDrag: [{ type: Input }], dragCursor: [{ type: Input }], dragActiveClass: [{ type: Input }], ghostElementAppendTo: [{ type: Input }], ghostElementTemplate: [{ type: Input }], touchStartLongPress: [{ type: Input }], autoScroll: [{ type: Input }], dragPointerDown: [{ type: Output }], dragStart: [{ type: Output }], ghostElementCreated: [{ type: Output }], dragging: [{ type: Output }], dragEnd: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJhZ2dhYmxlLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXItZHJhZ2dhYmxlLWRyb3BwYWJsZS9zcmMvbGliL2RyYWdnYWJsZS5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFJVCxNQUFNLEVBQ04sWUFBWSxFQUNaLEtBQUssRUFLTCxNQUFNLEVBR04sUUFBUSxHQUNULE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFDTCxPQUFPLEVBQ1AsVUFBVSxFQUNWLEtBQUssRUFDTCxhQUFhLEVBQ2IsYUFBYSxFQUNiLFNBQVMsR0FDVixNQUFNLE1BQU0sQ0FBQztBQUNkLE9BQU8sRUFDTCxHQUFHLEVBQ0gsUUFBUSxFQUNSLFNBQVMsRUFDVCxJQUFJLEVBQ0osUUFBUSxFQUNSLFFBQVEsRUFDUixLQUFLLEVBQ0wsTUFBTSxFQUNOLEtBQUssRUFDTCxTQUFTLEdBQ1YsTUFBTSxnQkFBZ0IsQ0FBQztBQUV4QixPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0MsT0FBTyxVQUFVLE1BQU0sK0JBQStCLENBQUM7QUFFdkQsT0FBTyxFQUFFLFFBQVEsRUFBRSxXQUFXLEVBQUUsTUFBTSxRQUFRLENBQUM7Ozs7QUEwRC9DLE1BQU0sT0FBTyxrQkFBa0I7SUFxSTdCOztPQUVHO0lBQ0gsWUFDVSxPQUFnQyxFQUNoQyxRQUFtQixFQUNuQixlQUFnQyxFQUNoQyxJQUFZLEVBQ1osR0FBcUIsRUFDVCxlQUFrRCxFQUM1QyxRQUFhO1FBTi9CLFlBQU8sR0FBUCxPQUFPLENBQXlCO1FBQ2hDLGFBQVEsR0FBUixRQUFRLENBQVc7UUFDbkIsb0JBQWUsR0FBZixlQUFlLENBQWlCO1FBQ2hDLFNBQUksR0FBSixJQUFJLENBQVE7UUFDWixRQUFHLEdBQUgsR0FBRyxDQUFrQjtRQUNULG9CQUFlLEdBQWYsZUFBZSxDQUFt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