@@ -2,48 +2,18 @@ import React from 'react';
22import ReactDOM from 'react-dom' ;
33import Sortable from 'sortablejs' ;
44
5- const defaultOptions = {
6- ref : 'list'
7- } ;
8-
9- const store = {
5+ const store = {
106 nextSibling : null ,
117 activeComponent : null
128} ;
139
14- const refName = 'sortableComponent' ;
15-
16- const extend = ( target , ...sources ) => {
17- if ( target === undefined || target === null ) {
18- throw new TypeError ( 'Cannot convert undefined or null to object' ) ;
19- }
20-
21- const output = Object ( target ) ;
22- for ( let index = 0 ; index < sources . length ; index ++ ) {
23- const source = sources [ index ] ;
24- if ( source !== undefined && source !== null ) {
25- for ( let key in source ) {
26- if ( source . hasOwnProperty ( key ) ) {
27- output [ key ] = source [ key ] ;
28- }
29- }
30- }
31- }
32- return output ;
33- } ;
34-
35- const SortableMixin = ( options = defaultOptions ) => ( Component ) => class extends React . Component {
36- static propTypes = {
37- items : React . PropTypes . array . isRequired ,
38- onChange : React . PropTypes . func . isRequired
39- } ;
40- state = {
41- sortableInstance : null
42- } ;
43- sortableOptions = extend ( { } , defaultOptions , options ) ;
10+ export default class extends React . Component {
11+ sortable = null ;
4412
4513 componentDidMount ( ) {
46- [ // Bind callbacks
14+ const { children, className, ...options } = this . props ;
15+
16+ [
4717 'onStart' ,
4818 'onEnd' ,
4919 'onAdd' ,
@@ -52,76 +22,43 @@ const SortableMixin = (options = defaultOptions) => (Component) => class extends
5222 'onRemove' ,
5323 'onFilter' ,
5424 'onMove'
55- ] . forEach ( name => {
56- const eventHandler = this . sortableOptions [ name ] ;
25+ ] . forEach ( ( name ) => {
26+ const eventHandler = options [ name ] ;
5727
58- this . sortableOptions [ name ] = ( evt ) => {
28+ options [ name ] = ( evt ) => {
5929 if ( name === 'onStart' ) {
6030 store . nextSibling = evt . item . nextElementSibling ;
6131 store . activeComponent = this ;
62- } else if ( name === 'onAdd' || name === 'onUpdate' ) {
63- evt . from . insertBefore ( evt . item , store . nextSibling ) ;
32+ } else if ( ( name === 'onAdd' || name === 'onUpdate' ) && this . props . onChange ) {
33+ const items = this . sortable . toArray ( ) ;
34+ const remote = store . activeComponent ;
35+ const remoteItems = remote . sortable . toArray ( ) ;
6436
65- const oldIndex = evt . oldIndex ;
66- const newIndex = evt . newIndex ;
67- let items = this . props . items ;
68- let remoteItems = [ ] ;
69-
70- if ( name === 'onAdd' ) {
71- remoteItems = store . activeComponent . props . items ;
72- items . splice ( newIndex , 0 , remoteItems . splice ( oldIndex , 1 ) [ 0 ] ) ;
73- } else {
74- items . splice ( newIndex , 0 , items . splice ( oldIndex , 1 ) [ 0 ] ) ;
37+ evt . from . insertBefore ( evt . item , store . nextSibling ) ;
38+
39+ if ( remote !== this && remote . props . group && remote . props . group . pull === 'clone' ) {
40+ // Remove the node with the same data-reactid
41+ evt . item . parentNode . removeChild ( evt . item ) ;
7542 }
7643
77- // Called by any change to the list (add / update / remove)
78- this . props . onChange ( items , this . state . sortableInstance ) ;
44+ this . props . onChange && this . props . onChange ( items , this . sortable ) ;
7945
80- if ( store . activeComponent !== this ) {
81- const sortableInstance = store . activeComponent . state . sortableInstance ;
82- store . activeComponent . props . onChange ( remoteItems , sortableInstance ) ;
46+ if ( remote !== this ) {
47+ remote . props . onChange && remote . props . onChange ( remoteItems , remote . sortable ) ;
8348 }
8449 }
8550
8651 setTimeout ( ( ) => {
87- // Event handler props
88- this . props [ name ] && this . props [ name ] ( evt , this . state . sortableInstance ) ;
89-
90- // Event handler options
91- eventHandler && eventHandler ( evt , this . state . sortableInstance ) ;
52+ eventHandler && eventHandler ( evt ) ;
9253 } , 0 ) ;
93- } ;
54+ }
9455 } ) ;
9556
96- const sortableComponent = this . refs [ refName ] ;
97- this . initSortable ( sortableComponent ) ;
98- }
99- componentDidUpdate ( prevProps , prevState ) {
100- if ( this . props . items !== prevProps . items ) {
101- this . initSortable ( this . refs [ refName ] ) ;
102- }
103- }
104- componentWillUnmount ( ) {
105- this . destroySortable ( ) ;
57+ this . sortable = Sortable . create ( ReactDOM . findDOMNode ( this ) , options ) ;
10658 }
107- initSortable ( sortableComponent ) {
108- this . destroySortable ( ) ;
109- const domNode = ReactDOM . findDOMNode ( sortableComponent . refs [ this . sortableOptions . ref ] || sortableComponent ) ;
110- const sortableInstance = Sortable . create ( domNode , this . sortableOptions ) ;
111- this . setState ( { sortableInstance : sortableInstance } ) ;
112- }
113- destroySortable ( ) {
114- if ( this . state . sortableInstance ) {
115- this . state . sortableInstance . destroy ( ) ;
116- this . setState ( { sortableInstance : null } ) ;
117- }
118- }
119-
12059 render ( ) {
12160 return (
122- < Component ref = { refName } { ... this . props } { ... this . state } / >
61+ < div className = { this . props . className } > { this . props . children } </ div >
12362 ) ;
12463 }
125- } ;
126-
127- export default SortableMixin ;
64+ }
0 commit comments