react-native-reorderable-list 0.13.1 → 0.14.1

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 (54) hide show
  1. package/README.md +69 -9
  2. package/lib/commonjs/components/{ReorderableListCore/useReorderableListCore.js → ReorderableListCore.js} +117 -58
  3. package/lib/commonjs/components/ReorderableListCore.js.map +1 -0
  4. package/lib/commonjs/components/ScrollViewContainer.js +12 -4
  5. package/lib/commonjs/components/ScrollViewContainer.js.map +1 -1
  6. package/lib/commonjs/components/{ReorderableListCore/animationDefaults.js → constants.js} +26 -2
  7. package/lib/commonjs/components/constants.js.map +1 -0
  8. package/lib/module/components/{ReorderableListCore/useReorderableListCore.js → ReorderableListCore.js} +117 -56
  9. package/lib/module/components/ReorderableListCore.js.map +1 -0
  10. package/lib/module/components/ScrollViewContainer.js +13 -4
  11. package/lib/module/components/ScrollViewContainer.js.map +1 -1
  12. package/lib/module/components/constants.js +52 -0
  13. package/lib/module/components/constants.js.map +1 -0
  14. package/lib/typescript/components/{ReorderableListCore/ReorderableListCore.d.ts → ReorderableListCore.d.ts} +1 -1
  15. package/lib/typescript/components/ReorderableListCore.d.ts.map +1 -0
  16. package/lib/typescript/components/ScrollViewContainer.d.ts +2 -1
  17. package/lib/typescript/components/ScrollViewContainer.d.ts.map +1 -1
  18. package/lib/typescript/components/{ReorderableListCore/animationDefaults.d.ts → constants.d.ts} +6 -1
  19. package/lib/typescript/components/constants.d.ts.map +1 -0
  20. package/lib/typescript/types/props.d.ts +9 -0
  21. package/lib/typescript/types/props.d.ts.map +1 -1
  22. package/package.json +1 -1
  23. package/src/components/{ReorderableListCore/useReorderableListCore.ts → ReorderableListCore.tsx} +189 -100
  24. package/src/components/ScrollViewContainer.tsx +22 -9
  25. package/src/components/{ReorderableListCore/animationDefaults.ts → constants.ts} +34 -0
  26. package/src/types/props.ts +9 -0
  27. package/lib/commonjs/components/ReorderableListCore/ReorderableListCore.js +0 -123
  28. package/lib/commonjs/components/ReorderableListCore/ReorderableListCore.js.map +0 -1
  29. package/lib/commonjs/components/ReorderableListCore/animationDefaults.js.map +0 -1
  30. package/lib/commonjs/components/ReorderableListCore/autoscrollConfig.js +0 -31
  31. package/lib/commonjs/components/ReorderableListCore/autoscrollConfig.js.map +0 -1
  32. package/lib/commonjs/components/ReorderableListCore/index.js +0 -17
  33. package/lib/commonjs/components/ReorderableListCore/index.js.map +0 -1
  34. package/lib/commonjs/components/ReorderableListCore/useReorderableListCore.js.map +0 -1
  35. package/lib/module/components/ReorderableListCore/ReorderableListCore.js +0 -116
  36. package/lib/module/components/ReorderableListCore/ReorderableListCore.js.map +0 -1
  37. package/lib/module/components/ReorderableListCore/animationDefaults.js +0 -28
  38. package/lib/module/components/ReorderableListCore/animationDefaults.js.map +0 -1
  39. package/lib/module/components/ReorderableListCore/autoscrollConfig.js +0 -25
  40. package/lib/module/components/ReorderableListCore/autoscrollConfig.js.map +0 -1
  41. package/lib/module/components/ReorderableListCore/index.js +0 -2
  42. package/lib/module/components/ReorderableListCore/index.js.map +0 -1
  43. package/lib/module/components/ReorderableListCore/useReorderableListCore.js.map +0 -1
  44. package/lib/typescript/components/ReorderableListCore/ReorderableListCore.d.ts.map +0 -1
  45. package/lib/typescript/components/ReorderableListCore/animationDefaults.d.ts.map +0 -1
  46. package/lib/typescript/components/ReorderableListCore/autoscrollConfig.d.ts +0 -6
  47. package/lib/typescript/components/ReorderableListCore/autoscrollConfig.d.ts.map +0 -1
  48. package/lib/typescript/components/ReorderableListCore/index.d.ts +0 -2
  49. package/lib/typescript/components/ReorderableListCore/index.d.ts.map +0 -1
  50. package/lib/typescript/components/ReorderableListCore/useReorderableListCore.d.ts +0 -183
  51. package/lib/typescript/components/ReorderableListCore/useReorderableListCore.d.ts.map +0 -1
  52. package/src/components/ReorderableListCore/ReorderableListCore.tsx +0 -178
  53. package/src/components/ReorderableListCore/autoscrollConfig.ts +0 -31
  54. package/src/components/ReorderableListCore/index.ts +0 -1
@@ -1,14 +1,18 @@
1
- import React, {useCallback, useEffect, useMemo, useState} from 'react';
1
+ import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';
2
2
  import {
3
+ CellRendererProps,
3
4
  FlatList,
5
+ FlatListProps,
4
6
  LayoutChangeEvent,
7
+ Platform,
5
8
  ScrollView,
6
- unstable_batchedUpdates,
7
9
  } from 'react-native';
8
10
 
9
11
  import {
10
12
  Gesture,
13
+ GestureDetector,
11
14
  GestureUpdateEvent,
15
+ NativeGesture,
12
16
  PanGestureHandlerEventPayload,
13
17
  State,
14
18
  } from 'react-native-gesture-handler';
@@ -23,84 +27,81 @@ import Animated, {
23
27
  useAnimatedReaction,
24
28
  useAnimatedRef,
25
29
  useAnimatedScrollHandler,
30
+ useComposedEventHandler,
26
31
  useDerivedValue,
27
32
  useSharedValue,
28
33
  withDelay,
29
34
  withTiming,
30
35
  } from 'react-native-reanimated';
31
36
 
37
+ import {ReorderableListContext} from '../contexts';
38
+ import {ReorderableListProps, ReorderableListState} from '../types';
32
39
  import {
40
+ AUTOSCROLL_CONFIG,
33
41
  OPACITY_ANIMATION_CONFIG_DEFAULT,
34
42
  SCALE_ANIMATION_CONFIG_DEFAULT,
35
- } from './animationDefaults';
36
- import {AUTOSCROLL_CONFIG} from './autoscrollConfig';
37
- import {
38
- ReorderableListCellAnimations,
39
- ReorderableListDragEndEvent,
40
- ReorderableListDragStartEvent,
41
- ReorderableListIndexChangeEvent,
42
- ReorderableListReorderEvent,
43
- ReorderableListState,
44
- } from '../../types';
45
-
46
- const version = React.version.split('.');
47
- const hasAutomaticBatching = version.length
48
- ? parseInt(version[0], 10) >= 18
49
- : false;
50
-
51
- interface UseReorderableListCoreArgs<T> {
52
- ref: React.ForwardedRef<FlatList<T>>;
53
- autoscrollThreshold: number;
54
- autoscrollThresholdOffset: {top?: number; bottom?: number} | undefined;
55
- autoscrollSpeedScale: number;
56
- autoscrollDelay: number;
57
- autoscrollActivationDelta: number;
58
- animationDuration: number;
59
- onReorder: (event: ReorderableListReorderEvent) => void;
60
- onDragStart?: (event: ReorderableListDragStartEvent) => void;
61
- onDragEnd?: (event: ReorderableListDragEndEvent) => void;
62
- onIndexChange?: (event: ReorderableListIndexChangeEvent) => void;
63
- onLayout?: (event: LayoutChangeEvent) => void;
43
+ } from './constants';
44
+ import {ReorderableListCell} from './ReorderableListCell';
45
+
46
+ const AnimatedFlatList = Animated.createAnimatedComponent(
47
+ FlatList,
48
+ ) as unknown as <T>(
49
+ props: FlatListProps<T> & {ref?: React.Ref<FlatList<T>>},
50
+ ) => React.ReactElement;
51
+
52
+ interface ReorderableListCoreProps<T> extends ReorderableListProps<T> {
53
+ // Not optional but undefined to force passing the prop.
64
54
  scrollViewContainerRef: React.RefObject<ScrollView> | undefined;
65
55
  scrollViewPageY: SharedValue<number> | undefined;
66
56
  scrollViewHeightY: SharedValue<number> | undefined;
67
57
  scrollViewScrollOffsetY: SharedValue<number> | undefined;
68
58
  scrollViewScrollEnabled: SharedValue<boolean> | undefined;
69
- scrollable: boolean | undefined;
70
- initialScrollEnabled: boolean | undefined;
59
+ outerScrollGesture: NativeGesture | undefined;
71
60
  initialScrollViewScrollEnabled: boolean | undefined;
72
- cellAnimations: ReorderableListCellAnimations | undefined;
73
- shouldUpdateActiveItem: boolean | undefined;
74
- panEnabled: boolean;
75
- panActivateAfterLongPress: number | undefined;
61
+ scrollable: boolean | undefined;
62
+ scrollEnabled: boolean | undefined;
76
63
  }
77
64
 
78
- export const useReorderableListCore = <T>({
79
- ref,
80
- autoscrollThreshold,
81
- autoscrollThresholdOffset,
82
- autoscrollSpeedScale,
83
- autoscrollDelay,
84
- autoscrollActivationDelta,
85
- animationDuration,
86
- onReorder,
87
- onDragStart,
88
- onDragEnd,
89
- onLayout,
90
- onIndexChange,
91
- scrollViewContainerRef,
92
- scrollViewPageY,
93
- scrollViewHeightY,
94
- scrollViewScrollOffsetY,
95
- scrollViewScrollEnabled,
96
- scrollable,
97
- initialScrollEnabled,
98
- initialScrollViewScrollEnabled,
99
- cellAnimations,
100
- shouldUpdateActiveItem,
101
- panActivateAfterLongPress,
102
- panEnabled,
103
- }: UseReorderableListCoreArgs<T>) => {
65
+ const ReorderableListCore = <T,>(
66
+ {
67
+ autoscrollThreshold = 0.1,
68
+ autoscrollThresholdOffset,
69
+ autoscrollSpeedScale = 1,
70
+ autoscrollDelay = AUTOSCROLL_CONFIG.delay,
71
+ autoscrollActivationDelta = 5,
72
+ animationDuration = 200,
73
+ onLayout,
74
+ onReorder,
75
+ onScroll,
76
+ onDragStart,
77
+ onDragEnd,
78
+ onIndexChange,
79
+ scrollViewContainerRef,
80
+ scrollViewPageY,
81
+ scrollViewHeightY,
82
+ scrollViewScrollOffsetY,
83
+ scrollViewScrollEnabled,
84
+ scrollable,
85
+ outerScrollGesture,
86
+ cellAnimations,
87
+ shouldUpdateActiveItem,
88
+ panGesture,
89
+ panEnabled = true,
90
+ panActivateAfterLongPress,
91
+ data,
92
+ ...rest
93
+ }: ReorderableListCoreProps<T>,
94
+ ref: React.ForwardedRef<FlatList<T>>,
95
+ ) => {
96
+ // FlatList will default to true if we pass explicitly undefined,
97
+ // but internally we would treat it as false, so we force true.
98
+ const initialScrollEnabled =
99
+ typeof rest.scrollEnabled === 'undefined' ? true : rest.scrollEnabled;
100
+ const initialScrollViewScrollEnabled =
101
+ typeof rest.initialScrollViewScrollEnabled === 'undefined'
102
+ ? true
103
+ : rest.initialScrollViewScrollEnabled;
104
+
104
105
  const flatListRef = useAnimatedRef<FlatList>();
105
106
  const [activeIndex, setActiveIndex] = useState(-1);
106
107
  const scrollEnabled = useSharedValue(initialScrollEnabled);
@@ -123,6 +124,9 @@ export const useReorderableListCore = <T>({
123
124
  const draggedHeight = useSharedValue(0);
124
125
  const itemOffset = useSharedValue<number[]>([]);
125
126
  const itemHeight = useSharedValue<number[]>([]);
127
+ // We need to track data length since itemOffset and itemHeight might contain more data than we need.
128
+ // e.g. items are removed from the list, in which case layout data for those items is set to 0.
129
+ const itemCount = useSharedValue(data.length);
126
130
  const autoscrollTrigger = useSharedValue(-1);
127
131
  const lastAutoscrollTrigger = useSharedValue(-1);
128
132
  const dragY = useSharedValue(0);
@@ -139,6 +143,7 @@ export const useReorderableListCore = <T>({
139
143
  const dragDirection = useSharedValue(0);
140
144
  const lastDragDirectionPivot = useSharedValue<number | null>(null);
141
145
  const autoscrollDelta = useSharedValue(autoscrollActivationDelta);
146
+ const prevItemCount = useRef(data.length);
142
147
 
143
148
  // Position of the list relative to the scroll container
144
149
  const nestedFlatListPositionY = useDerivedValue(
@@ -148,7 +153,31 @@ export const useReorderableListCore = <T>({
148
153
  useEffect(() => {
149
154
  duration.value = animationDuration;
150
155
  autoscrollDelta.value = autoscrollActivationDelta;
151
- }, [duration, animationDuration, autoscrollDelta, autoscrollActivationDelta]);
156
+ }, [
157
+ duration,
158
+ animationDuration,
159
+ autoscrollDelta,
160
+ autoscrollActivationDelta,
161
+ itemCount,
162
+ ]);
163
+
164
+ useEffect(() => {
165
+ itemCount.value = data.length;
166
+
167
+ // This could be done unmount of the removed cell, however it leads to bugs.
168
+ // Surprisingly the unmount gets sometimes called after the onLayout event
169
+ // setting all layout data to 0 and breaking the list. So we solve it like this.
170
+ if (data.length < prevItemCount.current) {
171
+ for (let i = data.length; i < prevItemCount.current; i++) {
172
+ runOnUI(() => {
173
+ itemHeight.value[i] = 0;
174
+ itemOffset.value[i] = 0;
175
+ })();
176
+ }
177
+ }
178
+
179
+ prevItemCount.current = data.length;
180
+ }, [data.length, itemHeight, itemOffset, itemCount]);
152
181
 
153
182
  const listContextValue = useMemo(
154
183
  () => ({
@@ -243,8 +272,10 @@ export const useReorderableListCore = <T>({
243
272
 
244
273
  const panGestureHandler = useMemo(
245
274
  () =>
246
- Gesture.Pan()
275
+ (panGesture || Gesture.Pan())
247
276
  .onBegin(e => {
277
+ 'worklet';
278
+
248
279
  // prevent new dragging until item is completely released
249
280
  if (state.value === ReorderableListState.IDLE) {
250
281
  startY.value = e.y;
@@ -255,6 +286,8 @@ export const useReorderableListCore = <T>({
255
286
  }
256
287
  })
257
288
  .onUpdate(e => {
289
+ 'worklet';
290
+
258
291
  if (state.value === ReorderableListState.DRAGGED) {
259
292
  setDragDirection(e);
260
293
  }
@@ -271,9 +304,18 @@ export const useReorderableListCore = <T>({
271
304
  gestureState.value = e.state;
272
305
  }
273
306
  })
274
- .onEnd(e => (gestureState.value = e.state))
275
- .onFinalize(e => (gestureState.value = e.state)),
307
+ .onEnd(e => {
308
+ 'worklet';
309
+
310
+ gestureState.value = e.state;
311
+ })
312
+ .onFinalize(e => {
313
+ 'worklet';
314
+
315
+ gestureState.value = e.state;
316
+ }),
276
317
  [
318
+ panGesture,
277
319
  state,
278
320
  startY,
279
321
  currentY,
@@ -287,7 +329,7 @@ export const useReorderableListCore = <T>({
287
329
  ],
288
330
  );
289
331
 
290
- const panGestureHandlerWithOptions = useMemo(() => {
332
+ const panGestureHandlerWithPropOptions = useMemo(() => {
291
333
  if (typeof panActivateAfterLongPress === 'number') {
292
334
  panGestureHandler.activateAfterLongPress(panActivateAfterLongPress);
293
335
  }
@@ -300,8 +342,9 @@ export const useReorderableListCore = <T>({
300
342
  }, [panActivateAfterLongPress, panEnabled, panGestureHandler]);
301
343
 
302
344
  const gestureHandler = useMemo(
303
- () => Gesture.Simultaneous(Gesture.Native(), panGestureHandlerWithOptions),
304
- [panGestureHandlerWithOptions],
345
+ () =>
346
+ Gesture.Simultaneous(Gesture.Native(), panGestureHandlerWithPropOptions),
347
+ [panGestureHandlerWithPropOptions],
305
348
  );
306
349
 
307
350
  const setScrollEnabled = useCallback(
@@ -363,15 +406,7 @@ export const useReorderableListCore = <T>({
363
406
  runOnUI(resetSharedValues)();
364
407
 
365
408
  if (fromIndex !== toIndex) {
366
- const updateState = () => {
367
- onReorder({from: fromIndex, to: toIndex});
368
- };
369
-
370
- if (!hasAutomaticBatching) {
371
- unstable_batchedUpdates(updateState);
372
- } else {
373
- updateState();
374
- }
409
+ onReorder({from: fromIndex, to: toIndex});
375
410
  }
376
411
  };
377
412
 
@@ -423,7 +458,7 @@ export const useReorderableListCore = <T>({
423
458
  const currentHeight = itemHeight.value[currentIndex.value];
424
459
  const currentCenter = currentOffset + currentHeight * 0.5;
425
460
 
426
- const max = itemOffset.value.length;
461
+ const max = itemCount.value;
427
462
  const possibleIndex =
428
463
  relativeDragCenterY < currentCenter
429
464
  ? Math.max(0, currentIndex.value - 1)
@@ -450,6 +485,7 @@ export const useReorderableListCore = <T>({
450
485
  }, [
451
486
  currentIndex,
452
487
  currentItemDragCenterY,
488
+ itemCount,
453
489
  itemOffset,
454
490
  itemHeight,
455
491
  flatListScrollOffsetY,
@@ -870,7 +906,11 @@ export const useReorderableListCore = <T>({
870
906
  return;
871
907
  }
872
908
 
873
- flatListPageY.value = measurement.pageY;
909
+ // We need to use pageY because the list might be nested into other views,
910
+ // It's important that we take the measurement of the list without any scroll offset
911
+ // from the scroll container.
912
+ flatListPageY.value =
913
+ measurement.pageY + (scrollViewScrollOffsetY?.value || 0);
874
914
  })();
875
915
  }, 100);
876
916
  }
@@ -886,27 +926,76 @@ export const useReorderableListCore = <T>({
886
926
  ],
887
927
  );
888
928
 
889
- const handleRef = (value: FlatList<T>) => {
890
- flatListRef(value);
929
+ const handleRef = useCallback(
930
+ (value: FlatList<T>) => {
931
+ flatListRef(value);
932
+
933
+ if (typeof ref === 'function') {
934
+ ref(value);
935
+ } else if (ref) {
936
+ ref.current = value;
937
+ }
938
+ },
939
+ [flatListRef, ref],
940
+ );
891
941
 
892
- if (typeof ref === 'function') {
893
- ref(value);
894
- } else if (ref) {
895
- ref.current = value;
942
+ const combinedGesture = useMemo(() => {
943
+ // android is able to handle nested scroll view, but not the full height ones like iOS
944
+ if (outerScrollGesture && !(Platform.OS === 'android' && scrollable)) {
945
+ return Gesture.Simultaneous(outerScrollGesture, gestureHandler);
896
946
  }
897
- };
898
947
 
899
- return {
900
- gestureHandler,
948
+ return gestureHandler;
949
+ }, [scrollable, outerScrollGesture, gestureHandler]);
950
+
951
+ const composedScrollHandler = useComposedEventHandler([
901
952
  handleScroll,
902
- handleFlatListLayout,
903
- handleRef,
904
- startDrag,
905
- listContextValue,
906
- itemOffset,
907
- itemHeight,
908
- draggedIndex,
909
- dragY,
910
- duration,
911
- };
953
+ onScroll || null,
954
+ ]);
955
+
956
+ const renderAnimatedCell = useCallback(
957
+ ({cellKey, ...props}: CellRendererProps<T>) => (
958
+ <ReorderableListCell
959
+ {...props}
960
+ // forces remount with key change on reorder
961
+ key={`${cellKey}+${props.index}`}
962
+ itemOffset={itemOffset}
963
+ itemHeight={itemHeight}
964
+ dragY={dragY}
965
+ draggedIndex={draggedIndex}
966
+ animationDuration={duration}
967
+ startDrag={startDrag}
968
+ />
969
+ ),
970
+ [itemOffset, itemHeight, dragY, draggedIndex, duration, startDrag],
971
+ );
972
+
973
+ return (
974
+ <ReorderableListContext.Provider value={listContextValue}>
975
+ <GestureDetector gesture={combinedGesture}>
976
+ <AnimatedFlatList
977
+ {...rest}
978
+ ref={handleRef}
979
+ data={data}
980
+ CellRendererComponent={renderAnimatedCell}
981
+ onLayout={handleFlatListLayout}
982
+ onScroll={composedScrollHandler}
983
+ scrollEventThrottle={1}
984
+ horizontal={false}
985
+ removeClippedSubviews={false}
986
+ numColumns={1}
987
+ />
988
+ </GestureDetector>
989
+ </ReorderableListContext.Provider>
990
+ );
912
991
  };
992
+
993
+ const MemoizedReorderableListCore = React.memo(
994
+ React.forwardRef(ReorderableListCore),
995
+ ) as <T>(
996
+ props: ReorderableListCoreProps<T> & {
997
+ ref?: React.ForwardedRef<FlatList<T> | null>;
998
+ },
999
+ ) => React.ReactElement;
1000
+
1001
+ export {MemoizedReorderableListCore as ReorderableListCore};
@@ -1,5 +1,5 @@
1
- import React, {useCallback, useMemo} from 'react';
2
- import {LayoutChangeEvent} from 'react-native';
1
+ import React, {forwardRef, useCallback, useMemo} from 'react';
2
+ import {LayoutChangeEvent, ScrollView} from 'react-native';
3
3
 
4
4
  import {Gesture, GestureDetector} from 'react-native-gesture-handler';
5
5
  import Animated, {
@@ -14,18 +14,29 @@ import Animated, {
14
14
  import {ScrollViewContainerContext} from '../contexts/ScrollViewContainerContext';
15
15
  import type {ScrollViewContainerProps} from '../types';
16
16
 
17
- export const ScrollViewContainer: React.FC<ScrollViewContainerProps> = ({
18
- onLayout,
19
- onScroll,
20
- scrollEnabled = true,
21
- ...rest
22
- }) => {
17
+ const ScrollViewContainerWithRef = (
18
+ {onLayout, onScroll, scrollEnabled = true, ...rest}: ScrollViewContainerProps,
19
+ ref: React.ForwardedRef<ScrollView>,
20
+ ) => {
23
21
  const scrollViewScrollEnabled = useSharedValue(scrollEnabled);
24
22
  const scrollViewContainerRef = useAnimatedRef<Animated.ScrollView>();
25
23
  const scrollViewScrollOffsetY = useSharedValue(0);
26
24
  const scrollViewPageY = useSharedValue(0);
27
25
  const scrollViewHeightY = useSharedValue(0);
28
26
 
27
+ const handleRef = useCallback(
28
+ (value: Animated.ScrollView) => {
29
+ scrollViewContainerRef(value);
30
+
31
+ if (typeof ref === 'function') {
32
+ ref(value);
33
+ } else if (ref) {
34
+ ref.current = value;
35
+ }
36
+ },
37
+ [scrollViewContainerRef, ref],
38
+ );
39
+
29
40
  const outerScrollGesture = useMemo(() => Gesture.Native(), []);
30
41
 
31
42
  const handleScroll = useAnimatedScrollHandler(
@@ -85,7 +96,7 @@ export const ScrollViewContainer: React.FC<ScrollViewContainerProps> = ({
85
96
  <GestureDetector gesture={outerScrollGesture}>
86
97
  <Animated.ScrollView
87
98
  {...rest}
88
- ref={scrollViewContainerRef}
99
+ ref={handleRef}
89
100
  onScroll={composedScrollHandler}
90
101
  onLayout={handleLayout}
91
102
  scrollEnabled={scrollEnabled}
@@ -94,3 +105,5 @@ export const ScrollViewContainer: React.FC<ScrollViewContainerProps> = ({
94
105
  </ScrollViewContainerContext.Provider>
95
106
  );
96
107
  };
108
+
109
+ export const ScrollViewContainer = forwardRef(ScrollViewContainerWithRef);
@@ -1,5 +1,39 @@
1
+ import {Platform} from 'react-native';
2
+
1
3
  import {Easing, WithTimingConfig} from 'react-native-reanimated';
2
4
 
5
+ const IOS_AUTOSCROLL_CONFIG = {
6
+ delay: 80,
7
+ increment: 100,
8
+ };
9
+
10
+ const ANDROID_FABRIC_AUTOSCROLL_CONFIG = {
11
+ delay: 50,
12
+ increment: 80,
13
+ };
14
+
15
+ const ANDROID_PAPER_AUTOSCROLL_CONFIG = {
16
+ delay: 10,
17
+ increment: 4,
18
+ };
19
+
20
+ export const IS_FABRIC =
21
+ global && typeof global === 'object' && 'nativeFabricUIManager' in global;
22
+
23
+ export const AUTOSCROLL_CONFIG = Platform.select({
24
+ // autoscroll behaves differently with Fabric and Paper on Android
25
+ android: IS_FABRIC
26
+ ? ANDROID_FABRIC_AUTOSCROLL_CONFIG
27
+ : ANDROID_PAPER_AUTOSCROLL_CONFIG,
28
+ ios: IOS_AUTOSCROLL_CONFIG,
29
+
30
+ // unsupported platforms
31
+ web: IOS_AUTOSCROLL_CONFIG,
32
+ macos: IOS_AUTOSCROLL_CONFIG,
33
+ windows: IOS_AUTOSCROLL_CONFIG,
34
+ native: IOS_AUTOSCROLL_CONFIG,
35
+ });
36
+
3
37
  const DURATION_START = 150;
4
38
  const DURATION_END = 200;
5
39
 
@@ -17,6 +17,7 @@ import type {
17
17
  ViewStyle,
18
18
  } from 'react-native';
19
19
 
20
+ import {PanGesture} from 'react-native-gesture-handler';
20
21
  import {SharedValue, useAnimatedScrollHandler} from 'react-native-reanimated';
21
22
 
22
23
  import {MaximumOneOf, SharedValueOrType} from './misc';
@@ -110,12 +111,20 @@ export interface ReorderableListProps<T>
110
111
  * Whether the active item should be updated. Enables usage of `useIsActive` hook. Default: `false`.
111
112
  */
112
113
  shouldUpdateActiveItem?: boolean;
114
+ /**
115
+ * Custom instance of pan gesture. See [GestureHandler docs](https://docs.swmansion.com/react-native-gesture-handler) for further info.
116
+ */
117
+ panGesture?: PanGesture;
113
118
  /**
114
119
  * Wether the pan gestures necessary for dragging are enabled. Default: `true`.
120
+ *
121
+ * @deprecated In favor of `panGesture` prop.
115
122
  */
116
123
  panEnabled?: boolean;
117
124
  /**
118
125
  * Duration in milliseconds of the long press on the list before the pan gesture for dragging is allowed to activate.
126
+ *
127
+ * @deprecated In favor of `panGesture` prop.
119
128
  */
120
129
  panActivateAfterLongPress?: number;
121
130
  /**
@@ -1,123 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.ReorderableListCore = void 0;
7
- var _react = _interopRequireWildcard(require("react"));
8
- var _reactNative = require("react-native");
9
- var _reactNativeGestureHandler = require("react-native-gesture-handler");
10
- var _reactNativeReanimated = _interopRequireWildcard(require("react-native-reanimated"));
11
- var _autoscrollConfig = require("./autoscrollConfig");
12
- var _useReorderableListCore = require("./useReorderableListCore");
13
- var _contexts = require("../../contexts");
14
- var _ReorderableListCell = require("../ReorderableListCell");
15
- function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
16
- function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
17
- function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
18
- const AnimatedFlatList = _reactNativeReanimated.default.createAnimatedComponent(_reactNative.FlatList);
19
- const ReorderableListCore = ({
20
- autoscrollThreshold = 0.1,
21
- autoscrollThresholdOffset,
22
- autoscrollSpeedScale = 1,
23
- autoscrollDelay = _autoscrollConfig.AUTOSCROLL_CONFIG.delay,
24
- autoscrollActivationDelta = 5,
25
- animationDuration = 200,
26
- onLayout,
27
- onReorder,
28
- onScroll,
29
- onDragStart,
30
- onDragEnd,
31
- onIndexChange,
32
- scrollViewContainerRef,
33
- scrollViewPageY,
34
- scrollViewHeightY,
35
- scrollViewScrollOffsetY,
36
- scrollViewScrollEnabled,
37
- initialScrollViewScrollEnabled,
38
- scrollable,
39
- outerScrollGesture,
40
- cellAnimations,
41
- shouldUpdateActiveItem,
42
- panEnabled = true,
43
- panActivateAfterLongPress,
44
- ...rest
45
- }, ref) => {
46
- const {
47
- gestureHandler,
48
- handleScroll,
49
- handleFlatListLayout,
50
- handleRef,
51
- startDrag,
52
- listContextValue,
53
- itemOffset,
54
- itemHeight,
55
- dragY,
56
- draggedIndex,
57
- duration
58
- } = (0, _useReorderableListCore.useReorderableListCore)({
59
- ref,
60
- autoscrollThreshold,
61
- autoscrollThresholdOffset,
62
- autoscrollSpeedScale,
63
- autoscrollDelay,
64
- autoscrollActivationDelta,
65
- animationDuration,
66
- onLayout,
67
- onReorder,
68
- onDragStart,
69
- onDragEnd,
70
- onIndexChange,
71
- scrollViewContainerRef,
72
- scrollViewPageY,
73
- scrollViewHeightY,
74
- scrollViewScrollOffsetY,
75
- scrollViewScrollEnabled,
76
- scrollable,
77
- // flatlist will default to true if we pass explicitly undefined,
78
- // but internally we would treat it as false, so we force true
79
- initialScrollEnabled: typeof rest.scrollEnabled === 'undefined' ? true : rest.scrollEnabled,
80
- initialScrollViewScrollEnabled: typeof initialScrollViewScrollEnabled === 'undefined' ? true : initialScrollViewScrollEnabled,
81
- cellAnimations,
82
- shouldUpdateActiveItem,
83
- panEnabled,
84
- panActivateAfterLongPress
85
- });
86
- const combinedGesture = (0, _react.useMemo)(() => {
87
- // android is able to handle nested scroll view, but not the full height ones like iOS
88
- if (outerScrollGesture && !(_reactNative.Platform.OS === 'android' && scrollable)) {
89
- return _reactNativeGestureHandler.Gesture.Simultaneous(outerScrollGesture, gestureHandler);
90
- }
91
- return gestureHandler;
92
- }, [scrollable, outerScrollGesture, gestureHandler]);
93
- const composedScrollHandler = (0, _reactNativeReanimated.useComposedEventHandler)([handleScroll, onScroll || null]);
94
- const renderAnimatedCell = (0, _react.useCallback)(({
95
- cellKey,
96
- ...props
97
- }) => /*#__PURE__*/_react.default.createElement(_ReorderableListCell.ReorderableListCell, _extends({}, props, {
98
- // forces remount with key change on reorder
99
- key: `${cellKey}+${props.index}`,
100
- itemOffset: itemOffset,
101
- itemHeight: itemHeight,
102
- dragY: dragY,
103
- draggedIndex: draggedIndex,
104
- animationDuration: duration,
105
- startDrag: startDrag
106
- })), [itemOffset, itemHeight, dragY, draggedIndex, duration, startDrag]);
107
- return /*#__PURE__*/_react.default.createElement(_contexts.ReorderableListContext.Provider, {
108
- value: listContextValue
109
- }, /*#__PURE__*/_react.default.createElement(_reactNativeGestureHandler.GestureDetector, {
110
- gesture: combinedGesture
111
- }, /*#__PURE__*/_react.default.createElement(AnimatedFlatList, _extends({}, rest, {
112
- ref: handleRef,
113
- CellRendererComponent: renderAnimatedCell,
114
- onLayout: handleFlatListLayout,
115
- onScroll: composedScrollHandler,
116
- scrollEventThrottle: 1,
117
- horizontal: false,
118
- removeClippedSubviews: false,
119
- numColumns: 1
120
- }))));
121
- };
122
- const MemoizedReorderableListCore = exports.ReorderableListCore = /*#__PURE__*/_react.default.memo(/*#__PURE__*/_react.default.forwardRef(ReorderableListCore));
123
- //# sourceMappingURL=ReorderableListCore.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","_reactNativeGestureHandler","_reactNativeReanimated","_autoscrollConfig","_useReorderableListCore","_contexts","_ReorderableListCell","_getRequireWildcardCache","e","WeakMap","r","t","__esModule","default","has","get","n","__proto__","a","Object","defineProperty","getOwnPropertyDescriptor","u","hasOwnProperty","call","i","set","_extends","assign","bind","arguments","length","apply","AnimatedFlatList","Animated","createAnimatedComponent","FlatList","ReorderableListCore","autoscrollThreshold","autoscrollThresholdOffset","autoscrollSpeedScale","autoscrollDelay","AUTOSCROLL_CONFIG","delay","autoscrollActivationDelta","animationDuration","onLayout","onReorder","onScroll","onDragStart","onDragEnd","onIndexChange","scrollViewContainerRef","scrollViewPageY","scrollViewHeightY","scrollViewScrollOffsetY","scrollViewScrollEnabled","initialScrollViewScrollEnabled","scrollable","outerScrollGesture","cellAnimations","shouldUpdateActiveItem","panEnabled","panActivateAfterLongPress","rest","ref","gestureHandler","handleScroll","handleFlatListLayout","handleRef","startDrag","listContextValue","itemOffset","itemHeight","dragY","draggedIndex","duration","useReorderableListCore","initialScrollEnabled","scrollEnabled","combinedGesture","useMemo","Platform","OS","Gesture","Simultaneous","composedScrollHandler","useComposedEventHandler","renderAnimatedCell","useCallback","cellKey","props","createElement","ReorderableListCell","key","index","ReorderableListContext","Provider","value","GestureDetector","gesture","CellRendererComponent","scrollEventThrottle","horizontal","removeClippedSubviews","numColumns","MemoizedReorderableListCore","exports","React","memo","forwardRef"],"sourceRoot":"../../../../src","sources":["components/ReorderableListCore/ReorderableListCore.tsx"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,uBAAA,CAAAC,OAAA;AACA,IAAAC,YAAA,GAAAD,OAAA;AAQA,IAAAE,0BAAA,GAAAF,OAAA;AAKA,IAAAG,sBAAA,GAAAJ,uBAAA,CAAAC,OAAA;AAKA,IAAAI,iBAAA,GAAAJ,OAAA;AACA,IAAAK,uBAAA,GAAAL,OAAA;AACA,IAAAM,SAAA,GAAAN,OAAA;AAEA,IAAAO,oBAAA,GAAAP,OAAA;AAA2D,SAAAQ,yBAAAC,CAAA,6BAAAC,OAAA,mBAAAC,CAAA,OAAAD,OAAA,IAAAE,CAAA,OAAAF,OAAA,YAAAF,wBAAA,YAAAA,CAAAC,CAAA,WAAAA,CAAA,GAAAG,CAAA,GAAAD,CAAA,KAAAF,CAAA;AAAA,SAAAV,wBAAAU,CAAA,EAAAE,CAAA,SAAAA,CAAA,IAAAF,CAAA,IAAAA,CAAA,CAAAI,UAAA,SAAAJ,CAAA,eAAAA,CAAA,uBAAAA,CAAA,yBAAAA,CAAA,WAAAK,OAAA,EAAAL,CAAA,QAAAG,CAAA,GAAAJ,wBAAA,CAAAG,CAAA,OAAAC,CAAA,IAAAA,CAAA,CAAAG,GAAA,CAAAN,CAAA,UAAAG,CAAA,CAAAI,GAAA,CAAAP,CAAA,OAAAQ,CAAA,KAAAC,SAAA,UAAAC,CAAA,GAAAC,MAAA,CAAAC,cAAA,IAAAD,MAAA,CAAAE,wBAAA,WAAAC,CAAA,IAAAd,CAAA,oBAAAc,CAAA,OAAAC,cAAA,CAAAC,IAAA,CAAAhB,CAAA,EAAAc,CAAA,SAAAG,CAAA,GAAAP,CAAA,GAAAC,MAAA,CAAAE,wBAAA,CAAAb,CAAA,EAAAc,CAAA,UAAAG,CAAA,KAAAA,CAAA,CAAAV,GAAA,IAAAU,CAAA,CAAAC,GAAA,IAAAP,MAAA,CAAAC,cAAA,CAAAJ,CAAA,EAAAM,CAAA,EAAAG,CAAA,IAAAT,CAAA,CAAAM,CAAA,IAAAd,CAAA,CAAAc,CAAA,YAAAN,CAAA,CAAAH,OAAA,GAAAL,CAAA,EAAAG,CAAA,IAAAA,CAAA,CAAAe,GAAA,CAAAlB,CAAA,EAAAQ,CAAA,GAAAA,CAAA;AAAA,SAAAW,SAAA,WAAAA,QAAA,GAAAR,MAAA,CAAAS,MAAA,GAAAT,MAAA,CAAAS,MAAA,CAAAC,IAAA,eAAAb,CAAA,aAAAR,CAAA,MAAAA,CAAA,GAAAsB,SAAA,CAAAC,MAAA,EAAAvB,CAAA,UAAAG,CAAA,GAAAmB,SAAA,CAAAtB,CAAA,YAAAE,CAAA,IAAAC,CAAA,OAAAY,cAAA,CAAAC,IAAA,CAAAb,CAAA,EAAAD,CAAA,MAAAM,CAAA,CAAAN,CAAA,IAAAC,CAAA,CAAAD,CAAA,aAAAM,CAAA,KAAAW,QAAA,CAAAK,KAAA,OAAAF,SAAA;AAE3D,MAAMG,gBAAgB,GAAGC,8BAAQ,CAACC,uBAAuB,CACvDC,qBACF,CAEuB;AAevB,MAAMC,mBAAmB,GAAGA,CAC1B;EACEC,mBAAmB,GAAG,GAAG;EACzBC,yBAAyB;EACzBC,oBAAoB,GAAG,CAAC;EACxBC,eAAe,GAAGC,mCAAiB,CAACC,KAAK;EACzCC,yBAAyB,GAAG,CAAC;EAC7BC,iBAAiB,GAAG,GAAG;EACvBC,QAAQ;EACRC,SAAS;EACTC,QAAQ;EACRC,WAAW;EACXC,SAAS;EACTC,aAAa;EACbC,sBAAsB;EACtBC,eAAe;EACfC,iBAAiB;EACjBC,uBAAuB;EACvBC,uBAAuB;EACvBC,8BAA8B;EAC9BC,UAAU;EACVC,kBAAkB;EAClBC,cAAc;EACdC,sBAAsB;EACtBC,UAAU,GAAG,IAAI;EACjBC,yBAAyB;EACzB,GAAGC;AACwB,CAAC,EAC9BC,GAAoC,KACjC;EACH,MAAM;IACJC,cAAc;IACdC,YAAY;IACZC,oBAAoB;IACpBC,SAAS;IACTC,SAAS;IACTC,gBAAgB;IAChBC,UAAU;IACVC,UAAU;IACVC,KAAK;IACLC,YAAY;IACZC;EACF,CAAC,GAAG,IAAAC,8CAAsB,EAAC;IACzBZ,GAAG;IACH3B,mBAAmB;IACnBC,yBAAyB;IACzBC,oBAAoB;IACpBC,eAAe;IACfG,yBAAyB;IACzBC,iBAAiB;IACjBC,QAAQ;IACRC,SAAS;IACTE,WAAW;IACXC,SAAS;IACTC,aAAa;IACbC,sBAAsB;IACtBC,eAAe;IACfC,iBAAiB;IACjBC,uBAAuB;IACvBC,uBAAuB;IACvBE,UAAU;IACV;IACA;IACAoB,oBAAoB,EAClB,OAAOd,IAAI,CAACe,aAAa,KAAK,WAAW,GAAG,IAAI,GAAGf,IAAI,CAACe,aAAa;IACvEtB,8BAA8B,EAC5B,OAAOA,8BAA8B,KAAK,WAAW,GACjD,IAAI,GACJA,8BAA8B;IACpCG,cAAc;IACdC,sBAAsB;IACtBC,UAAU;IACVC;EACF,CAAC,CAAC;EAEF,MAAMiB,eAAe,GAAG,IAAAC,cAAO,EAAC,MAAM;IACpC;IACA,IAAItB,kBAAkB,IAAI,EAAEuB,qBAAQ,CAACC,EAAE,KAAK,SAAS,IAAIzB,UAAU,CAAC,EAAE;MACpE,OAAO0B,kCAAO,CAACC,YAAY,CAAC1B,kBAAkB,EAAEO,cAAc,CAAC;IACjE;IAEA,OAAOA,cAAc;EACvB,CAAC,EAAE,CAACR,UAAU,EAAEC,kBAAkB,EAAEO,cAAc,CAAC,CAAC;EAEpD,MAAMoB,qBAAqB,GAAG,IAAAC,8CAAuB,EAAC,CACpDpB,YAAY,EACZnB,QAAQ,IAAI,IAAI,CACjB,CAAC;EAEF,MAAMwC,kBAAkB,GAAG,IAAAC,kBAAW,EACpC,CAAC;IAACC,OAAO;IAAE,GAAGC;EAA2B,CAAC,kBACxC9F,MAAA,CAAAgB,OAAA,CAAA+E,aAAA,CAACtF,oBAAA,CAAAuF,mBAAmB,EAAAlE,QAAA,KACdgE,KAAK;IACT;IACAG,GAAG,EAAE,GAAGJ,OAAO,IAAIC,KAAK,CAACI,KAAK,EAAG;IACjCvB,UAAU,EAAEA,UAAW;IACvBC,UAAU,EAAEA,UAAW;IACvBC,KAAK,EAAEA,KAAM;IACbC,YAAY,EAAEA,YAAa;IAC3B9B,iBAAiB,EAAE+B,QAAS;IAC5BN,SAAS,EAAEA;EAAU,EACtB,CACF,EACD,CAACE,UAAU,EAAEC,UAAU,EAAEC,KAAK,EAAEC,YAAY,EAAEC,QAAQ,EAAEN,SAAS,CACnE,CAAC;EAED,oBACEzE,MAAA,CAAAgB,OAAA,CAAA+E,aAAA,CAACvF,SAAA,CAAA2F,sBAAsB,CAACC,QAAQ;IAACC,KAAK,EAAE3B;EAAiB,gBACvD1E,MAAA,CAAAgB,OAAA,CAAA+E,aAAA,CAAC3F,0BAAA,CAAAkG,eAAe;IAACC,OAAO,EAAEpB;EAAgB,gBACxCnF,MAAA,CAAAgB,OAAA,CAAA+E,aAAA,CAAC3D,gBAAgB,EAAAN,QAAA,KACXqC,IAAI;IACRC,GAAG,EAAEI,SAAU;IACfgC,qBAAqB,EAAEb,kBAAmB;IAC1C1C,QAAQ,EAAEsB,oBAAqB;IAC/BpB,QAAQ,EAAEsC,qBAAsB;IAChCgB,mBAAmB,EAAE,CAAE;IACvBC,UAAU,EAAE,KAAM;IAClBC,qBAAqB,EAAE,KAAM;IAC7BC,UAAU,EAAE;EAAE,EACf,CACc,CACc,CAAC;AAEtC,CAAC;AAED,MAAMC,2BAA2B,GAAAC,OAAA,CAAAtE,mBAAA,gBAAGuE,cAAK,CAACC,IAAI,cAC5CD,cAAK,CAACE,UAAU,CAACzE,mBAAmB,CACtC,CAIuB","ignoreList":[]}