@lumel/react-sortable-hoc
v2.0.0
Published
Set of higher-order components to turn any list into a sortable, touch-friendly, animated list
Downloads
2,295
Readme
@lumel/react-sortable-hoc
A set of higher-order components to turn any list into an animated, accessible, and touch-friendly sortable list.
Maintenance Note: This is a fork of the original
react-sortable-hoc, specifically maintained by Lumel to provide compatibility with React 19 and resolve critical unmount/ref handling issues.
🚀 React 19 Ready (v2.0.0)
@lumel/react-sortable-hoc v2.0.0 is fully compatible with React 19. This version resolves the "Older version of React" rendering conflicts and implements safe ref handling.
⚠️ Critical Migration Requirement
If you are using functional components, you must wrap them with React.forwardRef to ensure the library can correctly attach refs for positioning calculations:
import {SortableElement} from '@lumel/react-sortable-hoc';
// ✅ CORRECT: Wrap with forwardRef and pass the ref
const SortableItem = SortableElement(
React.forwardRef((props, ref) => <li ref={ref}>{props.value}</li>),
);Features
- Higher Order Components – Integrates seamlessly with your existing components.
- Performance Focused – Optimized for smooth 60FPS animations.
- Touch Support – Built-in support for mobile and touch devices.
- Accessibility – Full support for keyboard-based sorting out of the box.
- Universal – Works with horizontal lists, vertical lists, and grids.
- Ecosystem Compatible – Tested with
react-virtualized,react-window,react-infinite, etc.
Installation
Using npm:
npm install @lumel/react-sortable-hocUsing yarn:
yarn add @lumel/react-sortable-hocBasic Usage
import React, {useState} from 'react';
import {SortableContainer, SortableElement} from '@lumel/react-sortable-hoc';
import {arrayMoveImmutable} from 'array-move';
// 1. Create your Sortable Element
const SortableItem = SortableElement(
React.forwardRef(({value}, ref) => (
<li ref={ref} className="list-item">
{value}
</li>
)),
);
// 2. Create your Sortable Container
const SortableList = SortableContainer(
React.forwardRef(({items}, ref) => (
<ul ref={ref}>
{items.map((value, index) => (
<SortableItem key={`item-${value}`} index={index} value={value} />
))}
</ul>
)),
);
// 3. Use the components
const SortableApp = () => {
const [items, setItems] = useState(['Item 1', 'Item 2', 'Item 3']);
const onSortEnd = ({oldIndex, newIndex}) => {
setItems(arrayMoveImmutable(items, oldIndex, newIndex));
};
return <SortableList items={items} onSortEnd={onSortEnd} />;
};Detailed Prop API
SortableContainer HOC
| Property | Type | Default | Description |
| :---------------- | :--------- | :------ | :------------------------------------------------------------------- |
| axis | string | 'y' | Sorting direction: 'x', 'y', or 'xy'. |
| lockAxis | string | - | Lock movement to 'x' or 'y'. |
| pressDelay | number | 0 | Delay (ms) before sorting starts (recommended for mobile: 200). |
| distance | number | 0 | Drag distance required (px) before sorting starts. |
| useDragHandle | boolean | false | Use if you're wrapping a sub-element with SortableHandle. |
| onSortStart | function | - | Callback: ({node, index, collection, isKeySorting}, event). |
| onSortEnd | function | - | Callback: ({oldIndex, newIndex, collection, isKeySorting}, event). |
| helperClass | string | - | CSS class applied to the floating helper item. |
SortableElement HOC
| Property | Type | Default | Description |
| :------------- | :----------------- | :------ | :------------------------------------------------------------- |
| index | number | - | Required. The position of the item in the collection. |
| collection | string \| number | 0 | Useful for managing multiple sortable groups in one container. |
| disabled | boolean | false | Disables sorting for this specific item. |
🛠 React 19 Migration Deep-Dive
Why is forwardRef now required?
In React 19, the underlying findDOMNode API is deprecated. To ensure high performance and accurate positioning without using deprecated APIs, the library now relies on direct ref access to the DOM elements. Wrapping your functional components in forwardRef is the way to grant the HOC access to the DOM node.
Troubleshooting "Older version of React" Errors
If you see the error "A React Element from an older version of React was rendered", ensure that your bundler (Webpack/Vite) is not including multiple copies of React.
In a monorepo, it is recommended to add a resolve alias to your bundler:
## Licensing & Contributions
Distributed under the MIT License. Contributions are welcome for bug fixes and compatibility updates.