kingdot
Version:
A UI Components Library For Vue
394 lines (357 loc) • 16 kB
JavaScript
var Sortable = require('./Sortable');
var _extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
function _toConsumableArray(arr) {
if (Array.isArray(arr)) {
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) {
arr2[i] = arr[i];
}
return arr2;
} else {
return Array.from(arr);
}
}
(function () {
if (!Array.from) {
Array.from = function (object) {
return [].slice.call(object);
};
}
// eslint-disable-next-line max-lines-per-function
function buildDraggable(Sortable) {
function removeNode(node) {
node.parentElement.removeChild(node);
}
function insertNodeAt(fatherNode, node, position) {
var refNode = position === 0 ? fatherNode.children[0] : fatherNode.children[position - 1].nextSibling;
fatherNode.insertBefore(node, refNode);
}
function computeVmIndex(vnodes, element) {
return vnodes.map(function (elt) {
return elt.elm;
}).indexOf(element);
}
function _computeIndexes(slots, children, isTransition) {
if (!slots) {
return [];
}
var elmFromNodes = slots.map(function (elt) {
return elt.elm;
});
var rawIndexes = [].concat(_toConsumableArray(children)).map(function (elt) {
return elmFromNodes.indexOf(elt);
});
return isTransition ? rawIndexes.filter(function (ind) {
return ind !== -1;
}) : rawIndexes;
}
function emit(evtName, evtData) {
var _this = this;
this.$nextTick(function () {
return _this.$emit(evtName.toLowerCase(), evtData);
});
}
function delegateAndEmit(evtName) {
var _this2 = this;
return function (evtData) {
if (_this2.realList !== null) {
_this2['onDrag' + evtName](evtData);
}
emit.call(_this2, evtName, evtData);
};
}
var eventsListened = ['Start', 'Add', 'Remove', 'Update', 'End'];
var eventsToEmit = ['Choose', 'Sort', 'Filter', 'Clone'];
var readonlyProperties = ['Move'].concat(eventsListened, eventsToEmit).map(function (evt) {
return 'on' + evt;
});
var draggingElement = null;
var props = {
options: Object,
list: {
type: Array,
required: false,
default: null
},
value: {
type: Array,
required: false,
default: null
},
noTransitionOnDrag: {
type: Boolean,
default: false
},
clone: {
type: Function,
default: function _default(original) {
return original;
}
},
element: {
type: String,
default: 'div'
},
move: {
type: Function,
default: null
}
};
var draggableComponent = {
name: 'KdDraggable',
props: props,
data: function data() {
return {
transitionMode: false,
noneFunctionalComponentMode: false,
init: false
};
},
render: function render(h) {
var slots = this.$slots.default;
if (slots && slots.length === 1) {
var child = slots[0];
if (child.componentOptions && child.componentOptions.tag === 'transition-group') {
this.transitionMode = true;
}
}
var children = slots;
var footer = this.$slots.footer;
if (footer) {
children = slots ? [].concat(_toConsumableArray(slots), _toConsumableArray(footer)) : [].concat(_toConsumableArray(footer));
}
return h(this.element, null, children);
},
mounted: function mounted() {
var _this3 = this;
this.noneFunctionalComponentMode = this.element.toLowerCase() !== this.$el.nodeName.toLowerCase();
if (this.noneFunctionalComponentMode && this.transitionMode) {
throw new Error('Transition-group inside component is not supported. Please alter element value or remove transition-group. Current element value: ' + this.element);
}
var optionsAdded = {};
eventsListened.forEach(function (elt) {
optionsAdded['on' + elt] = delegateAndEmit.call(_this3, elt);
});
eventsToEmit.forEach(function (elt) {
optionsAdded['on' + elt] = emit.bind(_this3, elt);
});
var options = _extends({}, this.options, optionsAdded, {
onMove: function onMove(evt, originalEvent) {
return _this3.onDragMove(evt, originalEvent);
}
});
!('draggable' in options) && (options.draggable = '>*');
this._sortable = new Sortable(this.rootContainer, options);
this.computeIndexes();
},
beforeDestroy: function beforeDestroy() {
this._sortable.destroy();
},
computed: {
rootContainer: function rootContainer() {
return this.transitionMode ? this.$el.children[0] : this.$el;
},
isCloning: function isCloning() {
return !!this.options && !!this.options.group && this.options.group.pull === 'clone';
},
realList: function realList() {
return this.list ? this.list : this.value;
}
},
watch: {
options: {
handler: function handler(newOptionValue) {
for (var property in newOptionValue) {
if (readonlyProperties.indexOf(property) == -1) {
this._sortable.option(property, newOptionValue[property]);
}
}
},
deep: true
},
realList: function realList() {
this.computeIndexes();
}
},
methods: {
getChildrenNodes: function getChildrenNodes() {
if (!this.init) {
this.noneFunctionalComponentMode = this.noneFunctionalComponentMode && this.$children.length == 1;
this.init = true;
}
if (this.noneFunctionalComponentMode) {
return this.$children[0].$slots.default;
}
var rawNodes = this.$slots.default;
return this.transitionMode ? rawNodes[0].child.$slots.default : rawNodes;
},
computeIndexes: function computeIndexes() {
var _this4 = this;
this.$nextTick(function () {
_this4.visibleIndexes = _computeIndexes(_this4.getChildrenNodes(), _this4.rootContainer.children, _this4.transitionMode);
});
},
getUnderlyingVm: function getUnderlyingVm(htmlElt) {
var index = computeVmIndex(this.getChildrenNodes() || [], htmlElt);
if (index === -1) {
// Edge case during move callback: related element might be
// an element different from collection
return null;
}
var element = this.realList[index];
return {index: index, element: element};
},
getUnderlyingPotencialDraggableComponent: function getUnderlyingPotencialDraggableComponent(_ref) {
var __vue__ = _ref.__vue__;
if (!__vue__ || !__vue__.$options || __vue__.$options._componentTag !== 'transition-group') {
return __vue__;
}
return __vue__.$parent;
},
emitChanges: function emitChanges(evt) {
var _this5 = this;
this.$nextTick(function () {
_this5.$emit('change', evt);
});
},
alterList: function alterList(onList) {
if (this.list) {
onList(this.list);
} else {
var newList = [].concat(_toConsumableArray(this.value));
onList(newList);
this.$emit('input', newList);
}
},
spliceList: function spliceList() {
var _arguments = arguments;
var spliceList = function spliceList(list) {
return list.splice.apply(list, _arguments);
};
this.alterList(spliceList);
},
updatePosition: function updatePosition(oldIndex, newIndex) {
var updatePosition = function updatePosition(list) {
return list.splice(newIndex, 0, list.splice(oldIndex, 1)[0]);
};
this.alterList(updatePosition);
},
getRelatedContextFromMoveEvent: function getRelatedContextFromMoveEvent(_ref2) {
var to = _ref2.to;
var related = _ref2.related;
var component = this.getUnderlyingPotencialDraggableComponent(to);
if (!component) {
return {component: component};
}
var list = component.realList;
var context = {list: list, component: component};
if (to !== related && list && component.getUnderlyingVm) {
var destination = component.getUnderlyingVm(related);
if (destination) {
return _extends(destination, context);
}
}
return context;
},
getVmIndex: function getVmIndex(domIndex) {
var indexes = this.visibleIndexes;
var numberIndexes = indexes.length;
return domIndex > numberIndexes - 1 ? numberIndexes : indexes[domIndex];
},
getComponent: function getComponent() {
return this.$slots.default[0].componentInstance;
},
resetTransitionData: function resetTransitionData(index) {
if (!this.noTransitionOnDrag || !this.transitionMode) {
return;
}
var nodes = this.getChildrenNodes();
nodes[index].data = null;
var transitionContainer = this.getComponent();
transitionContainer.children = [];
transitionContainer.kept = undefined;
},
onDragStart: function onDragStart(evt) {
// console.log(1)
this.context = this.getUnderlyingVm(evt.item);
// console.log(this.clone(this.context.element))
evt.item._underlying_vm_ = this.clone(this.context.element);
draggingElement = evt.item;
},
onDragAdd: function onDragAdd(evt) {
var element = evt.item._underlying_vm_;
if (element === undefined) {
return;
}
removeNode(evt.item);
var newIndex = this.getVmIndex(evt.newIndex);
this.spliceList(newIndex, 0, element);
this.computeIndexes();
var added = {element: element, newIndex: newIndex};
this.emitChanges({added: added});
},
onDragRemove: function onDragRemove(evt) {
insertNodeAt(this.rootContainer, evt.item, evt.oldIndex);
if (this.isCloning) {
removeNode(evt.clone);
return;
}
var oldIndex = this.context.index;
this.spliceList(oldIndex, 1);
var removed = {element: this.context.element, oldIndex: oldIndex};
this.resetTransitionData(oldIndex);
this.emitChanges({removed: removed});
},
onDragUpdate: function onDragUpdate(evt) {
removeNode(evt.item);
insertNodeAt(evt.from, evt.item, evt.oldIndex);
var oldIndex = this.context.index;
var newIndex = this.getVmIndex(evt.newIndex);
this.updatePosition(oldIndex, newIndex);
var moved = {element: this.context.element, oldIndex: oldIndex, newIndex: newIndex};
this.emitChanges({moved: moved});
},
computeFutureIndex: function computeFutureIndex(relatedContext, evt) {
if (!relatedContext.element) {
return 0;
}
var domChildren = [].concat(_toConsumableArray(evt.to.children)).filter(function (el) {
return el.style.display !== 'none';
});
var currentDOMIndex = domChildren.indexOf(evt.related);
var currentIndex = relatedContext.component.getVmIndex(currentDOMIndex);
var draggedInList = domChildren.indexOf(draggingElement) != -1;
return draggedInList || !evt.willInsertAfter ? currentIndex : currentIndex + 1;
},
onDragMove: function onDragMove(evt, originalEvent) {
var onMove = this.move;
if (!onMove || !this.realList) {
return true;
}
var relatedContext = this.getRelatedContextFromMoveEvent(evt);
var draggedContext = this.context;
var futureIndex = this.computeFutureIndex(relatedContext, evt);
_extends(draggedContext, {futureIndex: futureIndex});
_extends(evt, {relatedContext: relatedContext, draggedContext: draggedContext});
return onMove(evt, originalEvent);
},
onDragEnd: function onDragEnd(evt) {
this.computeIndexes();
draggingElement = null;
}
}
};
return draggableComponent;
}
const vuildComponent = buildDraggable(Sortable);
module.exports = vuildComponent;
})();