1
1
import {
2
+ Children ,
3
+ cloneElement ,
2
4
Component ,
3
5
createElement ,
4
6
createRef ,
5
- ReactNode ,
7
+ ReactElement ,
6
8
RefObject
7
9
} from "react" ;
8
- import Sortable , { MoveEvent , Options , SortableEvent } from "sortablejs" ;
10
+ import Sortable , { MoveEvent , Options , SortableEvent , Swap } from "sortablejs" ;
9
11
import {
10
12
AllMethodsExceptMove ,
11
13
HandledMethodNames ,
12
14
ReactSortableProps ,
13
15
Store ,
14
- UnHandledMethodNames
16
+ UnHandledMethodNames ,
17
+ ItemInterface
15
18
} from "./types" ;
16
- import {
17
- destructurePropsForOptions ,
18
- insertNodeAt ,
19
- modifyChildren ,
20
- removeNode
21
- } from "./util" ;
19
+ import { destructurePropsForOptions , insertNodeAt , removeNode } from "./util" ;
22
20
23
21
/** Holds a global reference for which react element is being dragged */
24
22
const store : Store = { dragging : null } ;
25
-
26
- export class ReactSortable < T > extends Component < ReactSortableProps < T > > {
23
+ /**
24
+ * React is built for synchornizing data with the browser.
25
+ *
26
+ * Data should be an object.
27
+ */
28
+ export class ReactSortable < T extends ItemInterface > extends Component <
29
+ ReactSortableProps < T >
30
+ > {
27
31
private ref : RefObject < HTMLElement > ;
28
32
29
33
static defaultProps : Partial < ReactSortableProps < any > > = {
@@ -35,17 +39,18 @@ export class ReactSortable<T> extends Component<ReactSortableProps<T>> {
35
39
super ( props ) ;
36
40
/** @todo forward ref this component */
37
41
this . ref = createRef < HTMLElement > ( ) ;
42
+ const { plugins } = props ;
43
+ // mount plugins if any
44
+ if ( plugins ) {
45
+ if ( plugins instanceof Array ) Sortable . mount ( ...plugins ) ;
46
+ else Sortable . mount ( plugins ) ;
47
+ }
38
48
}
39
49
40
50
componentDidMount ( ) {
41
51
if ( this . ref . current === null ) return ;
42
52
const newOptions = this . makeOptions ( ) ;
43
53
Sortable . create ( this . ref . current , newOptions ) ;
44
- // mount plugins if any
45
- const { plugins } = this . props ;
46
- if ( ! plugins ) return ;
47
- if ( plugins instanceof Array ) Sortable . mount ( ...plugins ) ;
48
- else Sortable . mount ( plugins ) ;
49
54
}
50
55
51
56
render ( ) {
@@ -54,15 +59,40 @@ export class ReactSortable<T> extends Component<ReactSortableProps<T>> {
54
59
55
60
/** if no tag, default to a `div` element */
56
61
const newTag = ! tag || tag === null ? "div" : tag ;
57
- const newChildren : ReactNode = modifyChildren ( this . props ) ;
58
62
return createElement (
59
63
newTag ,
60
64
{
61
65
/** @todo find a way (perhaps with the callback) to allow AntD components to work */
62
66
ref : this . ref ,
63
67
...classicProps
64
68
} ,
65
- newChildren
69
+ this . getChildren ( )
70
+ ) ;
71
+ }
72
+
73
+ // dev provides the class names and the app will asign them do the dom properly
74
+ private getChildren ( ) {
75
+ const {
76
+ children,
77
+ dataIdAttr,
78
+ selectedClass,
79
+ chosenClass,
80
+ dragClass,
81
+ fallbackClass,
82
+ ghostClass,
83
+ swapClass
84
+ } = this . props ;
85
+
86
+ // if no children, don't do anything.
87
+ if ( ! children || children == null ) return null ;
88
+
89
+ const dataid = dataIdAttr || "data-id" ;
90
+ const className = "" ;
91
+
92
+ return Children . map ( children as ReactElement < any > [ ] , child =>
93
+ cloneElement ( child , {
94
+ [ dataid ] : child . key
95
+ } )
66
96
) ;
67
97
}
68
98
@@ -73,10 +103,16 @@ export class ReactSortable<T> extends Component<ReactSortableProps<T>> {
73
103
const key = Object . keys ( el ) . find ( k => k . includes ( "Sortable" ) ) ;
74
104
if ( ! key ) return null ;
75
105
//@ts -ignore - I know what I'm doing.
76
- return el [ key ] ;
106
+ return el [ key ] as Sortable ;
77
107
}
78
108
79
- /** Converts all the props from `ReactSortable` into the `options` object that `Sortable.create(el, [options])` can use. */
109
+ /** const { plugins } = props;
110
+ // mount plugins if any
111
+ if (plugins) {
112
+ if (plugins instanceof Array) Sortable.mount(...plugins);
113
+ else Sortable.mount(plugins);
114
+ }
115
+ }Converts all the props from `ReactSortable` into the `options` object that `Sortable.create(el, [options])` can use. */
80
116
makeOptions ( ) : Options {
81
117
const DOMHandlers : HandledMethodNames [ ] = [
82
118
"onAdd" ,
@@ -167,7 +203,6 @@ export class ReactSortable<T> extends Component<ReactSortableProps<T>> {
167
203
const [ oldItem ] = newState . splice ( oldIndex ! , 1 ) ;
168
204
const newItem = this . props . clone ! ( oldItem , evt ) ;
169
205
170
- console . log ( { oldItem, newItem } ) ;
171
206
newState . splice ( oldIndex ! , 0 , newItem ) ;
172
207
setList ( newState , this . sortable , store ) ;
173
208
return ;
@@ -212,6 +247,8 @@ export class ReactSortable<T> extends Component<ReactSortableProps<T>> {
212
247
213
248
/** @todo */
214
249
onSelect ( evt : SortableEvent ) {
250
+ const { oldIndex, newIndex } = evt ;
251
+ console . log ( { oldIndex, newIndex } ) ;
215
252
// append the class name the classes of the item
216
253
// do it on the item?
217
254
// a seperate state?
0 commit comments