/** * Vue mixin that makes the component a droptarget * override canHandleDrop(event) and onDrop(event) * dragOverClasses can be bound to target class */ var Droptarget = { data() { return { droptargetCounter: 0, droptargetCanHandle: false } }, computed: { isDragingOver() { return this.droptargetCounter > 0; }, dropTargetClasses() { return { 'drag-hover': this.isDragingOver, 'unsupported-drop': this.isDragingOver && !this.droptargetCanHandle } } }, mounted() { this.$nextTick(function () { this.$el.addEventListener('dragenter', this._onDragEnter); this.$el.addEventListener('dragleave', this._onDragLeave); this.$el.addEventListener('dragend', this._onDragEnd); this.$el.addEventListener('dragover', this._onDragOver); this.$el.addEventListener('drop', this._onDrop); }); }, beforeDestroy() { this.$el.removeEventListener('dragenter', this._onDragEnter); this.$el.removeEventListener('dragleave', this._onDragLeave); this.$el.removeEventListener('dragend', this._onDragEnd); this.$el.removeEventListener('dragover', this._onDragOver); this.$el.removeEventListener('drop', this._onDrop); }, methods: { canHandleDrop(event) { throw Error('Not implemented'); }, onDrop(event) { throw Error('Not implemented'); }, _onDragEnter(event) { event.preventDefault(); event.stopPropagation(); this.droptargetCounter++; if(this.droptargetCounter === 1) { try { this.droptargetCanHandle = this.canHandleDrop(event); } catch (error) { console.warn(error); this.droptargetCanHandle = false; } } }, _onDragLeave() { this.droptargetCounter--; }, _onDragEnd() { this.droptargetCounter = 0; }, _onDragOver(event) { event.preventDefault(); event.stopPropagation(); }, _onDrop(event) { event.preventDefault(); event.stopPropagation(); if(this.droptargetCanHandle) { try { this.onDrop(event); } catch (error) { console.console.warn(error); } } this.droptargetCounter = 0; }, } } export { Droptarget }