A React component built on top of Sortable (https://github.com/SortableJS/Sortable).
npm install @timluo465/react-sortablejsbash
npm install --save react react-dom sortablejs@1.6.1 # Install peerDependencies
npm install --save react-sortablejs
`
Checkout the examples directory for a complete setup.
$3
You can create a standalone ES5 module as shown below:
`bash
$ git clone https://github.com/SortableJS/react-sortablejs.git
$ cd react-sortablejs
$ npm install
$ npm run build && npm run dist
`
Then, include these scripts into your html file:
`html
`
Use <ReactSortable /> instead of <Sortable /> in your JSX code since the Sortable library will export a window.Sortable object if you're running JSX code directly in the browser. For example:
`js
tag="ul"
onChange={(order) =>
this.props.onChange(order);
}}
>
{items}
`
Usage
File: sortable-list.jsx
`js
import uniqueId from 'lodash/uniqueId';
import React from 'react';
import Sortable from 'react-sortablejs';
// Functional Component
const SortableList = ({ items, onChange }) => {
let sortable = null; // sortable instance
const reverseOrder = (evt) => {
const order = sortable.toArray();
onChange(order.reverse());
};
const listItems = items.map(val => (List Item: {val} ));
return (
// Sortable options (https://github.com/RubaXa/Sortable#options)
options={{
}}
// [Optional] Use ref to get the sortable instance
// https://facebook.github.io/react/docs/more-about-refs.html#the-ref-callback-attribute
ref={(c) => {
if (c) {
sortable = c.sortable;
}
}}
// [Optional] A tag or react component to specify the wrapping element. Defaults to "div".
// In a case of a react component it is required to has children in the component
// and pass it down.
tag="ul"
// [Optional] The onChange method allows you to implement a controlled component and keep
// DOM nodes untouched. You have to change state to re-render the component.
// @param {Array} order An ordered array of items defined by the data-id attribute.
// @param {Object} sortable The sortable instance.
// @param {Event} evt The event object.
onChange={(order, sortable, evt) => {
onChange(order);
}}
>
{listItems}
);
};
SortableList.propTypes = {
items: React.PropTypes.array,
onChange: React.PropTypes.func
};
export default SortableList;
`
File: index.jsx
`js
import React from 'react';
import ReactDOM from 'react-dom';
import SortableList from './sortable-list';
class App extends React.Component {
state = {
items: [1, 2, 3, 4, 5, 6]
};
render() {
return (
items={this.state.items}
onChange={(items) => {
this.setState({ items });
}}
>
)
}
};
ReactDOM.render(
,
document.getElementById('container')
);
`
Examples
$3
An uncontrolled component allows Sortable to touch DOM nodes. It's useful when you don't need to maintain any state changes.
`js
import uniqueId from 'lodash/uniqueId';
import React from 'react';
import ReactDOM from 'react-dom';
import Sortable from 'react-sortablejs';
class App extends React.Component {
state = {
items: ['Apple', 'Banana', 'Cherry', 'Guava', 'Peach', 'Strawberry']
};
render() {
const items = this.state.items.map(val => ({val} ));
return (
tag="ul" // Defaults to "div"
>
{items}
);
}
}
ReactDOM.render(
,
document.getElementById('container')
);
`
$3
A controlled component will keep DOM nodes untouched. You have to change state to re-render the component.
`js
import uniqueId from 'lodash/uniqueId';
import React from 'react';
import ReactDOM from 'react-dom';
import Sortable from 'react-sortablejs';
class App extends React.Component {
state = {
items: ['Apple', 'Banana', 'Cherry', 'Guava', 'Peach', 'Strawberry']
};
render() {
const items = this.state.items.map(val => ({val} ));
return (
tag="ul" // Defaults to "div"
onChange={(order, sortable, evt) => {
this.setState({ items: order });
}}
>
{items}
);
}
}
ReactDOM.render(
,
document.getElementById('container')
);
`
$3
An example of using the group option to drag elements from one list into another.
File: shared-group.jsx
`js
import uniqueId from 'lodash/uniqueId';
import React from 'react';
import Sortable from 'react-sortablejs';
// Functional Component
const SharedGroup = ({ items }) => {
items = items.map(val => ({val} ));
return (
// See all Sortable options at https://github.com/RubaXa/Sortable#options
options={{
group: 'shared'
}}
tag="ul"
>
{items}
);
};
export default SharedGroup;
`
File: index.jsx
`js
import React from 'react';
import ReactDOM from 'react-dom';
import SharedGroup from './shared-group';
const App = (props) => {
return (
items={['Apple', 'Banana', 'Cherry', 'Grape']}
/>
items={['Lemon', 'Orange', 'Pear', 'Peach']}
/>
);
};
ReactDOM.render( , document.getElementById('container'));
``