Skip to content

Instantly share code, notes, and snippets.

@pgengler
Last active August 27, 2019 14:39
Show Gist options
  • Save pgengler/7f29e0b4d511fe3f3c5befa8ed4de869 to your computer and use it in GitHub Desktop.
Save pgengler/7f29e0b4d511fe3f3c5befa8ed4de869 to your computer and use it in GitHub Desktop.
// Borrowed from https://github.com/heroku/ember-sortable/pull/181
// until a version of ember-sortable with that PR (or something similar) lands
import { findAll, triggerEvent } from '@ember/test-helpers';
import { resolve } from 'rsvp';
export async function drag(mode, item, offsetFn, callbacks = {}) {
let start;
let move;
let end;
let which;
if (mode === 'mouse') {
start = 'mousedown';
move = 'mousemove';
end = 'mouseup';
which = 1;
} else if (mode === 'touch') {
start = 'touchstart';
move = 'touchmove';
end = 'touchend';
} else {
throw new Error(`Unsupported mode: '${mode}'`);
}
const itemOffset = {
left: item.offsetLeft,
top: item.offsetTop
};
const offset = offsetFn();
const rect = item.getBoundingClientRect();
const scale = item.clientHeight / (rect.bottom - rect.top);
const targetX = itemOffset.left + (offset.dx * scale);
const targetY = itemOffset.top + (offset.dy * scale);
await triggerEvent(item, start, {
clientX: itemOffset.left,
clientY: itemOffset.top,
which
});
if (callbacks.dragstart) {
await callbacks.dragstart();
}
await triggerEvent(item, move, {
clientX: itemOffset.left,
clientY: itemOffset.top
});
if (callbacks.dragmove) {
await callbacks.dragmove();
}
await triggerEvent(item, move, {
clientX: targetX,
clientY: targetY
});
await triggerEvent(item, end, {
clientX: targetX,
clientY: targetY
});
if (callbacks.dragend) {
await callbacks.dragend();
}
}
export async function reorder(mode, itemSelector, ...resultSelectors) {
await resultSelectors.reduce(async (acc, selector, targetIndex) => {
await acc;
const items = findAll(itemSelector);
const element = items.find(item => item.matches(selector));
const targetElement = items[targetIndex];
const dx = targetElement.offsetLeft - element.offsetLeft;
const dy = targetElement.offsetTop - element.offsetTop;
if (dx === 0 && dy === 0) {
return resolve();
}
return drag(mode, element, () => { return { dx, dy }; });
}, resolve());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment