fluid-dnd
Version:
An agnostic drag and drop library to sort all kind of lists. With current support for vue, react and svelte
75 lines (74 loc) • 3.52 kB
JavaScript
import { getParentDraggableChildren, getSiblings } from '../utils/GetStyles';
import getTranslationByDragging from '../events/dragAndDrop/getTranslationByDraggingAndEvent';
import { addTempChildOnInsert, removeTempChild } from '../tempChildren';
import { DISABLE_TRANSITION, DRAGGABLE_CLASS } from '../utils/classes';
import { addClass, containClass, removeClass } from '../utils/dom/classList';
import { isTempElement, observeMutation } from '../utils/observer';
import { useChangeDraggableStyles } from './changeDraggableStyles';
import { removeTranslateWhitoutTransition } from '../utils/SetStyles';
export default function useInsertEvents(currentConfig, parent, handlerPublisher, endDraggingAction) {
const { delayBeforeInsert } = currentConfig;
const [removeElementDraggingStyles, _, dragEventOverElement] = useChangeDraggableStyles(currentConfig, handlerPublisher, endDraggingAction);
// #region Insert
const emitInsertEventToSiblings = (targetIndex, draggedElement, droppable, value, droppableConfigurator) => {
const translation = getTranslationByDragging(draggedElement, 'insert', currentConfig.direction, droppable);
const { onInsertEvent } = currentConfig;
const siblings = getParentDraggableChildren(droppable);
for (const [index, sibling] of siblings.entries()) {
if (!containClass(sibling, DRAGGABLE_CLASS)) {
continue;
}
if (index >= targetIndex) {
dragEventOverElement(sibling, translation);
}
}
addTempChildOnInsert(draggedElement, false, droppableConfigurator);
setTimeout(() => {
onInsertEvent(targetIndex, value);
onFinishInsertElement(targetIndex, droppable, currentConfig);
removeElementDraggingStyles(draggedElement);
removeTranslateFromSiblings(draggedElement, parent);
removeTempChild(parent, 0, true);
}, delayBeforeInsert);
};
const removeTranslateFromSiblings = (element, parent) => {
const [siblings] = getSiblings(element, parent);
for (const sibling of [...siblings, element]) {
removeTranslateWhitoutTransition(sibling);
}
};
return [emitInsertEventToSiblings];
}
const childrenMutationFilter = (mutation) => {
const addedNodes = Array.from(mutation.addedNodes ?? [])
.values()
.filter((element) => !isTempElement(element))
.toArray();
return addedNodes.length > 0;
};
const onFinishInsertElement = (targetIndex, droppable, config) => {
const { insertingFromClass, animationDuration } = config;
const observer = observeMutation(() => {
const siblings = getParentDraggableChildren(droppable);
const newElement = siblings[targetIndex];
addClass(newElement, insertingFromClass);
addClass(newElement, DISABLE_TRANSITION);
setTimeout(() => {
removeClass(newElement, DISABLE_TRANSITION);
removeClass(newElement, insertingFromClass);
observer.disconnect();
}, animationDuration);
}, droppable, {
childList: true
}, childrenMutationFilter);
};
export const insertToListEmpty = (config, droppable, targetIndex, value) => {
if (!droppable) {
return;
}
const { onInsertEvent, delayBeforeInsert } = config;
setTimeout(() => {
onInsertEvent(targetIndex, value);
onFinishInsertElement(targetIndex, droppable, config);
}, delayBeforeInsert);
};