@@ -3,19 +3,13 @@ import ReactDOM from 'react-dom';
33import Sortable from 'sortablejs' ;
44
55const 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'
157} ;
168
17- let _nextSibling = null ;
18- let _activeWrapperComponent = null ;
9+ const store = {
10+ nextSibling : null ,
11+ activeComponent : null
12+ } ;
1913
2014const refName = 'sortableComponent' ;
2115
@@ -39,23 +33,16 @@ const extend = (target, ...sources) => {
3933} ;
4034
4135const SortableMixin = ( options = defaultOptions ) => ( Component ) => class extends React . Component {
36+ static propTypes = {
37+ items : React . PropTypes . array . isRequired ,
38+ onChange : React . PropTypes . func . isRequired
39+ } ;
4240 state = {
4341 sortableInstance : null
4442 } ;
45-
4643 sortableOptions = extend ( { } , defaultOptions , options ) ;
47- populatedOptions = { } ;
4844
4945 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-
5946 [ // Bind callbacks
6047 'onStart' ,
6148 'onEnd' ,
@@ -65,40 +52,42 @@ const SortableMixin = (options = defaultOptions) => (Component) => class extends
6552 'onRemove' ,
6653 'onFilter' ,
6754 'onMove'
68- ] . forEach ( ( name ) => {
69- copyOptions [ name ] = ( evt ) => {
55+ ] . forEach ( name => {
56+ this . sortableOptions [ name ] = ( evt ) => {
7057 if ( name === 'onStart' ) {
71- _nextSibling = evt . item . nextElementSibling ;
72- _activeWrapperComponent = this ;
58+ store . nextSibling = evt . item . nextElementSibling ;
59+ store . activeComponent = this ;
7360 } else if ( name === 'onAdd' || name === 'onUpdate' ) {
74- evt . from . insertBefore ( evt . item , _nextSibling ) ;
61+ evt . from . insertBefore ( evt . item , store . nextSibling ) ;
7562
7663 const oldIndex = evt . oldIndex ;
7764 const newIndex = evt . newIndex ;
7865 let items = this . props . items ;
7966 let remoteItems = [ ] ;
8067
8168 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 ] ) ;
8571 } else {
8672 items . splice ( newIndex , 0 , items . splice ( oldIndex , 1 ) [ 0 ] ) ;
8773 }
8874
89- this . props . onChange ( items ) ;
75+ // Called by any change to the list (add / update / remove)
76+ this . props . onChange ( items , this . state . sortableInstance ) ;
9077
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 ) ;
9381 }
9482 }
9583
9684 setTimeout ( ( ) => {
97- emitEvent ( name , evt ) ;
85+ this . props [ name ] && this . props [ name ] ( evt , this . state . sortableInstance ) ;
9886 } , 0 ) ;
9987 } ;
10088 } ) ;
101- this . populatedOptions = copyOptions
89+
90+ const sortableComponent = this . refs [ refName ] ;
10291 this . initSortable ( sortableComponent ) ;
10392 }
10493 componentDidUpdate ( prevProps , prevState ) {
@@ -115,8 +104,8 @@ const SortableMixin = (options = defaultOptions) => (Component) => class extends
115104 initSortable ( sortableComponent ) {
116105 this . destroySortable ( ) ;
117106 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 } ) ;
120109 }
121110 destroySortable ( ) {
122111 if ( this . state . sortableInstance ) {
0 commit comments