A Draggable tree component for react
react-draggable-tree
Draggable tree for react.
installation
npm install -S @feizheng/react-draggable-tree
update
npm update @feizheng/react-draggable-tree
properties
Name | Type | Required | Default | Description |
---|---|---|---|---|
className | string | false | - | The extended className for component. |
items | array | false | - | The data source. |
onChange | func | false | noop | The change handler. |
onInit | func | false | noop | The handler when sortable initialize. |
template | func | true | - | Item template. |
itemsKey | union | false | 'children' | Child item key. |
options | object | false | - | The core sortable component options (@sortable: https://github.com/SortableJS/Sortable). |
usage
- import css
@import "~@feizheng/react-draggable-tree/dist/style.scss";
// customize your styles:
$react-draggable-tree-options: ()
- import js
import React from 'react';
import ReactDOM from 'react-dom';
import ReactDraggableTree from '@feizheng/react-draggable-tree';
import dataJson from './assets/index.json';
import leveledJson from './assets/level-grouped.json';
import stdJson from './assets/std.json';
import './assets/style.scss';
import Helper from './helper';
class App extends React.Component {
state = {
items2: dataJson.data,
stdItems: stdJson.data,
leveledItems: leveledJson.data,
items: [
{
icon: 'm1-icon',
label: 'Menu1',
value: 'm1',
children: [
{
icon: 'm1-1-icon',
label: 'Menu1-1',
value: 'm1-1',
children: [
{
icon: 'm1-1-1-icon',
label: 'Menu-1-1',
value: 'm1-1-1'
},
{
icon: 'm1-1-2-icon',
label: 'Menu-1-2',
value: 'm1-1-2'
}
]
}
]
},
{
icon: 'm2-icon',
label: 'Menu2',
value: 'm2',
children: []
},
{
icon: 'mxx-icon',
label: '-',
value: '-',
children: []
},
{
disabled: false,
icon: 'm3-icon',
label: 'Menu3',
value: 'm3',
children: []
}
]
};
template = ({ item, independent, sortable }, cb) => {
// 这里的逻辑,直接决定了 children 下面可不可以继续加入元素。
if (!item.children) {
return (
<li key={item.value} className="is-node is-leaf">
<label className={'is-label'}>{item.label}</label>
</li>
);
} else {
return (
<li key={item.value} className={'is-node'}>
<label className="is-label">{item.label}</label>
<ul className="is-nodes nested-sortable" ref={sortable}>
{cb()}
</ul>
</li>
);
}
};
template2 = ({ item, independent, sortable }, cb) => {
if (independent) {
return (
<div key={item.uuid} className="is-node is-leaf">
<span className={'is-label'}>{item.name}</span>
<strong className="is-handle">≡</strong>
</div>
);
} else {
return (
<details key={item.uuid} className={'is-node'} open>
<summary>
<span className="is-label">{item.name}</span>
<strong className="is-handle">≡</strong>
</summary>
<ul className="is-nodes" ref={sortable}>
{cb()}
</ul>
</details>
);
}
};
template3 = ({ item, independent, sortable }, cb) => {
if (independent) {
return (
<div key={item.uuid} className="is-node is-leaf">
<span className={'is-label'}>
{item.name}-level: {item.level}
</span>
<strong className="is-handle">≡</strong>
</div>
);
} else {
return (
<details key={item.uuid} className={'is-node'} open>
<summary>
<span className="is-label">{item.name}</span>
<strong className="is-handle">≡</strong>
</summary>
<ul
className="is-nodes"
ref={(dom) => {
return sortable(dom, { group: item.level });
}}>
{cb()}
</ul>
</details>
);
}
};
render() {
const leveledItems = Helper.to(this.state.leveledItems);
return (
<div className="app-container">
<h3>Sort only children:</h3>
<ReactDraggableTree
template={this.template}
items={this.state.items}
onChange={(e) => {
console.log(e.target.value);
}}
/>
<h3>Sort only children - disabled:</h3>
<ReactDraggableTree
template={this.template}
items={this.state.items}
disabled
/>
<hr />
<h3>Sort with grouped:</h3>
<ReactDraggableTree
template={this.template}
items={this.state.items}
options={{ group: 'abcd' }}
onChange={(e) => {
// console.log(JSON.stringify(e.target.value, null, 2));
}}
/>
<hr />
<h3>Sort with itemsKey children:</h3>
<ReactDraggableTree
template={this.template2}
items={this.state.stdItems}
options={{ group: 'abced', handle: '.is-handle' }}
onChange={(e) => {
console.log(e.target.value);
// console.log(JSON.stringify(e.target.value, null, 2));
}}
/>
<hr />
<h3>Sort with external options:</h3>
<ReactDraggableTree
template={this.template3}
items={leveledItems}
options={{ group: 'abcedfg', handle: '.is-handle' }}
onChange={(e) => {
console.log(e.target.value);
// console.log(JSON.stringify(e.target.value, null, 2));
}}
onInit={(e) => {
console.log(e.target.value);
}}
/>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('app'));