react-reorder-list 0.6.7 → 0.7.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 +25 -1
- package/dist/animation.js +3 -9
- package/dist/hooks.d.ts +1 -0
- package/dist/hooks.js +8 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +22 -10
- package/dist/utils.d.ts +3 -0
- package/dist/utils.js +6 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -7,7 +7,8 @@ A simple react component that facilitates the reordering of JSX/HTML elements th
|
|
|
7
7
|
- Reorders list of elements using drag and drop.
|
|
8
8
|
- Easy to use
|
|
9
9
|
- Smooth transition using animation.
|
|
10
|
-
-
|
|
10
|
+
- Listens to children updates. See [listen to children updates](#listen-to-children-updates)
|
|
11
|
+
- Disables reordering for individual children. See [disable reordering for individual children](#disable-reordering-for-individual-children)
|
|
11
12
|
- Handles nested lists easily. See [nested list usage](#nested-list-usage)
|
|
12
13
|
|
|
13
14
|
## Installation
|
|
@@ -125,6 +126,29 @@ export default function App() {
|
|
|
125
126
|
}
|
|
126
127
|
```
|
|
127
128
|
|
|
129
|
+
#### Disable reordering for individual children
|
|
130
|
+
|
|
131
|
+
```jsx
|
|
132
|
+
import React from "react";
|
|
133
|
+
import ReorderList from "react-reorder-list";
|
|
134
|
+
|
|
135
|
+
export default function App() {
|
|
136
|
+
return (
|
|
137
|
+
<ReorderList>
|
|
138
|
+
<div key="div" data-disable-reorder={true}>
|
|
139
|
+
This div cannot be reordered
|
|
140
|
+
</div>
|
|
141
|
+
{[0, 1, 2, 3, 4].map((i) => {
|
|
142
|
+
return <div key={i}>Item {i}</div>; // Having a unique key is important
|
|
143
|
+
})}
|
|
144
|
+
<p key="p" data-disable-reorder={true}>
|
|
145
|
+
This p cannot be reordered either
|
|
146
|
+
</p>
|
|
147
|
+
</ReorderList>
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
128
152
|
#### Nested List Usage
|
|
129
153
|
|
|
130
154
|
```jsx
|
package/dist/animation.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { useState, useLayoutEffect, Children
|
|
2
|
-
|
|
1
|
+
import { useState, useLayoutEffect, Children } from "react";
|
|
2
|
+
import { usePrevious } from "./hooks.js";
|
|
3
|
+
import { getKey } from "./utils.js";
|
|
3
4
|
function calculateBoundingBoxes(children) {
|
|
4
5
|
const boundingBoxes = {};
|
|
5
6
|
Children.forEach(children, (child) => {
|
|
@@ -9,13 +10,6 @@ function calculateBoundingBoxes(children) {
|
|
|
9
10
|
});
|
|
10
11
|
return boundingBoxes;
|
|
11
12
|
}
|
|
12
|
-
function usePrevious(value) {
|
|
13
|
-
const prevChildrenRef = useRef();
|
|
14
|
-
useEffect(() => {
|
|
15
|
-
prevChildrenRef.current = value;
|
|
16
|
-
}, [value]);
|
|
17
|
-
return prevChildrenRef.current;
|
|
18
|
-
}
|
|
19
13
|
export default function Animation({ duration, children }) {
|
|
20
14
|
const [boundingBox, setBoundingBox] = useState({});
|
|
21
15
|
const prevBoundingBox = usePrevious(boundingBox);
|
package/dist/hooks.d.ts
CHANGED
package/dist/hooks.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useState } from "react";
|
|
1
|
+
import { useEffect, useRef, useState } from "react";
|
|
2
2
|
export function useDraggable(initValue = false) {
|
|
3
3
|
const [draggable, setDraggable] = useState(initValue);
|
|
4
4
|
const enableDragging = () => setDraggable(true);
|
|
@@ -6,3 +6,10 @@ export function useDraggable(initValue = false) {
|
|
|
6
6
|
const draggableProps = { onMouseEnter: enableDragging, onMouseLeave: disableDragging, onTouchStart: enableDragging, onTouchEnd: disableDragging };
|
|
7
7
|
return [draggable, draggableProps];
|
|
8
8
|
}
|
|
9
|
+
export function usePrevious(value) {
|
|
10
|
+
const prevChildrenRef = useRef();
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
prevChildrenRef.current = value;
|
|
13
|
+
}, [value]);
|
|
14
|
+
return prevChildrenRef.current;
|
|
15
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ export type DivDragEventHandler = DragEventHandler<HTMLDivElement>;
|
|
|
22
22
|
export type DivTouchEventHandler = TouchEventHandler<HTMLDivElement>;
|
|
23
23
|
export type ReorderItemProps = {
|
|
24
24
|
useOnlyIconToDrag: boolean;
|
|
25
|
+
disable: boolean;
|
|
25
26
|
style: CSSProperties;
|
|
26
27
|
onDragStart?: DivDragEventHandler;
|
|
27
28
|
onDragEnter: DivDragEventHandler;
|
package/dist/index.js
CHANGED
|
@@ -10,9 +10,10 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
10
10
|
return t;
|
|
11
11
|
};
|
|
12
12
|
import React, { Children, cloneElement, createRef, forwardRef, isValidElement, useEffect, useMemo, useRef, useState } from "react";
|
|
13
|
-
import { PiDotsSixVerticalBold } from "./icons.js";
|
|
14
13
|
import Animation from "./animation.js";
|
|
14
|
+
import { PiDotsSixVerticalBold } from "./icons.js";
|
|
15
15
|
import { useDraggable } from "./hooks.js";
|
|
16
|
+
import { swap } from "./utils.js";
|
|
16
17
|
if (typeof window !== "undefined")
|
|
17
18
|
import("drag-drop-touch");
|
|
18
19
|
const scrollThreshold = { x: 10, y: 100 };
|
|
@@ -25,7 +26,10 @@ export default function ReorderList({ useOnlyIconToDrag = false, selectedItemOpa
|
|
|
25
26
|
const [temp, setTemp] = useState({});
|
|
26
27
|
const [isAnimating, setIsAnimating] = useState(false);
|
|
27
28
|
const [scroll, setScroll] = useState();
|
|
28
|
-
const refs = useMemo(() => items.
|
|
29
|
+
const [refs, disableArr] = useMemo(() => items.reduce(([refs, disableArr], item) => {
|
|
30
|
+
var _a;
|
|
31
|
+
return [refs.concat(createRef()), disableArr.concat((_a = item === null || item === void 0 ? void 0 : item.props) === null || _a === void 0 ? void 0 : _a["data-disable-reorder"])];
|
|
32
|
+
}, [[], []]), [items]);
|
|
29
33
|
const findIndex = (key) => (key ? items.findIndex((item) => { var _a; return ((_a = item === null || item === void 0 ? void 0 : item.key) === null || _a === void 0 ? void 0 : _a.split(".$").at(-1)) === key; }) : -1);
|
|
30
34
|
useEffect(() => {
|
|
31
35
|
if (!watchChildrenUpdates)
|
|
@@ -65,10 +69,10 @@ export default function ReorderList({ useOnlyIconToDrag = false, selectedItemOpa
|
|
|
65
69
|
setStart(-1);
|
|
66
70
|
setSelected(-1);
|
|
67
71
|
}
|
|
68
|
-
return (React.createElement("div", Object.assign({ ref: ref }, props), disabled ? (children) : (React.createElement(Animation, { duration: +(start !== -1 && !scroll) && animationDuration },
|
|
72
|
+
return (React.createElement("div", Object.assign({ ref: ref }, props), disabled ? (children) : (React.createElement(Animation, { duration: +(start !== -1 && !scroll) && animationDuration }, items.map((child, i) => {
|
|
69
73
|
if (!isValidElement(child))
|
|
70
74
|
return child;
|
|
71
|
-
return (React.createElement(ReorderItemRef, { key: child.key, ref: refs[i], useOnlyIconToDrag: useOnlyIconToDrag, style: { opacity: selected === i ? selectedItemOpacity : 1, touchAction: "pan-y" }, onDragStart: (event) => {
|
|
75
|
+
return (React.createElement(ReorderItemRef, { key: child.key, ref: refs[i], useOnlyIconToDrag: useOnlyIconToDrag, disable: disableArr[i], style: { opacity: selected === i ? selectedItemOpacity : 1, touchAction: "pan-y" }, onDragStart: (event) => {
|
|
72
76
|
event.stopPropagation();
|
|
73
77
|
setStart(i);
|
|
74
78
|
setSelected(i);
|
|
@@ -83,8 +87,16 @@ export default function ReorderList({ useOnlyIconToDrag = false, selectedItemOpa
|
|
|
83
87
|
return;
|
|
84
88
|
setSelected(i);
|
|
85
89
|
setItems(() => {
|
|
86
|
-
const items = temp.items.
|
|
87
|
-
|
|
90
|
+
const items = temp.items.slice();
|
|
91
|
+
const shiftForward = start < i;
|
|
92
|
+
const increment = shiftForward ? 1 : -1;
|
|
93
|
+
let key = start;
|
|
94
|
+
for (let index = start + increment; shiftForward ? index <= i : index >= i; index += increment) {
|
|
95
|
+
if (disableArr[index])
|
|
96
|
+
continue;
|
|
97
|
+
swap(items, key, index);
|
|
98
|
+
key = index;
|
|
99
|
+
}
|
|
88
100
|
return items;
|
|
89
101
|
});
|
|
90
102
|
setIsAnimating(true);
|
|
@@ -107,20 +119,20 @@ export default function ReorderList({ useOnlyIconToDrag = false, selectedItemOpa
|
|
|
107
119
|
})))));
|
|
108
120
|
}
|
|
109
121
|
function ReorderItem(_a, ref) {
|
|
110
|
-
var { useOnlyIconToDrag, onTouchEnd: propOnTouchEnd
|
|
122
|
+
var { useOnlyIconToDrag, disable, style, children, onTouchEnd: propOnTouchEnd } = _a, events = __rest(_a, ["useOnlyIconToDrag", "disable", "style", "children", "onTouchEnd"]);
|
|
111
123
|
const [draggable, _b] = useDraggable(), { onTouchEnd: draggableOnTouchEnd } = _b, draggableProps = __rest(_b, ["onTouchEnd"]);
|
|
112
124
|
if (!draggable)
|
|
113
|
-
|
|
125
|
+
events.onDragStart = undefined;
|
|
114
126
|
const recursiveClone = (children) => Children.map(children, (child) => {
|
|
115
127
|
if (!isValidElement(child))
|
|
116
128
|
return child;
|
|
117
129
|
return cloneElement(child, child.type === ReorderIcon ? draggableProps : {}, recursiveClone(child.props.children));
|
|
118
130
|
});
|
|
119
131
|
const recursiveChildren = useMemo(() => (useOnlyIconToDrag ? recursiveClone(children) : children), [useOnlyIconToDrag, children]);
|
|
120
|
-
return (React.createElement("div", Object.assign({ ref: ref, draggable: draggable },
|
|
132
|
+
return (React.createElement("div", Object.assign({ ref: ref, draggable: !disable && draggable, style: style }, (!disable && Object.assign(Object.assign(Object.assign({}, events), (!useOnlyIconToDrag && draggableProps)), { onTouchEnd: (event) => {
|
|
121
133
|
draggableOnTouchEnd();
|
|
122
134
|
propOnTouchEnd(event);
|
|
123
|
-
} }), recursiveChildren));
|
|
135
|
+
} }))), recursiveChildren));
|
|
124
136
|
}
|
|
125
137
|
export function ReorderIcon(_a) {
|
|
126
138
|
var { children = React.createElement(PiDotsSixVerticalBold, null), style } = _a, props = __rest(_a, ["children", "style"]);
|
package/dist/utils.d.ts
ADDED
package/dist/utils.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export const getKey = (child) => { var _a; return (_a = child === null || child === void 0 ? void 0 : child.key) === null || _a === void 0 ? void 0 : _a.split("/.")[0]; };
|
|
2
|
+
export function swap(array, i, j) {
|
|
3
|
+
const temp = array[i];
|
|
4
|
+
array[i] = array[j];
|
|
5
|
+
array[j] = temp;
|
|
6
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-reorder-list",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.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",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"react": ">=17.0.0"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"@types/react": "^18.2.
|
|
32
|
+
"@types/react": "^18.2.69"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"drag-drop-touch": "^1.3.1"
|