react-native-reorderable-list 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +53 -47
- package/lib/commonjs/components/ReorderableList.js +11 -13
- package/lib/commonjs/components/ReorderableList.js.map +1 -1
- package/lib/commonjs/components/ReorderableListCell.js +39 -29
- package/lib/commonjs/components/ReorderableListCell.js.map +1 -1
- package/lib/commonjs/components/ReorderableListCore/ReorderableListCore.js +10 -7
- package/lib/commonjs/components/ReorderableListCore/ReorderableListCore.js.map +1 -1
- package/lib/commonjs/components/ReorderableListCore/animationDefaults.js +34 -0
- package/lib/commonjs/components/ReorderableListCore/animationDefaults.js.map +1 -0
- package/lib/commonjs/components/ReorderableListCore/autoscrollConfig.js +31 -0
- package/lib/commonjs/components/ReorderableListCore/autoscrollConfig.js.map +1 -0
- package/lib/commonjs/components/ReorderableListCore/useReorderableListCore.js +66 -41
- package/lib/commonjs/components/ReorderableListCore/useReorderableListCore.js.map +1 -1
- package/lib/commonjs/components/ScrollViewContainer.js +2 -2
- package/lib/commonjs/components/ScrollViewContainer.js.map +1 -1
- package/lib/commonjs/components/index.js +0 -11
- package/lib/commonjs/components/index.js.map +1 -1
- package/lib/commonjs/contexts/ReorderableListContext.js.map +1 -1
- package/lib/commonjs/index.js +0 -6
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/types/misc.js +3 -3
- package/lib/module/components/ReorderableList.js +11 -13
- package/lib/module/components/ReorderableList.js.map +1 -1
- package/lib/module/components/ReorderableListCell.js +40 -30
- package/lib/module/components/ReorderableListCell.js.map +1 -1
- package/lib/module/components/ReorderableListCore/ReorderableListCore.js +10 -6
- package/lib/module/components/ReorderableListCore/ReorderableListCore.js.map +1 -1
- package/lib/module/components/ReorderableListCore/animationDefaults.js +28 -0
- package/lib/module/components/ReorderableListCore/animationDefaults.js.map +1 -0
- package/lib/module/components/ReorderableListCore/autoscrollConfig.js +25 -0
- package/lib/module/components/ReorderableListCore/autoscrollConfig.js.map +1 -0
- package/lib/module/components/ReorderableListCore/useReorderableListCore.js +68 -43
- package/lib/module/components/ReorderableListCore/useReorderableListCore.js.map +1 -1
- package/lib/module/components/ScrollViewContainer.js +3 -3
- package/lib/module/components/ScrollViewContainer.js.map +1 -1
- package/lib/module/components/index.js +0 -1
- package/lib/module/components/index.js.map +1 -1
- package/lib/module/contexts/ReorderableListContext.js.map +1 -1
- package/lib/module/index.js +2 -2
- package/lib/module/index.js.map +1 -1
- package/lib/module/types/misc.js +3 -3
- package/lib/typescript/components/ReorderableList.d.ts.map +1 -1
- package/lib/typescript/components/ReorderableListCell.d.ts +1 -1
- package/lib/typescript/components/ReorderableListCell.d.ts.map +1 -1
- package/lib/typescript/components/ReorderableListCore/ReorderableListCore.d.ts.map +1 -1
- package/lib/typescript/components/ReorderableListCore/animationDefaults.d.ts +13 -0
- package/lib/typescript/components/ReorderableListCore/animationDefaults.d.ts.map +1 -0
- package/lib/typescript/components/ReorderableListCore/autoscrollConfig.d.ts +6 -0
- package/lib/typescript/components/ReorderableListCore/autoscrollConfig.d.ts.map +1 -0
- package/lib/typescript/components/ReorderableListCore/useReorderableListCore.d.ts +7 -4
- package/lib/typescript/components/ReorderableListCore/useReorderableListCore.d.ts.map +1 -1
- package/lib/typescript/components/ScrollViewContainer.d.ts.map +1 -1
- package/lib/typescript/components/index.d.ts +0 -1
- package/lib/typescript/components/index.d.ts.map +1 -1
- package/lib/typescript/contexts/ReorderableListContext.d.ts +2 -0
- package/lib/typescript/contexts/ReorderableListContext.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +3 -3
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/types/misc.d.ts +3 -3
- package/lib/typescript/types/misc.d.ts.map +1 -1
- package/lib/typescript/types/props.d.ts +25 -37
- package/lib/typescript/types/props.d.ts.map +1 -1
- package/package.json +19 -11
- package/src/components/ReorderableList.tsx +14 -16
- package/src/components/ReorderableListCell.tsx +36 -32
- package/src/components/ReorderableListCore/ReorderableListCore.tsx +16 -5
- package/src/components/ReorderableListCore/animationDefaults.ts +35 -0
- package/src/components/ReorderableListCore/autoscrollConfig.ts +31 -0
- package/src/components/ReorderableListCore/useReorderableListCore.ts +94 -52
- package/src/components/ScrollViewContainer.tsx +7 -3
- package/src/components/index.ts +0 -1
- package/src/contexts/ReorderableListContext.ts +2 -0
- package/src/index.ts +4 -6
- package/src/types/misc.ts +3 -3
- package/src/types/props.ts +26 -43
- package/lib/commonjs/components/ReorderableListCore/constants.ios.js +0 -10
- package/lib/commonjs/components/ReorderableListCore/constants.ios.js.map +0 -1
- package/lib/commonjs/components/ReorderableListCore/constants.js +0 -10
- package/lib/commonjs/components/ReorderableListCore/constants.js.map +0 -1
- package/lib/commonjs/components/ReorderableListItem.js +0 -87
- package/lib/commonjs/components/ReorderableListItem.js.map +0 -1
- package/lib/module/components/ReorderableListCore/constants.ios.js +0 -4
- package/lib/module/components/ReorderableListCore/constants.ios.js.map +0 -1
- package/lib/module/components/ReorderableListCore/constants.js +0 -4
- package/lib/module/components/ReorderableListCore/constants.js.map +0 -1
- package/lib/module/components/ReorderableListItem.js +0 -78
- package/lib/module/components/ReorderableListItem.js.map +0 -1
- package/lib/typescript/components/ReorderableListCore/constants.d.ts +0 -3
- package/lib/typescript/components/ReorderableListCore/constants.d.ts.map +0 -1
- package/lib/typescript/components/ReorderableListCore/constants.ios.d.ts +0 -3
- package/lib/typescript/components/ReorderableListCore/constants.ios.d.ts.map +0 -1
- package/lib/typescript/components/ReorderableListItem.d.ts +0 -4
- package/lib/typescript/components/ReorderableListItem.d.ts.map +0 -1
- package/src/components/ReorderableListCore/constants.ios.ts +0 -3
- package/src/components/ReorderableListCore/constants.ts +0 -3
- package/src/components/ReorderableListItem.tsx +0 -108
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import {Easing, WithTimingConfig} from 'react-native-reanimated';
|
|
2
|
+
|
|
3
|
+
const DURATION_START = 150;
|
|
4
|
+
const DURATION_END = 200;
|
|
5
|
+
|
|
6
|
+
interface AnimationConfig {
|
|
7
|
+
start: WithTimingConfig & {toValue: number};
|
|
8
|
+
end: WithTimingConfig & {toValue: number};
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const SCALE_ANIMATION_CONFIG_DEFAULT: AnimationConfig = {
|
|
12
|
+
start: {
|
|
13
|
+
toValue: 1.025,
|
|
14
|
+
easing: Easing.in(Easing.ease),
|
|
15
|
+
duration: DURATION_START,
|
|
16
|
+
},
|
|
17
|
+
end: {
|
|
18
|
+
toValue: 1,
|
|
19
|
+
easing: Easing.out(Easing.ease),
|
|
20
|
+
duration: DURATION_END,
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const OPACITY_ANIMATION_CONFIG_DEFAULT: AnimationConfig = {
|
|
25
|
+
start: {
|
|
26
|
+
toValue: 0.75,
|
|
27
|
+
easing: Easing.in(Easing.ease),
|
|
28
|
+
duration: DURATION_START,
|
|
29
|
+
},
|
|
30
|
+
end: {
|
|
31
|
+
toValue: 1,
|
|
32
|
+
easing: Easing.out(Easing.ease),
|
|
33
|
+
duration: DURATION_END,
|
|
34
|
+
},
|
|
35
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {Platform} from 'react-native';
|
|
2
|
+
|
|
3
|
+
const IOS_CONFIG = {
|
|
4
|
+
delay: 80,
|
|
5
|
+
increment: 100,
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
const ANDROID_FABRIC_CONFIG = {
|
|
9
|
+
delay: 50,
|
|
10
|
+
increment: 80,
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const ANDROID_PAPER_CONFIG = {
|
|
14
|
+
delay: 10,
|
|
15
|
+
increment: 4,
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const IS_FABRIC =
|
|
19
|
+
global && typeof global === 'object' && 'nativeFabricUIManager' in global;
|
|
20
|
+
|
|
21
|
+
export const AUTOSCROLL_CONFIG = Platform.select({
|
|
22
|
+
// autoscroll behaves differently with Fabric and Paper on Android
|
|
23
|
+
android: IS_FABRIC ? ANDROID_FABRIC_CONFIG : ANDROID_PAPER_CONFIG,
|
|
24
|
+
ios: IOS_CONFIG,
|
|
25
|
+
|
|
26
|
+
// unsupported platforms
|
|
27
|
+
web: IOS_CONFIG,
|
|
28
|
+
macos: IOS_CONFIG,
|
|
29
|
+
windows: IOS_CONFIG,
|
|
30
|
+
native: IOS_CONFIG,
|
|
31
|
+
});
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import React, {useCallback, useMemo} from 'react';
|
|
1
|
+
import React, {useCallback, useEffect, useMemo} from 'react';
|
|
2
2
|
import {
|
|
3
3
|
FlatList,
|
|
4
4
|
LayoutChangeEvent,
|
|
5
|
-
NativeScrollEvent,
|
|
6
5
|
ScrollView,
|
|
7
6
|
unstable_batchedUpdates,
|
|
8
7
|
} from 'react-native';
|
|
@@ -12,7 +11,6 @@ import Animated, {
|
|
|
12
11
|
AnimatedRef,
|
|
13
12
|
Easing,
|
|
14
13
|
SharedValue,
|
|
15
|
-
cancelAnimation,
|
|
16
14
|
runOnJS,
|
|
17
15
|
runOnUI,
|
|
18
16
|
scrollTo,
|
|
@@ -24,8 +22,17 @@ import Animated, {
|
|
|
24
22
|
withTiming,
|
|
25
23
|
} from 'react-native-reanimated';
|
|
26
24
|
|
|
27
|
-
import {
|
|
28
|
-
|
|
25
|
+
import {
|
|
26
|
+
OPACITY_ANIMATION_CONFIG_DEFAULT,
|
|
27
|
+
SCALE_ANIMATION_CONFIG_DEFAULT,
|
|
28
|
+
} from './animationDefaults';
|
|
29
|
+
import {AUTOSCROLL_CONFIG} from './autoscrollConfig';
|
|
30
|
+
import {
|
|
31
|
+
ReorderableListCellAnimations,
|
|
32
|
+
ReorderableListDragEndEvent,
|
|
33
|
+
ReorderableListDragStartEvent,
|
|
34
|
+
ReorderableListState,
|
|
35
|
+
} from '../../types';
|
|
29
36
|
import type {ReorderableListReorderEvent} from '../../types';
|
|
30
37
|
|
|
31
38
|
const version = React.version.split('.');
|
|
@@ -41,8 +48,8 @@ interface UseReorderableListCoreArgs<T> {
|
|
|
41
48
|
animationDuration: number;
|
|
42
49
|
dragReorderThreshold: number;
|
|
43
50
|
onReorder: (event: ReorderableListReorderEvent) => void;
|
|
51
|
+
onDragStart?: (event: ReorderableListDragStartEvent) => void;
|
|
44
52
|
onDragEnd?: (event: ReorderableListDragEndEvent) => void;
|
|
45
|
-
onScroll?: (event: NativeScrollEvent) => void;
|
|
46
53
|
onLayout?: (event: LayoutChangeEvent) => void;
|
|
47
54
|
scrollViewContainerRef: React.RefObject<ScrollView> | undefined;
|
|
48
55
|
scrollViewHeightY: SharedValue<number> | undefined;
|
|
@@ -51,6 +58,7 @@ interface UseReorderableListCoreArgs<T> {
|
|
|
51
58
|
initialScrollEnabled: boolean | undefined;
|
|
52
59
|
initialScrollViewScrollEnabled: boolean | undefined;
|
|
53
60
|
nestedScrollable: boolean | undefined;
|
|
61
|
+
cellAnimations: ReorderableListCellAnimations | undefined;
|
|
54
62
|
}
|
|
55
63
|
|
|
56
64
|
export const useReorderableListCore = <T>({
|
|
@@ -61,8 +69,8 @@ export const useReorderableListCore = <T>({
|
|
|
61
69
|
animationDuration,
|
|
62
70
|
dragReorderThreshold,
|
|
63
71
|
onReorder,
|
|
72
|
+
onDragStart,
|
|
64
73
|
onDragEnd,
|
|
65
|
-
onScroll,
|
|
66
74
|
onLayout,
|
|
67
75
|
scrollViewContainerRef,
|
|
68
76
|
scrollViewHeightY,
|
|
@@ -71,6 +79,7 @@ export const useReorderableListCore = <T>({
|
|
|
71
79
|
initialScrollEnabled,
|
|
72
80
|
initialScrollViewScrollEnabled,
|
|
73
81
|
nestedScrollable,
|
|
82
|
+
cellAnimations,
|
|
74
83
|
}: UseReorderableListCoreArgs<T>) => {
|
|
75
84
|
const flatListRef = useAnimatedRef<FlatList>();
|
|
76
85
|
const scrollEnabled = useSharedValue(initialScrollEnabled);
|
|
@@ -99,12 +108,15 @@ export const useReorderableListCore = <T>({
|
|
|
99
108
|
const dragEndHandlers = useSharedValue<
|
|
100
109
|
((from: number, to: number) => void)[][]
|
|
101
110
|
>([]);
|
|
102
|
-
|
|
103
|
-
// animation duration as a shared value allows to avoid re-rendering of all cells on value change
|
|
111
|
+
const startY = useSharedValue(0);
|
|
104
112
|
const duration = useSharedValue(animationDuration);
|
|
105
|
-
|
|
113
|
+
const scaleDefault = useSharedValue(1);
|
|
114
|
+
const opacityDefault = useSharedValue(1);
|
|
115
|
+
const {scale, opacity} = cellAnimations || {};
|
|
116
|
+
|
|
117
|
+
useEffect(() => {
|
|
106
118
|
duration.value = animationDuration;
|
|
107
|
-
}
|
|
119
|
+
}, [duration, animationDuration]);
|
|
108
120
|
|
|
109
121
|
const listContextValue = useMemo(
|
|
110
122
|
() => ({
|
|
@@ -112,12 +124,21 @@ export const useReorderableListCore = <T>({
|
|
|
112
124
|
currentIndex,
|
|
113
125
|
draggedIndex,
|
|
114
126
|
dragEndHandlers,
|
|
127
|
+
scale: scale || scaleDefault,
|
|
128
|
+
opacity: opacity || opacityDefault,
|
|
115
129
|
}),
|
|
116
|
-
[
|
|
130
|
+
[
|
|
131
|
+
draggedHeight,
|
|
132
|
+
currentIndex,
|
|
133
|
+
draggedIndex,
|
|
134
|
+
dragEndHandlers,
|
|
135
|
+
scale,
|
|
136
|
+
scaleDefault,
|
|
137
|
+
opacity,
|
|
138
|
+
opacityDefault,
|
|
139
|
+
],
|
|
117
140
|
);
|
|
118
141
|
|
|
119
|
-
const startY = useSharedValue(0);
|
|
120
|
-
|
|
121
142
|
const panGestureHandler = useMemo(
|
|
122
143
|
() =>
|
|
123
144
|
Gesture.Pan()
|
|
@@ -127,22 +148,18 @@ export const useReorderableListCore = <T>({
|
|
|
127
148
|
startY.value = e.y;
|
|
128
149
|
currentY.value = e.y;
|
|
129
150
|
currentTranslationY.value = e.translationY;
|
|
130
|
-
|
|
131
|
-
dragY.value = e.translationY;
|
|
132
|
-
}
|
|
151
|
+
dragY.value = e.translationY;
|
|
133
152
|
gestureState.value = e.state;
|
|
134
153
|
}
|
|
135
154
|
})
|
|
136
155
|
.onUpdate(e => {
|
|
137
|
-
if (state.value !== ReorderableListState.
|
|
156
|
+
if (state.value !== ReorderableListState.RELEASED) {
|
|
138
157
|
currentY.value = startY.value + e.translationY;
|
|
139
158
|
currentTranslationY.value = e.translationY;
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
scrollViewDragScrollTranslationY.value;
|
|
145
|
-
}
|
|
159
|
+
dragY.value =
|
|
160
|
+
e.translationY +
|
|
161
|
+
dragScrollTranslationY.value +
|
|
162
|
+
scrollViewDragScrollTranslationY.value;
|
|
146
163
|
gestureState.value = e.state;
|
|
147
164
|
}
|
|
148
165
|
})
|
|
@@ -153,7 +170,6 @@ export const useReorderableListCore = <T>({
|
|
|
153
170
|
currentY,
|
|
154
171
|
dragScrollTranslationY,
|
|
155
172
|
scrollViewDragScrollTranslationY,
|
|
156
|
-
draggedIndex,
|
|
157
173
|
gestureState,
|
|
158
174
|
dragY,
|
|
159
175
|
startY,
|
|
@@ -198,21 +214,23 @@ export const useReorderableListCore = <T>({
|
|
|
198
214
|
const resetSharedValues = useCallback(() => {
|
|
199
215
|
'worklet';
|
|
200
216
|
|
|
201
|
-
// current index is reset on item render for the on end event
|
|
202
|
-
draggedIndex.value = -1;
|
|
203
|
-
// released flag is reset after release is triggered in the item
|
|
204
217
|
state.value = ReorderableListState.IDLE;
|
|
218
|
+
draggedIndex.value = -1;
|
|
205
219
|
dragY.value = 0;
|
|
206
220
|
dragScrollTranslationY.value = 0;
|
|
207
221
|
scrollViewDragScrollTranslationY.value = 0;
|
|
208
222
|
}, [
|
|
223
|
+
draggedIndex,
|
|
209
224
|
dragY,
|
|
210
225
|
dragScrollTranslationY,
|
|
211
226
|
scrollViewDragScrollTranslationY,
|
|
212
|
-
draggedIndex,
|
|
213
227
|
state,
|
|
214
228
|
]);
|
|
215
229
|
|
|
230
|
+
const resetSharedValuesAfterAnimations = useCallback(() => {
|
|
231
|
+
setTimeout(runOnUI(resetSharedValues), duration.value);
|
|
232
|
+
}, [resetSharedValues, duration]);
|
|
233
|
+
|
|
216
234
|
const reorder = (fromIndex: number, toIndex: number) => {
|
|
217
235
|
runOnUI(resetSharedValues)();
|
|
218
236
|
|
|
@@ -316,19 +334,39 @@ export const useReorderableListCore = <T>({
|
|
|
316
334
|
],
|
|
317
335
|
);
|
|
318
336
|
|
|
337
|
+
const runDefaultDragAnimations = useCallback(
|
|
338
|
+
(type: 'start' | 'end') => {
|
|
339
|
+
'worklet';
|
|
340
|
+
|
|
341
|
+
// if animation is not disabled and not custom run the default
|
|
342
|
+
if (scale !== false && !scale) {
|
|
343
|
+
const scaleConfig = SCALE_ANIMATION_CONFIG_DEFAULT[type];
|
|
344
|
+
scaleDefault.value = withTiming(scaleConfig.toValue, scaleConfig);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// if animation is not disabled and not custom run the default
|
|
348
|
+
if (opacity !== false && !opacity) {
|
|
349
|
+
const opacityConfig = OPACITY_ANIMATION_CONFIG_DEFAULT[type];
|
|
350
|
+
opacityDefault.value = withTiming(opacityConfig.toValue, opacityConfig);
|
|
351
|
+
}
|
|
352
|
+
},
|
|
353
|
+
[scale, scaleDefault, opacity, opacityDefault],
|
|
354
|
+
);
|
|
355
|
+
|
|
319
356
|
useAnimatedReaction(
|
|
320
357
|
() => gestureState.value,
|
|
321
358
|
() => {
|
|
322
359
|
if (
|
|
323
360
|
gestureState.value !== State.ACTIVE &&
|
|
324
361
|
gestureState.value !== State.BEGAN &&
|
|
325
|
-
(state.value === ReorderableListState.
|
|
326
|
-
state.value === ReorderableListState.
|
|
362
|
+
(state.value === ReorderableListState.DRAGGED ||
|
|
363
|
+
state.value === ReorderableListState.AUTOSCROLL)
|
|
327
364
|
) {
|
|
328
|
-
state.value = ReorderableListState.
|
|
365
|
+
state.value = ReorderableListState.RELEASED;
|
|
329
366
|
|
|
330
367
|
// enable back scroll on releasing
|
|
331
368
|
runOnJS(setScrollEnabled)(true);
|
|
369
|
+
|
|
332
370
|
// trigger onDragEnd event
|
|
333
371
|
let e = {from: draggedIndex.value, to: currentIndex.value};
|
|
334
372
|
onDragEnd?.(e);
|
|
@@ -351,6 +389,8 @@ export const useReorderableListCore = <T>({
|
|
|
351
389
|
currentItemOffset +
|
|
352
390
|
(draggedItemHeight - currentItemHeight);
|
|
353
391
|
|
|
392
|
+
runDefaultDragAnimations('end');
|
|
393
|
+
|
|
354
394
|
if (dragY.value !== newTopPosition) {
|
|
355
395
|
// animate dragged item to its new position on release
|
|
356
396
|
dragY.value = withTiming(
|
|
@@ -367,7 +407,7 @@ export const useReorderableListCore = <T>({
|
|
|
367
407
|
// user might drag and release the item without moving it so,
|
|
368
408
|
// since the animation end callback is not executed in that case
|
|
369
409
|
// we need to reset values as the reorder function would do
|
|
370
|
-
|
|
410
|
+
runOnJS(resetSharedValuesAfterAnimations)();
|
|
371
411
|
}
|
|
372
412
|
}
|
|
373
413
|
},
|
|
@@ -488,20 +528,20 @@ export const useReorderableListCore = <T>({
|
|
|
488
528
|
() => currentY.value + scrollViewDragScrollTranslationY.value,
|
|
489
529
|
y => {
|
|
490
530
|
if (
|
|
491
|
-
state.value === ReorderableListState.
|
|
492
|
-
state.value === ReorderableListState.
|
|
531
|
+
state.value === ReorderableListState.DRAGGED ||
|
|
532
|
+
state.value === ReorderableListState.AUTOSCROLL
|
|
493
533
|
) {
|
|
494
534
|
setCurrentIndex(y);
|
|
495
535
|
|
|
496
|
-
if (scrollDirection(y)) {
|
|
497
|
-
if (state.value !== ReorderableListState.
|
|
536
|
+
if (scrollDirection(y) !== 0) {
|
|
537
|
+
if (state.value !== ReorderableListState.AUTOSCROLL) {
|
|
498
538
|
// trigger autoscroll
|
|
499
539
|
lastAutoscrollTrigger.value = autoscrollTrigger.value;
|
|
500
540
|
autoscrollTrigger.value *= -1;
|
|
541
|
+
state.value = ReorderableListState.AUTOSCROLL;
|
|
501
542
|
}
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
state.value = ReorderableListState.DRAGGING;
|
|
543
|
+
} else if (state.value === ReorderableListState.AUTOSCROLL) {
|
|
544
|
+
state.value = ReorderableListState.DRAGGED;
|
|
505
545
|
}
|
|
506
546
|
}
|
|
507
547
|
},
|
|
@@ -512,11 +552,13 @@ export const useReorderableListCore = <T>({
|
|
|
512
552
|
() => {
|
|
513
553
|
if (
|
|
514
554
|
autoscrollTrigger.value !== lastAutoscrollTrigger.value &&
|
|
515
|
-
state.value === ReorderableListState.
|
|
555
|
+
state.value === ReorderableListState.AUTOSCROLL
|
|
516
556
|
) {
|
|
517
557
|
let y = currentY.value + scrollViewDragScrollTranslationY.value;
|
|
518
558
|
const autoscrollIncrement =
|
|
519
|
-
scrollDirection(y) *
|
|
559
|
+
scrollDirection(y) *
|
|
560
|
+
AUTOSCROLL_CONFIG.increment *
|
|
561
|
+
autoscrollSpeedScale;
|
|
520
562
|
|
|
521
563
|
if (autoscrollIncrement !== 0) {
|
|
522
564
|
let scrollOffset = flatListScrollOffsetY.value;
|
|
@@ -545,28 +587,24 @@ export const useReorderableListCore = <T>({
|
|
|
545
587
|
|
|
546
588
|
// checking if the list is not scrollable instead of the scrolling state
|
|
547
589
|
// fixes a bug on iOS where the item is shifted after autoscrolling and then
|
|
548
|
-
// moving
|
|
590
|
+
// moving away from autoscroll area
|
|
549
591
|
if (!scrollEnabled.value) {
|
|
550
592
|
dragScrollTranslationY.value =
|
|
551
593
|
flatListScrollOffsetY.value - dragInitialScrollOffsetY.value;
|
|
552
594
|
}
|
|
553
595
|
|
|
554
|
-
if (state.value === ReorderableListState.
|
|
596
|
+
if (state.value === ReorderableListState.AUTOSCROLL) {
|
|
555
597
|
dragY.value =
|
|
556
598
|
currentTranslationY.value +
|
|
557
599
|
dragScrollTranslationY.value +
|
|
558
600
|
scrollViewDragScrollTranslationY.value;
|
|
559
601
|
|
|
560
|
-
cancelAnimation(autoscrollTrigger);
|
|
561
|
-
|
|
562
602
|
lastAutoscrollTrigger.value = autoscrollTrigger.value;
|
|
563
603
|
autoscrollTrigger.value = withDelay(
|
|
564
604
|
autoscrollDelay,
|
|
565
605
|
withTiming(autoscrollTrigger.value * -1, {duration: 0}),
|
|
566
606
|
);
|
|
567
607
|
}
|
|
568
|
-
|
|
569
|
-
onScroll?.(e);
|
|
570
608
|
});
|
|
571
609
|
|
|
572
610
|
// parent scroll handler
|
|
@@ -582,12 +620,10 @@ export const useReorderableListCore = <T>({
|
|
|
582
620
|
value - scrollViewDragInitialScrollOffsetY.value;
|
|
583
621
|
}
|
|
584
622
|
|
|
585
|
-
if (state.value === ReorderableListState.
|
|
623
|
+
if (state.value === ReorderableListState.AUTOSCROLL) {
|
|
586
624
|
dragY.value =
|
|
587
625
|
currentTranslationY.value + scrollViewDragScrollTranslationY.value;
|
|
588
626
|
|
|
589
|
-
cancelAnimation(autoscrollTrigger);
|
|
590
|
-
|
|
591
627
|
lastAutoscrollTrigger.value = autoscrollTrigger.value;
|
|
592
628
|
autoscrollTrigger.value = withDelay(
|
|
593
629
|
autoscrollDelay,
|
|
@@ -617,9 +653,13 @@ export const useReorderableListCore = <T>({
|
|
|
617
653
|
draggedIndex.value = index;
|
|
618
654
|
previousIndex.value = -1;
|
|
619
655
|
currentIndex.value = index;
|
|
620
|
-
state.value = ReorderableListState.
|
|
656
|
+
state.value = ReorderableListState.DRAGGED;
|
|
621
657
|
|
|
622
658
|
runOnJS(setScrollEnabled)(false);
|
|
659
|
+
|
|
660
|
+
// run animation before onDragStart to avoid potentially waiting for it
|
|
661
|
+
runDefaultDragAnimations('start');
|
|
662
|
+
onDragStart?.({index});
|
|
623
663
|
}
|
|
624
664
|
},
|
|
625
665
|
[
|
|
@@ -635,6 +675,8 @@ export const useReorderableListCore = <T>({
|
|
|
635
675
|
state,
|
|
636
676
|
flatListScrollOffsetY,
|
|
637
677
|
itemHeight,
|
|
678
|
+
onDragStart,
|
|
679
|
+
runDefaultDragAnimations,
|
|
638
680
|
],
|
|
639
681
|
);
|
|
640
682
|
|
|
@@ -5,6 +5,7 @@ import {Gesture, GestureDetector} from 'react-native-gesture-handler';
|
|
|
5
5
|
import Animated, {
|
|
6
6
|
useAnimatedRef,
|
|
7
7
|
useAnimatedScrollHandler,
|
|
8
|
+
useComposedEventHandler,
|
|
8
9
|
useSharedValue,
|
|
9
10
|
} from 'react-native-reanimated';
|
|
10
11
|
|
|
@@ -27,12 +28,15 @@ export const ScrollViewContainer: React.FC<ScrollViewContainerProps> = ({
|
|
|
27
28
|
const handleScroll = useAnimatedScrollHandler(
|
|
28
29
|
e => {
|
|
29
30
|
scrollViewScrollOffsetY.value = e.contentOffset.y;
|
|
30
|
-
|
|
31
|
-
onScroll?.(e);
|
|
32
31
|
},
|
|
33
32
|
[scrollViewScrollOffsetY],
|
|
34
33
|
);
|
|
35
34
|
|
|
35
|
+
const composedScrollHandler = useComposedEventHandler([
|
|
36
|
+
handleScroll,
|
|
37
|
+
onScroll || null,
|
|
38
|
+
]);
|
|
39
|
+
|
|
36
40
|
const contextValue = useMemo(
|
|
37
41
|
() => ({
|
|
38
42
|
scrollViewContainerRef,
|
|
@@ -64,7 +68,7 @@ export const ScrollViewContainer: React.FC<ScrollViewContainerProps> = ({
|
|
|
64
68
|
<Animated.ScrollView
|
|
65
69
|
{...rest}
|
|
66
70
|
ref={scrollViewContainerRef}
|
|
67
|
-
onScroll={
|
|
71
|
+
onScroll={composedScrollHandler}
|
|
68
72
|
onLayout={handleLayout}
|
|
69
73
|
scrollEnabled={scrollEnabled}
|
|
70
74
|
/>
|
package/src/components/index.ts
CHANGED
|
@@ -6,6 +6,8 @@ interface ReorderableListContextData {
|
|
|
6
6
|
currentIndex: SharedValue<number>;
|
|
7
7
|
draggedHeight: SharedValue<number>;
|
|
8
8
|
dragEndHandlers: SharedValue<((from: number, to: number) => void)[][]>;
|
|
9
|
+
scale: SharedValue<number>;
|
|
10
|
+
opacity: SharedValue<number>;
|
|
9
11
|
}
|
|
10
12
|
|
|
11
13
|
export const ReorderableListContext = React.createContext<
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
NestedReorderableList,
|
|
3
3
|
ReorderableList,
|
|
4
|
-
ReorderableListItem,
|
|
5
4
|
ScrollViewContainer,
|
|
6
5
|
} from './components';
|
|
7
6
|
import {
|
|
@@ -10,9 +9,9 @@ import {
|
|
|
10
9
|
useReorderableDragStart,
|
|
11
10
|
} from './hooks';
|
|
12
11
|
import type {
|
|
12
|
+
ReorderableListCellAnimations,
|
|
13
13
|
ReorderableListDragEndEvent,
|
|
14
|
-
|
|
15
|
-
ReorderableListItemProps,
|
|
14
|
+
ReorderableListDragStartEvent,
|
|
16
15
|
ReorderableListProps,
|
|
17
16
|
ReorderableListReorderEvent,
|
|
18
17
|
ScrollViewContainerProps,
|
|
@@ -25,10 +24,9 @@ export {
|
|
|
25
24
|
useReorderableDragEnd,
|
|
26
25
|
ReorderableListProps,
|
|
27
26
|
ReorderableListReorderEvent,
|
|
27
|
+
ReorderableListCellAnimations,
|
|
28
|
+
ReorderableListDragStartEvent,
|
|
28
29
|
ReorderableListDragEndEvent,
|
|
29
|
-
ReorderableListItem,
|
|
30
|
-
ReorderableListItemConfig,
|
|
31
|
-
ReorderableListItemProps,
|
|
32
30
|
ScrollViewContainer,
|
|
33
31
|
ScrollViewContainerProps,
|
|
34
32
|
NestedReorderableList,
|
package/src/types/misc.ts
CHANGED
package/src/types/props.ts
CHANGED
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
FlatListProps,
|
|
3
|
-
NativeScrollEvent,
|
|
4
|
-
ScrollViewProps,
|
|
5
|
-
ViewProps,
|
|
6
|
-
} from 'react-native';
|
|
1
|
+
import type {FlatListProps, ScrollViewProps} from 'react-native';
|
|
7
2
|
|
|
8
|
-
import {
|
|
3
|
+
import {SharedValue, useAnimatedScrollHandler} from 'react-native-reanimated';
|
|
9
4
|
|
|
10
5
|
export interface ReorderableListReorderEvent {
|
|
11
6
|
/**
|
|
@@ -18,6 +13,13 @@ export interface ReorderableListReorderEvent {
|
|
|
18
13
|
to: number;
|
|
19
14
|
}
|
|
20
15
|
|
|
16
|
+
export interface ReorderableListDragStartEvent {
|
|
17
|
+
/**
|
|
18
|
+
* Index of the dragged item.
|
|
19
|
+
*/
|
|
20
|
+
index: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
21
23
|
export interface ReorderableListDragEndEvent {
|
|
22
24
|
/**
|
|
23
25
|
* Index of the dragged item.
|
|
@@ -69,63 +71,44 @@ export interface ReorderableListProps<T>
|
|
|
69
71
|
*/
|
|
70
72
|
animationDuration?: number;
|
|
71
73
|
/**
|
|
72
|
-
*
|
|
73
|
-
*/
|
|
74
|
-
onReorder: (event: ReorderableListReorderEvent) => void;
|
|
75
|
-
/**
|
|
76
|
-
* Event fired at most once per frame during scrolling. Needs to be a `worklet`. See [Reanimated docs](https://docs.swmansion.com/react-native-reanimated) for further info.
|
|
74
|
+
* Allows passing an object with shared values that can animate a cell by using the `onDragStart` and `onDragEnd` events.
|
|
77
75
|
*/
|
|
78
|
-
|
|
76
|
+
cellAnimations?: ReorderableListCellAnimations;
|
|
79
77
|
/**
|
|
80
|
-
* Event fired
|
|
81
|
-
*/
|
|
82
|
-
onDragEnd?: (event: ReorderableListDragEndEvent) => void;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export interface ReorderableListItemConfig {
|
|
86
|
-
/**
|
|
87
|
-
* Value of the animated style on drag end.
|
|
88
|
-
*/
|
|
89
|
-
enabled?: boolean;
|
|
90
|
-
/**
|
|
91
|
-
* Value of the animated style on drag end.
|
|
92
|
-
*/
|
|
93
|
-
valueEnd?: number;
|
|
94
|
-
/**
|
|
95
|
-
* Value of the animated style on drag start.
|
|
78
|
+
* Event fired after an item is released and the list is reordered.
|
|
96
79
|
*/
|
|
97
|
-
|
|
80
|
+
onReorder: (event: ReorderableListReorderEvent) => void;
|
|
98
81
|
/**
|
|
99
|
-
*
|
|
82
|
+
* An animated scroll handler created with useAnimatedScrollHandler. See [Reanimated docs](https://docs.swmansion.com/react-native-reanimated) for further info.
|
|
100
83
|
*/
|
|
101
|
-
|
|
84
|
+
onScroll?: ReturnType<typeof useAnimatedScrollHandler>;
|
|
102
85
|
/**
|
|
103
|
-
*
|
|
86
|
+
* Event fired when an item is dragged. Needs to be a `worklet`. See [Reanimated docs](https://docs.swmansion.com/react-native-reanimated) for further info.
|
|
104
87
|
*/
|
|
105
|
-
|
|
88
|
+
onDragStart?: (event: ReorderableListDragStartEvent) => void;
|
|
106
89
|
/**
|
|
107
|
-
*
|
|
90
|
+
* Event fired when the dragged item is released. Needs to be a `worklet`. See [Reanimated docs](https://docs.swmansion.com/react-native-reanimated) for further info.
|
|
108
91
|
*/
|
|
109
|
-
|
|
92
|
+
onDragEnd?: (event: ReorderableListDragEndEvent) => void;
|
|
110
93
|
}
|
|
111
94
|
|
|
112
|
-
export interface
|
|
95
|
+
export interface ReorderableListCellAnimations {
|
|
113
96
|
/**
|
|
114
|
-
*
|
|
97
|
+
* Shared value to animate the opacity of a dragged item. Set to false to disable default opacity animations.
|
|
115
98
|
*/
|
|
116
|
-
|
|
99
|
+
opacity?: SharedValue<number> | false;
|
|
117
100
|
/**
|
|
118
|
-
*
|
|
101
|
+
* Shared value to animate the scale of a dragged item. Set to false to disable default scale animations.
|
|
119
102
|
*/
|
|
120
|
-
|
|
103
|
+
scale?: SharedValue<number> | false;
|
|
121
104
|
}
|
|
122
105
|
|
|
123
106
|
export interface ScrollViewContainerProps
|
|
124
107
|
extends Omit<ScrollViewProps, 'onScroll'> {
|
|
125
108
|
/**
|
|
126
|
-
*
|
|
109
|
+
* An animated scroll handler created with useAnimatedScrollHandler. See [Reanimated docs](https://docs.swmansion.com/react-native-reanimated) for further info.
|
|
127
110
|
*/
|
|
128
|
-
onScroll?:
|
|
111
|
+
onScroll?: ReturnType<typeof useAnimatedScrollHandler>;
|
|
129
112
|
}
|
|
130
113
|
|
|
131
114
|
export interface NestedReorderableListProps<T> extends ReorderableListProps<T> {
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.AUTOSCROLL_INCREMENT = exports.AUTOSCROLL_DELAY = void 0;
|
|
7
|
-
// iOS specific constants
|
|
8
|
-
const AUTOSCROLL_INCREMENT = exports.AUTOSCROLL_INCREMENT = 80;
|
|
9
|
-
const AUTOSCROLL_DELAY = exports.AUTOSCROLL_DELAY = 100;
|
|
10
|
-
//# sourceMappingURL=constants.ios.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["AUTOSCROLL_INCREMENT","exports","AUTOSCROLL_DELAY"],"sourceRoot":"../../../../src","sources":["components/ReorderableListCore/constants.ios.ts"],"mappings":";;;;;;AAAA;AACO,MAAMA,oBAAoB,GAAAC,OAAA,CAAAD,oBAAA,GAAG,EAAE;AAC/B,MAAME,gBAAgB,GAAAD,OAAA,CAAAC,gBAAA,GAAG,GAAG","ignoreList":[]}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.AUTOSCROLL_INCREMENT = exports.AUTOSCROLL_DELAY = void 0;
|
|
7
|
-
// Default constants
|
|
8
|
-
const AUTOSCROLL_INCREMENT = exports.AUTOSCROLL_INCREMENT = 5;
|
|
9
|
-
const AUTOSCROLL_DELAY = exports.AUTOSCROLL_DELAY = 0;
|
|
10
|
-
//# sourceMappingURL=constants.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["AUTOSCROLL_INCREMENT","exports","AUTOSCROLL_DELAY"],"sourceRoot":"../../../../src","sources":["components/ReorderableListCore/constants.ts"],"mappings":";;;;;;AAAA;AACO,MAAMA,oBAAoB,GAAAC,OAAA,CAAAD,oBAAA,GAAG,CAAC;AAC9B,MAAME,gBAAgB,GAAAD,OAAA,CAAAC,gBAAA,GAAG,CAAC","ignoreList":[]}
|