vue3-draggable-next
Version:
draggable component for vue
65 lines (56 loc) • 1.69 kB
JavaScript
import { ComponentStructure } from "./componentStructure";
import { isHtmlTag, isTransition } from "../util/tags";
import { resolveComponent, TransitionGroup } from "vue";
import { uniqueId } from "../util/string";
function getSlot(slots, key) {
const slotValue = slots[key];
return slotValue ? slotValue() : [];
}
function computeNodes({ $slots, realList, getKey }) {
const normalizedList = realList || [];
const [header, footer] = ["header", "footer"].map(name =>
getSlot($slots, name)
);
const { item } = $slots;
if (!item) {
throw new Error("draggable element must have an item slot");
}
const defaultNodes = normalizedList.flatMap((element, index) =>
item({ element, index }).map(node => {
node.key = getKey(element);
node.props = {
...(node.props || {}),
"data-draggable": true,
"data-id": uniqueId("drag_item")
};
return node;
})
);
if (defaultNodes.length !== normalizedList.length) {
throw new Error("Item slot must have only one child");
}
return {
header,
footer,
default: defaultNodes
};
}
function getRootInformation(tag) {
const transition = isTransition(tag);
const externalComponent = !isHtmlTag(tag) && !transition;
return {
transition,
externalComponent,
tag: externalComponent
? resolveComponent(tag)
: transition
? TransitionGroup
: tag
};
}
function computeComponentStructure({ $slots, tag, realList, getKey }) {
const nodes = computeNodes({ $slots, realList, getKey });
const root = getRootInformation(tag);
return new ComponentStructure({ nodes, root, realList });
}
export { computeComponentStructure };