fluid-dnd 2.0.0 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/{HandlerPublisher-BbQeSll4.js → HandlerPublisher-BYI2bw4n.js} +1 -1
- package/dist/{HandlerPublisher-F9_9P96L.cjs → HandlerPublisher-C-jTncuG.cjs} +1 -1
- package/dist/core/HandlerPublisher.js +20 -0
- package/dist/core/configHandler.d.ts +2 -3
- package/dist/core/configHandler.js +33 -0
- package/dist/core/dragAndDrop.d.ts +3 -3
- package/dist/core/dragAndDrop.js +62 -0
- package/dist/core/index.js +2 -0
- package/dist/core/useDraggable.d.ts +2 -3
- package/dist/core/useDraggable.js +328 -0
- package/dist/core/useDroppable.d.ts +2 -3
- package/dist/core/useDroppable.js +55 -0
- package/dist/core/utils/GetStyles.d.ts +2 -3
- package/dist/core/utils/GetStyles.js +138 -0
- package/dist/core/utils/ParseStyles.d.ts +2 -3
- package/dist/core/utils/ParseStyles.js +40 -0
- package/dist/core/utils/SetStyles.d.ts +1 -2
- package/dist/core/utils/SetStyles.js +192 -0
- package/dist/core/utils/SetTransform.d.ts +2 -3
- package/dist/core/utils/SetTransform.js +148 -0
- package/dist/core/utils/classes.js +9 -0
- package/dist/core/utils/config.d.ts +3 -3
- package/dist/core/utils/config.js +55 -0
- package/dist/core/utils/dom/classList.js +35 -0
- package/dist/core/utils/droppableConfigurator.d.ts +3 -4
- package/dist/core/utils/droppableConfigurator.js +106 -0
- package/dist/core/utils/events/emitEvents.d.ts +5 -6
- package/dist/core/utils/events/emitEvents.js +333 -0
- package/dist/core/utils/index.js +9 -0
- package/dist/core/utils/observer.js +11 -0
- package/dist/core/utils/scroll.d.ts +2 -3
- package/dist/core/utils/scroll.js +17 -0
- package/dist/core/utils/tempChildren.d.ts +1 -2
- package/dist/core/utils/tempChildren.js +146 -0
- package/dist/core/utils/touchDevice.js +3 -0
- package/dist/core/utils/translate/GetTranslateBeforeDropping.d.ts +2 -3
- package/dist/core/utils/translate/GetTranslateBeforeDropping.js +129 -0
- package/dist/core/utils/translate/GetTranslationByDraggingAndEvent.d.ts +2 -3
- package/dist/core/utils/translate/GetTranslationByDraggingAndEvent.js +48 -0
- package/dist/{index-8zYdjZIf.js → index-BQUYvZRn.js} +214 -214
- package/dist/index-DNmnvxhi.cjs +1 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +2 -0
- package/dist/index.mjs +4 -0
- package/dist/react/index.cjs +1 -1
- package/dist/react/index.d.ts +1 -2
- package/dist/react/index.js +2 -0
- package/dist/react/index.mjs +2 -2
- package/dist/react/useDragAndDrop.d.ts +2 -3
- package/dist/react/useDragAndDrop.js +28 -0
- package/dist/react/utils/ReactLilstConfig.d.ts +3 -4
- package/dist/react/utils/ReactLilstConfig.js +64 -0
- package/dist/svelte/index.cjs +1 -1
- package/dist/svelte/index.d.ts +1 -2
- package/dist/svelte/index.js +2 -0
- package/dist/svelte/index.mjs +2 -2
- package/dist/svelte/useDragAndDrop.d.ts +1 -2
- package/dist/svelte/useDragAndDrop.js +25 -0
- package/dist/svelte/utils/SvelteListCondig.d.ts +2 -2
- package/dist/svelte/utils/SvelteListCondig.js +36 -0
- package/dist/vue/index.cjs +1 -1
- package/dist/vue/index.d.ts +1 -2
- package/dist/vue/index.js +2 -0
- package/dist/vue/index.mjs +2 -2
- package/dist/vue/useDragAndDrop.d.ts +2 -3
- package/dist/vue/useDragAndDrop.js +23 -0
- package/dist/vue/utils/DropMethods.d.ts +1 -2
- package/dist/vue/utils/DropMethods.js +19 -0
- package/dist/vue/utils/VueListCondig.d.ts +3 -3
- package/dist/vue/utils/VueListCondig.js +28 -0
- package/package.json +5 -8
- package/dist/index/index.cjs +0 -1
- package/dist/index/index.mjs +0 -4
- package/dist/index-C37ab-rG.cjs +0 -1
package/README.md
CHANGED
@@ -55,7 +55,7 @@ library for lists with support for Vue, react and Svelte](https://fluid-dnd.netl
|
|
55
55
|
|
56
56
|
- 📚 Check out all the [docs](https://fluid-dnd.netlify.app/).
|
57
57
|
- 🛠️ Edit the previous [here](https://codesandbox.io/s/nifty-hooks-5plkpl).
|
58
|
-
- 📘 See others examples [here](https://fluid-dnd.netlify.app/example/vertical-list/single-vertical-list/).
|
58
|
+
- 📘 See others examples [here](https://fluid-dnd.netlify.app/vue/example/vertical-list/single-vertical-list/).
|
59
59
|
|
60
60
|
## 📚 Libraries Support
|
61
61
|
- **Vue** >=3.0.0
|
@@ -1,7 +1,7 @@
|
|
1
1
|
var d = Object.defineProperty;
|
2
2
|
var e = (a, s, l) => s in a ? d(a, s, { enumerable: !0, configurable: !0, writable: !0, value: l }) : a[s] = l;
|
3
3
|
var r = (a, s, l) => e(a, typeof s != "symbol" ? s + "" : s, l);
|
4
|
-
import { a as h, t as n, G as t } from "./index-
|
4
|
+
import { a as h, t as n, G as t } from "./index-BQUYvZRn.js";
|
5
5
|
class c {
|
6
6
|
constructor() {
|
7
7
|
r(this, "handlers");
|
@@ -1 +1 @@
|
|
1
|
-
"use strict";var d=Object.defineProperty;var n=(e,s,l)=>s in e?d(e,s,{enumerable:!0,configurable:!0,writable:!0,value:l}):e[s]=l;var a=(e,s,l)=>n(e,typeof s!="symbol"?s+"":s,l);const r=require("./index-
|
1
|
+
"use strict";var d=Object.defineProperty;var n=(e,s,l)=>s in e?d(e,s,{enumerable:!0,configurable:!0,writable:!0,value:l}):e[s]=l;var a=(e,s,l)=>n(e,typeof s!="symbol"?s+"":s,l);const r=require("./index-DNmnvxhi.cjs");class h{constructor(){a(this,"handlers");this.handlers=[]}addSubscriber(s){this.handlers.includes(s)||(this.handlers.push(s),r.addClass(s,r.GRAB_CLASS))}toggleGrabClass(s){for(const l of this.handlers)r.toggleClass(l,r.GRAB_CLASS,s)}}exports.HandlerPublisher=h;
|
@@ -0,0 +1,20 @@
|
|
1
|
+
import { GRAB_CLASS } from "./utils/classes";
|
2
|
+
import { addClass, toggleClass } from "./utils/dom/classList";
|
3
|
+
export default class HandlerPublisher {
|
4
|
+
handlers;
|
5
|
+
constructor() {
|
6
|
+
this.handlers = [];
|
7
|
+
}
|
8
|
+
addSubscriber(subscriber) {
|
9
|
+
if (this.handlers.includes(subscriber)) {
|
10
|
+
return;
|
11
|
+
}
|
12
|
+
this.handlers.push(subscriber);
|
13
|
+
addClass(subscriber, GRAB_CLASS);
|
14
|
+
}
|
15
|
+
toggleGrabClass(force) {
|
16
|
+
for (const handler of this.handlers) {
|
17
|
+
toggleClass(handler, GRAB_CLASS, force);
|
18
|
+
}
|
19
|
+
}
|
20
|
+
}
|
@@ -0,0 +1,33 @@
|
|
1
|
+
import { getScrollElement } from "./utils/GetStyles";
|
2
|
+
import { containstClasses } from "./utils/dom/classList";
|
3
|
+
export default class ConfigHandler {
|
4
|
+
static configs = [];
|
5
|
+
static addConfig(droppable, config) {
|
6
|
+
const configs = ConfigHandler.configs.filter((configHandler) => !configHandler.droppable.isSameNode(droppable));
|
7
|
+
const scroll = getScrollElement(droppable);
|
8
|
+
configs.push({
|
9
|
+
droppable,
|
10
|
+
config,
|
11
|
+
scroll,
|
12
|
+
});
|
13
|
+
ConfigHandler.configs = configs;
|
14
|
+
}
|
15
|
+
static removeObsoleteConfigs = () => {
|
16
|
+
const notObsoltete = ConfigHandler.configs.filter(({ droppable }) => document.contains(droppable));
|
17
|
+
ConfigHandler.configs = notObsoltete;
|
18
|
+
};
|
19
|
+
static updateScrolls(currentDroppable, droppableGroupClass) {
|
20
|
+
for (const configHandler of ConfigHandler.configs) {
|
21
|
+
const { droppable } = configHandler;
|
22
|
+
if ((droppableGroupClass &&
|
23
|
+
containstClasses(droppable, droppableGroupClass)) ||
|
24
|
+
droppable.isSameNode(currentDroppable)) {
|
25
|
+
configHandler.scroll = getScrollElement(droppable);
|
26
|
+
}
|
27
|
+
}
|
28
|
+
}
|
29
|
+
static getConfig(curerntDroppable) {
|
30
|
+
const config = ConfigHandler.configs.find(({ droppable }) => droppable.isSameNode(curerntDroppable));
|
31
|
+
return config;
|
32
|
+
}
|
33
|
+
}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import { ListCondig
|
2
|
-
import {
|
3
|
-
|
1
|
+
import { ListCondig } from ".";
|
2
|
+
import { Config } from ".";
|
3
|
+
import HandlerPublisher from "./HandlerPublisher";
|
4
4
|
export default function dragAndDrop<T>(listCondig: ListCondig<T>, handlerPublisher: HandlerPublisher, config?: Config<T>, indexAttr?: string): readonly [(index: number) => void, (index: number, value: T) => void, (parent: HTMLElement | null | undefined) => MutationObserver | undefined];
|
@@ -0,0 +1,62 @@
|
|
1
|
+
import { getConfig } from "./utils/config";
|
2
|
+
import useDroppable from "./useDroppable";
|
3
|
+
import ConfigHandler from "./configHandler";
|
4
|
+
import { observeMutation } from "./utils/observer";
|
5
|
+
import { addClass } from "./utils/dom/classList";
|
6
|
+
import { DROPPABLE_CLASS } from "./utils/classes";
|
7
|
+
import { isTempElement } from "./utils/tempChildren";
|
8
|
+
export default function dragAndDrop(listCondig, handlerPublisher, config, indexAttr = 'index') {
|
9
|
+
let removeAtFromElements = [];
|
10
|
+
let insertAtFromElements = [];
|
11
|
+
let currentObserver;
|
12
|
+
const coreConfig = getConfig(listCondig, config);
|
13
|
+
const removeAt = (index) => {
|
14
|
+
for (const removeAtFromElement of removeAtFromElements) {
|
15
|
+
removeAtFromElement(index);
|
16
|
+
}
|
17
|
+
};
|
18
|
+
const insertAt = (index, value) => {
|
19
|
+
const listLegth = coreConfig.onGetLegth();
|
20
|
+
if (listLegth === 0) {
|
21
|
+
listCondig.insertToListEmpty(coreConfig, index, value);
|
22
|
+
}
|
23
|
+
else {
|
24
|
+
for (const insertAtFromElement of insertAtFromElements) {
|
25
|
+
insertAtFromElement(index, value);
|
26
|
+
}
|
27
|
+
}
|
28
|
+
};
|
29
|
+
const makeChildrensDraggable = (parent) => {
|
30
|
+
const [removeAtFromElementList, insertAtFromElementList] = useDroppable(coreConfig, handlerPublisher, parent, indexAttr);
|
31
|
+
removeAtFromElements = removeAtFromElementList;
|
32
|
+
insertAtFromElements = insertAtFromElementList;
|
33
|
+
};
|
34
|
+
const childrenMutationFilter = (mutation) => {
|
35
|
+
const addedNodes = mutation.addedNodes.values().filter((element) => !isTempElement(element)).toArray();
|
36
|
+
const removedNodes = mutation.removedNodes.values().filter((element) => !isTempElement(element)).toArray();
|
37
|
+
return addedNodes.length > 0 || removedNodes.length > 0;
|
38
|
+
};
|
39
|
+
const observeChildrens = (parent) => {
|
40
|
+
currentObserver = observeMutation(() => {
|
41
|
+
makeChildrensDraggable(parent);
|
42
|
+
}, parent, { childList: true }, childrenMutationFilter);
|
43
|
+
};
|
44
|
+
const makeDroppable = (parent) => {
|
45
|
+
addClass(parent, DROPPABLE_CLASS);
|
46
|
+
};
|
47
|
+
const addConfigHandler = (parent) => {
|
48
|
+
ConfigHandler.addConfig(parent, coreConfig);
|
49
|
+
};
|
50
|
+
const onChangeParent = (parent) => {
|
51
|
+
if (!parent) {
|
52
|
+
return;
|
53
|
+
}
|
54
|
+
makeDroppable(parent);
|
55
|
+
addConfigHandler(parent);
|
56
|
+
observeChildrens(parent);
|
57
|
+
makeChildrensDraggable(parent);
|
58
|
+
ConfigHandler.removeObsoleteConfigs();
|
59
|
+
return currentObserver;
|
60
|
+
};
|
61
|
+
return [removeAt, insertAt, onChangeParent];
|
62
|
+
}
|
@@ -1,4 +1,3 @@
|
|
1
|
-
import { CoreConfig } from
|
2
|
-
import
|
3
|
-
|
1
|
+
import { CoreConfig } from ".";
|
2
|
+
import HandlerPublisher from "./HandlerPublisher";
|
4
3
|
export default function useDraggable<T>(draggableElement: HTMLElement, index: number, config: CoreConfig<T>, parent: HTMLElement, handlerPublisher: HandlerPublisher): readonly [(targetIndex: number) => void, (targetIndex: number, value: T) => void];
|
@@ -0,0 +1,328 @@
|
|
1
|
+
import { assignDraggingEvent, convetEventToDragMouseTouchEvent, moveTranslate, setCustomFixedSize, setEventWithInterval, setTranistion, } from "./utils/SetStyles";
|
2
|
+
import { useTransform } from "./utils/SetTransform";
|
3
|
+
import useEmitEvents from "./utils/events/emitEvents";
|
4
|
+
import { DRAG_EVENT, draggableTargetTimingFunction, START_DRAG_EVENT, START_DROP_EVENT } from "./utils";
|
5
|
+
import ConfigHandler from "./configHandler";
|
6
|
+
import { IsHTMLElement, isTouchEvent } from "./utils/touchDevice";
|
7
|
+
import { addTempChild, addTempChildOnInsert, removeTempChildrens } from "./utils/tempChildren";
|
8
|
+
import { DroppableConfigurator } from "./utils/droppableConfigurator";
|
9
|
+
import { addClass, containClass, getClassesList, getClassesSelector, removeClass, toggleClass, } from "./utils/dom/classList";
|
10
|
+
import { DRAGGABLE_CLASS, DRAGGING_CLASS, DROPPABLE_CLASS, HANDLER_CLASS } from "./utils/classes";
|
11
|
+
var DraggingState;
|
12
|
+
(function (DraggingState) {
|
13
|
+
DraggingState[DraggingState["NOT_DRAGGING"] = 0] = "NOT_DRAGGING";
|
14
|
+
DraggingState[DraggingState["START_DRAGGING"] = 1] = "START_DRAGGING";
|
15
|
+
DraggingState[DraggingState["DRAGING"] = 2] = "DRAGING";
|
16
|
+
DraggingState[DraggingState["END_DRAGGING"] = 3] = "END_DRAGGING";
|
17
|
+
})(DraggingState || (DraggingState = {}));
|
18
|
+
export default function useDraggable(draggableElement, index, config, parent, handlerPublisher) {
|
19
|
+
const { handlerSelector, isDraggable, droppableGroup, animationDuration, delayBeforeRemove, draggingClass, removingClass, onRemoveAtEvent, droppableClass, onDragStart, } = config;
|
20
|
+
const droppableGroupClass = getClassesList(droppableGroup)
|
21
|
+
.map((classGroup) => `droppable-group-${classGroup}`)
|
22
|
+
.join(" ");
|
23
|
+
let draggingState = DraggingState.NOT_DRAGGING;
|
24
|
+
let windowScroll = {
|
25
|
+
scrollX: 0,
|
26
|
+
scrollY: 0,
|
27
|
+
};
|
28
|
+
let pagePosition = { pageX: 0, pageY: 0 };
|
29
|
+
let delayTimeout;
|
30
|
+
let initialTouch;
|
31
|
+
const [setTransform, updateTransformState] = useTransform(draggableElement);
|
32
|
+
const [emitEventToSiblings, emitRemoveEventToSiblings, emitInsertEventToSiblings, emitFinishRemoveEventToSiblings, toggleDraggingClass,] = useEmitEvents(config, index, parent, droppableGroupClass, handlerPublisher, () => (draggingState = DraggingState.NOT_DRAGGING));
|
33
|
+
const setDraggable = () => {
|
34
|
+
addClass(draggableElement, DRAGGABLE_CLASS);
|
35
|
+
};
|
36
|
+
const addHandlerClass = (handlerElement) => {
|
37
|
+
addClass(handlerElement, HANDLER_CLASS);
|
38
|
+
handlerPublisher.addSubscriber(handlerElement);
|
39
|
+
};
|
40
|
+
const setHandlerStyles = () => {
|
41
|
+
if (isDraggable(draggableElement)) {
|
42
|
+
const handlerElement = draggableElement.querySelector(handlerSelector);
|
43
|
+
if (handlerElement) {
|
44
|
+
addHandlerClass(handlerElement);
|
45
|
+
}
|
46
|
+
else {
|
47
|
+
addHandlerClass(draggableElement);
|
48
|
+
}
|
49
|
+
}
|
50
|
+
};
|
51
|
+
const setCssStyles = () => {
|
52
|
+
setHandlerStyles();
|
53
|
+
setDraggable();
|
54
|
+
};
|
55
|
+
const getHandler = (element) => {
|
56
|
+
const handler = element?.querySelector(`.${HANDLER_CLASS}`);
|
57
|
+
const handlerParent = handler?.parentElement;
|
58
|
+
if (handler && handlerParent
|
59
|
+
&& containClass(handlerParent, DROPPABLE_CLASS)
|
60
|
+
&& !handlerParent.isSameNode(parent)) {
|
61
|
+
return null;
|
62
|
+
}
|
63
|
+
return handler;
|
64
|
+
};
|
65
|
+
const setSlotRefElementParams = (element) => {
|
66
|
+
const handlerElement = (getHandler(element) ?? element);
|
67
|
+
if (handlerElement && isDraggable(element)) {
|
68
|
+
assignDraggingEvent(handlerElement, "onmousedown", onmousedown("mousemove", "mouseup"));
|
69
|
+
assignDraggingEvent(handlerElement, "ontouchstart", onmousedown("touchmove", "touchend"), (event) => {
|
70
|
+
initialTouch = {
|
71
|
+
x: event.touches[0].clientX,
|
72
|
+
y: event.touches[0].clientY,
|
73
|
+
};
|
74
|
+
});
|
75
|
+
disableMousedownEventFromImages(handlerElement);
|
76
|
+
}
|
77
|
+
if (!element?.isSameNode(handlerElement)) {
|
78
|
+
assignDraggingEvent(element, "onmousedown", mousedownOnDraggablefunction);
|
79
|
+
}
|
80
|
+
addClass(parent, DROPPABLE_CLASS);
|
81
|
+
};
|
82
|
+
const disableMousedownEventFromImages = (handlerElement) => {
|
83
|
+
// Avoid dragging inner images
|
84
|
+
const images = handlerElement.querySelectorAll("img");
|
85
|
+
Array.from(images).forEach((image) => {
|
86
|
+
image.onmousedown = () => false;
|
87
|
+
});
|
88
|
+
};
|
89
|
+
const setTransformDragEvent = () => {
|
90
|
+
if (pagePosition.pageX == 0 && pagePosition.pageY == 0) {
|
91
|
+
return;
|
92
|
+
}
|
93
|
+
if (!droppableConfigurator.current) {
|
94
|
+
return;
|
95
|
+
}
|
96
|
+
const { droppable, config } = droppableConfigurator.current;
|
97
|
+
setTransform(draggableElement, droppable, pagePosition, config.direction);
|
98
|
+
emitEventToSiblings(draggableElement, DRAG_EVENT, windowScroll, droppableConfigurator.current);
|
99
|
+
};
|
100
|
+
const changeDroppable = (newdDroppableConfig, oldDroppableConfig) => {
|
101
|
+
if (oldDroppableConfig &&
|
102
|
+
draggingState == DraggingState.DRAGING &&
|
103
|
+
!newdDroppableConfig?.droppable.isSameNode(oldDroppableConfig.droppable)) {
|
104
|
+
emitEventToSiblings(draggableElement, DRAG_EVENT, windowScroll, oldDroppableConfig);
|
105
|
+
}
|
106
|
+
};
|
107
|
+
const droppableConfigurator = new DroppableConfigurator(draggableElement, droppableGroupClass, parent, setTransformDragEvent, changeDroppable, config.mapFrom);
|
108
|
+
const toggleDroppableClass = (isOutside) => {
|
109
|
+
if (!droppableConfigurator.current) {
|
110
|
+
return;
|
111
|
+
}
|
112
|
+
const droppables = droppableGroupClass ? Array.from(document.querySelectorAll(getClassesSelector(droppableGroupClass))) : [parent];
|
113
|
+
for (const droppable of droppables) {
|
114
|
+
droppable
|
115
|
+
.classList
|
116
|
+
.toggle(droppableClass, !isOutside && droppable.isSameNode(droppableConfigurator.current.droppable));
|
117
|
+
}
|
118
|
+
};
|
119
|
+
const onMove = (event, isTouchEvent = false) => {
|
120
|
+
droppableConfigurator.updateConfig(event);
|
121
|
+
const isOutside = droppableConfigurator.isOutside(event);
|
122
|
+
toggleDroppableClass(isOutside);
|
123
|
+
if (draggingState === DraggingState.START_DRAGGING && !isTouchEvent) {
|
124
|
+
startDragging(event);
|
125
|
+
}
|
126
|
+
else if (draggingState === DraggingState.DRAGING) {
|
127
|
+
updateTempChildren(isOutside);
|
128
|
+
setTransformEvent(event);
|
129
|
+
}
|
130
|
+
};
|
131
|
+
const updateTempChildren = (isOutside = true) => {
|
132
|
+
if (!droppableConfigurator.current) {
|
133
|
+
return;
|
134
|
+
}
|
135
|
+
const { droppable } = droppableConfigurator.current;
|
136
|
+
removeTempChildrens(droppable, parent, droppableGroupClass, animationDuration, isOutside);
|
137
|
+
if (isOutside) {
|
138
|
+
return;
|
139
|
+
}
|
140
|
+
addTempChild(draggableElement, parent, draggingState == DraggingState.START_DRAGGING, droppableConfigurator.current);
|
141
|
+
};
|
142
|
+
const cursorWasNotMoved = (event) => {
|
143
|
+
if (isTouchEvent(event) && initialTouch && draggingState == DraggingState.START_DRAGGING) {
|
144
|
+
const movedX = Math.abs(event.touches[0].clientX - initialTouch.x);
|
145
|
+
const movedY = Math.abs(event.touches[0].clientY - initialTouch.y);
|
146
|
+
if (Math.abs(movedX) > 5 && Math.abs(movedY) > 5) {
|
147
|
+
clearTimeout(delayTimeout);
|
148
|
+
return false;
|
149
|
+
}
|
150
|
+
}
|
151
|
+
return true;
|
152
|
+
};
|
153
|
+
const handleMove = (event) => {
|
154
|
+
clearTimeout(delayTimeout);
|
155
|
+
const eventToDragMouse = convetEventToDragMouseTouchEvent(event);
|
156
|
+
if (isTouchEvent(event) && event.cancelable) {
|
157
|
+
event.preventDefault();
|
158
|
+
}
|
159
|
+
if ((isTouchEvent(event) && !event.cancelable)
|
160
|
+
|| !cursorWasNotMoved(event)) {
|
161
|
+
disableDragging("touchmove", event);
|
162
|
+
return;
|
163
|
+
}
|
164
|
+
onMove(eventToDragMouse, isTouchEvent(event));
|
165
|
+
};
|
166
|
+
const addTouchDeviceDelay = (event, callback) => {
|
167
|
+
if (event == "touchmove") {
|
168
|
+
delayTimeout = setTimeout(() => {
|
169
|
+
callback();
|
170
|
+
}, 150);
|
171
|
+
}
|
172
|
+
else {
|
173
|
+
callback();
|
174
|
+
}
|
175
|
+
};
|
176
|
+
const cursorIsOnChildDraggable = (event, element) => {
|
177
|
+
const { clientX, clientY } = event;
|
178
|
+
const elementBelow = document.elementFromPoint(clientX, clientY);
|
179
|
+
const draggableAncestor = elementBelow?.closest(`.${DRAGGABLE_CLASS}`);
|
180
|
+
return draggableAncestor && element.isSameNode(draggableAncestor);
|
181
|
+
};
|
182
|
+
const getDragStartEventData = (element) => {
|
183
|
+
const value = config.onGetValue(index);
|
184
|
+
return ({ index, element, value });
|
185
|
+
};
|
186
|
+
const onmousedown = (moveEvent, onLeaveEvent) => {
|
187
|
+
return (event) => {
|
188
|
+
if (!cursorIsOnChildDraggable(event, draggableElement)) {
|
189
|
+
return;
|
190
|
+
}
|
191
|
+
ConfigHandler.updateScrolls(parent, droppableGroupClass);
|
192
|
+
const { scrollX, scrollY } = window;
|
193
|
+
windowScroll = { scrollX, scrollY };
|
194
|
+
if (draggingState === DraggingState.NOT_DRAGGING) {
|
195
|
+
draggingState = DraggingState.START_DRAGGING;
|
196
|
+
const data = getDragStartEventData(draggableElement);
|
197
|
+
data && onDragStart(data);
|
198
|
+
addTouchDeviceDelay(moveEvent, () => {
|
199
|
+
if (moveEvent == 'touchmove') {
|
200
|
+
droppableConfigurator.updateConfig(event);
|
201
|
+
toggleDroppableClass(droppableConfigurator.isOutside(event));
|
202
|
+
startDragging(event);
|
203
|
+
}
|
204
|
+
});
|
205
|
+
document.addEventListener(moveEvent, handleMove, {
|
206
|
+
passive: false,
|
207
|
+
});
|
208
|
+
makeScrollEventOnDroppable(parent);
|
209
|
+
document.addEventListener(onLeaveEvent, onLeave(moveEvent), {
|
210
|
+
once: true,
|
211
|
+
});
|
212
|
+
}
|
213
|
+
};
|
214
|
+
};
|
215
|
+
const mousedownOnDraggablefunction = (event) => {
|
216
|
+
return droppableConfigurator.updateConfig(event);
|
217
|
+
};
|
218
|
+
const onLeave = (moveEvent) => {
|
219
|
+
return (event) => {
|
220
|
+
disableDragging(moveEvent, event);
|
221
|
+
};
|
222
|
+
};
|
223
|
+
const disableDragging = (moveEvent, event) => {
|
224
|
+
toggleDroppableClass(true);
|
225
|
+
const convertedEvent = convetEventToDragMouseTouchEvent(event);
|
226
|
+
onDropDraggingEvent(droppableConfigurator.isOutside(convertedEvent, false));
|
227
|
+
clearTimeout(delayTimeout);
|
228
|
+
document.removeEventListener(moveEvent, handleMove);
|
229
|
+
droppableConfigurator.updateConfig(convertedEvent);
|
230
|
+
const currentConfig = droppableConfigurator.getCurrentConfig(convertedEvent);
|
231
|
+
if (currentConfig) {
|
232
|
+
const { droppable } = currentConfig;
|
233
|
+
removeOnScrollEvents(droppable);
|
234
|
+
}
|
235
|
+
parent.onscroll = null;
|
236
|
+
};
|
237
|
+
const removeOnScrollEvents = (droppable) => {
|
238
|
+
droppable.onscroll = null;
|
239
|
+
if (!droppableGroupClass) {
|
240
|
+
return;
|
241
|
+
}
|
242
|
+
const droppables = Array.from(document.querySelectorAll(getClassesSelector(droppableGroupClass)));
|
243
|
+
for (const droppable of droppables) {
|
244
|
+
if (IsHTMLElement(droppable)) {
|
245
|
+
droppable.onscroll = null;
|
246
|
+
}
|
247
|
+
}
|
248
|
+
};
|
249
|
+
const startDragging = (event) => {
|
250
|
+
addTempChild(draggableElement, parent, draggingState == DraggingState.START_DRAGGING, droppableConfigurator.current);
|
251
|
+
updateDraggingStateBeforeDragging();
|
252
|
+
emitEventToSiblings(draggableElement, START_DRAG_EVENT, windowScroll, droppableConfigurator.current);
|
253
|
+
setDraggingStyles(draggableElement);
|
254
|
+
updateTransformState(event, draggableElement);
|
255
|
+
};
|
256
|
+
const updateDraggingStateBeforeDragging = () => {
|
257
|
+
draggingState = DraggingState.DRAGING;
|
258
|
+
};
|
259
|
+
const setTransformEvent = (event) => {
|
260
|
+
const { pageX, pageY } = event;
|
261
|
+
pagePosition = { pageX, pageY };
|
262
|
+
setTransformDragEvent();
|
263
|
+
};
|
264
|
+
const makeScrollEventOnDroppable = (droppable) => {
|
265
|
+
return setEventWithInterval(droppable, "onscroll", onScrollEvent);
|
266
|
+
};
|
267
|
+
const onScrollEvent = () => {
|
268
|
+
return setTransformDragEvent();
|
269
|
+
};
|
270
|
+
const onDropDraggingEvent = (isOutsideAllDroppables) => {
|
271
|
+
if (draggingState !== DraggingState.DRAGING && draggingState !== DraggingState.START_DRAGGING) {
|
272
|
+
draggingState = DraggingState.NOT_DRAGGING;
|
273
|
+
return;
|
274
|
+
}
|
275
|
+
draggingState = DraggingState.END_DRAGGING;
|
276
|
+
removeDraggingStyles(draggableElement);
|
277
|
+
if (draggableElement.classList.contains(DRAGGING_CLASS)) {
|
278
|
+
emitEventToSiblings(draggableElement, START_DROP_EVENT, windowScroll, isOutsideAllDroppables ?
|
279
|
+
droppableConfigurator.initial :
|
280
|
+
droppableConfigurator.current, index);
|
281
|
+
}
|
282
|
+
};
|
283
|
+
const removeDraggingStyles = (element) => {
|
284
|
+
setTranistion(element, animationDuration, draggableTargetTimingFunction);
|
285
|
+
moveTranslate(element, 0, 0);
|
286
|
+
};
|
287
|
+
const setDraggingStyles = (element) => {
|
288
|
+
const { height, width } = element.getBoundingClientRect();
|
289
|
+
setCustomFixedSize(element, {
|
290
|
+
fixedHeight: `${height}px`,
|
291
|
+
fixedWidth: `${width}px`
|
292
|
+
});
|
293
|
+
toggleDraggingClass(element, true);
|
294
|
+
toggleClass(element, draggingClass, true);
|
295
|
+
element.style.transition = "";
|
296
|
+
};
|
297
|
+
const removeAfterRemovingClass = (targetIndex, config) => {
|
298
|
+
removeClass(draggableElement, removingClass);
|
299
|
+
addTempChild(draggableElement, parent, draggingState == DraggingState.START_DRAGGING, droppableConfigurator.initial);
|
300
|
+
emitRemoveEventToSiblings(targetIndex, draggableElement, config, (sibling) => {
|
301
|
+
removeDraggingStyles(sibling);
|
302
|
+
emitFinishRemoveEventToSiblings(draggableElement);
|
303
|
+
});
|
304
|
+
onRemoveAtEvent(index, true);
|
305
|
+
};
|
306
|
+
const removeAtFromElement = (targetIndex) => {
|
307
|
+
if (!droppableConfigurator.initial) {
|
308
|
+
return;
|
309
|
+
}
|
310
|
+
const config = droppableConfigurator.initial;
|
311
|
+
if (targetIndex == index) {
|
312
|
+
addClass(draggableElement, removingClass);
|
313
|
+
setTimeout(() => {
|
314
|
+
removeAfterRemovingClass(targetIndex, config);
|
315
|
+
}, delayBeforeRemove);
|
316
|
+
}
|
317
|
+
};
|
318
|
+
const insertAtFromElement = (targetIndex, value) => {
|
319
|
+
if (targetIndex === index || targetIndex === config.onGetLegth() && index === targetIndex - 1) {
|
320
|
+
emitInsertEventToSiblings(targetIndex, draggableElement, parent, value, () => {
|
321
|
+
addTempChildOnInsert(draggableElement, draggingState == DraggingState.START_DRAGGING, droppableConfigurator.initial);
|
322
|
+
});
|
323
|
+
}
|
324
|
+
};
|
325
|
+
setCssStyles();
|
326
|
+
setSlotRefElementParams(draggableElement);
|
327
|
+
return [removeAtFromElement, insertAtFromElement];
|
328
|
+
}
|
@@ -1,4 +1,3 @@
|
|
1
|
-
import { CoreConfig } from
|
2
|
-
import
|
3
|
-
|
1
|
+
import { CoreConfig } from ".";
|
2
|
+
import HandlerPublisher from "./HandlerPublisher";
|
4
3
|
export default function useDroppable<T>(coreConfig: CoreConfig<T>, handlerPublisher: HandlerPublisher, droppable?: HTMLElement, indexAttr?: string): readonly [((targetIndex: number) => void)[], ((targetIndex: number, value: T) => void)[]];
|
@@ -0,0 +1,55 @@
|
|
1
|
+
import { parseIntEmpty } from "./utils/GetStyles";
|
2
|
+
import { addMultipleClasses, getClassesList } from "./utils/dom/classList";
|
3
|
+
import useDraggable from "./useDraggable";
|
4
|
+
import { AddCssStylesToElement } from "./utils/SetStyles";
|
5
|
+
import { DRAGGABLE_CLASS, DRAGGING_CLASS, DRAGGING_HANDLER_CLASS, DROPPING_CLASS, GRAB_CLASS, GRABBING_CLASS, HANDLER_CLASS } from "./utils/classes";
|
6
|
+
const setDroppableGroupClass = (droppableGroupClass, droppable) => {
|
7
|
+
if (droppableGroupClass) {
|
8
|
+
addMultipleClasses(droppable, droppableGroupClass);
|
9
|
+
}
|
10
|
+
};
|
11
|
+
const createDraggableCssStyles = () => {
|
12
|
+
AddCssStylesToElement(document.body, [
|
13
|
+
`.${DRAGGABLE_CLASS}{touch-action:manipulation;user-select:none;box-sizing:border-box!important;-webkit-user-select:none;}`,
|
14
|
+
`.${HANDLER_CLASS}{pointer-events:auto!important;}`,
|
15
|
+
`.${GRAB_CLASS}{cursor:grab;}`,
|
16
|
+
".temp-child{touch-action:none;pointer-events:none;box-sizing:border-box!important;}",
|
17
|
+
`.droppable{box-sizing:border-box!important;}`,
|
18
|
+
`.${DRAGGING_CLASS}{position:fixed;z-index:5000;width:var(--fixedWidth)!important;height:var(--fixedHeight)!important;}`,
|
19
|
+
`.${DRAGGING_HANDLER_CLASS}{pointer-events:none!important;}`,
|
20
|
+
`.${DROPPING_CLASS}{pointer-events:none!important;}`,
|
21
|
+
`.${GRABBING_CLASS}{cursor:grabbing;}`,
|
22
|
+
`.disable-transition{transition:none!important;}`,
|
23
|
+
]);
|
24
|
+
};
|
25
|
+
export default function useDroppable(coreConfig, handlerPublisher, droppable, indexAttr = 'index') {
|
26
|
+
const INDEX_ATTR = indexAttr;
|
27
|
+
let removeAtFromElementList = [];
|
28
|
+
let insertAtFromElementList = [];
|
29
|
+
const { droppableGroup } = coreConfig;
|
30
|
+
if (!droppable) {
|
31
|
+
return [
|
32
|
+
removeAtFromElementList,
|
33
|
+
insertAtFromElementList
|
34
|
+
];
|
35
|
+
}
|
36
|
+
const droppableGroupClass = getClassesList(droppableGroup)
|
37
|
+
.map((classGroup) => `droppable-group-${classGroup}`)
|
38
|
+
.join(" ");
|
39
|
+
createDraggableCssStyles();
|
40
|
+
setDroppableGroupClass(droppableGroupClass, droppable);
|
41
|
+
for (const child of droppable.children) {
|
42
|
+
const index = child.getAttribute(INDEX_ATTR);
|
43
|
+
const numberIndex = parseIntEmpty(index);
|
44
|
+
const childHTMLElement = child;
|
45
|
+
if (childHTMLElement && numberIndex >= 0) {
|
46
|
+
const [removeAtFromElement, insertAtFromElement] = useDraggable(childHTMLElement, numberIndex, coreConfig, droppable, handlerPublisher);
|
47
|
+
removeAtFromElementList.push(removeAtFromElement);
|
48
|
+
insertAtFromElementList.push(insertAtFromElement);
|
49
|
+
}
|
50
|
+
}
|
51
|
+
return [
|
52
|
+
removeAtFromElementList,
|
53
|
+
insertAtFromElementList
|
54
|
+
];
|
55
|
+
}
|
@@ -1,6 +1,5 @@
|
|
1
|
-
import { Direction } from
|
2
|
-
import { BeforeMargin, AfterMargin, BorderWidth, PaddingBefore, Before } from
|
3
|
-
|
1
|
+
import { Direction } from "..";
|
2
|
+
import { BeforeMargin, AfterMargin, BorderWidth, PaddingBefore, Before } from "../../../index";
|
4
3
|
export declare const getWindowScroll: () => {
|
5
4
|
scrollX: number;
|
6
5
|
scrollY: number;
|