fluid-dnd 2.3.0 → 2.5.0
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 +14 -15
- package/dist/{HandlerPublisher-BNn5KECH.cjs → HandlerPublisher-1MmlNkG3.cjs} +1 -1
- package/dist/{HandlerPublisher-xM3zyGAn.js → HandlerPublisher-DBjPMiyO.js} +1 -1
- package/dist/core/{configHandler.d.ts → config/configHandler.d.ts} +2 -2
- package/dist/core/{configHandler.js → config/configHandler.js} +7 -8
- package/dist/core/{utils → config}/droppableConfigurator.d.ts +5 -4
- package/dist/core/{utils → config}/droppableConfigurator.js +42 -29
- package/dist/core/dragAndDrop.d.ts +3 -3
- package/dist/core/dragAndDrop.js +53 -9
- package/dist/core/events/changeDraggableStyles.d.ts +4 -0
- package/dist/core/events/changeDraggableStyles.js +38 -0
- package/dist/core/events/dragAndDrop/dragAndDrop.d.ts +9 -0
- package/dist/core/events/dragAndDrop/dragAndDrop.js +202 -0
- package/dist/core/{utils/translate/GetTranslateBeforeDropping.d.ts → events/dragAndDrop/getTranslateBeforeDropping.d.ts} +2 -2
- package/dist/core/{utils/translate/GetTranslateBeforeDropping.js → events/dragAndDrop/getTranslateBeforeDropping.js} +33 -41
- package/dist/core/{utils/translate/GetTranslationByDraggingAndEvent.d.ts → events/dragAndDrop/getTranslationByDraggingAndEvent.d.ts} +2 -2
- package/dist/core/{utils/translate/GetTranslationByDraggingAndEvent.js → events/dragAndDrop/getTranslationByDraggingAndEvent.js} +12 -13
- package/dist/core/events/insert.d.ts +5 -0
- package/dist/core/events/insert.js +74 -0
- package/dist/core/events/remove.d.ts +4 -0
- package/dist/core/events/remove.js +66 -0
- package/dist/core/index.d.ts +6 -0
- package/dist/core/index.js +7 -0
- package/dist/core/{utils/scroll.d.ts → positioning/autoScroll.d.ts} +0 -2
- package/dist/core/{utils/scroll.js → positioning/autoScroll.js} +6 -9
- package/dist/core/{utils/SetTransform.d.ts → positioning/usePositioning.d.ts} +1 -1
- package/dist/core/{utils/SetTransform.js → positioning/usePositioning.js} +24 -27
- package/dist/core/{utils/tempChildren.d.ts → tempChildren.d.ts} +1 -2
- package/dist/core/{utils/tempChildren.js → tempChildren.js} +44 -47
- package/dist/core/useDraggable.js +50 -57
- package/dist/core/useDroppable.d.ts +2 -2
- package/dist/core/useDroppable.js +10 -16
- package/dist/core/utils/GetStyles.d.ts +24 -3
- package/dist/core/utils/GetStyles.js +53 -5
- package/dist/core/utils/ParseStyles.d.ts +3 -2
- package/dist/core/utils/ParseStyles.js +12 -12
- package/dist/core/utils/SetStyles.d.ts +6 -5
- package/dist/core/utils/SetStyles.js +30 -25
- package/dist/core/utils/index.d.ts +5 -1
- package/dist/core/utils/index.js +7 -6
- package/dist/core/utils/observer.d.ts +1 -0
- package/dist/core/utils/observer.js +8 -0
- package/dist/fluid-dnd-logo.png +0 -0
- package/dist/index-BdOAK6C7.cjs +1 -0
- package/dist/index-HczUoMBK.js +1131 -0
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +2 -2
- package/dist/insert-Dd8savAS.js +51 -0
- package/dist/insert-T4Y6rI_j.cjs +1 -0
- package/dist/react/index.cjs +1 -1
- package/dist/react/index.mjs +32 -37
- package/dist/react/utils/ReactLilstConfig.d.ts +2 -2
- package/dist/react/utils/ReactLilstConfig.js +9 -18
- package/dist/remove-BC4sUY1o.cjs +1 -0
- package/dist/remove-M01dmTvo.js +48 -0
- package/dist/svelte/index.cjs +1 -1
- package/dist/svelte/index.mjs +18 -16
- package/dist/svelte/utils/SvelteListCondig.js +3 -2
- package/dist/vue/index.cjs +1 -1
- package/dist/vue/index.mjs +26 -24
- package/dist/vue/utils/VueListCondig.d.ts +3 -3
- package/dist/vue/utils/VueListCondig.js +4 -6
- package/package.json +1 -1
- package/dist/core/utils/config.d.ts +0 -5
- package/dist/core/utils/config.js +0 -57
- package/dist/core/utils/events/emitEvents.d.ts +0 -11
- package/dist/core/utils/events/emitEvents.js +0 -333
- package/dist/index-BYT3HBbe.cjs +0 -1
- package/dist/index-m7C-XuaH.js +0 -1275
- /package/dist/core/utils/{touchDevice.d.ts → typesCheckers.d.ts} +0 -0
- /package/dist/core/utils/{touchDevice.js → typesCheckers.js} +0 -0
package/README.md
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
<h1 align="center">
|
2
|
-
<img src="public/fluid-dnd.
|
3
|
-
alt="Icon" width="
|
4
|
-
<br>Fluid DnD<br>
|
2
|
+
<img src="public/fluid-dnd-logo.png"
|
3
|
+
alt="Icon" width="200" height="200" />
|
5
4
|
</h1>
|
6
5
|
|
7
6
|
<div align="center">
|
@@ -11,15 +10,20 @@
|
|
11
10
|
[](https://www.npmjs.com/package/fluid-dnd)
|
12
11
|

|
13
12
|

|
14
|
-
[](https://codeclimate.com/github/carlosjorger/fluid-dnd/test_coverage)
|
15
13
|
|
16
|
-
|
14
|
+
_Drag and drop elements of your list smoothly and effortlessly_
|
17
15
|
|
18
|
-
|
19
|
-
library for lists; with support for **Vue**, **React** and **Svelte**](https://fluid-dnd.netlify.app/). It's a **lightweight** tool ~8 Kb (gzip) with no depenencies.
|
16
|
+
[📖 **Documentation**](https://fluid-dnd.netlify.app/) | [🤹 **Examples**](https://fluid-dnd.netlify.app/vue/example/vertical-list/single-vertical-list/)
|
20
17
|
|
21
18
|
<img src="https://github.com/user-attachments/assets/1b7ac5e3-48e9-43f9-a577-e78c6b9eacae" width="100%"/>
|
22
19
|
|
20
|
+
</div>
|
21
|
+
|
22
|
+
## 🪪 About
|
23
|
+
|
24
|
+
Fluid DnD is a **fluid**, **agnostic** and **versatile** drag and drop
|
25
|
+
library for lists; with support for **Vue**, **React** and **Svelte**. It's a **lightweight** tool ~8 Kb (gzip) with no depenencies.
|
26
|
+
|
23
27
|
## 🧰 Features
|
24
28
|
|
25
29
|
- ✅ **Fully customizable 🎨**.
|
@@ -50,21 +54,16 @@ library for lists; with support for **Vue**, **React** and **Svelte**](https://f
|
|
50
54
|
pnpm i fluid-dnd
|
51
55
|
```
|
52
56
|
|
53
|
-
3. **Documentation**
|
54
|
-
|
55
|
-
- 📚 Check out all the [docs](https://fluid-dnd.netlify.app/).
|
56
|
-
- 🛠️ Edit this example [here](https://codesandbox.io/s/nifty-hooks-5plkpl).
|
57
|
-
- 📘 See other examples [here](https://fluid-dnd.netlify.app/vue/example/vertical-list/single-vertical-list/).
|
58
|
-
|
59
57
|
## 📚 Libraries Support
|
58
|
+
|
60
59
|
- **Vue** >=3.0.0
|
61
60
|
- **React** >= 18.0.0
|
62
61
|
- **Svelte** >= 5.0.0
|
63
62
|
|
64
63
|
## 🤝 Contributing
|
65
64
|
|
66
|
-
If you're interested in contributing to [fluid-dnd](https://github.com/carlosjorger/fluid-dnd), please read our [CONTRIBUTING
|
65
|
+
If you're interested in contributing to [fluid-dnd](https://github.com/carlosjorger/fluid-dnd), please read our [CONTRIBUTING GUIDELINES](./CONTRIBUTING.md) before submitting a pull request.
|
67
66
|
|
68
67
|
## 🔑 License
|
69
68
|
|
70
|
-
- [MIT](https://github.com/carlosjorger/fluid-dnd/blob/main/LICENSE).
|
69
|
+
- [MIT](https://github.com/carlosjorger/fluid-dnd/blob/main/LICENSE).
|
@@ -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-BdOAK6C7.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;
|
@@ -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-HczUoMBK.js";
|
5
5
|
class c {
|
6
6
|
constructor() {
|
7
7
|
r(this, "handlers");
|
@@ -1,14 +1,14 @@
|
|
1
|
-
import { getScrollElement } from
|
2
|
-
import { containstClasses } from
|
1
|
+
import { getScrollElement, isSameNode } from '../utils/GetStyles';
|
2
|
+
import { containstClasses } from '../utils/dom/classList';
|
3
3
|
export default class ConfigHandler {
|
4
4
|
static configs = [];
|
5
5
|
static addConfig(droppable, config) {
|
6
|
-
const configs = ConfigHandler.configs.filter((configHandler) => !configHandler.droppable
|
6
|
+
const configs = ConfigHandler.configs.filter((configHandler) => !isSameNode(configHandler.droppable, droppable));
|
7
7
|
const scroll = getScrollElement(droppable);
|
8
8
|
configs.push({
|
9
9
|
droppable,
|
10
10
|
config,
|
11
|
-
scroll
|
11
|
+
scroll
|
12
12
|
});
|
13
13
|
ConfigHandler.configs = configs;
|
14
14
|
}
|
@@ -19,15 +19,14 @@ export default class ConfigHandler {
|
|
19
19
|
static updateScrolls(currentDroppable, droppableGroupClass) {
|
20
20
|
for (const configHandler of ConfigHandler.configs) {
|
21
21
|
const { droppable } = configHandler;
|
22
|
-
if ((droppableGroupClass &&
|
23
|
-
|
24
|
-
droppable.isSameNode(currentDroppable)) {
|
22
|
+
if ((droppableGroupClass && containstClasses(droppable, droppableGroupClass)) ||
|
23
|
+
isSameNode(currentDroppable, droppable)) {
|
25
24
|
configHandler.scroll = getScrollElement(droppable);
|
26
25
|
}
|
27
26
|
}
|
28
27
|
}
|
29
28
|
static getConfig(curerntDroppable) {
|
30
|
-
const config = ConfigHandler.configs.find(({ droppable }) =>
|
29
|
+
const config = ConfigHandler.configs.find(({ droppable }) => isSameNode(curerntDroppable, droppable));
|
31
30
|
return config;
|
32
31
|
}
|
33
32
|
}
|
@@ -1,6 +1,6 @@
|
|
1
|
-
import { DroppableConfig } from
|
2
|
-
import { DragMouseTouchEvent } from
|
3
|
-
import { MapFrom } from
|
1
|
+
import { DroppableConfig } from './configHandler';
|
2
|
+
import { DragMouseTouchEvent } from '../../../index';
|
3
|
+
import { MapFrom } from '..';
|
4
4
|
export declare class DroppableConfigurator<T> {
|
5
5
|
initial: DroppableConfig<any> | undefined;
|
6
6
|
current: DroppableConfig<T> | undefined;
|
@@ -19,7 +19,8 @@ export declare class DroppableConfigurator<T> {
|
|
19
19
|
private onScrollEvent;
|
20
20
|
private setOnScroll;
|
21
21
|
getConfigFrom(element: Element): DroppableConfig<any> | undefined;
|
22
|
+
droppableIfInsideCurrent(droppable: Element | null | undefined, current: HTMLElement): boolean | null | undefined;
|
22
23
|
getCurrentConfig(event: DragMouseTouchEvent): DroppableConfig<any> | DroppableConfig<T> | undefined;
|
23
24
|
updateConfig(event: DragMouseTouchEvent): void;
|
24
|
-
isOutside(event: DragMouseTouchEvent
|
25
|
+
isOutside(event: DragMouseTouchEvent): boolean;
|
25
26
|
}
|
@@ -1,9 +1,24 @@
|
|
1
|
-
import ConfigHandler from
|
2
|
-
import { draggableIsOutside } from
|
3
|
-
import { IsHTMLElement } from
|
4
|
-
import { setEventWithInterval } from
|
5
|
-
import { getClassesSelector } from
|
6
|
-
|
1
|
+
import ConfigHandler from './configHandler';
|
2
|
+
import { draggableIsOutside, isSameNode } from '../utils/GetStyles';
|
3
|
+
import { IsHTMLElement } from '../utils/typesCheckers';
|
4
|
+
import { setEventWithInterval } from '../utils/SetStyles';
|
5
|
+
import { getClassesSelector } from '../utils/dom/classList';
|
6
|
+
const MapConfig = (coreConfig, mapFrom) => {
|
7
|
+
const { config, droppable } = coreConfig;
|
8
|
+
const { onInsertEvent, onDragEnd } = config;
|
9
|
+
const mapOnInsertEvent = (index, value) => {
|
10
|
+
return onInsertEvent(index, mapFrom(value, droppable), true);
|
11
|
+
};
|
12
|
+
const mapOnDragEnd = (eventData) => {
|
13
|
+
const { index, value } = eventData;
|
14
|
+
onDragEnd({ index, value: mapFrom(value, droppable) });
|
15
|
+
};
|
16
|
+
return {
|
17
|
+
...config,
|
18
|
+
onDragEnd: mapOnDragEnd,
|
19
|
+
onInsertEvent: mapOnInsertEvent
|
20
|
+
};
|
21
|
+
};
|
7
22
|
export class DroppableConfigurator {
|
8
23
|
initial;
|
9
24
|
current;
|
@@ -19,32 +34,23 @@ export class DroppableConfigurator {
|
|
19
34
|
this.groupClass = droppableGroupClass;
|
20
35
|
this.dragEvent = setTransformDragEvent;
|
21
36
|
this.mapFrom = mapFrom;
|
22
|
-
this.initial =
|
37
|
+
this.initial = ConfigHandler.getConfig(parent);
|
23
38
|
this.changeDroppable = changeDroppable;
|
24
39
|
}
|
25
40
|
getDraggableAncestor(clientX, clientY, draggable) {
|
26
41
|
return document
|
27
42
|
.elementsFromPoint(clientX, clientY)
|
28
|
-
.filter((element) => !
|
43
|
+
.filter((element) => !isSameNode(draggable, element));
|
29
44
|
}
|
30
|
-
getElementBelow(currentElement, event
|
45
|
+
getElementBelow(currentElement, event) {
|
31
46
|
const getElementBelow = (config) => {
|
32
47
|
const [elementBelow] = config.getDraggableAncestor(event.clientX, event.clientY, currentElement);
|
33
48
|
return elementBelow;
|
34
49
|
};
|
35
|
-
|
36
|
-
if (hiddenDraggable) {
|
37
|
-
currentElement.hidden = true;
|
38
|
-
elementBelow = getElementBelow(this);
|
39
|
-
currentElement.hidden = false;
|
40
|
-
}
|
41
|
-
else {
|
42
|
-
elementBelow = getElementBelow(this);
|
43
|
-
}
|
44
|
-
return elementBelow;
|
50
|
+
return getElementBelow(this);
|
45
51
|
}
|
46
|
-
getCurrent(currentElement, event
|
47
|
-
const elementBelow = this.getElementBelow(currentElement, event
|
52
|
+
getCurrent(currentElement, event) {
|
53
|
+
const elementBelow = this.getElementBelow(currentElement, event);
|
48
54
|
if (!this.groupClass || !elementBelow) {
|
49
55
|
return;
|
50
56
|
}
|
@@ -52,7 +58,9 @@ export class DroppableConfigurator {
|
|
52
58
|
return currentDroppable;
|
53
59
|
}
|
54
60
|
isOutsideOfAllDroppables(currentElement) {
|
55
|
-
const droppables = this.groupClass
|
61
|
+
const droppables = this.groupClass
|
62
|
+
? Array.from(document.querySelectorAll(getClassesSelector(this.groupClass)))
|
63
|
+
: [this.parent];
|
56
64
|
return droppables.every((droppable) => draggableIsOutside(currentElement, droppable));
|
57
65
|
}
|
58
66
|
isNotInsideAnotherDroppable(currentElement, droppable) {
|
@@ -62,16 +70,17 @@ export class DroppableConfigurator {
|
|
62
70
|
onScrollEvent() {
|
63
71
|
this.dragEvent();
|
64
72
|
}
|
65
|
-
;
|
66
73
|
setOnScroll(droppable) {
|
67
|
-
setEventWithInterval(droppable,
|
74
|
+
setEventWithInterval(droppable, 'onscroll', () => {
|
75
|
+
this.onScrollEvent();
|
76
|
+
});
|
68
77
|
}
|
69
78
|
getConfigFrom(element) {
|
70
79
|
const coreConfig = ConfigHandler.getConfig(element);
|
71
80
|
if (!coreConfig) {
|
72
81
|
return undefined;
|
73
82
|
}
|
74
|
-
if (
|
83
|
+
if (isSameNode(this.parent, element)) {
|
75
84
|
return coreConfig;
|
76
85
|
}
|
77
86
|
return {
|
@@ -79,13 +88,17 @@ export class DroppableConfigurator {
|
|
79
88
|
config: MapConfig(coreConfig, this.mapFrom)
|
80
89
|
};
|
81
90
|
}
|
91
|
+
droppableIfInsideCurrent(droppable, current) {
|
92
|
+
return droppable && !isSameNode(current, droppable) && current.contains(droppable);
|
93
|
+
}
|
82
94
|
getCurrentConfig(event) {
|
83
95
|
const currentElement = this.draggableElement;
|
96
|
+
const currentDroppable = this.getCurrent(currentElement, event);
|
84
97
|
if (this.current &&
|
85
|
-
this.isNotInsideAnotherDroppable(currentElement, this.current?.droppable)
|
98
|
+
this.isNotInsideAnotherDroppable(currentElement, this.current?.droppable) &&
|
99
|
+
!this.droppableIfInsideCurrent(currentDroppable, this.current?.droppable)) {
|
86
100
|
return this.current;
|
87
101
|
}
|
88
|
-
const currentDroppable = this.getCurrent(currentElement, event);
|
89
102
|
if (!currentDroppable) {
|
90
103
|
return this.getConfigFrom(this.parent);
|
91
104
|
}
|
@@ -99,8 +112,8 @@ export class DroppableConfigurator {
|
|
99
112
|
this.current = this.getCurrentConfig(event);
|
100
113
|
this.changeDroppable(this.current, oldDroppableConfig);
|
101
114
|
}
|
102
|
-
isOutside(event
|
115
|
+
isOutside(event) {
|
103
116
|
const currentElement = this.draggableElement;
|
104
|
-
return !Boolean(this.getCurrent(currentElement, event
|
117
|
+
return !Boolean(this.getCurrent(currentElement, event));
|
105
118
|
}
|
106
119
|
}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import { ListCondig } from
|
2
|
-
import { Config } from
|
3
|
-
import HandlerPublisher from
|
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];
|
package/dist/core/dragAndDrop.js
CHANGED
@@ -1,10 +1,48 @@
|
|
1
|
-
import {
|
2
|
-
import useDroppable from
|
3
|
-
import ConfigHandler from
|
4
|
-
import { observeMutation } from
|
5
|
-
import { addClass } from
|
6
|
-
import { DROPPABLE_CLASS } from
|
7
|
-
|
1
|
+
import { VERTICAL } from '.';
|
2
|
+
import useDroppable from './useDroppable';
|
3
|
+
import ConfigHandler from './config/configHandler';
|
4
|
+
import { isTempElement, observeMutation } from './utils/observer';
|
5
|
+
import { addClass } from './utils/dom/classList';
|
6
|
+
import { DRAGGABLE_CLASS, DROPPABLE_CLASS } from './utils/classes';
|
7
|
+
const getConfig = (listCondig, config) => {
|
8
|
+
const onRemoveAtEvent = (index, sync) => {
|
9
|
+
return listCondig.removeAtEvent(index, sync);
|
10
|
+
};
|
11
|
+
const onInsertEvent = (index, value, sync) => {
|
12
|
+
return listCondig.insertEvent(index, value, sync);
|
13
|
+
};
|
14
|
+
const onGetLegth = () => {
|
15
|
+
return listCondig.getLength();
|
16
|
+
};
|
17
|
+
const onGetValue = (index) => {
|
18
|
+
return listCondig.getValue(index);
|
19
|
+
};
|
20
|
+
const defaultMapFrom = (object) => {
|
21
|
+
return object;
|
22
|
+
};
|
23
|
+
return {
|
24
|
+
direction: config?.direction ?? VERTICAL,
|
25
|
+
handlerSelector: config?.handlerSelector ?? DRAGGABLE_CLASS,
|
26
|
+
draggingClass: config?.draggingClass ?? 'dragging',
|
27
|
+
droppableClass: config?.droppableClass ?? 'droppable-hover',
|
28
|
+
isDraggable: config?.isDraggable ?? (() => true),
|
29
|
+
onDragStart: config?.onDragStart ?? (() => { }),
|
30
|
+
onDragEnd: config?.onDragEnd ?? (() => { }),
|
31
|
+
droppableGroup: config?.droppableGroup,
|
32
|
+
onRemoveAtEvent,
|
33
|
+
onInsertEvent,
|
34
|
+
onGetLegth,
|
35
|
+
onGetValue,
|
36
|
+
animationDuration: config?.animationDuration ?? 200,
|
37
|
+
removingClass: config?.removingClass ?? 'removing',
|
38
|
+
insertingFromClass: config?.insertingFromClass ?? 'from-inserting',
|
39
|
+
delayBeforeRemove: config?.delayBeforeRemove ?? 200,
|
40
|
+
delayBeforeInsert: config?.delayBeforeInsert ?? 200,
|
41
|
+
mapFrom: config?.mapFrom ?? defaultMapFrom,
|
42
|
+
delayBeforeTouchMoveEvent: config?.delayBeforeTouchMoveEvent ?? 150,
|
43
|
+
coordinateTransform: config?.coordinateTransform ?? [(coordinate) => coordinate]
|
44
|
+
};
|
45
|
+
};
|
8
46
|
export default function dragAndDrop(listCondig, handlerPublisher, config, indexAttr = 'index') {
|
9
47
|
let removeAtFromElements = [];
|
10
48
|
let insertAtFromElements = [];
|
@@ -32,8 +70,14 @@ export default function dragAndDrop(listCondig, handlerPublisher, config, indexA
|
|
32
70
|
insertAtFromElements = insertAtFromElementList;
|
33
71
|
};
|
34
72
|
const childrenMutationFilter = (mutation) => {
|
35
|
-
const addedNodes = mutation.addedNodes
|
36
|
-
|
73
|
+
const addedNodes = mutation.addedNodes
|
74
|
+
.values()
|
75
|
+
.filter((element) => !isTempElement(element))
|
76
|
+
.toArray();
|
77
|
+
const removedNodes = mutation.removedNodes
|
78
|
+
.values()
|
79
|
+
.filter((element) => !isTempElement(element))
|
80
|
+
.toArray();
|
37
81
|
return addedNodes.length > 0 || removedNodes.length > 0;
|
38
82
|
};
|
39
83
|
const observeChildrens = (parent) => {
|
@@ -0,0 +1,4 @@
|
|
1
|
+
import { Translate } from 'index';
|
2
|
+
import { CoreConfig } from '..';
|
3
|
+
import HandlerPublisher from '../HandlerPublisher';
|
4
|
+
export declare const useChangeDraggableStyles: <T>(currentConfig: CoreConfig<T>, handlerPublisher: HandlerPublisher, endDraggingAction: () => void) => readonly [(element: HTMLElement) => void, (element: Element, force: boolean) => void, (element: Element, translation: Translate) => void];
|
@@ -0,0 +1,38 @@
|
|
1
|
+
import { DRAGGING_CLASS, DRAGGING_HANDLER_CLASS, GRABBING_CLASS } from '../utils/classes';
|
2
|
+
import { toggleClass } from '../utils/dom/classList';
|
3
|
+
import { moveTranslate, removeTranslateWhitoutTransition, setCustomFixedSize, setTranistion } from '../utils/SetStyles';
|
4
|
+
import { draggableTargetTimingFunction } from '../utils';
|
5
|
+
export const useChangeDraggableStyles = (currentConfig, handlerPublisher, endDraggingAction) => {
|
6
|
+
const { handlerSelector, animationDuration } = currentConfig;
|
7
|
+
const removeElementDraggingStyles = (element) => {
|
8
|
+
endDraggingAction();
|
9
|
+
toggleDraggingClass(element, false);
|
10
|
+
removeTranslateWhitoutTransition(element);
|
11
|
+
element.style.top = '';
|
12
|
+
element.style.left = '';
|
13
|
+
setCustomFixedSize(element, {
|
14
|
+
fixedHeight: '',
|
15
|
+
fixedWidth: ''
|
16
|
+
});
|
17
|
+
};
|
18
|
+
const toggleDraggingClass = (element, force) => {
|
19
|
+
toggleClass(element, DRAGGING_CLASS, force);
|
20
|
+
toogleHandlerDraggingClass(force, element);
|
21
|
+
handlerPublisher.toggleGrabClass(!force);
|
22
|
+
};
|
23
|
+
const toogleHandlerDraggingClass = (force, element) => {
|
24
|
+
const handlerElement = element.querySelector(handlerSelector);
|
25
|
+
toggleClass(document.body, GRABBING_CLASS, force);
|
26
|
+
if (handlerElement) {
|
27
|
+
toggleClass(handlerElement, DRAGGING_HANDLER_CLASS, force);
|
28
|
+
}
|
29
|
+
else {
|
30
|
+
toggleClass(element, DRAGGING_HANDLER_CLASS, force);
|
31
|
+
}
|
32
|
+
};
|
33
|
+
const dragEventOverElement = (element, translation) => {
|
34
|
+
setTranistion(element, animationDuration, draggableTargetTimingFunction);
|
35
|
+
moveTranslate(element, translation);
|
36
|
+
};
|
37
|
+
return [removeElementDraggingStyles, toggleDraggingClass, dragEventOverElement];
|
38
|
+
};
|
@@ -0,0 +1,9 @@
|
|
1
|
+
import { WindowScroll } from '../../../../index';
|
2
|
+
import { CoreConfig } from '../..';
|
3
|
+
import { DRAG_EVENT, START_DRAG_EVENT, START_DROP_EVENT } from '../../utils';
|
4
|
+
import { DroppableConfig } from '../../config/configHandler';
|
5
|
+
import HandlerPublisher from '../../HandlerPublisher';
|
6
|
+
type DraggingEvent = typeof DRAG_EVENT | typeof START_DRAG_EVENT;
|
7
|
+
type DropEvent = 'drop' | typeof START_DROP_EVENT;
|
8
|
+
export default function useDragAndDropEvents<T>(currentConfig: CoreConfig<T>, index: number, parent: HTMLElement, droppableGroupClass: string | null, handlerPublisher: HandlerPublisher, endDraggingAction: () => void): readonly [(draggedElement: HTMLElement, event: DraggingEvent, droppableConfig: DroppableConfig<T> | undefined) => void, (draggedElement: HTMLElement, event: DropEvent, droppableConfig: DroppableConfig<T> | undefined, initialWindowScroll: WindowScroll, positionOnSourceDroppable?: number) => void, (element: Element, force: boolean) => void];
|
9
|
+
export {};
|
@@ -0,0 +1,202 @@
|
|
1
|
+
import { draggableIsOutside, getAxisValue, getBefore, getDistanceValue, getRect, getSiblings, getTransform, getWindowScroll, isSameNode } from '../../utils/GetStyles';
|
2
|
+
import { moveTranslate, removeTranslateWhitoutTransition } from '../../utils/SetStyles';
|
3
|
+
import getTranslationByDragging from './getTranslationByDraggingAndEvent';
|
4
|
+
import getTranslateBeforeDropping from './getTranslateBeforeDropping';
|
5
|
+
import { DRAG_EVENT, NONE_TRANSLATE, START_DRAG_EVENT, START_DROP_EVENT, TEMP_CHILD_CLASS } from '../../utils';
|
6
|
+
import { IsHTMLElement } from '../../utils/typesCheckers';
|
7
|
+
import { removeTempChild } from '../../tempChildren';
|
8
|
+
import { DRAGGABLE_CLASS, DROPPING_CLASS } from '../../utils/classes';
|
9
|
+
import { addClass, containClass, getClassesSelector, removeClass } from '../../utils/dom/classList';
|
10
|
+
import { useChangeDraggableStyles } from '../changeDraggableStyles';
|
11
|
+
const DELAY_TIME_TO_SWAP = 50;
|
12
|
+
export default function useDragAndDropEvents(currentConfig, index, parent, droppableGroupClass, handlerPublisher, endDraggingAction) {
|
13
|
+
let actualIndex = index;
|
14
|
+
const { onRemoveAtEvent, animationDuration, draggingClass } = currentConfig;
|
15
|
+
const [removeElementDraggingStyles, toggleDraggingClass, dragEventOverElement] = useChangeDraggableStyles(currentConfig, handlerPublisher, endDraggingAction);
|
16
|
+
const emitDraggingEvent = (draggedElement, event, droppableConfig) => {
|
17
|
+
if (!droppableConfig) {
|
18
|
+
return;
|
19
|
+
}
|
20
|
+
const { droppable, config } = droppableConfig;
|
21
|
+
const tranlation = getTranslationByDragging(draggedElement, event, config.direction, droppable);
|
22
|
+
emitDraggingEventToSiblings(draggedElement, event, tranlation, droppable, config);
|
23
|
+
};
|
24
|
+
const emitDroppingEvent = (draggedElement, event, droppableConfig, initialWindowScroll, positionOnSourceDroppable) => {
|
25
|
+
if (!droppableConfig) {
|
26
|
+
return;
|
27
|
+
}
|
28
|
+
const { droppable, scroll, config } = droppableConfig;
|
29
|
+
const tranlation = getTranslationByDragging(draggedElement, event, config.direction, droppable);
|
30
|
+
emitDroppingEventToSiblings(draggedElement, event, tranlation, initialWindowScroll, droppable, scroll, config, positionOnSourceDroppable);
|
31
|
+
};
|
32
|
+
// #region Drag events
|
33
|
+
const emitDraggingEventToSiblings = (draggedElement, event, translation, droppable, config) => {
|
34
|
+
const [siblings] = getSiblings(draggedElement, droppable);
|
35
|
+
const isOutside = draggableIsOutside(draggedElement, droppable);
|
36
|
+
const { direction } = config;
|
37
|
+
if (siblings.length == 0) {
|
38
|
+
updateActualIndexBaseOnTranslation(translation, 1, direction, siblings);
|
39
|
+
}
|
40
|
+
for (const [index, sibling] of siblings.entries()) {
|
41
|
+
if (!containClass(sibling, DRAGGABLE_CLASS)) {
|
42
|
+
continue;
|
43
|
+
}
|
44
|
+
const siblingTransition = canChangeDraggable(direction, draggedElement, sibling, translation);
|
45
|
+
if (!isOutside && siblingTransition) {
|
46
|
+
translation = siblingTransition;
|
47
|
+
}
|
48
|
+
else if (!isOutside) {
|
49
|
+
continue;
|
50
|
+
}
|
51
|
+
const siblingRealIndex = siblings.length - index;
|
52
|
+
updateActualIndexBaseOnTranslation(translation, siblingRealIndex, direction, siblings);
|
53
|
+
if (event === START_DRAG_EVENT) {
|
54
|
+
moveTranslate(sibling, translation);
|
55
|
+
}
|
56
|
+
else if (event === DRAG_EVENT) {
|
57
|
+
dragEventOverElement(sibling, translation);
|
58
|
+
}
|
59
|
+
}
|
60
|
+
};
|
61
|
+
const canChangeDraggable = (direction, sourceElement, targetElement, translation) => {
|
62
|
+
const currentBoundingClientRect = getRect(sourceElement);
|
63
|
+
const targetBoundingClientRect = getRect(targetElement);
|
64
|
+
const currentPosition = getBefore(direction, currentBoundingClientRect);
|
65
|
+
const targetPosition = getBefore(direction, targetBoundingClientRect);
|
66
|
+
const [targetSize] = getDistanceValue(direction, targetBoundingClientRect);
|
67
|
+
const targetMiddle = targetPosition + targetSize / 2;
|
68
|
+
const targetTransform = getAxisValue(direction, getTransform(targetElement));
|
69
|
+
const targetMiddleWithoutTransform = targetMiddle - targetTransform;
|
70
|
+
if (currentPosition > targetMiddleWithoutTransform) {
|
71
|
+
return NONE_TRANSLATE;
|
72
|
+
}
|
73
|
+
return translation;
|
74
|
+
};
|
75
|
+
const updateActualIndexBaseOnTranslation = (translation, siblingIndex, direction, siblings) => {
|
76
|
+
const itemsCount = siblings.filter((sibling) => containClass(sibling, DRAGGABLE_CLASS)).length;
|
77
|
+
const [distance] = getDistanceValue(direction, translation);
|
78
|
+
if (distance == 0) {
|
79
|
+
actualIndex = Math.max(actualIndex, siblingIndex);
|
80
|
+
}
|
81
|
+
else {
|
82
|
+
actualIndex = Math.min(actualIndex, siblingIndex - 1);
|
83
|
+
}
|
84
|
+
actualIndex = Math.min(actualIndex, itemsCount);
|
85
|
+
};
|
86
|
+
// #region Drop events
|
87
|
+
const emitDroppingEventToSiblings = (draggedElement, event, translation, initialWindowScroll, droppable, scroll, config, positionOnSourceDroppable) => {
|
88
|
+
const [siblings, positionOnDroppable] = getSiblings(draggedElement, droppable);
|
89
|
+
const allSiblings = siblings.toReversed();
|
90
|
+
const realPositionOnDroppable = positionOnDroppable === -1 ? allSiblings.length : positionOnDroppable;
|
91
|
+
allSiblings.splice(realPositionOnDroppable, 0, draggedElement);
|
92
|
+
const [previousElement, nextElement, targetIndex] = getPreviousAndNextElement(draggedElement, positionOnDroppable, allSiblings, droppable);
|
93
|
+
translation = getTranslationByDragging(draggedElement, event, config.direction, parent, previousElement, nextElement);
|
94
|
+
const windowScroll = getWindowScroll();
|
95
|
+
const draggableTranslation = getTranslateBeforeDropping(config.direction, allSiblings, positionOnDroppable, targetIndex, windowScroll, scroll, initialWindowScroll, droppable, draggedElement);
|
96
|
+
if (siblings.length == 0) {
|
97
|
+
startDropEventOverElement(undefined, translation, draggedElement, draggableTranslation);
|
98
|
+
}
|
99
|
+
for (const [index, sibling] of siblings.toReversed().entries()) {
|
100
|
+
let newTranslation = translation;
|
101
|
+
if (targetIndex - 1 >= index) {
|
102
|
+
newTranslation = NONE_TRANSLATE;
|
103
|
+
}
|
104
|
+
if (event === START_DROP_EVENT && !containClass(sibling, TEMP_CHILD_CLASS)) {
|
105
|
+
startDropEventOverElement(sibling, newTranslation, draggedElement, draggableTranslation);
|
106
|
+
}
|
107
|
+
}
|
108
|
+
dropEventOverElement(targetIndex, draggedElement, config, droppable, positionOnSourceDroppable);
|
109
|
+
};
|
110
|
+
const getPreviousAndNextElement = (draggedElement, elementPosition, allSiblings, droppable) => {
|
111
|
+
const isOutside = draggableIsOutside(draggedElement, droppable);
|
112
|
+
const targetIndex = isOutside ? elementPosition : actualIndex;
|
113
|
+
const getPreviousAndNextElementIndex = () => {
|
114
|
+
if (elementPosition < targetIndex) {
|
115
|
+
return [targetIndex, targetIndex + 1];
|
116
|
+
}
|
117
|
+
else if (elementPosition > targetIndex) {
|
118
|
+
return [targetIndex - 1, targetIndex];
|
119
|
+
}
|
120
|
+
else {
|
121
|
+
return [targetIndex - 1, targetIndex + 1];
|
122
|
+
}
|
123
|
+
};
|
124
|
+
const [previousIndex, nextIndex] = getPreviousAndNextElementIndex();
|
125
|
+
const previousElement = allSiblings[previousIndex] ?? null;
|
126
|
+
const nextElement = allSiblings[nextIndex] ?? null;
|
127
|
+
return [previousElement, nextElement, targetIndex];
|
128
|
+
};
|
129
|
+
const startDropEventOverElement = (targetElement, translation, element, sourceElementTranlation) => {
|
130
|
+
moveTranslate(targetElement, translation);
|
131
|
+
moveTranslate(element, sourceElementTranlation);
|
132
|
+
};
|
133
|
+
const dropEventOverElement = (targetIndex, element, config, droppable, positionOnSourceDroppable) => {
|
134
|
+
const { onInsertEvent, onDragEnd } = config;
|
135
|
+
addClass(element, DROPPING_CLASS);
|
136
|
+
removeStytes(element, parent, droppable, () => {
|
137
|
+
removeClass(element, DROPPING_CLASS);
|
138
|
+
if (positionOnSourceDroppable != undefined) {
|
139
|
+
const value = onRemoveAtEvent(positionOnSourceDroppable, true);
|
140
|
+
if (value != undefined) {
|
141
|
+
onInsertEvent(targetIndex, value, true);
|
142
|
+
onDragEnd({ value, index: targetIndex });
|
143
|
+
}
|
144
|
+
manageDraggingClass(element);
|
145
|
+
clearExcessTranslateStyles();
|
146
|
+
}
|
147
|
+
});
|
148
|
+
};
|
149
|
+
const clearExcessTranslateStyles = () => {
|
150
|
+
if (!droppableGroupClass) {
|
151
|
+
return;
|
152
|
+
}
|
153
|
+
var children = document.querySelectorAll(`${getClassesSelector(droppableGroupClass)} > .${DRAGGABLE_CLASS}`);
|
154
|
+
for (const element of children) {
|
155
|
+
removeTranslateWhitoutTransition(element);
|
156
|
+
}
|
157
|
+
};
|
158
|
+
const manageDraggingClass = (element) => {
|
159
|
+
setTimeout(() => {
|
160
|
+
removeClass(element, draggingClass);
|
161
|
+
}, DELAY_TIME_TO_SWAP);
|
162
|
+
};
|
163
|
+
const removeStytes = (element, parent, droppable, func) => {
|
164
|
+
setTimeout(() => {
|
165
|
+
func && func();
|
166
|
+
removeTempChildOnDroppables(parent, droppable);
|
167
|
+
reduceTempchildSize(droppable);
|
168
|
+
removeElementDraggingStyles(element);
|
169
|
+
removeTranslateFromSiblings(element, parent);
|
170
|
+
removeTranslateFromSiblings(element, droppable);
|
171
|
+
}, animationDuration);
|
172
|
+
};
|
173
|
+
const removeTempChildOnDroppables = (parent, droppable) => {
|
174
|
+
if (isSameNode(parent, droppable)) {
|
175
|
+
removeTempChild(parent, animationDuration);
|
176
|
+
}
|
177
|
+
else {
|
178
|
+
removeTempChild(parent, animationDuration, true);
|
179
|
+
removeTempChild(droppable, animationDuration);
|
180
|
+
}
|
181
|
+
};
|
182
|
+
const reduceTempchildSize = (droppable) => {
|
183
|
+
if (isSameNode(parent, droppable)) {
|
184
|
+
return;
|
185
|
+
}
|
186
|
+
var [lastChildren] = parent.querySelectorAll(`.${TEMP_CHILD_CLASS}`);
|
187
|
+
if (!lastChildren) {
|
188
|
+
return;
|
189
|
+
}
|
190
|
+
if (IsHTMLElement(lastChildren)) {
|
191
|
+
lastChildren.style.height = '0px';
|
192
|
+
lastChildren.style.width = '0px';
|
193
|
+
}
|
194
|
+
};
|
195
|
+
const removeTranslateFromSiblings = (element, parent) => {
|
196
|
+
const [siblings] = getSiblings(element, parent);
|
197
|
+
for (const sibling of [...siblings, element]) {
|
198
|
+
removeTranslateWhitoutTransition(sibling);
|
199
|
+
}
|
200
|
+
};
|
201
|
+
return [emitDraggingEvent, emitDroppingEvent, toggleDraggingClass];
|
202
|
+
}
|
@@ -1,5 +1,5 @@
|
|
1
|
-
import { Direction } from
|
2
|
-
import { Translate, WindowScroll } from
|
1
|
+
import { Direction } from '../..';
|
2
|
+
import { Translate, WindowScroll } from '../../../../index';
|
3
3
|
export default function getTranslateBeforeDropping(direction: Direction, siblings: Element[], sourceIndex: number, targetIndex: number, scroll: WindowScroll, previousScroll: {
|
4
4
|
scrollLeft: number;
|
5
5
|
scrollTop: number;
|