Socket
Socket
Sign inDemoInstall

react-reorder-list

Package Overview
Dependencies
5
Maintainers
1
Versions
26
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.2.1 to 0.3.0

18

dist/animation.js

@@ -1,2 +0,2 @@

import React, { useState, useLayoutEffect, Children, isValidElement, useEffect, useRef } from "react";
import React, { useState, useLayoutEffect, Children, useEffect, useRef } from "react";
function usePrevious(value) {

@@ -10,6 +10,3 @@ const prevChildrenRef = useRef();

const boundingBoxes = {};
Children.forEach(children, (child, i) => {
if (isValidElement(child))
boundingBoxes[child.key || i] = child.ref.current.getBoundingClientRect();
});
Children.forEach(children, child => boundingBoxes[child.key.split("/.")[0]] = child.ref.current.getBoundingClientRect());
return boundingBoxes;

@@ -27,8 +24,7 @@ }

if (prevBoundingBox && Object.keys(prevBoundingBox).length)
Children.forEach(children, (child, i) => {
if (!isValidElement(child))
return;
Children.forEach(children, child => {
const domNode = child.ref.current;
const { left: prevLeft, top: prevTop } = prevBoundingBox[child.key || i];
const { left, top } = boundingBox[child.key || i];
const key = child.key.split("/.")[0];
const { left: prevLeft, top: prevTop } = prevBoundingBox[key] || {};
const { left, top } = boundingBox[key];
const changeInX = prevLeft - left, changeInY = prevTop - top;

@@ -50,3 +46,3 @@ if (changeInX || changeInY)

export default function Animation({ duration, children }) {
return duration ? React.createElement(Animate, { duration: duration }, children) : children;
return duration > 0 ? React.createElement(Animate, { duration: duration }, children) : children;
}

@@ -1,2 +0,2 @@

import React, { DetailedHTMLProps, HTMLAttributes, ReactNode } from 'react';
import React, { DetailedHTMLProps, HTMLAttributes, ReactNode } from "react";
export type Props = DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>;

@@ -13,2 +13,3 @@ export type PositionChangeHandler = (params?: {

animationDuration?: number;
watchChildrenUpdates: boolean;
onPositionChange?: PositionChangeHandler;

@@ -20,3 +21,3 @@ disable?: boolean;

export type { IconProps } from './icons.js';
export default function ReorderList({ useOnlyIconToDrag, selectedItemOpacity, animationDuration, onPositionChange, disable, props, children }: ReorderListProps): React.JSX.Element;
export default function ReorderList({ useOnlyIconToDrag, selectedItemOpacity, animationDuration, watchChildrenUpdates, onPositionChange, disable, props, children }: ReorderListProps): React.JSX.Element;
export declare const ReorderIcon: ({ children, style, ...props }: Props) => React.JSX.Element;

@@ -12,32 +12,33 @@ var __rest = (this && this.__rest) || function (s, e) {

};
import React, { Children, cloneElement, createRef, forwardRef, isValidElement, useMemo, useRef, useState } from 'react';
import { PiDotsSixVerticalBold } from './icons.js';
import Animation from './animation.js';
const ReorderItem = forwardRef(({ useOnlyIconToDrag, draggable, style, onDragStart, onDragEnter, onDragEnd, onPointerEnter, onPointerLeave, children }, ref) => {
const props = draggable ? { draggable, onDragStart, onDragEnter, onDragEnd } : {};
const recursiveClone = (children) => Children.map(children, child => {
if (!isValidElement(child))
return child;
const childProps = {};
if (useOnlyIconToDrag && child.type.name === 'ReorderIcon') {
childProps.onPointerEnter = onPointerEnter;
childProps.onPointerLeave = onPointerLeave;
}
return cloneElement(child, Object.assign({ children: recursiveClone(child.props.children) }, childProps));
});
const recursiveChildren = useMemo(() => recursiveClone(children), [children]);
return React.createElement("div", Object.assign({ ref: ref, style: style }, props), recursiveChildren);
});
export default function ReorderList({ useOnlyIconToDrag = false, selectedItemOpacity = 0.5, animationDuration = 400, onPositionChange, disable = false, props, children }) {
const ref = useRef();
const [draggable, setDraggable] = useState(!useOnlyIconToDrag);
import React, { Children, cloneElement, createRef, forwardRef, isValidElement, useEffect, useMemo, useRef, useState } from "react";
import { PiDotsSixVerticalBold } from "./icons.js";
import Animation from "./animation.js";
const ReorderItemRef = forwardRef(ReorderItem);
export default function ReorderList({ useOnlyIconToDrag = false, selectedItemOpacity = 0.5, animationDuration = 400, watchChildrenUpdates = false, onPositionChange, disable = false, props, children }) {
const ref = useRef(null);
const [draggable, setDraggable] = useState(false);
const [start, setStart] = useState(-1);
const [selected, setSelected] = useState(-1);
const [items, setItems] = useState(children);
const [items, setItems] = useState(Children.toArray(children));
const [temp, setTemp] = useState({});
const [isAnimating, setIsAnimating] = useState(false);
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;
useEffect(() => {
if (!watchChildrenUpdates)
return;
const items = [];
const newItems = [];
Children.forEach(children, child => {
var _a;
const index = findIndex((_a = child === null || child === void 0 ? void 0 : child.key) !== null && _a !== void 0 ? _a : child === null || child === void 0 ? void 0 : child.toString());
if (index === -1)
newItems.push(child);
else
items[index] = child;
});
setItems(items.filter(item => item !== undefined).concat(newItems));
}, [children]);
return React.createElement("div", Object.assign({ ref: ref }, props), disable ? children : React.createElement(Animation, { duration: +draggable && animationDuration }, Children.map(items, (child, i) => {
if (!isValidElement(child))
return child;
return React.createElement(ReorderItem, { key: child.key || i, ref: createRef(), useOnlyIconToDrag: useOnlyIconToDrag, draggable: draggable, style: { opacity: selected === i ? selectedItemOpacity : 1 }, onDragStart: event => {
var _a;
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: createRef(), useOnlyIconToDrag: useOnlyIconToDrag, draggable: draggable, style: { opacity: selected === i ? selectedItemOpacity : 1 }, onDragStart: event => {
event.stopPropagation();

@@ -72,2 +73,15 @@ setStart(i);

}
function ReorderItem({ useOnlyIconToDrag, draggable, style, onDragStart, onDragEnter, onDragEnd, onPointerEnter, onPointerLeave, children }, ref) {
let props = useOnlyIconToDrag ? {} : { onPointerEnter, onPointerLeave };
if (draggable)
props = Object.assign(Object.assign({}, props), { draggable, onDragStart, onDragEnter, onDragEnd });
const recursiveClone = (children) => Children.map(children, child => {
if (!isValidElement(child))
return child;
const childProps = useOnlyIconToDrag && child.type.name === 'ReorderIcon' ? { onPointerEnter, onPointerLeave } : {};
return cloneElement(child, Object.assign({ children: recursiveClone(child.props.children) }, childProps));
});
const recursiveChildren = useMemo(() => recursiveClone(children), [children]);
return React.createElement("div", Object.assign({ ref: ref, style: style }, props), recursiveChildren);
}
export const ReorderIcon = (_a) => {

@@ -74,0 +88,0 @@ var { children = React.createElement(PiDotsSixVerticalBold, null), style } = _a, props = __rest(_a, ["children", "style"]);

{
"name": "react-reorder-list",
"version": "0.2.1",
"version": "0.3.0",
"description": "A simple react component that facilitates the reordering of JSX/HTML elements through drag-and-drop functionality, allowing for easy position changes.",

@@ -5,0 +5,0 @@ "type": "module",

@@ -6,3 +6,4 @@ # react-reorder-list

- Easy to use
- Fully Customizable
- Smooth transition using animation.
- Listen to children updates. See [listen to children updates](#listen-to-children-updates)
- Handles nested lists easily. See [nested list usage](#nested-list-usage)

@@ -38,3 +39,3 @@ ## Installation

{/* Having a unique key is important */}
return <div key={i}>{i}</div>
return <div key={i}>Item {i}</div>
})}

@@ -68,2 +69,36 @@ </ReorderList>

```
#### Listen to Children Updates
`<ReorderList>` can listen to updates to it's children components using the `watchChildrenUpdates` prop as shown below.
If set to `true`, updates to children like state changes, additions/omissions of children components will reflect in real time.
If set to `false`, any updates made in children component except reordering won't reflect.
```jsx
import React, { useState } from 'react'
import ReorderList from 'react-reorder-list'
export default function App() {
const [array, setArray] = useState([0, 1, 2, 3, 4])
function setNewArray() {
setArray(prev => {
const array = []
prev.forEach(_ => {
do {
var item = Math.floor(Math.random() * 9)
} while (array.includes(item))
array.push(item)
})
return array
})
}
return <div>
<ReorderList watchChildrenUpdates={true} animationDuration={200}>
{array.map(i => <div key={i}>Item {i}</div>)}
</ReorderList>
<button onClick={setNewArray}>Click me</button>
</div>
}
```
#### Nested List Usage

@@ -99,5 +134,6 @@ ```jsx

| `selectedItemOpacity` | `Number (0 to 1)` | No | 0.5 | This determines the opacity of the item being dragged, until released. |
| `animationDuration` | `Number` | No | 400 | The duration of swapping animation between items. If set to 0, animation will be disabled. |
| `animationDuration` | `Number` | No | 400 | The duration (in ms) of swapping animation between items. If set to 0, animation will be disabled. |
| `watchChildrenUpdates` | `Boolean` | No | false | Enable this to listen to any updates in children of `<ReorderList>` and update the state accordingly. See [listen to children updates](#listen-to-children-updates) |
| `onPositionChange` | [`PositionChangeHandler`](#positionchangehandler) | No | - | Function to be executed on item position change. |
| `disable` | `Boolean` | No | false | When set to true, `ReorderList` will work as a plain `div` with no functionality. |
| `disable` | `Boolean` | No | false | When set to true, `<ReorderList>` will work as a plain `div` with no functionality. |
| `props` | `React.DetailedHTMLProps` | No | - | Props to customize the `<ReorderList>` component. |

@@ -104,0 +140,0 @@ ### Types

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc