UNPKG

angular-draggable-droppable

Version:
807 lines (797 loc) 36 kB
import * as i0 from '@angular/core'; import { Injectable, Directive, EventEmitter, Optional, Inject, Input, Output, NgModule } from '@angular/core'; import { Subject, Observable, ReplaySubject, merge, combineLatest, fromEvent } from 'rxjs'; import { filter, mergeMap, startWith, map, share, takeUntil, take, takeLast, count, pairwise, distinctUntilChanged } from 'rxjs/operators'; import { DOCUMENT } from '@angular/common'; import autoScroll from '@mattlewis92/dom-autoscroller'; function addClass(renderer, element, classToAdd) { if (classToAdd) { classToAdd .split(' ') .forEach((className) => renderer.addClass(element.nativeElement, className)); } } function removeClass(renderer, element, classToRemove) { if (classToRemove) { classToRemove .split(' ') .forEach((className) => renderer.removeClass(element.nativeElement, className)); } } class DraggableHelper { constructor() { this.currentDrag = new Subject(); } } DraggableHelper.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.3", ngImport: i0, type: DraggableHelper, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); DraggableHelper.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.3", ngImport: i0, type: DraggableHelper, providedIn: 'root' }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.3", ngImport: i0, type: DraggableHelper, decorators: [{ type: Injectable, args: [{ providedIn: 'root', }] }] }); /** * If the window isn't scrollable, then place this on the scrollable container that draggable elements are inside. e.g. * ```html <div style="overflow: scroll" mwlDraggableScrollContainer> <div mwlDraggable>Drag me!</div> </div> ``` */ class DraggableScrollContainerDirective { /** * @hidden */ constructor(elementRef) { this.elementRef = elementRef; } } DraggableScrollContainerDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.3", ngImport: i0, type: DraggableScrollContainerDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); DraggableScrollContainerDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.0.3", type: DraggableScrollContainerDirective, selector: "[mwlDraggableScrollContainer]", ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.3", ngImport: i0, type: DraggableScrollContainerDirective, decorators: [{ type: Directive, args: [{ selector: '[mwlDraggableScrollContainer]', }] }], ctorParameters: function () { return [{ type: i0.ElementRef }]; } }); 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: DraggableHelper }, { token: i0.NgZone }, { token: i0.ViewContainerRef }, { token: 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: DraggableHelper }, { type: i0.NgZone }, { type: i0.ViewContainerRef }, { type: 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 }] } }); function isCoordinateWithinRectangle(clientX, clientY, rect) { return (clientX >= rect.left && clientX <= rect.right && clientY >= rect.top && clientY <= rect.bottom); } class DroppableDirective { constructor(element, draggableHelper, zone, renderer, scrollContainer) { this.element = element; this.draggableHelper = draggableHelper; this.zone = zone; this.renderer = renderer; this.scrollContainer = scrollContainer; /** * Called when a draggable element starts overlapping the element */ this.dragEnter = new EventEmitter(); /** * Called when a draggable element stops overlapping the element */ this.dragLeave = new EventEmitter(); /** * Called when a draggable element is moved over the element */ this.dragOver = new EventEmitter(); /** * Called when a draggable element is dropped on this element */ this.drop = new EventEmitter(); // eslint-disable-line @angular-eslint/no-output-native } ngOnInit() { this.currentDragSubscription = this.draggableHelper.currentDrag.subscribe((drag$) => { addClass(this.renderer, this.element, this.dragActiveClass); const droppableElement = { updateCache: true, }; const deregisterScrollListener = this.renderer.listen(this.scrollContainer ? this.scrollContainer.elementRef.nativeElement : 'window', 'scroll', () => { droppableElement.updateCache = true; }); let currentDragEvent; const overlaps$ = drag$.pipe(map(({ clientX, clientY, dropData, target }) => { currentDragEvent = { clientX, clientY, dropData, target }; if (droppableElement.updateCache) { droppableElement.rect = this.element.nativeElement.getBoundingClientRect(); if (this.scrollContainer) { droppableElement.scrollContainerRect = this.scrollContainer.elementRef.nativeElement.getBoundingClientRect(); } droppableElement.updateCache = false; } const isWithinElement = isCoordinateWithinRectangle(clientX, clientY, droppableElement.rect); const isDropAllowed = !this.validateDrop || this.validateDrop({ clientX, clientY, target, dropData }); if (droppableElement.scrollContainerRect) { return (isWithinElement && isDropAllowed && isCoordinateWithinRectangle(clientX, clientY, droppableElement.scrollContainerRect)); } else { return isWithinElement && isDropAllowed; } })); const overlapsChanged$ = overlaps$.pipe(distinctUntilChanged()); let dragOverActive; // TODO - see if there's a way of doing this via rxjs overlapsChanged$ .pipe(filter((overlapsNow) => overlapsNow)) .subscribe(() => { dragOverActive = true; addClass(this.renderer, this.element, this.dragOverClass); if (this.dragEnter.observers.length > 0) { this.zone.run(() => { this.dragEnter.next(currentDragEvent); }); } }); overlaps$.pipe(filter((overlapsNow) => overlapsNow)).subscribe(() => { if (this.dragOver.observers.length > 0) { this.zone.run(() => { this.dragOver.next(currentDragEvent); }); } }); overlapsChanged$ .pipe(pairwise(), filter(([didOverlap, overlapsNow]) => didOverlap && !overlapsNow)) .subscribe(() => { dragOverActive = false; removeClass(this.renderer, this.element, this.dragOverClass); if (this.dragLeave.observers.length > 0) { this.zone.run(() => { this.dragLeave.next(currentDragEvent); }); } }); drag$.subscribe({ complete: () => { deregisterScrollListener(); removeClass(this.renderer, this.element, this.dragActiveClass); if (dragOverActive) { removeClass(this.renderer, this.element, this.dragOverClass); if (this.drop.observers.length > 0) { this.zone.run(() => { this.drop.next(currentDragEvent); }); } } }, }); }); } ngOnDestroy() { if (this.currentDragSubscription) { this.currentDragSubscription.unsubscribe(); } } } DroppableDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.3", ngImport: i0, type: DroppableDirective, deps: [{ token: i0.ElementRef }, { token: DraggableHelper }, { token: i0.NgZone }, { token: i0.Renderer2 }, { token: DraggableScrollContainerDirective, optional: true }], target: i0.ɵɵFactoryTarget.Directive }); DroppableDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.0.3", type: DroppableDirective, selector: "[mwlDroppable]", inputs: { dragOverClass: "dragOverClass", dragActiveClass: "dragActiveClass", validateDrop: "validateDrop" }, outputs: { dragEnter: "dragEnter", dragLeave: "dragLeave", dragOver: "dragOver", drop: "drop" }, ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.3", ngImport: i0, type: DroppableDirective, decorators: [{ type: Directive, args: [{ selector: '[mwlDroppable]', }] }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: DraggableHelper }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: DraggableScrollContainerDirective, decorators: [{ type: Optional }] }]; }, propDecorators: { dragOverClass: [{ type: Input }], dragActiveClass: [{ type: Input }], validateDrop: [{ type: Input }], dragEnter: [{ type: Output }], dragLeave: [{ type: Output }], dragOver: [{ type: Output }], drop: [{ type: Output }] } }); class DragAndDropModule { } DragAndDropModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.3", ngImport: i0, type: DragAndDropModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); DragAndDropModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.0.3", ngImport: i0, type: DragAndDropModule, declarations: [DraggableDirective, DroppableDirective, DraggableScrollContainerDirective], exports: [DraggableDirective, DroppableDirective, DraggableScrollContainerDirective] }); DragAndDropModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.0.3", ngImport: i0, type: DragAndDropModule }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.3", ngImport: i0, type: DragAndDropModule, decorators: [{ type: NgModule, args: [{ declarations: [ DraggableDirective, DroppableDirective, DraggableScrollContainerDirective, ], exports: [ DraggableDirective, DroppableDirective, DraggableScrollContainerDirective, ], }] }] }); /* * Public API Surface of angular-draggable-droppable */ /** * Generated bundle index. Do not edit. */ export { DragAndDropModule, DraggableDirective, DraggableScrollContainerDirective, DroppableDirective }; //# sourceMappingURL=angular-draggable-droppable.mjs.map //# sourceMappingURL=angular-draggable-droppable.mjs.map