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 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
- - Listen to children updates. See [listen to children updates](#listen-to-children-updates)
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, useEffect, useRef } from "react";
2
- 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]; };
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
@@ -4,3 +4,4 @@ export declare function useDraggable(initValue?: boolean): readonly [boolean, {
4
4
  onTouchStart: () => void;
5
5
  onTouchEnd: () => void;
6
6
  }];
7
+ export declare function usePrevious<T>(value: T): T | undefined;
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.map((_) => createRef()), [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 }, Children.map(items, (child, i) => {
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.filter((_, i) => i !== start);
87
- items.splice(i, 0, temp.items[start]);
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, children } = _a, props = __rest(_a, ["useOnlyIconToDrag", "onTouchEnd", "children"]);
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
- props.onDragStart = undefined;
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 }, props, (!useOnlyIconToDrag && draggableProps), { onTouchEnd: (event) => {
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"]);
@@ -0,0 +1,3 @@
1
+ import { ReactNode } from "react";
2
+ export declare const getKey: (child: ReactNode) => string | undefined;
3
+ export declare function swap(array: any[], i: number, j: number): void;
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.6.7",
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.67"
32
+ "@types/react": "^18.2.69"
33
33
  },
34
34
  "dependencies": {
35
35
  "drag-drop-touch": "^1.3.1"