wix-style-react
Version:
132 lines (115 loc) • 3.78 kB
JavaScript
import { findInstance } from 'react-dom-instance';
import {
getInstanceOfDraggableProvider,
getInstanceOfDraggableSource,
getInstanceOfDraggableTarget,
} from './dragAndDropTestUtils';
import { dataAttributes } from '../../DragAndDrop/Draggable/constants';
import { dragAndDropPuppeteerDriverFactory } from './dragAndDropPuppeteerDriverFactory';
const getManager = instance =>
getInstanceOfDraggableProvider(instance).getManager();
const getDraggableId = (element, dataHook, id) =>
dataHook
? element
.querySelector(`[data-hook="${dataHook}"]`)
.getAttribute(dataAttributes.id)
: id;
const simulateMouseMove = (dndInstance, draggableId) => {
getManager(dndInstance)
.getBackend()
.simulateHover([
getInstanceOfDraggableTarget(dndInstance, draggableId).getHandlerId(),
]);
};
export const dragAndDropDriverFactory = ({ base, element }) => {
const isPuppeteer = base?.type === 'puppeteer';
const dragAndDropPuppeteerDriver = dragAndDropPuppeteerDriverFactory({
base,
element,
});
return {
beginDrag: async ({ dataHook, id }) => {
if (isPuppeteer) {
return dragAndDropPuppeteerDriver.beginDrag({ dataHook, id });
}
const dndInstance = findInstance(element);
const draggableId = getDraggableId(element, dataHook, id);
const handleId = getInstanceOfDraggableSource(
dndInstance,
draggableId,
).getHandlerId();
getManager(dndInstance).getBackend().simulateBeginDrag([handleId]);
},
dragOver: async ({ dataHook, id, offset }) => {
if (isPuppeteer) {
return dragAndDropPuppeteerDriver.dragOver({ dataHook, id, offset });
}
const dndInstance = findInstance(element);
const draggableId = getDraggableId(element, dataHook, id);
if (offset) {
getManager(dndInstance).getMonitor().getClientOffset = jest.fn(
() => offset,
);
// on horizontal item move we have to simulate one more mouse move event
// in order to get correct drop target
simulateMouseMove(dndInstance, draggableId);
}
simulateMouseMove(dndInstance, draggableId);
},
endDrag: async item => {
if (isPuppeteer) {
return dragAndDropPuppeteerDriver.endDrag({ dataHook: item.dataHook });
}
const backend = getManager(findInstance(element)).getBackend();
backend.simulateDrop();
backend.simulateEndDrag();
},
getItemPosition: async ({ dataHook }) => {
const draggableItems = await base
.$$(`[${dataAttributes.draggableTarget}]`)
.map(async item => ({
dataHook: await (
await item.$$(`[${dataAttributes.draggableSource}]`).get(0)
).attr('data-hook'),
}));
return draggableItems.findIndex(item => item.dataHook === dataHook);
},
getItemDepth: async ({ dataHook }) => {
const depth = await base
.$(`[data-hook="${dataHook}"]`)
.attr(dataAttributes.depth);
return parseInt(depth, 10);
},
};
};
const changeItemDepthByOneLevel = async ({
dragAndDropDriver,
dataHook,
offset,
}) => {
await dragAndDropDriver.beginDrag({ dataHook });
await dragAndDropDriver.dragOver({
dataHook,
offset: {
x: offset,
y: 0,
},
});
await dragAndDropDriver.endDrag({ dataHook });
};
export const changeItemDepth = async ({
dragAndDropDriver,
depthLevel,
threshold,
dataHook,
}) => {
for (let i = 0; i < Math.abs(depthLevel); i++) {
// we have to move one level at a time,
// so the drop targets could be registered successfully
await changeItemDepthByOneLevel({
dragAndDropDriver,
dataHook,
offset: depthLevel > 0 ? threshold : threshold * -1,
});
}
};