8000 moves create children function into the component · dasveloper/react-sortablejs@4d46054 · GitHub
[go: up one dir, main page]

Skip to content

Commit 4d46054

Browse files
author
Wayne Van Son
committed
moves create children function into the component
1 parent 33426ee commit 4d46054

File tree

4 files changed

+116
-92
lines changed

4 files changed

+116
-92
lines changed

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
export { ReactSortable } from "./react-sortable";
22
export * from "./types";
3+
export { MultiDrag, OnSpill, AutoScroll, Swap } from "sortablejs";

src/react-sortable.tsx

Lines changed: 58 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,33 @@
11
import {
2+
Children,
3+
cloneElement,
24
Component,
35
createElement,
46
createRef,
5-
ReactNode,
7+
ReactElement,
68
RefObject
79
} from "react";
8-
import Sortable, { MoveEvent, Options, SortableEvent } from "sortablejs";
10+
import Sortable, { MoveEvent, Options, SortableEvent, Swap } from "sortablejs";
911
import {
1012
AllMethodsExceptMove,
1113
HandledMethodNames,
1214
ReactSortableProps,
1315
Store,
14-
UnHandledMethodNames
16+
UnHandledMethodNames,
17+
ItemInterface
1518
} from "./types";
16-
import {
17-
destructurePropsForOptions,
18-
insertNodeAt,
19-
modifyChildren,
20-
removeNode
21-
} from "./util";
19+
import { destructurePropsForOptions, insertNodeAt, removeNode } from "./util";
2220

2321
/** Holds a global reference for which react element is being dragged */
2422
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+
> {
2731
private ref: RefObject<HTMLElement>;
2832

2933
static defaultProps: Partial<ReactSortableProps<any>> = {
@@ -35,17 +39,18 @@ export class ReactSortable<T> extends Component<ReactSortableProps<T>> {
3539
super(props);
3640
/** @todo forward ref this component */
3741
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+
}
3848
}
3949

4050
componentDidMount() {
4151
if (this.ref.current === null) return;
4252
const newOptions = this.makeOptions();
4353
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);
4954
}
5055

5156
render() {
@@ -54,15 +59,40 @@ export class ReactSortable<T> extends Component<ReactSortableProps<T>> {
5459

5560
/** if no tag, default to a `div` element */
5661
const newTag = !tag || tag === null ? "div" : tag;
57-
const newChildren: ReactNode = modifyChildren(this.props);
5862
return createElement(
5963
newTag,
6064
{
6165
/** @todo find a way (perhaps with the callback) to allow AntD components to work */
6266
ref: this.ref,
6367
...classicProps
6468
},
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+
})
6696
);
6797
}
6898

@@ -73,10 +103,16 @@ export class ReactSortable<T> extends Component<ReactSortableProps<T>> {
73103
const key = Object.keys(el).find(k => k.includes("Sortable"));
74104
if (!key) return null;
75105
//@ts-ignore - I know what I'm doing.
76-
return el[key];
106+
return el[key] as Sortable;
77107
}
78108

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. */
80116
makeOptions(): Options {
81117
const DOMHandlers: HandledMethodNames[] = [
82118
"onAdd",
@@ -167,7 +203,6 @@ export class ReactSortable<T> extends Component<ReactSortableProps<T>> {
167203
const [oldItem] = newState.splice(oldIndex!, 1);
168204
const newItem = this.props.clone!(oldItem, evt);
169205

170-
console.log({ oldItem, newItem });
171206
newState.splice(oldIndex!, 0, newItem);
172207
setList(newState, this.sortable, store);
173208
return;
@@ -212,6 +247,8 @@ export class ReactSortable<T> extends Component<ReactSortableProps<T>> {
212247

213248
/** @todo */
214249
onSelect(evt: SortableEvent) {
250+
const { oldIndex, newIndex } = evt;
251+
console.log({ oldIndex, newIndex });
215252
// append the class name the classes of the item
216253
// do it on the item?
217254
// a seperate state?

src/types.ts

Lines changed: 56 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,31 @@
1-
import Sortable, { SortableEvent, Options, MoveEvent } from 'sortablejs'
1+
import Sortable, { SortableEvent, Options, MoveEvent } from "sortablejs";
22

3-
import { ForwardRefExoticComponent, RefAttributes, ReactHTML, CSSProperties } from 'react'
3+
import {
4+
ForwardRefExoticComponent,
5+
RefAttributes,
6+
ReactHTML,
7+
CSSProperties
8+
} from "react";
49

5-
import { ReactSortable } from './react-sortable'
10+
import { ReactSortable } from "./react-sortable";
11+
12+
export interface ItemInterface {
13+
id: string | number;
14+
selected?: boolean;
15+
chosen?: boolean;
16+
filtered?: boolean;
17+
[property: string]: any;
18+
}
619

7-
//
8-
// TYPES
9-
//
1020
export interface ReactSortableProps<T> extends ReactSortableOptions {
1121
/**
1222
* The list of items to use.
1323
*/
14-
list: T[]
24+
list: T[];
1525
/**
1626
* Sets the state for your list of items.
1727
*/
18-
setList: (newState: T[], sortable: Sortable | null, store: Store) => void
28+
setList: (newState: T[], sortable: Sortable | null, store: Store) => void;
1929
/**
2030
* If parsing in a component WITHOUT a ref, an error will be thrown.
2131
*
@@ -24,28 +34,28 @@ export interface ReactSortableProps<T> extends ReactSortableOptions {
2434
* @example
2535
* forwardRef<HTMLElement, YOURPROPS>((props, ref) => <button {...props} ref={ref} />)
2636
*/
27-
tag?: ForwardRefExoticComponent<RefAttributes<any>> | keyof ReactHTML
28-
style?: CSSProperties
29-
className?: string
37+
tag?: ForwardRefExoticComponent<RefAttributes<any>> | keyof ReactHTML;
38+
style?: CSSProperties;
39+
className?: string;
3040
/**
3141
* Parse the plugins you'd like to use in Sortable.
3242
*/
33-
plugins?: Sortable.Plugin | Array<Sortable.Plugin>
43+
plugins?: Sortable.Plugin | Array<Sortable.Plugin>;
3444
/**
3545
* If this is provided, the function will replace the clone in place.
3646
*
3747
* When an is moved from `A` to `B` with `pull: 'clone'`,
3848
* the original element will be moved to `B`
3949
* and the new clone will be placed in `A`
4050
*/
41-
clone?: (currentItem: T, evt: SortableEvent) => T
51+
clone?: (currentItem: T, evt: SortableEvent) => T;
4252
}
4353

4454
/**
4555
* Used as
4656
*/
4757
export interface Store {
48-
dragging: null | ReactSortable<any>
58+
dragging: null | ReactSortable<any>;
4959
}
5060

5161
//
@@ -77,42 +87,46 @@ export type ReactSortableOptions = Omit<Options, AllMethodNames> &
7787
originalEvent: Event,
7888
sortable: Sortable | null,
7989
store: Store
80-
) => boolean | -1 | 1 | void
81-
}
90+
) => boolean | -1 | 1 | void;
91+
};
8292

8393
// STRINGS
8494

8595
/** All method names starting with `on` in `Sortable.Options` */
8696
export type AllMethodNames =
87-
| 'onAdd'
88-
| 'onChange'
89-
| 'onChoose'
90-
| 'onClone'
91-
| 'onEnd'
92-
| 'onFilter'
93-
| 'onMove'
94-
| 'onRemove'
95-
| 'onSort'
96-
| 'onSpill'
97-
| 'onStart'
98-
| 'onUnchoose'
99-
| 'onUpdate'
100-
| 'onSelect'
101-
| 'onDeselect'
97+
| "onAdd"
98+
| "onChange"
99+
| "onChoose"
100+
| "onClone"
101+
| "onEnd"
102+
| "onFilter"
103+
| "onMove"
104+
| "onRemove"
105+
| "onSort"
106+
| "onSpill"
107+
| "onStart"
108+
| "onUnchoose"
109+
| "onUpdate"
110+
| "onSelect"
111+
| "onDeselect";
102112

103113
/** Method names that fire in `this`, when this is react-sortable */
104114
export type HandledMethodNames =
105-
| 'onAdd'
106-
| 'onRemove'
107-
| 'onUpdate'
108-
| 'onStart'
109-
| 'onEnd'
110-
| 'onSpill'
111-
| 'onSelect'
112-
| 'onDeselect'
113-
| 'onClone'
114-
export type UnHandledMethodNames = Exclude<AllMethodsExceptMove, HandledMethodNames | 'onMove'>
115+
| "onAdd"
116+
| "onRemove"
117+
| "onUpdate"
118+
| "onStart"
119+
| "onEnd"
120+
| "onSpill"
121+
| "onSelect"
122+
| "onDeselect"
123+
| "onClone";
124+
125+
export type UnHandledMethodNames = Exclude<
126+
AllMethodsExceptMove,
127+
HandledMethodNames | "onMove"
128+
>;
115129
/**
116130
* Same as `SortableMethodKeys` type but with out the string `onMove`.
117131
*/
118-
export type AllMethodsExceptMove = Exclude<AllMethodNames, 'onMove'>
132+
export type AllMethodsExceptMove = Exclude<AllMethodNames, "onMove">;

src/util.ts

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,7 @@
1-
import { Children, cloneElement, PropsWithChildren, ReactElement } from "react";
1+
import { PropsWithChildren } from "react";
22
import { Options } from "sortablejs";
33
import { AllMethodNames, ReactSortableProps } from "./types";
44

5-
/**
6-
* @summary uses the key the attribute `data-id` to children, which is used internally by SortableJS.
7-
* @param children ReactSortable children
8-
* @todo string concat for sortbale-selected
9-
*/
10-
export function modifyChildren<T>(
11-
props: PropsWithChildren<ReactSortableProps<T>>
12-
) {
13-
const { children, dataIdAttr, className: _className, selectedClass } = props;
14-
// if no children, don't do anything.
15-
if (!children || children == null) return null;
16-
17-
const dataid = dataIdAttr || "data-id";
18-
// const className = (_className || "").split(" ").reduce((acc, curr, _,array) => {
19-
// if (array.includes())
20-
// return "";
21-
// });
22-
23-
const childFunction = (child: ReactElement) => {
24-
return cloneElement(child, {
25-
[dataid]: child.key,
26-
// className
27-
});
28-
};
29-
30-
return Children.map(children as ReactElement<any>[], childFunction);
31-
}
32-
335
/**
346
* Removes the `node` from the DOM
357
* @param node

0 commit comments

Comments
 (0)
0