@@ -3,19 +3,13 @@ import ReactDOM from 'react-dom';
3
3
import Sortable from 'sortablejs' ;
4
4
5
5
const defaultOptions = {
6
- ref : 'list' ,
7
- onStart : 'handleStart' ,
8
- onEnd : 'handleEnd' ,
9
- onAdd : 'handleAdd' ,
10
- onUpdate : 'handleUpdate' ,
11
- onRemove : 'handleRemove' ,
12
- onSort : 'handleSort' ,
13
- onFilter : 'handleFilter' ,
14
- onMove : 'handleMove'
6
+ ref : 'list'
15
7
} ;
16
8
17
- let _nextSibling = null ;
18
- let _activeWrapperComponent = null ;
9
+ const store = {
10
+ nextSibling : null ,
11
+ activeComponent : null
12
+ } ;
19
13
20
14
const refName = 'sortableComponent' ;
21
15
@@ -39,23 +33,16 @@ const extend = (target, ...sources) => {
39
33
} ;
40
34
41
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
+ } ;
42
40
state = {
43
41
sortableInstance : null
44
42
} ;
45
-
46
43
sortableOptions = extend ( { } , defaultOptions , options ) ;
47
- populatedOptions = { } ;
48
44
49
45
componentDidMount ( ) {
50
- const sortableComponent = this . refs [ refName ] ;
51
- const emitEvent = ( type , evt ) => {
52
- const methodName = this . sortableOptions [ type ] ;
53
- const method = sortableComponent [ methodName ] ;
54
- method && method . call ( sortableComponent , evt , this . state . sortableInstance ) ;
55
- } ;
56
-
57
- let copyOptions = extend ( { } , this . sortableOptions ) ;
58
-
59
46
[ // Bind callbacks
60
47
'onStart' ,
61
48
'onEnd' ,
@@ -65,40 +52,42 @@ const SortableMixin = (options = defaultOptions) => (Component) => class extends
65
52
'onRemove' ,
66
53
'onFilter' ,
67
54
'onMove'
68
- ] . forEach ( ( name ) => {
69
- copyOptions [ name ] = ( evt ) => {
55
+ ] . forEach ( name => {
56
+ this . sortableOptions [ name ] = ( evt ) => {
70
57
if ( name === 'onStart' ) {
71
- _nextSibling = evt . item . nextElementSibling ;
72
- _activeWrapperComponent = this ;
58
+ store . nextSibling = evt . item . nextElementSibling ;
59
+ store . activeComponent = this ;
73
60
} else if ( name === 'onAdd' || name === 'onUpdate' ) {
74
- evt . from . insertBefore ( evt . item , _nextSibling ) ;
61
+ evt . from . insertBefore ( evt . item , store . nextSibling ) ;
75
62
76
63
const oldIndex = evt . oldIndex ;
77
64
const newIndex = evt . newIndex ;
78
65
let items = this . props . items ;
79
66
let remoteItems = [ ] ;
80
67
81
68
if ( name === 'onAdd' ) {
82
- remoteItems = _activeWrapperComponent . props . items ;
83
- let item = remoteItems . splice ( oldIndex , 1 ) [ 0 ] ;
84
- items . splice ( newIndex , 0 , item ) ;
69
+ remoteItems = store . activeComponent . props . items ;
70
+ items . splice ( newIndex , 0 , remoteItems . splice ( oldIndex , 1 ) [ 0 ] ) ;
85
71
} else {
86
72
items . splice ( newIndex , 0 , items . splice ( oldIndex , 1 ) [ 0 ] ) ;
87
73
}
88
74
89
- this . props . onChange ( items ) ;
75
+ // Called by any change to the list (add / update / remove)
76
+ this . props . onChange ( items , this . state . sortableInstance ) ;
90
77
91
- if ( _activeWrapperComponent !== this ) {
92
- _activeWrapperComponent . props . onChange ( remoteItems ) ;
78
+ if ( store . activeComponent !== this ) {
79
+ const sortableInstance = store . activeComponent . state . sortableInstance ;
80
+ store . activeComponent . props . onChange ( remoteItems , sortableInstance ) ;
93
81
}
94
82
}
95
83
96
84
setTimeout ( ( ) => {
97
- emitEvent ( name , evt ) ;
85
+ this . props [ name ] && this . props [ name ] ( evt , this . state . sortableInstance ) ;
98
86
} , 0 ) ;
99
87
} ;
100
88
} ) ;
101
- this . populatedOptions = copyOptions
89
+
90
+ const sortableComponent = this . refs [ refName ] ;
102
91
this . initSortable ( sortableComponent ) ;
103
92
}
104
93
componentDidUpdate ( prevProps , prevState ) {
@@ -115,8 +104,8 @@ const SortableMixin = (options = defaultOptions) => (Component) => class extends
115
104
initSortable ( sortableComponent ) {
116
105
this . destroySortable ( ) ;
117
106
const domNode = ReactDOM . findDOMNode ( sortableComponent . refs [ this . sortableOptions . ref ] || sortableComponent ) ;
118
- const sortableInstance = Sortable . create ( domNode , this . populatedOptions ) ;
119
- this . setState ( { sortableInstance } ) ;
107
+ const sortableInstance = Sortable . create ( domNode , this . sortableOptions ) ;
108
+ this . setState ( { sortableInstance : sortableInstance } ) ;
120
109
}
121
110
destroySortable ( ) {
122
111
if ( this . state . sortableInstance ) {
0 commit comments