react-reorder-list 0.5.0 → 0.6.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/dist/hooks.d.ts +6 -0
- package/dist/hooks.js +8 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +43 -19
- package/package.json +4 -1
package/dist/hooks.d.ts
ADDED
package/dist/hooks.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
export default function useDraggable(initValue = false) {
|
|
3
|
+
const [draggable, setDraggable] = useState(initValue);
|
|
4
|
+
const enableDragging = () => setDraggable(true);
|
|
5
|
+
const disableDragging = () => setDraggable(false);
|
|
6
|
+
const draggableProps = { onMouseEnter: enableDragging, onMouseLeave: disableDragging, onTouchStart: enableDragging, onTouchEnd: disableDragging };
|
|
7
|
+
return { draggable, draggableProps };
|
|
8
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import React, {
|
|
2
|
-
|
|
1
|
+
import React, { ReactNode } from "react";
|
|
2
|
+
import { Props } from "./hooks.js";
|
|
3
|
+
export type { Props } from './hooks.js';
|
|
3
4
|
export type PositionChangeHandler = (params?: {
|
|
4
5
|
start?: number;
|
|
5
6
|
end?: number;
|
package/dist/index.js
CHANGED
|
@@ -12,6 +12,10 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
12
12
|
import React, { Children, cloneElement, createRef, forwardRef, isValidElement, useEffect, useMemo, useRef, useState } from "react";
|
|
13
13
|
import { PiDotsSixVerticalBold } from "./icons.js";
|
|
14
14
|
import Animation from "./animation.js";
|
|
15
|
+
import useDraggable from "./hooks.js";
|
|
16
|
+
if (typeof window !== "undefined")
|
|
17
|
+
import('drag-drop-touch');
|
|
18
|
+
const scrollThreshold = { x: 10, y: 100 };
|
|
15
19
|
const ReorderItemRef = forwardRef(ReorderItem);
|
|
16
20
|
export default function ReorderList({ useOnlyIconToDrag = false, selectedItemOpacity = 0.5, animationDuration = 400, watchChildrenUpdates = false, preserveOrder = false, onPositionChange, disabled = false, props, children }) {
|
|
17
21
|
const ref = useRef(null);
|
|
@@ -20,13 +24,14 @@ export default function ReorderList({ useOnlyIconToDrag = false, selectedItemOpa
|
|
|
20
24
|
const [items, setItems] = useState(Children.toArray(children));
|
|
21
25
|
const [temp, setTemp] = useState({});
|
|
22
26
|
const [isAnimating, setIsAnimating] = useState(false);
|
|
27
|
+
const [scroll, setScroll] = useState();
|
|
23
28
|
const refs = useMemo(() => items.map(_ => createRef()), [items]);
|
|
24
29
|
const findIndex = (key) => key ? items.findIndex(item => { var _a, _b; return ((_b = (_a = item === null || item === void 0 ? void 0 : item.key) === null || _a === void 0 ? void 0 : _a.split(".$").at(-1)) !== null && _b !== void 0 ? _b : item === null || item === void 0 ? void 0 : item.toString()) === key; }) : -1;
|
|
25
30
|
useEffect(() => {
|
|
26
31
|
if (!watchChildrenUpdates)
|
|
27
32
|
return;
|
|
28
33
|
if (selected !== -1)
|
|
29
|
-
handleDragEnd(selected, preserveOrder);
|
|
34
|
+
handleDragEnd(null, selected, preserveOrder);
|
|
30
35
|
if (preserveOrder) {
|
|
31
36
|
const items = [];
|
|
32
37
|
const newItems = [];
|
|
@@ -43,15 +48,27 @@ export default function ReorderList({ useOnlyIconToDrag = false, selectedItemOpa
|
|
|
43
48
|
else
|
|
44
49
|
setItems(Children.toArray(children));
|
|
45
50
|
}, [children]);
|
|
46
|
-
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
if (!scroll)
|
|
53
|
+
return;
|
|
54
|
+
const { left, top } = scroll;
|
|
55
|
+
const { scrollWidth, scrollHeight } = document.body;
|
|
56
|
+
const interval = setInterval(() => {
|
|
57
|
+
if (left < 0 || top < 0 || scrollWidth - scrollX > innerWidth - left || scrollHeight - scrollY > innerHeight - top)
|
|
58
|
+
scrollBy({ left, top, behavior: 'instant' });
|
|
59
|
+
}, 20);
|
|
60
|
+
return () => clearInterval(interval);
|
|
61
|
+
}, [scroll]);
|
|
62
|
+
function handleDragEnd(event, end = selected, handlePositionChange = true) {
|
|
63
|
+
event === null || event === void 0 ? void 0 : event.stopPropagation();
|
|
47
64
|
if (handlePositionChange && end !== start)
|
|
48
65
|
onPositionChange === null || onPositionChange === void 0 ? void 0 : onPositionChange({ start, end, oldItems: temp.items, newItems: items, revert: () => setItems(temp.items) });
|
|
49
66
|
setStart(-1);
|
|
50
67
|
setSelected(-1);
|
|
51
68
|
}
|
|
52
|
-
return React.createElement("div", Object.assign({ ref: ref }, props), disabled ? children : React.createElement(Animation, { duration: +(start !== -1) && animationDuration }, Children.map(items, (child, i) => {
|
|
69
|
+
return React.createElement("div", Object.assign({ ref: ref }, props), disabled ? children : React.createElement(Animation, { duration: +(start !== -1 && !scroll) && animationDuration }, Children.map(items, (child, i) => {
|
|
53
70
|
var _a;
|
|
54
|
-
return React.createElement(ReorderItemRef, { key: (_a = child === null || child === void 0 ? void 0 : child.key) !== null && _a !== void 0 ? _a : child === null || child === void 0 ? void 0 : child.toString(), ref: refs[i], useOnlyIconToDrag: useOnlyIconToDrag, style: { opacity: selected === i ? selectedItemOpacity : 1 }, onDragStart: event => {
|
|
71
|
+
return React.createElement(ReorderItemRef, { key: (_a = child === null || child === void 0 ? void 0 : child.key) !== null && _a !== void 0 ? _a : child === null || child === void 0 ? void 0 : child.toString(), ref: refs[i], useOnlyIconToDrag: useOnlyIconToDrag, style: { opacity: selected === i ? selectedItemOpacity : 1, touchAction: "pan-y" }, onDragStart: event => {
|
|
55
72
|
event.stopPropagation();
|
|
56
73
|
setStart(i);
|
|
57
74
|
setSelected(i);
|
|
@@ -61,7 +78,7 @@ export default function ReorderList({ useOnlyIconToDrag = false, selectedItemOpa
|
|
|
61
78
|
if (start === -1 || selected === i || isAnimating)
|
|
62
79
|
return;
|
|
63
80
|
const { width: startWidth, height: startHeight } = temp.rect;
|
|
64
|
-
const { left, top, width, height } = event.
|
|
81
|
+
const { left, top, width, height } = event.target.getBoundingClientRect();
|
|
65
82
|
if (event.clientX - left > Math.min(startWidth, width) || event.clientY - top > Math.min(startHeight, height))
|
|
66
83
|
return;
|
|
67
84
|
setSelected(i);
|
|
@@ -72,27 +89,34 @@ export default function ReorderList({ useOnlyIconToDrag = false, selectedItemOpa
|
|
|
72
89
|
});
|
|
73
90
|
setIsAnimating(true);
|
|
74
91
|
setTimeout(() => setIsAnimating(false), animationDuration);
|
|
75
|
-
}, onDragEnd: event => {
|
|
76
|
-
event.
|
|
77
|
-
|
|
78
|
-
|
|
92
|
+
}, onDragEnd: handleDragEnd, onTouchMove: event => {
|
|
93
|
+
const { clientX, screenX, clientY, screenY } = event.touches[0];
|
|
94
|
+
let left = 0, top = 0;
|
|
95
|
+
if (clientX < scrollThreshold.x)
|
|
96
|
+
left = -5;
|
|
97
|
+
else if (innerWidth - screenX < scrollThreshold.x)
|
|
98
|
+
left = 5;
|
|
99
|
+
if (clientY < scrollThreshold.y)
|
|
100
|
+
top = -10;
|
|
101
|
+
else if (innerHeight - screenY < scrollThreshold.y)
|
|
102
|
+
top = 10;
|
|
103
|
+
setScroll((left || top) ? { left, top } : undefined);
|
|
104
|
+
}, onTouchEnd: () => setScroll(undefined) }, child);
|
|
79
105
|
})));
|
|
80
106
|
}
|
|
81
|
-
function ReorderItem(
|
|
82
|
-
|
|
83
|
-
const
|
|
84
|
-
const onPointerLeave = () => setDraggable(false);
|
|
85
|
-
let props = { draggable, onDragStart, onDragEnter, onDragEnd };
|
|
86
|
-
if (!useOnlyIconToDrag)
|
|
87
|
-
props = Object.assign(Object.assign({}, props), { onPointerEnter, onPointerLeave });
|
|
107
|
+
function ReorderItem(_a, ref) {
|
|
108
|
+
var { useOnlyIconToDrag, onTouchEnd: propOnTouchEnd, children } = _a, props = __rest(_a, ["useOnlyIconToDrag", "onTouchEnd", "children"]);
|
|
109
|
+
const _b = useDraggable(), { draggable } = _b, _c = _b.draggableProps, { onTouchEnd: draggableOnTouchEnd } = _c, draggableProps = __rest(_c, ["onTouchEnd"]);
|
|
88
110
|
const recursiveClone = (children) => Children.map(children, child => {
|
|
89
111
|
if (!isValidElement(child))
|
|
90
112
|
return child;
|
|
91
|
-
|
|
92
|
-
return cloneElement(child, Object.assign({ children: recursiveClone(child.props.children) }, childProps));
|
|
113
|
+
return cloneElement(child, Object.assign({ children: recursiveClone(child.props.children) }, (child.type === ReorderIcon && draggableProps)));
|
|
93
114
|
});
|
|
94
115
|
const recursiveChildren = useMemo(() => useOnlyIconToDrag ? recursiveClone(children) : children, [children]);
|
|
95
|
-
return React.createElement("div", Object.assign({ ref: ref,
|
|
116
|
+
return React.createElement("div", Object.assign({ ref: ref, draggable: draggable }, props, (!useOnlyIconToDrag && draggableProps), { onTouchEnd: event => {
|
|
117
|
+
draggableOnTouchEnd(event);
|
|
118
|
+
propOnTouchEnd(event);
|
|
119
|
+
} }), recursiveChildren);
|
|
96
120
|
}
|
|
97
121
|
export function ReorderIcon(_a) {
|
|
98
122
|
var { children = React.createElement(PiDotsSixVerticalBold, null), style } = _a, props = __rest(_a, ["children", "style"]);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-reorder-list",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "A simple react component that facilitates the reordering of JSX/HTML elements through drag-and-drop functionality, allowing for easy position changes.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -32,6 +32,9 @@
|
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@types/react": "^18.2.48"
|
|
34
34
|
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"drag-drop-touch": "^1.3.1"
|
|
37
|
+
},
|
|
35
38
|
"scripts": {
|
|
36
39
|
"build": "pnpm i && tsc"
|
|
37
40
|
}
|