@@ -8,11 +8,14 @@ Consider trying it out if you had any troubles earlier.
8
8
9
9
## Things still to do.
10
10
11
- We've released version 2.0,
11
+ We've released version 2.0 but there are still some things to do. We needed public feedback and a major release was the easiest way to get it.
12
12
13
13
- [x] Create examples from [ SortableJS Examples] ( https://sortablejs.github.io/Sortable/ )
14
- - [ ] Create all tests for examples (for 'ron)
15
- - Currently weve got a few.
14
+ - [ ] Examples with code underneath.
15
+ - [ ] List Props in readme.
16
+ - [ ] Allow React to manage class names. Halfway there.
17
+ - [x] Write docs for plugins
18
+ - [ ] Create all tests for examples (for 'ron). Started
16
19
- [ ] Test the following UI component libraries:
17
20
- [x] Styled Components
18
21
- [ ] AntD
@@ -22,6 +25,40 @@ We've released version 2.0,
22
25
- [ ] React Toolbox
23
26
- [ ] Your suggestion? :)
24
27
28
+
29
+ ## Table of Contents
30
+ <!-- START doctoc generated TOC please keep comment here to allow auto update -->
31
+ <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
32
+
33
+
34
+ - [ Features] ( #features )
35
+ - [ SortableJS] ( #sortablejs )
36
+ - [ Component Specific] ( #component-specific )
37
+ - [ Installation] ( #installation )
38
+ - [ Learn] ( #learn )
39
+ - [ Usage/Examples] ( #usageexamples )
40
+ - [ Function Component] ( #function-component )
41
+ - [ Class Component] ( #class-component )
42
+ - [ Plugins] ( #plugins )
43
+ - [ Sortable API] ( #sortable-api )
44
+ - [ React API] ( #react-api )
45
+ - [ id, className, style] ( #id-classname-style )
46
+ - [ list] ( #list )
47
+ - [ setList] ( #setlist )
48
+ - [ clone] ( #clone )
49
+ - [ tag] ( #tag )
50
+ - [ HTML Element] ( #html-element )
51
+ - [ Custom Component] ( #custom-component )
52
+ - [ How does it work?] ( #how-does-it-work )
53
+ - [ Caveats / Gotchas] ( #caveats--gotchas )
54
+ - [ ` key !== index ` ] ( #key--index )
55
+ - [ Nesting] ( #nesting )
56
+ - [ Problem] ( #problem )
57
+ - [ What does work?] ( #what-does-work )
58
+ - [ Solutions] ( #solutions )
59
+
60
+ <!-- END doctoc generated TOC please keep comment here to allow auto update -->
61
+
25
62
## Features
26
63
27
64
### SortableJS
@@ -43,16 +80,23 @@ If you find any features lacking, create an issue and/or pull request.
43
80
## Installation
44
81
45
82
``` shell
46
- npm install --save react-sortablejs-typescript
83
+ npm install --save react-sortablejs
47
84
# OR
48
- yarn add react-sortablejs-typescript
85
+ yarn add react-sortablejs
49
86
```
50
87
51
- ## What you should endeavour to know.
88
+ Please note that ` sortablejs ` is not required, as it's bundled in this component.
89
+
90
+ ## Learn
91
+
92
+ Here is the TLDR of what sortable is:
52
93
53
- - Explore the [ Sortable Options API] ( https://github.com/SortableJS/Sortable#options )
54
- - Array.map
55
- - React.forwardRef
94
+ ``` md
95
+ - Shopping List: # list of items / sortable. This represents `react-sortablejs`
96
+ - eggs # list item. These are all the items in the list and is what you move around.
97
+ - bread # list item
98
+ - milk # list item
99
+ ```
56
100
57
101
## Usage/Examples
58
102
@@ -112,34 +156,37 @@ export class BasicClass extends Component<{}, BasicClassState> {
112
156
}
113
157
```
114
158
115
- ### ReactSortable renders a ` div ` as the parent by default.
159
+ ## Plugins
116
160
117
- ReactSortable is a ` div ` element by default. This can be changed to be any HTML element (for example ` ul ` , ` ol ` )
118
- or can be a React component.
161
+ Sortable has some pretty cool pplugins such as MultiDrag and Swap.
119
162
120
- This value, be the component or the HTML element should be passed down under ` props.tag ` .
163
+ By Default:
121
164
122
- Let's explore both here.
165
+ - AutoScroll is premounted and enabled.
166
+ - OnSpill is premounted and NOT enabled.
167
+ - MultiDrag and Swap and NOT premounted and NOT enabled
123
168
124
- #### HTML Element
125
-
126
- Here we will use a ` ul ` . You can use any HTML.
127
- Just add the string and ReactSortable will use a ` li ` instead of a ` div ` .
169
+ You must mount mount the plugin with sortable ** ONCE ONLY** .
128
170
129
171
``` tsx
130
- import React , { FC , useState , forwardRef } from " react" ;
131
- import { ReactSortable } from " react-sortablejs-typescript " ;
172
+ import React from " react" ;
173
+ import { ReactSortable , Sortable , MultiDrag , Swap } from " react-sortablejs" ;
132
174
133
- interface ItemType {
134
- id: string ;
135
- name: string ;
136
- }
175
+ // mount whatever plugins you'd like to. These are the only current options.
176
+ Sortable .mount (new MultiDrag (), new Swap ());
137
177
138
- export const BasicFunction: FC = props => {
139
- const [state, setState] = useState <ItemType []>([{ id: " 1" , name: " shrek" }]);
178
+ const App = () => {
179
+ const [state, setState] = useState ([
180
+ { id: 1 , name: " shrek" },
181
+ { id: 2 , name: " fiona" }
182
+ ]);
140
183
141
184
return (
142
- <ReactSortable tag = " ul" list = { state } setList = { setState } >
185
+ <ReactSortable
186
+ multiDrag // enables mutidrag
187
+ // OR
188
+ swap // enables swap
189
+ >
143
190
{ state .map (item => (
144
191
<div key = { item .id } >{ item .name } </div >
145
192
))}
@@ -148,44 +195,41 @@ export const BasicFunction: FC = props => {
148
195
};
149
196
```
150
197
151
- #### Custom Component
152
-
153
- When using a custom component in the ` tag ` prop, the only component it allows is a ` forwardRef ` component.
154
-
155
- #### Solution
198
+ ## Sortable API
156
199
157
- If it doesn't have one, you can add one using ` React.forwardRef() ` .
158
- This fantastic API allows the ref to be visible when creating components.
159
-
160
- Use this when third party UI libraries.
200
+ For a comprehensive list of options, please visit https://github.com/SortableJS/Sortable#options .
161
201
162
- ** NOTE:** You may experience inconsistencies with this until we launch the proper version.
163
-
164
- > todo: Some third party UI components may have nested elements to create the look they're after.
165
- > This could be an issue and not sure how to fix.
202
+ Those options are applied as follows.
166
203
167
204
``` tsx
168
- import React , { FC , useState , forwardRef } from " react" ;
169
- import { ReactSortable } from " react-sortablejs-typescript" ;
205
+ Sortable .create (element , {
206
+ group: " groupName" ,
207
+ animation: 200 ,
208
+ delayOnTouchStart: true ,
209
+ delay: 2
210
+ });
170
211
171
- interface ItemType {
172
- id: string ;
173
- name: string ;
174
- }
212
+ // --------------------------
213
+ // Will now be..
214
+ // --------------------------
175
215
176
- // This is just like a normal component, but the
177
- const CustomComponent = forwardRef <HTMLDivElement , any >((props , ref ) => {
178
- return <div ref = { ref } >{ props .children } </div >;
179
- });
216
+ import React from " react" ;
217
+ import { ReactSortable } from " react-sortablejs" ;
180
218
181
- export const BasicFunction : FC = props => {
182
- const [state, setState] = useState < ItemType []> ([
219
+ const App = () => {
220
+ const [state, setState] = useState ([
183
221
{ id: 1 , name: " shrek" },
184
222
{ id: 2 , name: " fiona" }
185
223
]);
186
224
187
225
return (
188
- <ReactSortable tag = { CustomComponent } list = { state } setList = { setState } >
226
+ <ReactSortable
227
+ // here they are!
228
+ group = " groupName"
229
+ animation = { 200 }
230
+ delayOnTouchStart = { true }
231
+ delay = { 2 }
232
+ >
189
233
{ state .map (item => (
190
234
<div key = { item .id } >{ item .name } </div >
191
235
))}
@@ -194,84 +238,98 @@ export const BasicFunction: FC = props => {
194
238
};
195
239
```
196
240
197
- ## How does it work?
241
+ ## React API
198
242
199
- Sortable affects the DOM, adding, and removing nodes/css when it needs to in order to achieve the smooth transitions we all know an love.
200
- This component reverses many of it's actions of the DOM so React can handle this when the state changes.
243
+ ### id, className, style
201
244
202
- ## Caveats / Gotchas
245
+ Thes are all defaults DOM attributes. Nothing special here.
203
246
204
- ### ` key !== index `
247
+ ### list
205
248
206
- DO NOT use the index as a key for your list items. Sorting will not work.
249
+ The same as ` state ` in ` const [ state, setState] = useState([{ id: 1}, {id: 2}]) `
207
250
208
- In all the examples above, I used an object with an ID. You should do the same!
251
+ ` state ` must be an array of items, with each item being an object that has the following shape:
209
252
210
- I may even enforce this into the design to eliminate errors.
253
+ ``` ts
254
+ /** The unique id associated with your item. It's recommended this is the same as the key prop for your list item. */
255
+ id : string | number ;
256
+ /** When true, the item is selected using MultiDrag */
257
+ selected ?: boolean ;
258
+ /** When true, the item is deemed "chosen", which basically just a mousedown event. */
259
+ chosen ?: boolean ;
260
+ /** When true, it will not be possible to pick this item up in the list. */
261
+ filtered ?: boolean ;
262
+ [property : string ]: any ;
263
+ ```
211
264
212
- ### ` setState() `
265
+ ### setList
213
266
214
- #### Problem
267
+ The same as ` setState ` in ` const [ state, setState] = useState([{ id: 1}, {id: 2}]) `
215
268
216
- ` setState ` takes one argument only. If we look in the type defs, it does say that it has a second argument, but it is already deprecated. ReactSortable passes three arguments to ` setState ` .
269
+ ### clone
217
270
218
- If you pass the ` setState ` straight from a ` useState ` hook, it will work as expected. However, there will be a warning in the console:
271
+ If you're using ` {group: { name: 'groupName', pull: 'clone'}} ` , this means your in 'clone' mode. You should provide a function for this.
219
272
220
- > Warning: State updates from the useState() and useReducer() Hooks don't support the second callback argument.
221
- > To execute a side effect after rendering, declare it in the component body with useEffect().
273
+ Check out the source code of the clone example for more information. I'll write it here soon.
222
274
223
- It's just a warning and there's nothing to worry about. Nothing will break if you leave the messages there.
275
+ ### tag
276
+
277
+ ReactSortable is a ` div ` element by default. This can be changed to be any HTML element (for example ` ul ` , ` ol ` )
278
+ or can be a React component.
279
+
280
+ This value, be the component or the HTML element should be passed down under ` props.tag ` .
281
+
282
+ Let's explore both here.
283
+
284
+ #### HTML Element
285
+
286
+ Here we will use a ` ul ` . You can use any HTML.
287
+ Just add the string and ReactSortable will use a ` li ` instead of a ` div ` .
224
288
225
289
``` tsx
226
- import React , { FC , useState } from " react" ;
290
+ import React , { FC , useState , forwardRef } from " react" ;
227
291
import { ReactSortable } from " react-sortablejs-typescript" ;
228
292
229
- interface ItemType {
230
- id: string ;
231
- name: string ;
232
- }
233
-
234
293
export const BasicFunction: FC = props => {
235
- const [state, setState] = useState < ItemType []> ([{ id: " 1" , name: " shrek" }]);
294
+ const [state, setState] = useState ([{ id: " 1" , name: " shrek" }]);
236
295
237
296
return (
238
- <ReactSortable
239
- list = { state }
240
- // will cause warnings in dev mode only.
241
- setList = { setState }
242
- >
297
+ <ReactSortable tag = " ul" list = { state } setList = { setState } >
243
298
{ state .map (item => (
244
- <div key = { item .id } >{ item .name } </div >
299
+ <li key = { item .id } >{ item .name } </li >
245
300
))}
246
301
</ReactSortable >
247
302
);
248
303
};
249
304
```
250
305
251
- This is just a warning, but can be annoying when developing.
306
+ #### Custom Component
307
+
308
+ When using a custom component in the ` tag ` prop, the only component it allows is a ` forwardRef ` component.
309
+ Currently we only support components who use the ` React.forwardRef ` API.
252
310
253
- Instead of passing ` setState ` in directly, be explicit in your callback:
311
+ If it doesn't have one, you can add one using ` React.forwardRef() ` .
312
+
313
+ > todo: Some third party UI components may have nested elements to create the look they're after.
314
+ > This could be an issue and not sure how to fix.
254
315
255
316
``` tsx
256
- import React , { FC , useState } from " react" ;
317
+ import React , { FC , useState , forwardRef } from " react" ;
257
318
import { ReactSortable } from " react-sortablejs-typescript" ;
258
319
259
- interface ItemType {
260
- id : string ;
261
- name : string ;
262
- }
320
+ // This is just like a normal component, but now has a ref.
321
+ const CustomComponent = forwardRef < HTMLDivElement , any >(( props , ref ) => {
322
+ return < div ref = { ref } > { props . children } </ div > ;
323
+ });
263
324
264
325
export const BasicFunction: FC = props => {
265
- const [state, setState] = useState <ItemType []>([{ id: " 1" , name: " shrek" }]);
326
+ const [state, setState] = useState ([
327
+ { id: 1 , name: " shrek" },
328
+ { id: 2 , name: " fiona" }
329
+ ]);
266
330
267
331
return (
268
- // `sortable` and `store` arguments are here just to show what arguments have been passed.
269
- // They are not required to be used and you shouldn't really need them.
270
- <ReactSortable
271
- list = { state }
272
- // will not cause warnings in dev mode only.
273
- setList = { (newState , sortable , store ) => setState (newState )}
274
- >
332
+ <ReactSortable tag = { CustomComponent } list = { state } setList = { setState } >
275
333
{ state .map (item => (
276
334
<div key = { item .id } >{ item .name } </div >
277
335
))}
@@ -280,6 +338,21 @@ export const BasicFunction: FC = props => {
280
338
};
281
339
```
282
340
341
+ ## How does it work?
342
+
343
+ Sortable affects the DOM, adding, and removing nodes/css when it needs to in order to achieve the smooth transitions we all know an love.
344
+ This component reverses many of it's actions of the DOM so React can handle this when the state changes.
345
+
346
+ ## Caveats / Gotchas
347
+
348
+ ### ` key !== index `
349
+
350
+ DO NOT use the index as a key for your list items. Sorting will not work.
351
+
352
+ In all the examples above, I used an object with an ID. You should do the same!
353
+
354
+ I may even enforce this into the design to eliminate errors.
355
+
283
356
### Nesting
284
357
285
358
#### Problem
0 commit comments