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.
Files changed (96) hide show
  1. package/README.md +53 -47
  2. package/lib/commonjs/components/ReorderableList.js +11 -13
  3. package/lib/commonjs/components/ReorderableList.js.map +1 -1
  4. package/lib/commonjs/components/ReorderableListCell.js +39 -29
  5. package/lib/commonjs/components/ReorderableListCell.js.map +1 -1
  6. package/lib/commonjs/components/ReorderableListCore/ReorderableListCore.js +10 -7
  7. package/lib/commonjs/components/ReorderableListCore/ReorderableListCore.js.map +1 -1
  8. package/lib/commonjs/components/ReorderableListCore/animationDefaults.js +34 -0
  9. package/lib/commonjs/components/ReorderableListCore/animationDefaults.js.map +1 -0
  10. package/lib/commonjs/components/ReorderableListCore/autoscrollConfig.js +31 -0
  11. package/lib/commonjs/components/ReorderableListCore/autoscrollConfig.js.map +1 -0
  12. package/lib/commonjs/components/ReorderableListCore/useReorderableListCore.js +66 -41
  13. package/lib/commonjs/components/ReorderableListCore/useReorderableListCore.js.map +1 -1
  14. package/lib/commonjs/components/ScrollViewContainer.js +2 -2
  15. package/lib/commonjs/components/ScrollViewContainer.js.map +1 -1
  16. package/lib/commonjs/components/index.js +0 -11
  17. package/lib/commonjs/components/index.js.map +1 -1
  18. package/lib/commonjs/contexts/ReorderableListContext.js.map +1 -1
  19. package/lib/commonjs/index.js +0 -6
  20. package/lib/commonjs/index.js.map +1 -1
  21. package/lib/commonjs/types/misc.js +3 -3
  22. package/lib/module/components/ReorderableList.js +11 -13
  23. package/lib/module/components/ReorderableList.js.map +1 -1
  24. package/lib/module/components/ReorderableListCell.js +40 -30
  25. package/lib/module/components/ReorderableListCell.js.map +1 -1
  26. package/lib/module/components/ReorderableListCore/ReorderableListCore.js +10 -6
  27. package/lib/module/components/ReorderableListCore/ReorderableListCore.js.map +1 -1
  28. package/lib/module/components/ReorderableListCore/animationDefaults.js +28 -0
  29. package/lib/module/components/ReorderableListCore/animationDefaults.js.map +1 -0
  30. package/lib/module/components/ReorderableListCore/autoscrollConfig.js +25 -0
  31. package/lib/module/components/ReorderableListCore/autoscrollConfig.js.map +1 -0
  32. package/lib/module/components/ReorderableListCore/useReorderableListCore.js +68 -43
  33. package/lib/module/components/ReorderableListCore/useReorderableListCore.js.map +1 -1
  34. package/lib/module/components/ScrollViewContainer.js +3 -3
  35. package/lib/module/components/ScrollViewContainer.js.map +1 -1
  36. package/lib/module/components/index.js +0 -1
  37. package/lib/module/components/index.js.map +1 -1
  38. package/lib/module/contexts/ReorderableListContext.js.map +1 -1
  39. package/lib/module/index.js +2 -2
  40. package/lib/module/index.js.map +1 -1
  41. package/lib/module/types/misc.js +3 -3
  42. package/lib/typescript/components/ReorderableList.d.ts.map +1 -1
  43. package/lib/typescript/components/ReorderableListCell.d.ts +1 -1
  44. package/lib/typescript/components/ReorderableListCell.d.ts.map +1 -1
  45. package/lib/typescript/components/ReorderableListCore/ReorderableListCore.d.ts.map +1 -1
  46. package/lib/typescript/components/ReorderableListCore/animationDefaults.d.ts +13 -0
  47. package/lib/typescript/components/ReorderableListCore/animationDefaults.d.ts.map +1 -0
  48. package/lib/typescript/components/ReorderableListCore/autoscrollConfig.d.ts +6 -0
  49. package/lib/typescript/components/ReorderableListCore/autoscrollConfig.d.ts.map +1 -0
  50. package/lib/typescript/components/ReorderableListCore/useReorderableListCore.d.ts +7 -4
  51. package/lib/typescript/components/ReorderableListCore/useReorderableListCore.d.ts.map +1 -1
  52. package/lib/typescript/components/ScrollViewContainer.d.ts.map +1 -1
  53. package/lib/typescript/components/index.d.ts +0 -1
  54. package/lib/typescript/components/index.d.ts.map +1 -1
  55. package/lib/typescript/contexts/ReorderableListContext.d.ts +2 -0
  56. package/lib/typescript/contexts/ReorderableListContext.d.ts.map +1 -1
  57. package/lib/typescript/index.d.ts +3 -3
  58. package/lib/typescript/index.d.ts.map +1 -1
  59. package/lib/typescript/types/misc.d.ts +3 -3
  60. package/lib/typescript/types/misc.d.ts.map +1 -1
  61. package/lib/typescript/types/props.d.ts +25 -37
  62. package/lib/typescript/types/props.d.ts.map +1 -1
  63. package/package.json +19 -11
  64. package/src/components/ReorderableList.tsx +14 -16
  65. package/src/components/ReorderableListCell.tsx +36 -32
  66. package/src/components/ReorderableListCore/ReorderableListCore.tsx +16 -5
  67. package/src/components/ReorderableListCore/animationDefaults.ts +35 -0
  68. package/src/components/ReorderableListCore/autoscrollConfig.ts +31 -0
  69. package/src/components/ReorderableListCore/useReorderableListCore.ts +94 -52
  70. package/src/components/ScrollViewContainer.tsx +7 -3
  71. package/src/components/index.ts +0 -1
  72. package/src/contexts/ReorderableListContext.ts +2 -0
  73. package/src/index.ts +4 -6
  74. package/src/types/misc.ts +3 -3
  75. package/src/types/props.ts +26 -43
  76. package/lib/commonjs/components/ReorderableListCore/constants.ios.js +0 -10
  77. package/lib/commonjs/components/ReorderableListCore/constants.ios.js.map +0 -1
  78. package/lib/commonjs/components/ReorderableListCore/constants.js +0 -10
  79. package/lib/commonjs/components/ReorderableListCore/constants.js.map +0 -1
  80. package/lib/commonjs/components/ReorderableListItem.js +0 -87
  81. package/lib/commonjs/components/ReorderableListItem.js.map +0 -1
  82. package/lib/module/components/ReorderableListCore/constants.ios.js +0 -4
  83. package/lib/module/components/ReorderableListCore/constants.ios.js.map +0 -1
  84. package/lib/module/components/ReorderableListCore/constants.js +0 -4
  85. package/lib/module/components/ReorderableListCore/constants.js.map +0 -1
  86. package/lib/module/components/ReorderableListItem.js +0 -78
  87. package/lib/module/components/ReorderableListItem.js.map +0 -1
  88. package/lib/typescript/components/ReorderableListCore/constants.d.ts +0 -3
  89. package/lib/typescript/components/ReorderableListCore/constants.d.ts.map +0 -1
  90. package/lib/typescript/components/ReorderableListCore/constants.ios.d.ts +0 -3
  91. package/lib/typescript/components/ReorderableListCore/constants.ios.d.ts.map +0 -1
  92. package/lib/typescript/components/ReorderableListItem.d.ts +0 -4
  93. package/lib/typescript/components/ReorderableListItem.d.ts.map +0 -1
  94. package/src/components/ReorderableListCore/constants.ios.ts +0 -3
  95. package/src/components/ReorderableListCore/constants.ts +0 -3
  96. 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 {AUTOSCROLL_INCREMENT} from './constants';
28
- import {ReorderableListDragEndEvent, ReorderableListState} from '../../types';
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
- if (duration.value !== animationDuration) {
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
- [draggedHeight, currentIndex, draggedIndex, dragEndHandlers],
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
- if (draggedIndex.value >= 0) {
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.RELEASING) {
156
+ if (state.value !== ReorderableListState.RELEASED) {
138
157
  currentY.value = startY.value + e.translationY;
139
158
  currentTranslationY.value = e.translationY;
140
- if (draggedIndex.value >= 0) {
141
- dragY.value =
142
- e.translationY +
143
- dragScrollTranslationY.value +
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.DRAGGING ||
326
- state.value === ReorderableListState.AUTO_SCROLL)
362
+ (state.value === ReorderableListState.DRAGGED ||
363
+ state.value === ReorderableListState.AUTOSCROLL)
327
364
  ) {
328
- state.value = ReorderableListState.RELEASING;
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
- resetSharedValues();
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.DRAGGING ||
492
- state.value === ReorderableListState.AUTO_SCROLL
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.AUTO_SCROLL) {
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
- state.value = ReorderableListState.AUTO_SCROLL;
503
- } else {
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.AUTO_SCROLL
555
+ state.value === ReorderableListState.AUTOSCROLL
516
556
  ) {
517
557
  let y = currentY.value + scrollViewDragScrollTranslationY.value;
518
558
  const autoscrollIncrement =
519
- scrollDirection(y) * AUTOSCROLL_INCREMENT * autoscrollSpeedScale;
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 await from autoscroll area
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.AUTO_SCROLL) {
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.AUTO_SCROLL) {
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.DRAGGING;
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={handleScroll}
71
+ onScroll={composedScrollHandler}
68
72
  onLayout={handleLayout}
69
73
  scrollEnabled={scrollEnabled}
70
74
  />
@@ -1,5 +1,4 @@
1
1
  export * from './ReorderableList';
2
2
  export * from './NestedReorderableList';
3
3
  export * from './ReorderableListCell';
4
- export * from './ReorderableListItem';
5
4
  export * from './ScrollViewContainer';
@@ -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
- ReorderableListItemConfig,
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
@@ -1,6 +1,6 @@
1
1
  export enum ReorderableListState {
2
2
  IDLE = 0,
3
- DRAGGING,
4
- RELEASING,
5
- AUTO_SCROLL,
3
+ DRAGGED,
4
+ RELEASED,
5
+ AUTOSCROLL,
6
6
  }
@@ -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 {EasingFunction} from 'react-native-reanimated';
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
- * Event fired after an item is released and the list is reordered.
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
- onScroll?: (event: NativeScrollEvent) => void;
76
+ cellAnimations?: ReorderableListCellAnimations;
79
77
  /**
80
- * 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.
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
- valueStart?: number;
80
+ onReorder: (event: ReorderableListReorderEvent) => void;
98
81
  /**
99
- * Easing function for the animation to the end value. Default: `Easing.in(Easing.ease)`.
82
+ * An animated scroll handler created with useAnimatedScrollHandler. See [Reanimated docs](https://docs.swmansion.com/react-native-reanimated) for further info.
100
83
  */
101
- easingEnd?: EasingFunction;
84
+ onScroll?: ReturnType<typeof useAnimatedScrollHandler>;
102
85
  /**
103
- * Easing function for the animation to the start value. Default: `Easing.out(Easing.ease)`.
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
- easingStart?: EasingFunction;
88
+ onDragStart?: (event: ReorderableListDragStartEvent) => void;
106
89
  /**
107
- * Duration of the animations in milliseconds. Default: `200`.
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
- duration?: number;
92
+ onDragEnd?: (event: ReorderableListDragEndEvent) => void;
110
93
  }
111
94
 
112
- export interface ReorderableListItemProps extends ViewProps {
95
+ export interface ReorderableListCellAnimations {
113
96
  /**
114
- * Config for the `opacity` animation. Enabled by default with custom default options.
97
+ * Shared value to animate the opacity of a dragged item. Set to false to disable default opacity animations.
115
98
  */
116
- opacityAnimationConfig?: ReorderableListItemConfig;
99
+ opacity?: SharedValue<number> | false;
117
100
  /**
118
- * Config for the `scale` animation. Enabled by default with custom default options.
101
+ * Shared value to animate the scale of a dragged item. Set to false to disable default scale animations.
119
102
  */
120
- scaleAnimationConfig?: ReorderableListItemConfig;
103
+ scale?: SharedValue<number> | false;
121
104
  }
122
105
 
123
106
  export interface ScrollViewContainerProps
124
107
  extends Omit<ScrollViewProps, 'onScroll'> {
125
108
  /**
126
- * 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.
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?: (event: NativeScrollEvent) => void;
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":[]}