react-reorder-list 0.10.1 → 0.10.3

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.
@@ -0,0 +1,21 @@
1
+ import { o as DivProps, p as ReorderListProps } from "./types-CRxTdmXH.mjs";
2
+ import { JSX } from "react";
3
+
4
+ //#region src/components.d.ts
5
+ declare function ReorderIcon({
6
+ children,
7
+ style,
8
+ ...props
9
+ }: DivProps): JSX.Element;
10
+ declare function ReorderList({
11
+ useOnlyIconToDrag,
12
+ selectedItemOpacity,
13
+ animationDuration,
14
+ preserveOrder,
15
+ onPositionChange,
16
+ disabled,
17
+ props,
18
+ children
19
+ }: ReorderListProps): JSX.Element;
20
+ //#endregion
21
+ export { ReorderIcon, ReorderList as default };
package/dist/index.mjs ADDED
@@ -0,0 +1,279 @@
1
+ import React, { Children, cloneElement, createRef, isValidElement, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
2
+ //#region src/constants.ts
3
+ const scrollThreshold = {
4
+ x: 10,
5
+ y: 100
6
+ };
7
+ //#endregion
8
+ //#region src/hooks.ts
9
+ function useDraggable(initValue = false) {
10
+ const [draggable, setDraggable] = useState(initValue);
11
+ const enableDragging = useCallback(() => setDraggable(true), []);
12
+ const disableDragging = useCallback(() => setDraggable(false), []);
13
+ return {
14
+ draggable,
15
+ onMouseEnter: enableDragging,
16
+ onMouseLeave: disableDragging,
17
+ onTouchStart: enableDragging,
18
+ onTouchEnd: disableDragging
19
+ };
20
+ }
21
+ function useStateWithHistory(initValue) {
22
+ const [state, setState] = useState(initValue);
23
+ const [prevState, setPrevState] = useState();
24
+ function setStateWithHistory(value) {
25
+ setPrevState(state);
26
+ setState(value);
27
+ }
28
+ return [
29
+ state,
30
+ prevState,
31
+ setStateWithHistory
32
+ ];
33
+ }
34
+ //#endregion
35
+ //#region src/icons.tsx
36
+ function PiDotsSixVerticalBold(props) {
37
+ return /* @__PURE__ */ React.createElement("span", props, /* @__PURE__ */ React.createElement("svg", {
38
+ viewBox: "0 0 256 256",
39
+ fill: "currentColor",
40
+ width: "1.25rem",
41
+ height: "1.25rem"
42
+ }, /* @__PURE__ */ React.createElement("path", { d: "M108,60A16,16,0,1,1,92,44,16,16,0,0,1,108,60Zm56,16a16,16,0,1,0-16-16A16,16,0,0,0,164,76ZM92,112a16,16,0,1,0,16,16A16,16,0,0,0,92,112Zm72,0a16,16,0,1,0,16,16A16,16,0,0,0,164,112ZM92,180a16,16,0,1,0,16,16A16,16,0,0,0,92,180Zm72,0a16,16,0,1,0,16,16A16,16,0,0,0,164,180Z" })));
43
+ }
44
+ //#endregion
45
+ //#region src/lib/react.ts
46
+ function calculateBoundingBoxes(children) {
47
+ const boundingBoxes = {};
48
+ Children.forEach(children, (child) => {
49
+ const { key } = child;
50
+ if (key) boundingBoxes[key] = child.props.ref.current.getBoundingClientRect();
51
+ });
52
+ return boundingBoxes;
53
+ }
54
+ //#endregion
55
+ //#region src/lib/utils.ts
56
+ const areOrdersEqual = (a, b) => a.length === b.length && a.every((key, index) => key === b[index]);
57
+ function swap(array, i, j) {
58
+ const temp = array[i];
59
+ array[i] = array[j];
60
+ array[j] = temp;
61
+ }
62
+ //#endregion
63
+ //#region src/components.tsx
64
+ if (typeof window !== "undefined") import("drag-drop-touch");
65
+ function Animation({ duration, children }) {
66
+ const [boundingBox, prevBoundingBox, setBoundingBox] = useStateWithHistory({});
67
+ useLayoutEffect(() => {
68
+ if (duration > 0) setBoundingBox(calculateBoundingBoxes(children));
69
+ else setBoundingBox({});
70
+ }, [children]);
71
+ useLayoutEffect(() => {
72
+ if (duration <= 0 || !prevBoundingBox || !Object.keys(prevBoundingBox).length) return;
73
+ children.forEach((child) => {
74
+ const { key } = child;
75
+ if (key == null) return;
76
+ const domNode = child.props.ref.current;
77
+ if (!domNode) return;
78
+ const { left: prevLeft, top: prevTop } = prevBoundingBox[key] || {};
79
+ const { left, top } = boundingBox[key] || {};
80
+ const changeInX = prevLeft - left;
81
+ const changeInY = prevTop - top;
82
+ if (!changeInX && !changeInY) return;
83
+ requestAnimationFrame(() => {
84
+ domNode.style.transform = `translate(${changeInX}px, ${changeInY}px)`;
85
+ domNode.style.transition = "none";
86
+ requestAnimationFrame(() => {
87
+ domNode.style.transform = "";
88
+ domNode.style.transition = `transform ${duration}ms`;
89
+ });
90
+ });
91
+ });
92
+ }, [boundingBox]);
93
+ return children;
94
+ }
95
+ function ReorderIcon({ children = /* @__PURE__ */ React.createElement(PiDotsSixVerticalBold, null), style, ...props }) {
96
+ return /* @__PURE__ */ React.createElement("span", {
97
+ style: {
98
+ cursor: "grab",
99
+ ...style
100
+ },
101
+ ...props
102
+ }, children);
103
+ }
104
+ function ReorderItem({ useOnlyIconToDrag, disable, ref, style, children, onTouchEnd: propOnTouchEnd, ...events }) {
105
+ const { draggable, onTouchEnd: draggableOnTouchEnd, ...draggableProps } = useDraggable();
106
+ const recursiveClone = (children) => Children.map(children, (child) => {
107
+ if (!isValidElement(child)) return child;
108
+ return cloneElement(child, child.type === ReorderIcon ? draggableProps : {}, recursiveClone(child.props.children));
109
+ });
110
+ const recursiveChildren = useMemo(() => useOnlyIconToDrag ? recursiveClone(children) : children, [useOnlyIconToDrag, children]);
111
+ return /* @__PURE__ */ React.createElement("div", {
112
+ ref,
113
+ draggable: !disable && draggable,
114
+ style: {
115
+ ...style,
116
+ touchAction: "pan-y",
117
+ cursor: useOnlyIconToDrag ? "default" : "grab"
118
+ },
119
+ ...!disable && {
120
+ ...events,
121
+ ...!useOnlyIconToDrag && draggableProps,
122
+ onTouchEnd: (event) => {
123
+ draggableOnTouchEnd(event);
124
+ propOnTouchEnd(event);
125
+ }
126
+ }
127
+ }, recursiveChildren);
128
+ }
129
+ function ReorderList({ useOnlyIconToDrag = false, selectedItemOpacity = .5, animationDuration = 300, preserveOrder = true, onPositionChange, disabled = false, props, children }) {
130
+ const containerRef = useRef(null);
131
+ const itemRefs = useRef(/* @__PURE__ */ new Map());
132
+ const [order, setOrder] = useState([]);
133
+ const [dragState, setDragState] = useState();
134
+ const [isAnimating, setIsAnimating] = useState(false);
135
+ const [scroll, setScroll] = useState();
136
+ const childMap = useMemo(() => {
137
+ const map = /* @__PURE__ */ new Map();
138
+ Children.forEach(children, (child) => {
139
+ if (!isValidElement(child)) return;
140
+ const { key, props } = child;
141
+ if (key != null) map.set(key, {
142
+ child,
143
+ disabled: props["data-disable-reorder"]
144
+ });
145
+ });
146
+ return map;
147
+ }, [children]);
148
+ const orderedChildren = useMemo(() => {
149
+ if (!order.length) return [];
150
+ return order.flatMap((key, orderIndex) => {
151
+ const entry = childMap.get(key);
152
+ if (!entry) return [];
153
+ const { child, disabled } = entry;
154
+ const ref = getRef(key);
155
+ const isSelected = dragState?.currentIndex === orderIndex;
156
+ return /* @__PURE__ */ React.createElement(ReorderItem, {
157
+ key,
158
+ ref,
159
+ useOnlyIconToDrag,
160
+ disable: disabled,
161
+ style: { opacity: isSelected ? selectedItemOpacity : 1 },
162
+ onDragStart: (event) => {
163
+ event.stopPropagation();
164
+ setDragState({
165
+ startIndex: orderIndex,
166
+ currentIndex: orderIndex,
167
+ startOrder: [...order],
168
+ startRect: ref.current?.getBoundingClientRect?.() || void 0
169
+ });
170
+ },
171
+ onDragEnter: (event) => {
172
+ event.stopPropagation();
173
+ if (!dragState || dragState.currentIndex === orderIndex || isAnimating) return;
174
+ const { width: startWidth, height: startHeight } = dragState.startRect || {
175
+ width: 0,
176
+ height: 0
177
+ };
178
+ const { left, top, width, height } = event.currentTarget.getBoundingClientRect();
179
+ if (event.clientX - left > Math.min(startWidth, width) || event.clientY - top > Math.min(startHeight, height)) return;
180
+ setDragState((prev) => prev ? {
181
+ ...prev,
182
+ currentIndex: orderIndex
183
+ } : void 0);
184
+ setOrder(() => {
185
+ const newOrder = [...dragState.startOrder];
186
+ const shiftForward = dragState.startIndex < orderIndex;
187
+ const increment = shiftForward ? 1 : -1;
188
+ let currentPos = dragState.startIndex;
189
+ for (let index = dragState.startIndex + increment; shiftForward ? index <= orderIndex : index >= orderIndex; index += increment) {
190
+ const key = dragState.startOrder[index];
191
+ if (childMap.get(key)?.disabled) continue;
192
+ swap(newOrder, currentPos, index);
193
+ currentPos = index;
194
+ }
195
+ return newOrder;
196
+ });
197
+ setIsAnimating(true);
198
+ setTimeout(() => setIsAnimating(false), animationDuration);
199
+ },
200
+ onDragEnd: handleDragEnd,
201
+ onTouchMove: (event) => {
202
+ if (!dragState) return;
203
+ const { clientX, screenX, clientY, screenY } = event.touches[0];
204
+ const left = clientX < scrollThreshold.x ? -5 : innerWidth - screenX < scrollThreshold.x ? 5 : 0;
205
+ const top = clientY < scrollThreshold.y ? -10 : innerHeight - screenY < scrollThreshold.y ? 10 : 0;
206
+ setScroll(left || top ? {
207
+ left,
208
+ top
209
+ } : void 0);
210
+ },
211
+ onTouchEnd: () => setScroll(void 0)
212
+ }, child);
213
+ });
214
+ }, [
215
+ childMap,
216
+ order,
217
+ dragState,
218
+ isAnimating,
219
+ useOnlyIconToDrag,
220
+ selectedItemOpacity,
221
+ animationDuration
222
+ ]);
223
+ function getRef(key) {
224
+ if (!itemRefs.current.has(key)) itemRefs.current.set(key, createRef());
225
+ return itemRefs.current.get(key);
226
+ }
227
+ function handleDragEnd(event) {
228
+ if (event) {
229
+ event.stopPropagation();
230
+ if (dragState && dragState.currentIndex !== dragState.startIndex) onPositionChange?.({
231
+ start: dragState.startIndex,
232
+ end: dragState.currentIndex,
233
+ oldOrder: dragState.startOrder,
234
+ newOrder: order,
235
+ revert: () => setOrder(dragState.startOrder)
236
+ });
237
+ }
238
+ setDragState(void 0);
239
+ setScroll(void 0);
240
+ }
241
+ useEffect(() => {
242
+ const currentKeys = [];
243
+ Children.forEach(children, (child) => {
244
+ if (!isValidElement(child)) return;
245
+ const { key } = child;
246
+ if (key != null) currentKeys.push(key);
247
+ });
248
+ let newOrder;
249
+ if (preserveOrder) {
250
+ const currentKeySet = new Set(currentKeys);
251
+ const orderSet = new Set(order);
252
+ const newKeys = currentKeys.filter((key) => !orderSet.has(key));
253
+ newOrder = [...order.filter((key) => currentKeySet.has(key)), ...newKeys];
254
+ } else newOrder = currentKeys;
255
+ if (!areOrdersEqual(order, newOrder)) {
256
+ if (dragState) setDragState(void 0);
257
+ setOrder(newOrder);
258
+ }
259
+ }, [children]);
260
+ useEffect(() => {
261
+ if (!scroll) return;
262
+ const { left, top } = scroll;
263
+ const { scrollWidth, scrollHeight } = document.body;
264
+ const interval = setInterval(() => {
265
+ if (left < 0 || top < 0 || scrollWidth - scrollX > innerWidth - left || scrollHeight - scrollY > innerHeight - top) scrollBy({
266
+ left,
267
+ top,
268
+ behavior: "instant"
269
+ });
270
+ }, 20);
271
+ return () => clearInterval(interval);
272
+ }, [scroll]);
273
+ return /* @__PURE__ */ React.createElement("div", {
274
+ ref: containerRef,
275
+ ...props
276
+ }, disabled ? children : /* @__PURE__ */ React.createElement(Animation, { duration: dragState && !scroll ? animationDuration : 0 }, orderedChildren));
277
+ }
278
+ //#endregion
279
+ export { ReorderIcon, ReorderList as default };
@@ -0,0 +1,50 @@
1
+ import { CSSProperties, DetailedHTMLProps, DragEventHandler, HTMLAttributes, Key, MouseEventHandler, ReactElement, ReactNode, RefObject, TouchEventHandler } from "react";
2
+
3
+ //#region src/types.d.ts
4
+ type AnimationProps = {
5
+ duration: number;
6
+ children: Child[];
7
+ };
8
+ type BoundingBox = Record<string, DOMRect>;
9
+ type Child = ReactElement<{
10
+ ref: RefObject<HTMLElement>;
11
+ }>;
12
+ type Order = Key[];
13
+ type DivDragEventHandler = DragEventHandler<HTMLDivElement>;
14
+ type DivMouseEventHandler = MouseEventHandler<HTMLDivElement>;
15
+ type DivProps = DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>;
16
+ type DivRef = RefObject<HTMLDivElement | null>;
17
+ type DivTouchEventHandler = TouchEventHandler<HTMLDivElement>;
18
+ type PositionChangeHandler = (event: {
19
+ start: number;
20
+ end: number;
21
+ oldOrder: Order;
22
+ newOrder: Order;
23
+ revert: RevertHandler;
24
+ }) => void;
25
+ type ReorderItemProps = {
26
+ useOnlyIconToDrag: boolean;
27
+ disable?: boolean;
28
+ ref: DivRef;
29
+ style: CSSProperties;
30
+ onDragStart?: DivDragEventHandler;
31
+ onDragEnter: DivDragEventHandler;
32
+ onDragEnd: DivDragEventHandler;
33
+ onTouchMove: DivTouchEventHandler;
34
+ onTouchEnd: DivTouchEventHandler;
35
+ children: ReactNode;
36
+ };
37
+ type ReorderListProps = {
38
+ useOnlyIconToDrag?: boolean;
39
+ selectedItemOpacity?: number;
40
+ animationDuration?: number;
41
+ preserveOrder?: boolean;
42
+ onPositionChange?: PositionChangeHandler;
43
+ disabled?: boolean;
44
+ props?: DivProps;
45
+ children?: ReactNode;
46
+ };
47
+ type RevertHandler = () => void;
48
+ type IconProps = React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>;
49
+ //#endregion
50
+ export { DivMouseEventHandler as a, DivTouchEventHandler as c, PositionChangeHandler as d, ReorderItemProps as f, DivDragEventHandler as i, IconProps as l, RevertHandler as m, BoundingBox as n, DivProps as o, ReorderListProps as p, Child as r, DivRef as s, AnimationProps as t, Order as u };
@@ -0,0 +1,2 @@
1
+ import { a as DivMouseEventHandler, c as DivTouchEventHandler, d as PositionChangeHandler, f as ReorderItemProps, i as DivDragEventHandler, l as IconProps, m as RevertHandler, n as BoundingBox, o as DivProps, p as ReorderListProps, r as Child, s as DivRef, t as AnimationProps, u as Order } from "./types-CRxTdmXH.mjs";
2
+ export { AnimationProps, BoundingBox, Child, DivDragEventHandler, DivMouseEventHandler, DivProps, DivRef, DivTouchEventHandler, IconProps, Order, PositionChangeHandler, ReorderItemProps, ReorderListProps, RevertHandler };
package/dist/types.mjs ADDED
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-reorder-list",
3
- "version": "0.10.1",
3
+ "version": "0.10.3",
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
  "license": "MIT",
6
6
  "author": "Sahil Aggarwal <aggarwalsahil2004@gmail.com>",
@@ -15,15 +15,14 @@
15
15
  },
16
16
  "type": "module",
17
17
  "exports": {
18
- ".": "./dist/index.js",
19
- "./types": "./dist/types.js"
18
+ ".": "./dist/index.mjs",
19
+ "./types": "./dist/types.mjs"
20
20
  },
21
- "main": "dist/index.js",
22
21
  "files": [
23
22
  "dist"
24
23
  ],
25
24
  "sideEffects": true,
26
- "types": "dist/index.d.ts",
25
+ "types": "./dist/index.d.ts",
27
26
  "dependencies": {
28
27
  "drag-drop-touch": "^1.3.1"
29
28
  },
@@ -35,7 +34,7 @@
35
34
  "@types/react": "^19.2.14",
36
35
  "prettier-package-json": "^2.8.0",
37
36
  "release-it": "^19.2.4",
38
- "tsup": "^8.5.1",
37
+ "tsdown": "^0.21.0",
39
38
  "typescript": "^5.9.3"
40
39
  },
41
40
  "keywords": [
@@ -50,8 +49,8 @@
50
49
  ],
51
50
  "scripts": {
52
51
  "build": "pnpm i && pnpm run compile",
53
- "compile": "tsup",
54
- "dev": "tsup --watch",
52
+ "compile": "tsdown",
53
+ "dev": "tsdown --watch",
55
54
  "dry-release": "release-it --ci --dry-run",
56
55
  "prettier": "prettier-package-json --write package.json",
57
56
  "pub": "pnpm login && pnpm publish",
@@ -1,248 +0,0 @@
1
- import React2, { useRef, useState, useMemo, Children, isValidElement, createRef, useEffect, useLayoutEffect, useCallback, cloneElement } from 'react';
2
-
3
- var __defProp = Object.defineProperty;
4
- var __defProps = Object.defineProperties;
5
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
6
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
9
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
10
- var __spreadValues = (a, b) => {
11
- for (var prop in b || (b = {}))
12
- if (__hasOwnProp.call(b, prop))
13
- __defNormalProp(a, prop, b[prop]);
14
- if (__getOwnPropSymbols)
15
- for (var prop of __getOwnPropSymbols(b)) {
16
- if (__propIsEnum.call(b, prop))
17
- __defNormalProp(a, prop, b[prop]);
18
- }
19
- return a;
20
- };
21
- var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
22
- var __objRest = (source, exclude) => {
23
- var target = {};
24
- for (var prop in source)
25
- if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
26
- target[prop] = source[prop];
27
- if (source != null && __getOwnPropSymbols)
28
- for (var prop of __getOwnPropSymbols(source)) {
29
- if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
30
- target[prop] = source[prop];
31
- }
32
- return target;
33
- };
34
-
35
- // src/constants.ts
36
- var scrollThreshold = { x: 10, y: 100 };
37
- function useDraggable(initValue = false) {
38
- const [draggable, setDraggable] = useState(initValue);
39
- const enableDragging = useCallback(() => setDraggable(true), []);
40
- const disableDragging = useCallback(() => setDraggable(false), []);
41
- return { draggable, onMouseEnter: enableDragging, onMouseLeave: disableDragging, onTouchStart: enableDragging, onTouchEnd: disableDragging };
42
- }
43
- function useStateWithHistory(initValue) {
44
- const [state, setState] = useState(initValue);
45
- const [prevState, setPrevState] = useState();
46
- function setStateWithHistory(value) {
47
- setPrevState(state);
48
- setState(value);
49
- }
50
- return [state, prevState, setStateWithHistory];
51
- }
52
- function PiDotsSixVerticalBold(props) {
53
- return /* @__PURE__ */ React2.createElement("span", __spreadValues({}, props), /* @__PURE__ */ React2.createElement("svg", { viewBox: "0 0 256 256", fill: "currentColor", width: "1.25rem", height: "1.25rem" }, /* @__PURE__ */ React2.createElement("path", { d: "M108,60A16,16,0,1,1,92,44,16,16,0,0,1,108,60Zm56,16a16,16,0,1,0-16-16A16,16,0,0,0,164,76ZM92,112a16,16,0,1,0,16,16A16,16,0,0,0,92,112Zm72,0a16,16,0,1,0,16,16A16,16,0,0,0,164,112ZM92,180a16,16,0,1,0,16,16A16,16,0,0,0,92,180Zm72,0a16,16,0,1,0,16,16A16,16,0,0,0,164,180Z" })));
54
- }
55
- function calculateBoundingBoxes(children) {
56
- const boundingBoxes = {};
57
- Children.forEach(children, (child) => {
58
- const { key } = child;
59
- if (key) boundingBoxes[key] = child.props.ref.current.getBoundingClientRect();
60
- });
61
- return boundingBoxes;
62
- }
63
-
64
- // src/lib/utils.ts
65
- var areOrdersEqual = (a, b) => a.length === b.length && a.every((key, index) => key === b[index]);
66
- function swap(array, i, j) {
67
- const temp = array[i];
68
- array[i] = array[j];
69
- array[j] = temp;
70
- }
71
-
72
- // src/components.tsx
73
- if (typeof window !== "undefined") import('drag-drop-touch');
74
- function Animation({ duration, children }) {
75
- const [boundingBox, prevBoundingBox, setBoundingBox] = useStateWithHistory({});
76
- useLayoutEffect(() => {
77
- if (duration > 0) setBoundingBox(calculateBoundingBoxes(children));
78
- else setBoundingBox({});
79
- }, [children]);
80
- useLayoutEffect(() => {
81
- if (duration <= 0 || !prevBoundingBox || !Object.keys(prevBoundingBox).length) return;
82
- children.forEach((child) => {
83
- const { key } = child;
84
- if (!key) return;
85
- const domNode = child.props.ref.current;
86
- if (!domNode) return;
87
- const { left: prevLeft, top: prevTop } = prevBoundingBox[key] || {};
88
- const { left, top } = boundingBox[key] || {};
89
- const changeInX = prevLeft - left;
90
- const changeInY = prevTop - top;
91
- if (!changeInX && !changeInY) return;
92
- requestAnimationFrame(() => {
93
- domNode.style.transform = `translate(${changeInX}px, ${changeInY}px)`;
94
- domNode.style.transition = "none";
95
- requestAnimationFrame(() => {
96
- domNode.style.transform = "";
97
- domNode.style.transition = `transform ${duration}ms`;
98
- });
99
- });
100
- });
101
- }, [boundingBox]);
102
- return children;
103
- }
104
- function ReorderIcon(_a) {
105
- var _b = _a, { children = /* @__PURE__ */ React2.createElement(PiDotsSixVerticalBold, null), style } = _b, props = __objRest(_b, ["children", "style"]);
106
- return /* @__PURE__ */ React2.createElement("span", __spreadValues({ style: __spreadValues({ cursor: "grab" }, style) }, props), children);
107
- }
108
- function ReorderItem(_a) {
109
- var _b = _a, { useOnlyIconToDrag, disable, ref, style, children, onTouchEnd: propOnTouchEnd } = _b, events = __objRest(_b, ["useOnlyIconToDrag", "disable", "ref", "style", "children", "onTouchEnd"]);
110
- const _a2 = useDraggable(), { draggable, onTouchEnd: draggableOnTouchEnd } = _a2, draggableProps = __objRest(_a2, ["draggable", "onTouchEnd"]);
111
- const recursiveClone = (children2) => Children.map(children2, (child) => {
112
- if (!isValidElement(child)) return child;
113
- return cloneElement(child, child.type === ReorderIcon ? draggableProps : {}, recursiveClone(child.props.children));
114
- });
115
- const recursiveChildren = useMemo(() => useOnlyIconToDrag ? recursiveClone(children) : children, [useOnlyIconToDrag, children]);
116
- return /* @__PURE__ */ React2.createElement(
117
- "div",
118
- __spreadValues({
119
- ref,
120
- draggable: !disable && draggable,
121
- style: __spreadProps(__spreadValues({}, style), { touchAction: "pan-y", cursor: useOnlyIconToDrag ? "default" : "grab" })
122
- }, !disable && __spreadProps(__spreadValues(__spreadValues({}, events), !useOnlyIconToDrag && draggableProps), {
123
- onTouchEnd: (event) => {
124
- draggableOnTouchEnd(event);
125
- propOnTouchEnd(event);
126
- }
127
- })),
128
- recursiveChildren
129
- );
130
- }
131
- function ReorderList({ useOnlyIconToDrag = false, selectedItemOpacity = 0.5, animationDuration = 300, preserveOrder = true, onPositionChange, disabled = false, props, children }) {
132
- const containerRef = useRef(null);
133
- const itemRefs = useRef(/* @__PURE__ */ new Map());
134
- const [order, setOrder] = useState([]);
135
- const [dragState, setDragState] = useState();
136
- const [isAnimating, setIsAnimating] = useState(false);
137
- const [scroll, setScroll] = useState();
138
- const childMap = useMemo(() => {
139
- const map = /* @__PURE__ */ new Map();
140
- Children.forEach(children, (child) => {
141
- if (!isValidElement(child)) return;
142
- const { key, props: props2 } = child;
143
- if (!key) return;
144
- map.set(key, { child, disabled: props2["data-disable-reorder"] });
145
- });
146
- return map;
147
- }, [children]);
148
- const orderedChildren = useMemo(() => {
149
- if (!order.length) return [];
150
- return order.flatMap((key, orderIndex) => {
151
- const { child, disabled: disabled2 } = childMap.get(key) || {};
152
- if (!isValidElement(child)) return [];
153
- const ref = getRef(key);
154
- const isSelected = (dragState == null ? void 0 : dragState.currentIndex) === orderIndex;
155
- return /* @__PURE__ */ React2.createElement(
156
- ReorderItem,
157
- {
158
- key,
159
- ref,
160
- useOnlyIconToDrag,
161
- disable: disabled2,
162
- style: { opacity: isSelected ? selectedItemOpacity : 1 },
163
- onDragStart: (event) => {
164
- var _a, _b;
165
- event.stopPropagation();
166
- setDragState({ startIndex: orderIndex, currentIndex: orderIndex, startOrder: [...order], startRect: ((_b = (_a = ref.current) == null ? void 0 : _a.getBoundingClientRect) == null ? void 0 : _b.call(_a)) || void 0 });
167
- },
168
- onDragEnter: (event) => {
169
- event.stopPropagation();
170
- if (!dragState || dragState.currentIndex === orderIndex || isAnimating) return;
171
- const { width: startWidth, height: startHeight } = dragState.startRect || { width: 0, height: 0 };
172
- const { left, top, width, height } = event.currentTarget.getBoundingClientRect();
173
- if (event.clientX - left > Math.min(startWidth, width) || event.clientY - top > Math.min(startHeight, height)) return;
174
- setDragState((prev) => prev ? __spreadProps(__spreadValues({}, prev), { currentIndex: orderIndex }) : void 0);
175
- setOrder(() => {
176
- var _a;
177
- const newOrder = [...dragState.startOrder];
178
- const shiftForward = dragState.startIndex < orderIndex;
179
- const increment = shiftForward ? 1 : -1;
180
- let currentPos = dragState.startIndex;
181
- for (let index = dragState.startIndex + increment; shiftForward ? index <= orderIndex : index >= orderIndex; index += increment) {
182
- const key2 = dragState.startOrder[index];
183
- if ((_a = childMap.get(key2)) == null ? void 0 : _a.disabled) continue;
184
- swap(newOrder, currentPos, index);
185
- currentPos = index;
186
- }
187
- return newOrder;
188
- });
189
- setIsAnimating(true);
190
- setTimeout(() => setIsAnimating(false), animationDuration);
191
- },
192
- onDragEnd: handleDragEnd,
193
- onTouchMove: (event) => {
194
- if (!dragState) return;
195
- const { clientX, screenX, clientY, screenY } = event.touches[0];
196
- const left = clientX < scrollThreshold.x ? -5 : innerWidth - screenX < scrollThreshold.x ? 5 : 0;
197
- const top = clientY < scrollThreshold.y ? -10 : innerHeight - screenY < scrollThreshold.y ? 10 : 0;
198
- setScroll(left || top ? { left, top } : void 0);
199
- },
200
- onTouchEnd: () => setScroll(void 0)
201
- },
202
- child
203
- );
204
- });
205
- }, [childMap, order, dragState, isAnimating, useOnlyIconToDrag, selectedItemOpacity, animationDuration]);
206
- function getRef(key) {
207
- if (!itemRefs.current.has(key)) itemRefs.current.set(key, createRef());
208
- return itemRefs.current.get(key);
209
- }
210
- function handleDragEnd(event) {
211
- if (event) {
212
- event.stopPropagation();
213
- if (dragState && dragState.currentIndex !== dragState.startIndex) onPositionChange == null ? void 0 : onPositionChange({ start: dragState.startIndex, end: dragState.currentIndex, oldOrder: dragState.startOrder, newOrder: order, revert: () => setOrder(dragState.startOrder) });
214
- }
215
- setDragState(void 0);
216
- setScroll(void 0);
217
- }
218
- useEffect(() => {
219
- const currentKeys = [];
220
- Children.forEach(children, (child) => {
221
- const { key } = child;
222
- if (key) currentKeys.push(key);
223
- });
224
- let newOrder;
225
- if (preserveOrder) {
226
- const currentKeySet = new Set(currentKeys);
227
- const newKeys = currentKeys.filter((key) => !order.includes(key));
228
- const filteredOrder = order.filter((key) => currentKeySet.has(key));
229
- newOrder = [...filteredOrder, ...newKeys];
230
- } else newOrder = currentKeys;
231
- if (!areOrdersEqual(order, newOrder)) {
232
- if (dragState) setDragState(void 0);
233
- setOrder(newOrder);
234
- }
235
- }, [children]);
236
- useEffect(() => {
237
- if (!scroll) return;
238
- const { left, top } = scroll;
239
- const { scrollWidth, scrollHeight } = document.body;
240
- const interval = setInterval(() => {
241
- if (left < 0 || top < 0 || scrollWidth - scrollX > innerWidth - left || scrollHeight - scrollY > innerHeight - top) scrollBy({ left, top, behavior: "instant" });
242
- }, 20);
243
- return () => clearInterval(interval);
244
- }, [scroll]);
245
- return /* @__PURE__ */ React2.createElement("div", __spreadValues({ ref: containerRef }, props), disabled ? children : /* @__PURE__ */ React2.createElement(Animation, { duration: dragState && !scroll ? animationDuration : 0 }, orderedChildren));
246
- }
247
-
248
- export { ReorderIcon, ReorderList };
@@ -1,7 +0,0 @@
1
- import { JSX } from 'react';
2
- import { ReorderListProps, DivProps } from './types.js';
3
-
4
- declare function ReorderIcon({ children, style, ...props }: DivProps): JSX.Element;
5
- declare function ReorderList({ useOnlyIconToDrag, selectedItemOpacity, animationDuration, preserveOrder, onPositionChange, disabled, props, children }: ReorderListProps): JSX.Element;
6
-
7
- export { ReorderIcon, ReorderList as default };
@@ -1 +0,0 @@
1
- export { ReorderIcon, ReorderList as default } from './chunks/chunk-RWSH3ATP.js';
package/dist/index.d.ts DELETED
@@ -1,3 +0,0 @@
1
- export { ReorderIcon, default } from './components.js';
2
- import 'react';
3
- import './types.js';
package/dist/index.js DELETED
@@ -1 +0,0 @@
1
- export { ReorderIcon, ReorderList as default } from './chunks/chunk-RWSH3ATP.js';
package/dist/types.d.ts DELETED
@@ -1,49 +0,0 @@
1
- import { Key, DetailedHTMLProps, HTMLAttributes, ReactNode, ReactElement, RefObject, DragEventHandler, MouseEventHandler, TouchEventHandler, CSSProperties } from 'react';
2
-
3
- type AnimationProps = {
4
- duration: number;
5
- children: Child[];
6
- };
7
- type BoundingBox = Record<string, DOMRect>;
8
- type Child = ReactElement<{
9
- ref: RefObject<HTMLElement>;
10
- }>;
11
- type Order = Key[];
12
- type DivDragEventHandler = DragEventHandler<HTMLDivElement>;
13
- type DivMouseEventHandler = MouseEventHandler<HTMLDivElement>;
14
- type DivProps = DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>;
15
- type DivRef = RefObject<HTMLDivElement | null>;
16
- type DivTouchEventHandler = TouchEventHandler<HTMLDivElement>;
17
- type PositionChangeHandler = (event: {
18
- start: number;
19
- end: number;
20
- oldOrder: Order;
21
- newOrder: Order;
22
- revert: RevertHandler;
23
- }) => void;
24
- type ReorderItemProps = {
25
- useOnlyIconToDrag: boolean;
26
- disable?: boolean;
27
- ref: DivRef;
28
- style: CSSProperties;
29
- onDragStart?: DivDragEventHandler;
30
- onDragEnter: DivDragEventHandler;
31
- onDragEnd: DivDragEventHandler;
32
- onTouchMove: DivTouchEventHandler;
33
- onTouchEnd: DivTouchEventHandler;
34
- children: ReactNode;
35
- };
36
- type ReorderListProps = {
37
- useOnlyIconToDrag?: boolean;
38
- selectedItemOpacity?: number;
39
- animationDuration?: number;
40
- preserveOrder?: boolean;
41
- onPositionChange?: PositionChangeHandler;
42
- disabled?: boolean;
43
- props?: DivProps;
44
- children?: ReactNode;
45
- };
46
- type RevertHandler = () => void;
47
- type IconProps = React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>;
48
-
49
- export type { AnimationProps, BoundingBox, Child, DivDragEventHandler, DivMouseEventHandler, DivProps, DivRef, DivTouchEventHandler, IconProps, Order, PositionChangeHandler, ReorderItemProps, ReorderListProps, RevertHandler };
package/dist/types.js DELETED
@@ -1 +0,0 @@
1
-