@@ -8,11 +8,14 @@ Consider trying it out if you had any troubles earlier.
88
99## Things still to do.
1010
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.
1212
1313- [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
1619- [ ] Test the following UI component libraries:
1720 - [x] Styled Components
1821 - [ ] AntD
@@ -22,6 +25,40 @@ We've released version 2.0,
2225 - [ ] React Toolbox
2326 - [ ] Your suggestion? :)
2427
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+
2562## Features
2663
2764### SortableJS
@@ -43,16 +80,23 @@ If you find any features lacking, create an issue and/or pull request.
4380## Installation
4481
4582``` shell
46- npm install --save react-sortablejs-typescript
83+ npm install --save react-sortablejs
4784# OR
48- yarn add react-sortablejs-typescript
85+ yarn add react-sortablejs
4986```
5087
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:
5293
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+ ```
56100
57101## Usage/Examples
58102
@@ -112,34 +156,37 @@ export class BasicClass extends Component<{}, BasicClassState> {
112156}
113157```
114158
115- ### ReactSortable renders a ` div ` as the parent by default.
159+ ## Plugins
116160
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.
119162
120- This value, be the component or the HTML element should be passed down under ` props.tag ` .
163+ By Default:
121164
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
123168
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** .
128170
129171``` 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" ;
132174
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 ());
137177
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+ ]);
140183
141184 return (
142- <ReactSortable tag = " ul" list = { state } setList = { setState } >
185+ <ReactSortable
186+ multiDrag // enables mutidrag
187+ // OR
188+ swap // enables swap
189+ >
143190 { state .map (item => (
144191 <div key = { item .id } >{ item .name } </div >
145192 ))}
@@ -148,44 +195,41 @@ export const BasicFunction: FC = props => {
148195};
149196```
150197
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
156199
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 .
161201
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.
166203
167204``` 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+ });
170211
171- interface ItemType {
172- id: string ;
173- name: string ;
174- }
212+ // --------------------------
213+ // Will now be..
214+ // --------------------------
175215
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" ;
180218
181- export const BasicFunction : FC = props => {
182- const [state, setState] = useState < ItemType []> ([
219+ const App = () => {
220+ const [state, setState] = useState ([
183221 { id: 1 , name: " shrek" },
184222 { id: 2 , name: " fiona" }
185223 ]);
186224
187225 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+ >
189233 { state .map (item => (
190234 <div key = { item .id } >{ item .name } </div >
191235 ))}
@@ -194,84 +238,98 @@ export const BasicFunction: FC = props => {
194238};
195239```
196240
197- ## How does it work?
241+ ## React API
198242
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
201244
202- ## Caveats / Gotchas
245+ Thes are all defaults DOM attributes. Nothing special here.
203246
204- ### ` key !== index `
247+ ### list
205248
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}]) `
207250
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:
209252
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+ ```
211264
212- ### ` setState() `
265+ ### setList
213266
214- #### Problem
267+ The same as ` setState ` in ` const [ state, setState] = useState([{ id: 1}, {id: 2}]) `
215268
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
217270
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.
219272
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.
222274
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 ` .
224288
225289``` tsx
226- import React , { FC , useState } from " react" ;
290+ import React , { FC , useState , forwardRef } from " react" ;
227291import { ReactSortable } from " react-sortablejs-typescript" ;
228292
229- interface ItemType {
230- id: string ;
231- name: string ;
232- }
233-
234293export const BasicFunction: FC = props => {
235- const [state, setState] = useState < ItemType []> ([{ id: " 1" , name: " shrek" }]);
294+ const [state, setState] = useState ([{ id: " 1" , name: " shrek" }]);
236295
237296 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 } >
243298 { state .map (item => (
244- <div key = { item .id } >{ item .name } </div >
299+ <li key = { item .id } >{ item .name } </li >
245300 ))}
246301 </ReactSortable >
247302 );
248303};
249304```
250305
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.
252310
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.
254315
255316``` tsx
256- import React , { FC , useState } from " react" ;
317+ import React , { FC , useState , forwardRef } from " react" ;
257318import { ReactSortable } from " react-sortablejs-typescript" ;
258319
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+ });
263324
264325export 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+ ]);
266330
267331 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 } >
275333 { state .map (item => (
276334 <div key = { item .id } >{ item .name } </div >
277335 ))}
@@ -280,6 +338,21 @@ export const BasicFunction: FC = props => {
280338};
281339```
282340
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+
283356### Nesting
284357
285358#### Problem
0 commit comments