UNPKG

3.35 kBJavaScriptView Raw
1export function arrayMove(array, from, to) {
2 array = array.slice();
3 array.splice(to < 0 ? array.length + to : to, 0, array.splice(from, 1)[0]);
4 return array;
5}
6export function arrayRemove(array, index) {
7 array = array.slice();
8 array.splice(index, 1);
9 return array;
10}
11export function getTranslateOffset(element) {
12 const style = window.getComputedStyle(element);
13 return (Math.max(parseInt(style['margin-top'], 10), parseInt(style['margin-bottom'], 10)) + element.getBoundingClientRect().height);
14}
15export function isTouchEvent(event) {
16 return ((event.touches && event.touches.length) ||
17 (event.changedTouches && event.changedTouches.length));
18}
19export function transformItem(element, offsetY = 0, offsetX = 0) {
20 if (!element)
21 return;
22 if (offsetY === null || offsetX === null) {
23 element.style.removeProperty('transform');
24 return;
25 }
26 element.style.transform = `translate(${offsetX}px, ${offsetY}px)`;
27}
28export function isItemTransformed(element) {
29 return !!element.style.transform;
30}
31export function setItemTransition(element, duration, timing) {
32 if (element) {
33 element.style['transition'] = `transform ${duration}ms${timing ? ` ${timing}` : ''}`;
34 }
35}
36// returns the "slot" for the targetValue, aka where it should go
37// in an ordered "array", it starts with -1 index
38export function binarySearch(array, targetValue) {
39 let min = 0;
40 let max = array.length - 1;
41 let guess;
42 while (min <= max) {
43 guess = Math.floor((max + min) / 2);
44 if (!array[guess + 1] ||
45 (array[guess] <= targetValue && array[guess + 1] >= targetValue)) {
46 return guess;
47 }
48 else if (array[guess] < targetValue && array[guess + 1] < targetValue) {
49 min = guess + 1;
50 }
51 else {
52 max = guess - 1;
53 }
54 }
55 return -1;
56}
57// adapted from https://github.com/alexreardon/raf-schd
58export const schd = (fn) => {
59 let lastArgs = [];
60 let frameId = null;
61 const wrapperFn = (...args) => {
62 lastArgs = args;
63 if (frameId) {
64 return;
65 }
66 frameId = requestAnimationFrame(() => {
67 frameId = null;
68 fn(...lastArgs);
69 });
70 };
71 wrapperFn.cancel = () => {
72 if (frameId) {
73 cancelAnimationFrame(frameId);
74 }
75 };
76 return wrapperFn;
77};
78export function checkIfInteractive(target, rootElement) {
79 const DISABLED_ELEMENTS = [
80 'input',
81 'textarea',
82 'select',
83 'option',
84 'optgroup',
85 'video',
86 'audio',
87 'button',
88 'a'
89 ];
90 const DISABLED_ROLES = ['button', 'link', 'checkbox', 'tab'];
91 while (target !== rootElement) {
92 if (target.getAttribute('data-movable-handle')) {
93 return false;
94 }
95 if (DISABLED_ELEMENTS.includes(target.tagName.toLowerCase())) {
96 return true;
97 }
98 const role = target.getAttribute('role');
99 if (role && DISABLED_ROLES.includes(role.toLowerCase())) {
100 return true;
101 }
102 if (target.tagName.toLowerCase() === 'label' &&
103 target.hasAttribute('for')) {
104 return true;
105 }
106 if (target.tagName)
107 target = target.parentElement;
108 }
109 return false;
110}