react-native-reorderable-list 0.7.1 → 0.9.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 +131 -47
- package/lib/commonjs/components/ReorderableList.js +11 -13
- package/lib/commonjs/components/ReorderableList.js.map +1 -1
- package/lib/commonjs/components/ReorderableListCell.js +44 -31
- package/lib/commonjs/components/ReorderableListCell.js.map +1 -1
- package/lib/commonjs/components/ReorderableListCore/ReorderableListCore.js +18 -17
- 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/{constants.js → autoscrollConfig.js} +1 -1
- package/lib/commonjs/components/ReorderableListCore/autoscrollConfig.js.map +1 -0
- package/lib/commonjs/components/ReorderableListCore/useReorderableListCore.js +82 -33
- 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/ReorderableCellContext.js.map +1 -1
- package/lib/commonjs/contexts/ReorderableListContext.js.map +1 -1
- package/lib/commonjs/hooks/index.js +11 -0
- package/lib/commonjs/hooks/index.js.map +1 -1
- package/lib/commonjs/hooks/useIsActive.js +16 -0
- package/lib/commonjs/hooks/useIsActive.js.map +1 -0
- package/lib/commonjs/index.js +6 -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 +45 -32
- package/lib/module/components/ReorderableListCell.js.map +1 -1
- package/lib/module/components/ReorderableListCore/ReorderableListCore.js +17 -15
- 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/{constants.js → autoscrollConfig.js} +1 -1
- package/lib/module/components/ReorderableListCore/autoscrollConfig.js.map +1 -0
- package/lib/module/components/ReorderableListCore/useReorderableListCore.js +82 -33
- 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/ReorderableCellContext.js.map +1 -1
- package/lib/module/contexts/ReorderableListContext.js.map +1 -1
- package/lib/module/hooks/index.js +1 -0
- package/lib/module/hooks/index.js.map +1 -1
- package/lib/module/hooks/useIsActive.js +9 -0
- package/lib/module/hooks/useIsActive.js.map +1 -0
- package/lib/module/index.js +3 -3
- 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/{constants.d.ts → autoscrollConfig.d.ts} +1 -1
- package/lib/typescript/components/ReorderableListCore/autoscrollConfig.d.ts.map +1 -0
- package/lib/typescript/components/ReorderableListCore/useReorderableListCore.d.ts +11 -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/ReorderableCellContext.d.ts +1 -0
- package/lib/typescript/contexts/ReorderableCellContext.d.ts.map +1 -1
- package/lib/typescript/contexts/ReorderableListContext.d.ts +3 -0
- package/lib/typescript/contexts/ReorderableListContext.d.ts.map +1 -1
- package/lib/typescript/hooks/index.d.ts +1 -0
- package/lib/typescript/hooks/index.d.ts.map +1 -1
- package/lib/typescript/hooks/useIsActive.d.ts +2 -0
- package/lib/typescript/hooks/useIsActive.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +4 -4
- 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 +31 -31
- package/lib/typescript/types/props.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/components/ReorderableList.tsx +14 -16
- package/src/components/ReorderableListCell.tsx +38 -33
- package/src/components/ReorderableListCore/ReorderableListCore.tsx +22 -13
- package/src/components/ReorderableListCore/animationDefaults.ts +35 -0
- package/src/components/ReorderableListCore/useReorderableListCore.ts +117 -40
- package/src/components/ScrollViewContainer.tsx +7 -3
- package/src/components/index.ts +0 -1
- package/src/contexts/ReorderableCellContext.ts +1 -0
- package/src/contexts/ReorderableListContext.ts +3 -0
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useIsActive.ts +7 -0
- package/src/index.ts +6 -6
- package/src/types/misc.ts +3 -3
- package/src/types/props.ts +32 -37
- 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.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.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/ReorderableListItem.tsx +0 -108
- /package/src/components/ReorderableListCore/{constants.ts → autoscrollConfig.ts} +0 -0
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import React, {useCallback, useEffect, useMemo} from 'react';
|
|
1
|
+
import React, {useCallback, useEffect, useMemo, useState} 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';
|
|
@@ -23,8 +22,17 @@ import Animated, {
|
|
|
23
22
|
withTiming,
|
|
24
23
|
} from 'react-native-reanimated';
|
|
25
24
|
|
|
26
|
-
import {
|
|
27
|
-
|
|
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';
|
|
28
36
|
import type {ReorderableListReorderEvent} from '../../types';
|
|
29
37
|
|
|
30
38
|
const version = React.version.split('.');
|
|
@@ -40,8 +48,8 @@ interface UseReorderableListCoreArgs<T> {
|
|
|
40
48
|
animationDuration: number;
|
|
41
49
|
dragReorderThreshold: number;
|
|
42
50
|
onReorder: (event: ReorderableListReorderEvent) => void;
|
|
51
|
+
onDragStart?: (event: ReorderableListDragStartEvent) => void;
|
|
43
52
|
onDragEnd?: (event: ReorderableListDragEndEvent) => void;
|
|
44
|
-
onScroll?: (event: NativeScrollEvent) => void;
|
|
45
53
|
onLayout?: (event: LayoutChangeEvent) => void;
|
|
46
54
|
scrollViewContainerRef: React.RefObject<ScrollView> | undefined;
|
|
47
55
|
scrollViewHeightY: SharedValue<number> | undefined;
|
|
@@ -50,6 +58,10 @@ interface UseReorderableListCoreArgs<T> {
|
|
|
50
58
|
initialScrollEnabled: boolean | undefined;
|
|
51
59
|
initialScrollViewScrollEnabled: boolean | undefined;
|
|
52
60
|
nestedScrollable: boolean | undefined;
|
|
61
|
+
cellAnimations: ReorderableListCellAnimations | undefined;
|
|
62
|
+
shouldUpdateActiveItem: boolean | undefined;
|
|
63
|
+
panEnabled: boolean;
|
|
64
|
+
panActivateAfterLongPress: number | undefined;
|
|
53
65
|
}
|
|
54
66
|
|
|
55
67
|
export const useReorderableListCore = <T>({
|
|
@@ -60,8 +72,8 @@ export const useReorderableListCore = <T>({
|
|
|
60
72
|
animationDuration,
|
|
61
73
|
dragReorderThreshold,
|
|
62
74
|
onReorder,
|
|
75
|
+
onDragStart,
|
|
63
76
|
onDragEnd,
|
|
64
|
-
onScroll,
|
|
65
77
|
onLayout,
|
|
66
78
|
scrollViewContainerRef,
|
|
67
79
|
scrollViewHeightY,
|
|
@@ -70,8 +82,13 @@ export const useReorderableListCore = <T>({
|
|
|
70
82
|
initialScrollEnabled,
|
|
71
83
|
initialScrollViewScrollEnabled,
|
|
72
84
|
nestedScrollable,
|
|
85
|
+
cellAnimations,
|
|
86
|
+
shouldUpdateActiveItem,
|
|
87
|
+
panActivateAfterLongPress,
|
|
88
|
+
panEnabled,
|
|
73
89
|
}: UseReorderableListCoreArgs<T>) => {
|
|
74
90
|
const flatListRef = useAnimatedRef<FlatList>();
|
|
91
|
+
const [activeIndex, setActiveIndex] = useState(-1);
|
|
75
92
|
const scrollEnabled = useSharedValue(initialScrollEnabled);
|
|
76
93
|
const gestureState = useSharedValue<State>(State.UNDETERMINED);
|
|
77
94
|
const currentY = useSharedValue(0);
|
|
@@ -100,6 +117,9 @@ export const useReorderableListCore = <T>({
|
|
|
100
117
|
>([]);
|
|
101
118
|
const startY = useSharedValue(0);
|
|
102
119
|
const duration = useSharedValue(animationDuration);
|
|
120
|
+
const scaleDefault = useSharedValue(1);
|
|
121
|
+
const opacityDefault = useSharedValue(1);
|
|
122
|
+
const {scale, opacity} = cellAnimations || {};
|
|
103
123
|
|
|
104
124
|
useEffect(() => {
|
|
105
125
|
duration.value = animationDuration;
|
|
@@ -111,8 +131,21 @@ export const useReorderableListCore = <T>({
|
|
|
111
131
|
currentIndex,
|
|
112
132
|
draggedIndex,
|
|
113
133
|
dragEndHandlers,
|
|
134
|
+
activeIndex,
|
|
135
|
+
scale: scale || scaleDefault,
|
|
136
|
+
opacity: opacity || opacityDefault,
|
|
114
137
|
}),
|
|
115
|
-
[
|
|
138
|
+
[
|
|
139
|
+
draggedHeight,
|
|
140
|
+
currentIndex,
|
|
141
|
+
draggedIndex,
|
|
142
|
+
dragEndHandlers,
|
|
143
|
+
activeIndex,
|
|
144
|
+
scale,
|
|
145
|
+
scaleDefault,
|
|
146
|
+
opacity,
|
|
147
|
+
opacityDefault,
|
|
148
|
+
],
|
|
116
149
|
);
|
|
117
150
|
|
|
118
151
|
const panGestureHandler = useMemo(
|
|
@@ -124,22 +157,18 @@ export const useReorderableListCore = <T>({
|
|
|
124
157
|
startY.value = e.y;
|
|
125
158
|
currentY.value = e.y;
|
|
126
159
|
currentTranslationY.value = e.translationY;
|
|
127
|
-
|
|
128
|
-
dragY.value = e.translationY;
|
|
129
|
-
}
|
|
160
|
+
dragY.value = e.translationY;
|
|
130
161
|
gestureState.value = e.state;
|
|
131
162
|
}
|
|
132
163
|
})
|
|
133
164
|
.onUpdate(e => {
|
|
134
|
-
if (state.value !== ReorderableListState.
|
|
165
|
+
if (state.value !== ReorderableListState.RELEASED) {
|
|
135
166
|
currentY.value = startY.value + e.translationY;
|
|
136
167
|
currentTranslationY.value = e.translationY;
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
scrollViewDragScrollTranslationY.value;
|
|
142
|
-
}
|
|
168
|
+
dragY.value =
|
|
169
|
+
e.translationY +
|
|
170
|
+
dragScrollTranslationY.value +
|
|
171
|
+
scrollViewDragScrollTranslationY.value;
|
|
143
172
|
gestureState.value = e.state;
|
|
144
173
|
}
|
|
145
174
|
})
|
|
@@ -150,7 +179,6 @@ export const useReorderableListCore = <T>({
|
|
|
150
179
|
currentY,
|
|
151
180
|
dragScrollTranslationY,
|
|
152
181
|
scrollViewDragScrollTranslationY,
|
|
153
|
-
draggedIndex,
|
|
154
182
|
gestureState,
|
|
155
183
|
dragY,
|
|
156
184
|
startY,
|
|
@@ -158,9 +186,21 @@ export const useReorderableListCore = <T>({
|
|
|
158
186
|
],
|
|
159
187
|
);
|
|
160
188
|
|
|
189
|
+
const panGestureHandlerWithOptions = useMemo(() => {
|
|
190
|
+
if (typeof panActivateAfterLongPress === 'number') {
|
|
191
|
+
panGestureHandler.activateAfterLongPress(panActivateAfterLongPress);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (!panEnabled) {
|
|
195
|
+
panGestureHandler.enabled(panEnabled);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return panGestureHandler;
|
|
199
|
+
}, [panActivateAfterLongPress, panEnabled, panGestureHandler]);
|
|
200
|
+
|
|
161
201
|
const gestureHandler = useMemo(
|
|
162
|
-
() => Gesture.Simultaneous(Gesture.Native(),
|
|
163
|
-
[
|
|
202
|
+
() => Gesture.Simultaneous(Gesture.Native(), panGestureHandlerWithOptions),
|
|
203
|
+
[panGestureHandlerWithOptions],
|
|
164
204
|
);
|
|
165
205
|
|
|
166
206
|
const setScrollEnabled = useCallback(
|
|
@@ -195,21 +235,23 @@ export const useReorderableListCore = <T>({
|
|
|
195
235
|
const resetSharedValues = useCallback(() => {
|
|
196
236
|
'worklet';
|
|
197
237
|
|
|
198
|
-
// current index is reset on item render for the on end event
|
|
199
|
-
draggedIndex.value = -1;
|
|
200
|
-
// released flag is reset after release is triggered in the item
|
|
201
238
|
state.value = ReorderableListState.IDLE;
|
|
239
|
+
draggedIndex.value = -1;
|
|
202
240
|
dragY.value = 0;
|
|
203
241
|
dragScrollTranslationY.value = 0;
|
|
204
242
|
scrollViewDragScrollTranslationY.value = 0;
|
|
205
243
|
}, [
|
|
244
|
+
draggedIndex,
|
|
206
245
|
dragY,
|
|
207
246
|
dragScrollTranslationY,
|
|
208
247
|
scrollViewDragScrollTranslationY,
|
|
209
|
-
draggedIndex,
|
|
210
248
|
state,
|
|
211
249
|
]);
|
|
212
250
|
|
|
251
|
+
const resetSharedValuesAfterAnimations = useCallback(() => {
|
|
252
|
+
setTimeout(runOnUI(resetSharedValues), duration.value);
|
|
253
|
+
}, [resetSharedValues, duration]);
|
|
254
|
+
|
|
213
255
|
const reorder = (fromIndex: number, toIndex: number) => {
|
|
214
256
|
runOnUI(resetSharedValues)();
|
|
215
257
|
|
|
@@ -313,19 +355,43 @@ export const useReorderableListCore = <T>({
|
|
|
313
355
|
],
|
|
314
356
|
);
|
|
315
357
|
|
|
358
|
+
const runDefaultDragAnimations = useCallback(
|
|
359
|
+
(type: 'start' | 'end') => {
|
|
360
|
+
'worklet';
|
|
361
|
+
|
|
362
|
+
// if animation is not disabled and not custom run the default
|
|
363
|
+
if (scale !== false && !scale) {
|
|
364
|
+
const scaleConfig = SCALE_ANIMATION_CONFIG_DEFAULT[type];
|
|
365
|
+
scaleDefault.value = withTiming(scaleConfig.toValue, scaleConfig);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// if animation is not disabled and not custom run the default
|
|
369
|
+
if (opacity !== false && !opacity) {
|
|
370
|
+
const opacityConfig = OPACITY_ANIMATION_CONFIG_DEFAULT[type];
|
|
371
|
+
opacityDefault.value = withTiming(opacityConfig.toValue, opacityConfig);
|
|
372
|
+
}
|
|
373
|
+
},
|
|
374
|
+
[scale, scaleDefault, opacity, opacityDefault],
|
|
375
|
+
);
|
|
376
|
+
|
|
316
377
|
useAnimatedReaction(
|
|
317
378
|
() => gestureState.value,
|
|
318
379
|
() => {
|
|
319
380
|
if (
|
|
320
381
|
gestureState.value !== State.ACTIVE &&
|
|
321
382
|
gestureState.value !== State.BEGAN &&
|
|
322
|
-
(state.value === ReorderableListState.
|
|
323
|
-
state.value === ReorderableListState.
|
|
383
|
+
(state.value === ReorderableListState.DRAGGED ||
|
|
384
|
+
state.value === ReorderableListState.AUTOSCROLL)
|
|
324
385
|
) {
|
|
325
|
-
state.value = ReorderableListState.
|
|
386
|
+
state.value = ReorderableListState.RELEASED;
|
|
326
387
|
|
|
327
388
|
// enable back scroll on releasing
|
|
328
389
|
runOnJS(setScrollEnabled)(true);
|
|
390
|
+
|
|
391
|
+
if (shouldUpdateActiveItem) {
|
|
392
|
+
runOnJS(setActiveIndex)(-1);
|
|
393
|
+
}
|
|
394
|
+
|
|
329
395
|
// trigger onDragEnd event
|
|
330
396
|
let e = {from: draggedIndex.value, to: currentIndex.value};
|
|
331
397
|
onDragEnd?.(e);
|
|
@@ -348,6 +414,8 @@ export const useReorderableListCore = <T>({
|
|
|
348
414
|
currentItemOffset +
|
|
349
415
|
(draggedItemHeight - currentItemHeight);
|
|
350
416
|
|
|
417
|
+
runDefaultDragAnimations('end');
|
|
418
|
+
|
|
351
419
|
if (dragY.value !== newTopPosition) {
|
|
352
420
|
// animate dragged item to its new position on release
|
|
353
421
|
dragY.value = withTiming(
|
|
@@ -364,7 +432,7 @@ export const useReorderableListCore = <T>({
|
|
|
364
432
|
// user might drag and release the item without moving it so,
|
|
365
433
|
// since the animation end callback is not executed in that case
|
|
366
434
|
// we need to reset values as the reorder function would do
|
|
367
|
-
|
|
435
|
+
runOnJS(resetSharedValuesAfterAnimations)();
|
|
368
436
|
}
|
|
369
437
|
}
|
|
370
438
|
},
|
|
@@ -485,20 +553,20 @@ export const useReorderableListCore = <T>({
|
|
|
485
553
|
() => currentY.value + scrollViewDragScrollTranslationY.value,
|
|
486
554
|
y => {
|
|
487
555
|
if (
|
|
488
|
-
state.value === ReorderableListState.
|
|
489
|
-
state.value === ReorderableListState.
|
|
556
|
+
state.value === ReorderableListState.DRAGGED ||
|
|
557
|
+
state.value === ReorderableListState.AUTOSCROLL
|
|
490
558
|
) {
|
|
491
559
|
setCurrentIndex(y);
|
|
492
560
|
|
|
493
561
|
if (scrollDirection(y) !== 0) {
|
|
494
|
-
if (state.value !== ReorderableListState.
|
|
562
|
+
if (state.value !== ReorderableListState.AUTOSCROLL) {
|
|
495
563
|
// trigger autoscroll
|
|
496
564
|
lastAutoscrollTrigger.value = autoscrollTrigger.value;
|
|
497
565
|
autoscrollTrigger.value *= -1;
|
|
498
|
-
state.value = ReorderableListState.
|
|
566
|
+
state.value = ReorderableListState.AUTOSCROLL;
|
|
499
567
|
}
|
|
500
|
-
} else if (state.value === ReorderableListState.
|
|
501
|
-
state.value = ReorderableListState.
|
|
568
|
+
} else if (state.value === ReorderableListState.AUTOSCROLL) {
|
|
569
|
+
state.value = ReorderableListState.DRAGGED;
|
|
502
570
|
}
|
|
503
571
|
}
|
|
504
572
|
},
|
|
@@ -509,7 +577,7 @@ export const useReorderableListCore = <T>({
|
|
|
509
577
|
() => {
|
|
510
578
|
if (
|
|
511
579
|
autoscrollTrigger.value !== lastAutoscrollTrigger.value &&
|
|
512
|
-
state.value === ReorderableListState.
|
|
580
|
+
state.value === ReorderableListState.AUTOSCROLL
|
|
513
581
|
) {
|
|
514
582
|
let y = currentY.value + scrollViewDragScrollTranslationY.value;
|
|
515
583
|
const autoscrollIncrement =
|
|
@@ -550,7 +618,7 @@ export const useReorderableListCore = <T>({
|
|
|
550
618
|
flatListScrollOffsetY.value - dragInitialScrollOffsetY.value;
|
|
551
619
|
}
|
|
552
620
|
|
|
553
|
-
if (state.value === ReorderableListState.
|
|
621
|
+
if (state.value === ReorderableListState.AUTOSCROLL) {
|
|
554
622
|
dragY.value =
|
|
555
623
|
currentTranslationY.value +
|
|
556
624
|
dragScrollTranslationY.value +
|
|
@@ -562,8 +630,6 @@ export const useReorderableListCore = <T>({
|
|
|
562
630
|
withTiming(autoscrollTrigger.value * -1, {duration: 0}),
|
|
563
631
|
);
|
|
564
632
|
}
|
|
565
|
-
|
|
566
|
-
onScroll?.(e);
|
|
567
633
|
});
|
|
568
634
|
|
|
569
635
|
// parent scroll handler
|
|
@@ -579,7 +645,7 @@ export const useReorderableListCore = <T>({
|
|
|
579
645
|
value - scrollViewDragInitialScrollOffsetY.value;
|
|
580
646
|
}
|
|
581
647
|
|
|
582
|
-
if (state.value === ReorderableListState.
|
|
648
|
+
if (state.value === ReorderableListState.AUTOSCROLL) {
|
|
583
649
|
dragY.value =
|
|
584
650
|
currentTranslationY.value + scrollViewDragScrollTranslationY.value;
|
|
585
651
|
|
|
@@ -603,6 +669,10 @@ export const useReorderableListCore = <T>({
|
|
|
603
669
|
// after scrolling the parent list it would offset the new dragged item in another nested list
|
|
604
670
|
resetSharedValues();
|
|
605
671
|
|
|
672
|
+
if (shouldUpdateActiveItem) {
|
|
673
|
+
runOnJS(setActiveIndex)(index);
|
|
674
|
+
}
|
|
675
|
+
|
|
606
676
|
dragInitialScrollOffsetY.value = flatListScrollOffsetY.value;
|
|
607
677
|
scrollViewDragInitialScrollOffsetY.value = scrollViewScrollOffsetY
|
|
608
678
|
? scrollViewScrollOffsetY.value
|
|
@@ -612,13 +682,18 @@ export const useReorderableListCore = <T>({
|
|
|
612
682
|
draggedIndex.value = index;
|
|
613
683
|
previousIndex.value = -1;
|
|
614
684
|
currentIndex.value = index;
|
|
615
|
-
state.value = ReorderableListState.
|
|
685
|
+
state.value = ReorderableListState.DRAGGED;
|
|
616
686
|
|
|
617
687
|
runOnJS(setScrollEnabled)(false);
|
|
688
|
+
|
|
689
|
+
// run animation before onDragStart to avoid potentially waiting for it
|
|
690
|
+
runDefaultDragAnimations('start');
|
|
691
|
+
onDragStart?.({index});
|
|
618
692
|
}
|
|
619
693
|
},
|
|
620
694
|
[
|
|
621
695
|
resetSharedValues,
|
|
696
|
+
shouldUpdateActiveItem,
|
|
622
697
|
dragInitialScrollOffsetY,
|
|
623
698
|
scrollViewScrollOffsetY,
|
|
624
699
|
scrollViewDragInitialScrollOffsetY,
|
|
@@ -630,6 +705,8 @@ export const useReorderableListCore = <T>({
|
|
|
630
705
|
state,
|
|
631
706
|
flatListScrollOffsetY,
|
|
632
707
|
itemHeight,
|
|
708
|
+
onDragStart,
|
|
709
|
+
runDefaultDragAnimations,
|
|
633
710
|
],
|
|
634
711
|
);
|
|
635
712
|
|
|
@@ -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,9 @@ 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>;
|
|
11
|
+
activeIndex: number;
|
|
9
12
|
}
|
|
10
13
|
|
|
11
14
|
export const ReorderableListContext = React.createContext<
|
package/src/hooks/index.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import {
|
|
2
2
|
NestedReorderableList,
|
|
3
3
|
ReorderableList,
|
|
4
|
-
ReorderableListItem,
|
|
5
4
|
ScrollViewContainer,
|
|
6
5
|
} from './components';
|
|
7
6
|
import {
|
|
7
|
+
useIsActive,
|
|
8
8
|
useReorderableDrag,
|
|
9
9
|
useReorderableDragEnd,
|
|
10
10
|
useReorderableDragStart,
|
|
11
11
|
} from './hooks';
|
|
12
12
|
import type {
|
|
13
|
+
ReorderableListCellAnimations,
|
|
13
14
|
ReorderableListDragEndEvent,
|
|
14
|
-
|
|
15
|
-
ReorderableListItemProps,
|
|
15
|
+
ReorderableListDragStartEvent,
|
|
16
16
|
ReorderableListProps,
|
|
17
17
|
ReorderableListReorderEvent,
|
|
18
18
|
ScrollViewContainerProps,
|
|
@@ -20,15 +20,15 @@ import type {
|
|
|
20
20
|
import {reorderItems} from './utils';
|
|
21
21
|
|
|
22
22
|
export {
|
|
23
|
+
useIsActive,
|
|
23
24
|
useReorderableDrag,
|
|
24
25
|
useReorderableDragStart,
|
|
25
26
|
useReorderableDragEnd,
|
|
26
27
|
ReorderableListProps,
|
|
27
28
|
ReorderableListReorderEvent,
|
|
29
|
+
ReorderableListCellAnimations,
|
|
30
|
+
ReorderableListDragStartEvent,
|
|
28
31
|
ReorderableListDragEndEvent,
|
|
29
|
-
ReorderableListItem,
|
|
30
|
-
ReorderableListItemConfig,
|
|
31
|
-
ReorderableListItemProps,
|
|
32
32
|
ScrollViewContainer,
|
|
33
33
|
ScrollViewContainerProps,
|
|
34
34
|
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,56 @@ export interface ReorderableListProps<T>
|
|
|
69
71
|
*/
|
|
70
72
|
animationDuration?: number;
|
|
71
73
|
/**
|
|
72
|
-
*
|
|
74
|
+
* Allows passing an object with shared values that can animate a cell by using the `onDragStart` and `onDragEnd` events.
|
|
73
75
|
*/
|
|
74
|
-
|
|
76
|
+
cellAnimations?: ReorderableListCellAnimations;
|
|
75
77
|
/**
|
|
76
|
-
*
|
|
78
|
+
* Whether the active item should be updated. Enables usage of `useIsActive` hook. Default: `false`.
|
|
77
79
|
*/
|
|
78
|
-
|
|
80
|
+
shouldUpdateActiveItem?: boolean;
|
|
79
81
|
/**
|
|
80
|
-
*
|
|
82
|
+
* Wether the pan gestures necessary for dragging are enabled. Default: `true`.
|
|
81
83
|
*/
|
|
82
|
-
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export interface ReorderableListItemConfig {
|
|
86
|
-
/**
|
|
87
|
-
* Value of the animated style on drag end.
|
|
88
|
-
*/
|
|
89
|
-
enabled?: boolean;
|
|
84
|
+
panEnabled?: boolean;
|
|
90
85
|
/**
|
|
91
|
-
*
|
|
86
|
+
* Duration in milliseconds of a long press on the list before pan gestures, necessary for dragging, are allowed to activate.
|
|
92
87
|
*/
|
|
93
|
-
|
|
88
|
+
panActivateAfterLongPress?: number;
|
|
94
89
|
/**
|
|
95
|
-
*
|
|
90
|
+
* Event fired after an item is released and the list is reordered.
|
|
96
91
|
*/
|
|
97
|
-
|
|
92
|
+
onReorder: (event: ReorderableListReorderEvent) => void;
|
|
98
93
|
/**
|
|
99
|
-
*
|
|
94
|
+
* An animated scroll handler created with useAnimatedScrollHandler. See [Reanimated docs](https://docs.swmansion.com/react-native-reanimated) for further info.
|
|
100
95
|
*/
|
|
101
|
-
|
|
96
|
+
onScroll?: ReturnType<typeof useAnimatedScrollHandler>;
|
|
102
97
|
/**
|
|
103
|
-
*
|
|
98
|
+
* 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
99
|
*/
|
|
105
|
-
|
|
100
|
+
onDragStart?: (event: ReorderableListDragStartEvent) => void;
|
|
106
101
|
/**
|
|
107
|
-
*
|
|
102
|
+
* 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
103
|
*/
|
|
109
|
-
|
|
104
|
+
onDragEnd?: (event: ReorderableListDragEndEvent) => void;
|
|
110
105
|
}
|
|
111
106
|
|
|
112
|
-
export interface
|
|
107
|
+
export interface ReorderableListCellAnimations {
|
|
113
108
|
/**
|
|
114
|
-
*
|
|
109
|
+
* Shared value to animate the opacity of a dragged item. Set to false to disable default opacity animations.
|
|
115
110
|
*/
|
|
116
|
-
|
|
111
|
+
opacity?: SharedValue<number> | false;
|
|
117
112
|
/**
|
|
118
|
-
*
|
|
113
|
+
* Shared value to animate the scale of a dragged item. Set to false to disable default scale animations.
|
|
119
114
|
*/
|
|
120
|
-
|
|
115
|
+
scale?: SharedValue<number> | false;
|
|
121
116
|
}
|
|
122
117
|
|
|
123
118
|
export interface ScrollViewContainerProps
|
|
124
119
|
extends Omit<ScrollViewProps, 'onScroll'> {
|
|
125
120
|
/**
|
|
126
|
-
*
|
|
121
|
+
* An animated scroll handler created with useAnimatedScrollHandler. See [Reanimated docs](https://docs.swmansion.com/react-native-reanimated) for further info.
|
|
127
122
|
*/
|
|
128
|
-
onScroll?:
|
|
123
|
+
onScroll?: ReturnType<typeof useAnimatedScrollHandler>;
|
|
129
124
|
}
|
|
130
125
|
|
|
131
126
|
export interface NestedReorderableListProps<T> extends ReorderableListProps<T> {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["_reactNative","require","IOS_CONFIG","delay","increment","ANDROID_FABRIC_CONFIG","ANDROID_PAPER_CONFIG","IS_FABRIC","exports","global","AUTOSCROLL_CONFIG","Platform","select","android","ios","web","macos","windows","native"],"sourceRoot":"../../../../src","sources":["components/ReorderableListCore/constants.ts"],"mappings":";;;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AAEA,MAAMC,UAAU,GAAG;EACjBC,KAAK,EAAE,EAAE;EACTC,SAAS,EAAE;AACb,CAAC;AAED,MAAMC,qBAAqB,GAAG;EAC5BF,KAAK,EAAE,EAAE;EACTC,SAAS,EAAE;AACb,CAAC;AAED,MAAME,oBAAoB,GAAG;EAC3BH,KAAK,EAAE,EAAE;EACTC,SAAS,EAAE;AACb,CAAC;AAEM,MAAMG,SAAS,GAAAC,OAAA,CAAAD,SAAA,GACpBE,MAAM,IAAI,OAAOA,MAAM,KAAK,QAAQ,IAAI,uBAAuB,IAAIA,MAAM;AAEpE,MAAMC,iBAAiB,GAAAF,OAAA,CAAAE,iBAAA,GAAGC,qBAAQ,CAACC,MAAM,CAAC;EAC/C;EACAC,OAAO,EAAEN,SAAS,GAAGF,qBAAqB,GAAGC,oBAAoB;EACjEQ,GAAG,EAAEZ,UAAU;EAEf;EACAa,GAAG,EAAEb,UAAU;EACfc,KAAK,EAAEd,UAAU;EACjBe,OAAO,EAAEf,UAAU;EACnBgB,MAAM,EAAEhB;AACV,CAAC,CAAC","ignoreList":[]}
|