@souscheflabs/reanimated-flashlist 0.1.7

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 (104) hide show
  1. package/README.md +282 -0
  2. package/lib/AnimatedFlashList.d.ts +6 -0
  3. package/lib/AnimatedFlashList.d.ts.map +1 -0
  4. package/lib/AnimatedFlashList.js +207 -0
  5. package/lib/AnimatedFlashListItem.d.ts +33 -0
  6. package/lib/AnimatedFlashListItem.d.ts.map +1 -0
  7. package/lib/AnimatedFlashListItem.js +155 -0
  8. package/lib/__tests__/utils/test-utils.d.ts +82 -0
  9. package/lib/__tests__/utils/test-utils.d.ts.map +1 -0
  10. package/lib/__tests__/utils/test-utils.js +115 -0
  11. package/lib/constants/animations.d.ts +39 -0
  12. package/lib/constants/animations.d.ts.map +1 -0
  13. package/lib/constants/animations.js +100 -0
  14. package/lib/constants/drag.d.ts +11 -0
  15. package/lib/constants/drag.d.ts.map +1 -0
  16. package/lib/constants/drag.js +47 -0
  17. package/lib/constants/index.d.ts +3 -0
  18. package/lib/constants/index.d.ts.map +1 -0
  19. package/lib/constants/index.js +18 -0
  20. package/lib/contexts/DragStateContext.d.ts +73 -0
  21. package/lib/contexts/DragStateContext.d.ts.map +1 -0
  22. package/lib/contexts/DragStateContext.js +148 -0
  23. package/lib/contexts/ListAnimationContext.d.ts +104 -0
  24. package/lib/contexts/ListAnimationContext.d.ts.map +1 -0
  25. package/lib/contexts/ListAnimationContext.js +184 -0
  26. package/lib/contexts/index.d.ts +5 -0
  27. package/lib/contexts/index.d.ts.map +1 -0
  28. package/lib/contexts/index.js +10 -0
  29. package/lib/hooks/animations/index.d.ts +9 -0
  30. package/lib/hooks/animations/index.d.ts.map +1 -0
  31. package/lib/hooks/animations/index.js +13 -0
  32. package/lib/hooks/animations/useListEntryAnimation.d.ts +38 -0
  33. package/lib/hooks/animations/useListEntryAnimation.d.ts.map +1 -0
  34. package/lib/hooks/animations/useListEntryAnimation.js +90 -0
  35. package/lib/hooks/animations/useListExitAnimation.d.ts +67 -0
  36. package/lib/hooks/animations/useListExitAnimation.d.ts.map +1 -0
  37. package/lib/hooks/animations/useListExitAnimation.js +146 -0
  38. package/lib/hooks/drag/index.d.ts +20 -0
  39. package/lib/hooks/drag/index.d.ts.map +1 -0
  40. package/lib/hooks/drag/index.js +26 -0
  41. package/lib/hooks/drag/useDragAnimatedStyle.d.ts +33 -0
  42. package/lib/hooks/drag/useDragAnimatedStyle.d.ts.map +1 -0
  43. package/lib/hooks/drag/useDragAnimatedStyle.js +61 -0
  44. package/lib/hooks/drag/useDragGesture.d.ts +30 -0
  45. package/lib/hooks/drag/useDragGesture.d.ts.map +1 -0
  46. package/lib/hooks/drag/useDragGesture.js +189 -0
  47. package/lib/hooks/drag/useDragShift.d.ts +21 -0
  48. package/lib/hooks/drag/useDragShift.d.ts.map +1 -0
  49. package/lib/hooks/drag/useDragShift.js +85 -0
  50. package/lib/hooks/drag/useDropCompensation.d.ts +27 -0
  51. package/lib/hooks/drag/useDropCompensation.d.ts.map +1 -0
  52. package/lib/hooks/drag/useDropCompensation.js +90 -0
  53. package/lib/hooks/index.d.ts +8 -0
  54. package/lib/hooks/index.d.ts.map +1 -0
  55. package/lib/hooks/index.js +18 -0
  56. package/lib/index.d.ts +42 -0
  57. package/lib/index.d.ts.map +1 -0
  58. package/lib/index.js +69 -0
  59. package/lib/types/animations.d.ts +71 -0
  60. package/lib/types/animations.d.ts.map +1 -0
  61. package/lib/types/animations.js +2 -0
  62. package/lib/types/drag.d.ts +94 -0
  63. package/lib/types/drag.d.ts.map +1 -0
  64. package/lib/types/drag.js +2 -0
  65. package/lib/types/index.d.ts +4 -0
  66. package/lib/types/index.d.ts.map +1 -0
  67. package/lib/types/index.js +19 -0
  68. package/lib/types/list.d.ts +136 -0
  69. package/lib/types/list.d.ts.map +1 -0
  70. package/lib/types/list.js +2 -0
  71. package/package.json +73 -0
  72. package/src/AnimatedFlashList.tsx +411 -0
  73. package/src/AnimatedFlashListItem.tsx +212 -0
  74. package/src/__tests__/components/AnimatedFlashList.test.tsx +365 -0
  75. package/src/__tests__/components/AnimatedFlashListItem.test.tsx +371 -0
  76. package/src/__tests__/contexts/DragStateContext.test.tsx +169 -0
  77. package/src/__tests__/contexts/ListAnimationContext.test.tsx +324 -0
  78. package/src/__tests__/hooks/useDragAnimatedStyle.test.tsx +118 -0
  79. package/src/__tests__/hooks/useDragGesture.test.tsx +169 -0
  80. package/src/__tests__/hooks/useDragShift.test.tsx +94 -0
  81. package/src/__tests__/hooks/useDropCompensation.test.tsx +182 -0
  82. package/src/__tests__/hooks/useListEntryAnimation.test.tsx +135 -0
  83. package/src/__tests__/hooks/useListExitAnimation.test.tsx +175 -0
  84. package/src/__tests__/utils/test-utils.tsx +159 -0
  85. package/src/constants/animations.ts +107 -0
  86. package/src/constants/drag.ts +51 -0
  87. package/src/constants/index.ts +2 -0
  88. package/src/contexts/DragStateContext.tsx +197 -0
  89. package/src/contexts/ListAnimationContext.tsx +302 -0
  90. package/src/contexts/index.ts +9 -0
  91. package/src/hooks/animations/index.ts +9 -0
  92. package/src/hooks/animations/useListEntryAnimation.ts +108 -0
  93. package/src/hooks/animations/useListExitAnimation.ts +197 -0
  94. package/src/hooks/drag/index.ts +20 -0
  95. package/src/hooks/drag/useDragAnimatedStyle.ts +80 -0
  96. package/src/hooks/drag/useDragGesture.ts +267 -0
  97. package/src/hooks/drag/useDragShift.ts +119 -0
  98. package/src/hooks/drag/useDropCompensation.ts +120 -0
  99. package/src/hooks/index.ts +16 -0
  100. package/src/index.ts +105 -0
  101. package/src/types/animations.ts +76 -0
  102. package/src/types/drag.ts +101 -0
  103. package/src/types/index.ts +3 -0
  104. package/src/types/list.ts +178 -0
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useDragShift = useDragShift;
4
+ const react_native_reanimated_1 = require("react-native-reanimated");
5
+ const DragStateContext_1 = require("../../contexts/DragStateContext");
6
+ /**
7
+ * Hook that calculates shift animation for non-dragged items.
8
+ *
9
+ * When an item is being dragged, other items need to shift up or down
10
+ * to make room for the dragged item at its new position. This hook
11
+ * calculates the target shift based on:
12
+ * - The current drag position (from context)
13
+ * - The scroll delta (accounting for autoscroll)
14
+ * - The item's index relative to the dragged item
15
+ *
16
+ * The shift is animated with timing for smooth transitions.
17
+ *
18
+ * @example
19
+ * ```tsx
20
+ * const { shiftY } = useDragShift({ itemId: item.id, index });
21
+ * // Use shiftY.value in animated style
22
+ * ```
23
+ */
24
+ function useDragShift(config) {
25
+ const { itemId, index } = config;
26
+ // Global drag state for coordinating animations across all items
27
+ const { isDragging: globalIsDragging, draggedIndex, draggedItemId, currentTranslateY, scrollOffset, dragStartScrollOffset, dragUpdateTrigger, measuredItemHeight, isDropping, config: dragConfig, } = (0, DragStateContext_1.useDragState)();
28
+ // Shift animation SharedValue
29
+ const shiftY = (0, react_native_reanimated_1.useSharedValue)(0);
30
+ // Calculate target shift using useDerivedValue
31
+ const targetShiftY = (0, react_native_reanimated_1.useDerivedValue)(() => {
32
+ 'worklet';
33
+ // Force re-evaluation on every drag state change
34
+ // eslint-disable-next-line @typescript-eslint/no-unused-expressions
35
+ dragUpdateTrigger.value;
36
+ // During drop transition, freeze shift values
37
+ if (isDropping.value) {
38
+ return shiftY.value;
39
+ }
40
+ const currentDraggedIndex = draggedIndex.value;
41
+ const isDraggingNow = globalIsDragging.value;
42
+ const translateYNow = currentTranslateY.value;
43
+ const currentDraggedItemId = draggedItemId.value;
44
+ // If I'm the dragged item, no shift needed
45
+ if (currentDraggedItemId === itemId)
46
+ return 0;
47
+ // If not dragging, reset to 0
48
+ if (!isDraggingNow)
49
+ return 0;
50
+ // Use dynamically measured height + margins, or fall back to config
51
+ const itemHeight = measuredItemHeight.value > 0
52
+ ? measuredItemHeight.value + dragConfig.itemVerticalMargin
53
+ : dragConfig.itemHeight;
54
+ // Calculate effective translateY including scroll delta
55
+ const scrollDelta = scrollOffset.value - dragStartScrollOffset.value;
56
+ const effectiveTranslateY = translateYNow + scrollDelta;
57
+ // Calculate which index the dragged item is hovering over
58
+ const offset = effectiveTranslateY > 0 ? 0.2 : effectiveTranslateY < 0 ? -0.2 : 0;
59
+ const hoveredIndex = currentDraggedIndex + Math.round(effectiveTranslateY / itemHeight + offset);
60
+ // Moving DOWN: items between original and hovered positions shift UP
61
+ if (hoveredIndex > currentDraggedIndex) {
62
+ if (index > currentDraggedIndex && index <= hoveredIndex) {
63
+ return -itemHeight;
64
+ }
65
+ }
66
+ // Moving UP: items between hovered and original positions shift DOWN
67
+ else if (hoveredIndex < currentDraggedIndex) {
68
+ if (index < currentDraggedIndex && index >= hoveredIndex) {
69
+ return itemHeight;
70
+ }
71
+ }
72
+ return 0;
73
+ }, [index, itemId]);
74
+ // Animate shift when target changes
75
+ (0, react_native_reanimated_1.useAnimatedReaction)(() => targetShiftY.value, (target, prev) => {
76
+ 'worklet';
77
+ if (target !== prev) {
78
+ shiftY.value = (0, react_native_reanimated_1.withTiming)(target, {
79
+ duration: 100,
80
+ easing: react_native_reanimated_1.Easing.out(react_native_reanimated_1.Easing.ease),
81
+ });
82
+ }
83
+ });
84
+ return { shiftY };
85
+ }
@@ -0,0 +1,27 @@
1
+ import type { UseDropCompensationConfig } from '../../types';
2
+ /**
3
+ * Hook that handles index change compensation after drag reorder.
4
+ *
5
+ * When an item is dropped and the data updates, React re-renders with new indices.
6
+ * This causes a visual jump because items suddenly have different positions.
7
+ * This hook compensates by:
8
+ * 1. Detecting index changes (via useRecyclingState for FlashList recycling)
9
+ * 2. Adjusting translateY to compensate for the position delta
10
+ * 3. Animating the dragged item back to 0 (settle animation)
11
+ * 4. Resetting global drag state after animation completes
12
+ * 5. Resetting shiftY on UI thread via useAnimatedReaction
13
+ *
14
+ * useLayoutEffect runs synchronously before paint to prevent visual flash.
15
+ *
16
+ * @example
17
+ * ```tsx
18
+ * useDropCompensation({
19
+ * itemId: item.id,
20
+ * index,
21
+ * translateY,
22
+ * shiftY,
23
+ * });
24
+ * ```
25
+ */
26
+ export declare function useDropCompensation(config: UseDropCompensationConfig): void;
27
+ //# sourceMappingURL=useDropCompensation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useDropCompensation.d.ts","sourceRoot":"","sources":["../../../src/hooks/drag/useDropCompensation.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAE7D;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,yBAAyB,GAAG,IAAI,CAoF3E"}
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useDropCompensation = useDropCompensation;
4
+ const react_1 = require("react");
5
+ const react_native_reanimated_1 = require("react-native-reanimated");
6
+ const flash_list_1 = require("@shopify/flash-list");
7
+ const DragStateContext_1 = require("../../contexts/DragStateContext");
8
+ /**
9
+ * Hook that handles index change compensation after drag reorder.
10
+ *
11
+ * When an item is dropped and the data updates, React re-renders with new indices.
12
+ * This causes a visual jump because items suddenly have different positions.
13
+ * This hook compensates by:
14
+ * 1. Detecting index changes (via useRecyclingState for FlashList recycling)
15
+ * 2. Adjusting translateY to compensate for the position delta
16
+ * 3. Animating the dragged item back to 0 (settle animation)
17
+ * 4. Resetting global drag state after animation completes
18
+ * 5. Resetting shiftY on UI thread via useAnimatedReaction
19
+ *
20
+ * useLayoutEffect runs synchronously before paint to prevent visual flash.
21
+ *
22
+ * @example
23
+ * ```tsx
24
+ * useDropCompensation({
25
+ * itemId: item.id,
26
+ * index,
27
+ * translateY,
28
+ * shiftY,
29
+ * });
30
+ * ```
31
+ */
32
+ function useDropCompensation(config) {
33
+ const { itemId, index, translateY, shiftY } = config;
34
+ // Track index on UI thread for synchronized shift reset
35
+ const indexShared = (0, react_native_reanimated_1.useSharedValue)(index);
36
+ // Global drag state
37
+ const { isDragging: globalIsDragging, draggedIndex, draggedItemId, measuredItemHeight, isDropping, dragUpdateTrigger, config: dragConfig, } = (0, DragStateContext_1.useDragState)();
38
+ // Use FlashList's useRecyclingState for automatic reset on view recycling
39
+ const [prevIndex, setPrevIndex] = (0, flash_list_1.useRecyclingState)(index, [itemId]);
40
+ // Handle index changes after data updates (drop compensation)
41
+ (0, react_1.useLayoutEffect)(() => {
42
+ if (index !== prevIndex) {
43
+ // Compensate for index change by adjusting translateY
44
+ const indexDelta = index - prevIndex;
45
+ const heightDelta = indexDelta * dragConfig.itemHeight;
46
+ // Check if this is the dragged item completing its drop
47
+ const isTheDraggedItem = draggedItemId.value === itemId;
48
+ // Compensate translateY for position change
49
+ const compensatedY = translateY.value - heightDelta;
50
+ if (isTheDraggedItem) {
51
+ // Dragged item: animate smoothly to 0 from compensated position
52
+ translateY.value = compensatedY;
53
+ translateY.value = (0, react_native_reanimated_1.withTiming)(0, { duration: 150, easing: react_native_reanimated_1.Easing.out(react_native_reanimated_1.Easing.ease) }, finished => {
54
+ 'worklet';
55
+ if (finished) {
56
+ // Reset ALL global state after settle animation
57
+ isDropping.value = false;
58
+ globalIsDragging.value = false;
59
+ draggedIndex.value = -1;
60
+ draggedItemId.value = '';
61
+ measuredItemHeight.value = 0;
62
+ dragUpdateTrigger.value = (0, react_native_reanimated_1.withTiming)(dragUpdateTrigger.value + 1, {
63
+ duration: 1,
64
+ });
65
+ }
66
+ });
67
+ }
68
+ else if (Math.abs(translateY.value) > 1) {
69
+ // Non-dragged item: just compensate without animation
70
+ translateY.value = compensatedY;
71
+ }
72
+ // Update tracked index
73
+ setPrevIndex(index);
74
+ }
75
+ // eslint-disable-next-line react-hooks/exhaustive-deps
76
+ }, [index, prevIndex, translateY, setPrevIndex, itemId]);
77
+ // Sync JS index to SharedValue for UI thread access
78
+ (0, react_1.useLayoutEffect)(() => {
79
+ indexShared.value = index;
80
+ }, [index, indexShared]);
81
+ // Reset shiftY on UI thread when index changes
82
+ (0, react_native_reanimated_1.useAnimatedReaction)(() => indexShared.value, (currentIndex, prevIdx) => {
83
+ 'worklet';
84
+ if (prevIdx !== null &&
85
+ currentIndex !== prevIdx &&
86
+ Math.abs(shiftY.value) > 1) {
87
+ shiftY.value = 0;
88
+ }
89
+ });
90
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Hooks for AnimatedFlashList
3
+ *
4
+ * Re-exports all hooks for both drag and animation functionality.
5
+ */
6
+ export { useDragGesture, useDragShift, useDragAnimatedStyle, useDropCompensation, } from './drag';
7
+ export { useListExitAnimation, useListEntryAnimation } from './animations';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACL,cAAc,EACd,YAAY,EACZ,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,QAAQ,CAAC;AAGhB,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ /**
3
+ * Hooks for AnimatedFlashList
4
+ *
5
+ * Re-exports all hooks for both drag and animation functionality.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.useListEntryAnimation = exports.useListExitAnimation = exports.useDropCompensation = exports.useDragAnimatedStyle = exports.useDragShift = exports.useDragGesture = void 0;
9
+ // Drag hooks
10
+ var drag_1 = require("./drag");
11
+ Object.defineProperty(exports, "useDragGesture", { enumerable: true, get: function () { return drag_1.useDragGesture; } });
12
+ Object.defineProperty(exports, "useDragShift", { enumerable: true, get: function () { return drag_1.useDragShift; } });
13
+ Object.defineProperty(exports, "useDragAnimatedStyle", { enumerable: true, get: function () { return drag_1.useDragAnimatedStyle; } });
14
+ Object.defineProperty(exports, "useDropCompensation", { enumerable: true, get: function () { return drag_1.useDropCompensation; } });
15
+ // Animation hooks
16
+ var animations_1 = require("./animations");
17
+ Object.defineProperty(exports, "useListExitAnimation", { enumerable: true, get: function () { return animations_1.useListExitAnimation; } });
18
+ Object.defineProperty(exports, "useListEntryAnimation", { enumerable: true, get: function () { return animations_1.useListEntryAnimation; } });
package/lib/index.d.ts ADDED
@@ -0,0 +1,42 @@
1
+ /**
2
+ * @souschef/reanimated-flashlist
3
+ *
4
+ * A high-performance animated FlashList with drag-to-reorder and entry/exit animations.
5
+ *
6
+ * @example
7
+ * ```tsx
8
+ * import {
9
+ * AnimatedFlashList,
10
+ * type AnimatedListItem,
11
+ * } from '@souschef/reanimated-flashlist';
12
+ *
13
+ * interface MyItem extends AnimatedListItem {
14
+ * title: string;
15
+ * }
16
+ *
17
+ * <AnimatedFlashList<MyItem>
18
+ * data={items}
19
+ * keyExtractor={(item) => item.id}
20
+ * renderItem={({ item, dragHandleProps, triggerExitAnimation }) => (
21
+ * <View>
22
+ * <Text>{item.title}</Text>
23
+ * {dragHandleProps && (
24
+ * <GestureDetector gesture={dragHandleProps.gesture}>
25
+ * <DragIcon />
26
+ * </GestureDetector>
27
+ * )}
28
+ * </View>
29
+ * )}
30
+ * dragEnabled
31
+ * onReorder={(itemId, from, to) => handleReorder(itemId, from, to)}
32
+ * />
33
+ * ```
34
+ */
35
+ export { AnimatedFlashList } from './AnimatedFlashList';
36
+ export { AnimatedFlashListItem } from './AnimatedFlashListItem';
37
+ export { DragStateProvider, useDragState, ListAnimationProvider, useListAnimation, useListAnimationOptional, } from './contexts';
38
+ export { useDragGesture, useDragShift, useDragAnimatedStyle, useDropCompensation, useListExitAnimation, useListEntryAnimation, } from './hooks';
39
+ export { DEFAULT_DRAG_CONFIG, createDragConfig, DEFAULT_EXIT_ANIMATION, FAST_EXIT_ANIMATION, DEFAULT_ENTRY_ANIMATION, getExitAnimationConfig, createEntryAnimationConfig, standardEasing, } from './constants';
40
+ export type { AnimatedListItem, AnimatedFlashListProps, AnimatedFlashListRef, AnimatedFlashListConfig, AnimatedRenderItemInfo, DragHandleProps, DragConfig, UseDragGestureConfig, UseDragGestureCallbacks, UseDragGestureResult, UseDragShiftConfig, UseDragShiftResult, UseDropCompensationConfig, UseDragAnimatedStyleResult, AnimationDirection, ExitAnimationPreset, ExitAnimationConfig, EntryAnimationConfig, PendingEntryAnimation, ExitAnimationTrigger, HapticFeedbackType, } from './types';
41
+ export type { DragStateContextValue, ListAnimationContextValue, } from './contexts';
42
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAGH,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAGhE,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,qBAAqB,EACrB,gBAAgB,EAChB,wBAAwB,GACzB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAEL,cAAc,EACd,YAAY,EACZ,oBAAoB,EACpB,mBAAmB,EAEnB,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,sBAAsB,EACtB,mBAAmB,EACnB,uBAAuB,EACvB,sBAAsB,EACtB,0BAA0B,EAC1B,cAAc,GACf,MAAM,aAAa,CAAC;AAGrB,YAAY,EAEV,gBAAgB,EAChB,sBAAsB,EACtB,oBAAoB,EACpB,uBAAuB,EACvB,sBAAsB,EACtB,eAAe,EAEf,UAAU,EACV,oBAAoB,EACpB,uBAAuB,EACvB,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,EAClB,yBAAyB,EACzB,0BAA0B,EAE1B,kBAAkB,EAClB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,SAAS,CAAC;AAGjB,YAAY,EACV,qBAAqB,EACrB,yBAAyB,GAC1B,MAAM,YAAY,CAAC"}
package/lib/index.js ADDED
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ /**
3
+ * @souschef/reanimated-flashlist
4
+ *
5
+ * A high-performance animated FlashList with drag-to-reorder and entry/exit animations.
6
+ *
7
+ * @example
8
+ * ```tsx
9
+ * import {
10
+ * AnimatedFlashList,
11
+ * type AnimatedListItem,
12
+ * } from '@souschef/reanimated-flashlist';
13
+ *
14
+ * interface MyItem extends AnimatedListItem {
15
+ * title: string;
16
+ * }
17
+ *
18
+ * <AnimatedFlashList<MyItem>
19
+ * data={items}
20
+ * keyExtractor={(item) => item.id}
21
+ * renderItem={({ item, dragHandleProps, triggerExitAnimation }) => (
22
+ * <View>
23
+ * <Text>{item.title}</Text>
24
+ * {dragHandleProps && (
25
+ * <GestureDetector gesture={dragHandleProps.gesture}>
26
+ * <DragIcon />
27
+ * </GestureDetector>
28
+ * )}
29
+ * </View>
30
+ * )}
31
+ * dragEnabled
32
+ * onReorder={(itemId, from, to) => handleReorder(itemId, from, to)}
33
+ * />
34
+ * ```
35
+ */
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.standardEasing = exports.createEntryAnimationConfig = exports.getExitAnimationConfig = exports.DEFAULT_ENTRY_ANIMATION = exports.FAST_EXIT_ANIMATION = exports.DEFAULT_EXIT_ANIMATION = exports.createDragConfig = exports.DEFAULT_DRAG_CONFIG = exports.useListEntryAnimation = exports.useListExitAnimation = exports.useDropCompensation = exports.useDragAnimatedStyle = exports.useDragShift = exports.useDragGesture = exports.useListAnimationOptional = exports.useListAnimation = exports.ListAnimationProvider = exports.useDragState = exports.DragStateProvider = exports.AnimatedFlashListItem = exports.AnimatedFlashList = void 0;
38
+ // Main component
39
+ var AnimatedFlashList_1 = require("./AnimatedFlashList");
40
+ Object.defineProperty(exports, "AnimatedFlashList", { enumerable: true, get: function () { return AnimatedFlashList_1.AnimatedFlashList; } });
41
+ var AnimatedFlashListItem_1 = require("./AnimatedFlashListItem");
42
+ Object.defineProperty(exports, "AnimatedFlashListItem", { enumerable: true, get: function () { return AnimatedFlashListItem_1.AnimatedFlashListItem; } });
43
+ // Contexts (for advanced usage)
44
+ var contexts_1 = require("./contexts");
45
+ Object.defineProperty(exports, "DragStateProvider", { enumerable: true, get: function () { return contexts_1.DragStateProvider; } });
46
+ Object.defineProperty(exports, "useDragState", { enumerable: true, get: function () { return contexts_1.useDragState; } });
47
+ Object.defineProperty(exports, "ListAnimationProvider", { enumerable: true, get: function () { return contexts_1.ListAnimationProvider; } });
48
+ Object.defineProperty(exports, "useListAnimation", { enumerable: true, get: function () { return contexts_1.useListAnimation; } });
49
+ Object.defineProperty(exports, "useListAnimationOptional", { enumerable: true, get: function () { return contexts_1.useListAnimationOptional; } });
50
+ // Hooks (for advanced/custom implementations)
51
+ var hooks_1 = require("./hooks");
52
+ // Drag hooks
53
+ Object.defineProperty(exports, "useDragGesture", { enumerable: true, get: function () { return hooks_1.useDragGesture; } });
54
+ Object.defineProperty(exports, "useDragShift", { enumerable: true, get: function () { return hooks_1.useDragShift; } });
55
+ Object.defineProperty(exports, "useDragAnimatedStyle", { enumerable: true, get: function () { return hooks_1.useDragAnimatedStyle; } });
56
+ Object.defineProperty(exports, "useDropCompensation", { enumerable: true, get: function () { return hooks_1.useDropCompensation; } });
57
+ // Animation hooks
58
+ Object.defineProperty(exports, "useListExitAnimation", { enumerable: true, get: function () { return hooks_1.useListExitAnimation; } });
59
+ Object.defineProperty(exports, "useListEntryAnimation", { enumerable: true, get: function () { return hooks_1.useListEntryAnimation; } });
60
+ // Constants (for customization)
61
+ var constants_1 = require("./constants");
62
+ Object.defineProperty(exports, "DEFAULT_DRAG_CONFIG", { enumerable: true, get: function () { return constants_1.DEFAULT_DRAG_CONFIG; } });
63
+ Object.defineProperty(exports, "createDragConfig", { enumerable: true, get: function () { return constants_1.createDragConfig; } });
64
+ Object.defineProperty(exports, "DEFAULT_EXIT_ANIMATION", { enumerable: true, get: function () { return constants_1.DEFAULT_EXIT_ANIMATION; } });
65
+ Object.defineProperty(exports, "FAST_EXIT_ANIMATION", { enumerable: true, get: function () { return constants_1.FAST_EXIT_ANIMATION; } });
66
+ Object.defineProperty(exports, "DEFAULT_ENTRY_ANIMATION", { enumerable: true, get: function () { return constants_1.DEFAULT_ENTRY_ANIMATION; } });
67
+ Object.defineProperty(exports, "getExitAnimationConfig", { enumerable: true, get: function () { return constants_1.getExitAnimationConfig; } });
68
+ Object.defineProperty(exports, "createEntryAnimationConfig", { enumerable: true, get: function () { return constants_1.createEntryAnimationConfig; } });
69
+ Object.defineProperty(exports, "standardEasing", { enumerable: true, get: function () { return constants_1.standardEasing; } });
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Animation direction for entry/exit animations
3
+ * 1 = forward/right, -1 = backward/left
4
+ */
5
+ export type AnimationDirection = 1 | -1;
6
+ /**
7
+ * Animation preset type for exit animations
8
+ * - 'default': Standard exit animation (for swipe/delete actions)
9
+ * - 'fast': Quick exit animation (for checkbox toggles)
10
+ */
11
+ export type ExitAnimationPreset = 'default' | 'fast';
12
+ /**
13
+ * Haptic feedback types that can be triggered during animations
14
+ */
15
+ export type HapticFeedbackType = 'light' | 'medium' | 'heavy' | 'selection';
16
+ /**
17
+ * Configuration for exit animations
18
+ */
19
+ export interface ExitAnimationConfig {
20
+ slide: {
21
+ duration: number;
22
+ distance: number;
23
+ };
24
+ fade: {
25
+ delay: number;
26
+ duration: number;
27
+ };
28
+ scale: {
29
+ delay: number;
30
+ duration: number;
31
+ toValue: number;
32
+ };
33
+ removalDelay: number;
34
+ layoutAnimation: {
35
+ duration: number;
36
+ };
37
+ }
38
+ /**
39
+ * Configuration for entry animations
40
+ */
41
+ export interface EntryAnimationConfig {
42
+ fade: {
43
+ duration: number;
44
+ };
45
+ slide: {
46
+ distance: number;
47
+ duration: number;
48
+ };
49
+ }
50
+ /**
51
+ * Pending entry animation info
52
+ */
53
+ export interface PendingEntryAnimation {
54
+ itemId: string;
55
+ direction: AnimationDirection;
56
+ timestamp: number;
57
+ }
58
+ /**
59
+ * Exit animation trigger function type
60
+ */
61
+ export type ExitAnimationTrigger = (direction: AnimationDirection, onComplete: () => void, preset?: ExitAnimationPreset) => void;
62
+ /**
63
+ * Info about an item currently exiting (for layout compensation)
64
+ */
65
+ export interface ExitingItemInfo {
66
+ itemId: string;
67
+ index: number;
68
+ height: number;
69
+ timestamp: number;
70
+ }
71
+ //# sourceMappingURL=animations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"animations.d.ts","sourceRoot":"","sources":["../../src/types/animations.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;AAExC;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG,MAAM,CAAC;AAErD;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,WAAW,CAAC;AAE5E;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE;QACL,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,KAAK,EAAE;QACL,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE;QACf,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3B,KAAK,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/C;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,kBAAkB,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,CACjC,SAAS,EAAE,kBAAkB,EAC7B,UAAU,EAAE,MAAM,IAAI,EACtB,MAAM,CAAC,EAAE,mBAAmB,KACzB,IAAI,CAAC;AAEV;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB"}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,94 @@
1
+ import type { SharedValue, AnimatedRef } from 'react-native-reanimated';
2
+ import type { GestureType } from 'react-native-gesture-handler';
3
+ import type Animated from 'react-native-reanimated';
4
+ /**
5
+ * Configuration for drag behavior
6
+ */
7
+ export interface DragConfig {
8
+ /** Fixed height for list items (used for drag calculations) */
9
+ itemHeight: number;
10
+ /** Scale factor applied to dragged item */
11
+ dragScale: number;
12
+ /** Shadow opacity for dragged item */
13
+ dragShadowOpacity: number;
14
+ /** Vertical margin per item */
15
+ itemVerticalMargin: number;
16
+ /** Duration (ms) to hold drag handle before drag activates */
17
+ longPressDuration: number;
18
+ /** Pixels from viewport edge to trigger autoscroll */
19
+ edgeThreshold: number;
20
+ /** Maximum scroll speed in pixels per frame */
21
+ maxScrollSpeed: number;
22
+ }
23
+ /**
24
+ * Configuration for useDragGesture hook
25
+ */
26
+ export interface UseDragGestureConfig {
27
+ /** Item ID for stable identity */
28
+ itemId: string;
29
+ /** Current index in list */
30
+ index: number;
31
+ /** Total number of items in the list */
32
+ totalItems: number;
33
+ /** Whether drag is enabled for this item */
34
+ enabled: boolean;
35
+ /** Ref to measure item container */
36
+ containerRef: AnimatedRef<Animated.View>;
37
+ }
38
+ /**
39
+ * Callbacks for drag gesture events
40
+ */
41
+ export interface UseDragGestureCallbacks {
42
+ /** Called when reorder should occur (with index delta) */
43
+ onReorderByDelta?: (itemId: string, delta: number) => void;
44
+ /** Optional haptic feedback callback */
45
+ onHapticFeedback?: (type: 'light' | 'medium') => void;
46
+ }
47
+ /**
48
+ * Return value from useDragGesture hook
49
+ */
50
+ export interface UseDragGestureResult {
51
+ /** The pan gesture to attach to drag handle */
52
+ panGesture: GestureType;
53
+ /** Whether this item is currently being dragged */
54
+ isDragging: SharedValue<boolean>;
55
+ /** Current translateY of this item */
56
+ translateY: SharedValue<number>;
57
+ }
58
+ /**
59
+ * Configuration for useDragShift hook
60
+ */
61
+ export interface UseDragShiftConfig {
62
+ /** Item ID for identity check (to skip shift for the dragged item) */
63
+ itemId: string;
64
+ /** Current index in list */
65
+ index: number;
66
+ }
67
+ /**
68
+ * Return value from useDragShift hook
69
+ */
70
+ export interface UseDragShiftResult {
71
+ /** Animated shift value for non-dragged items */
72
+ shiftY: SharedValue<number>;
73
+ }
74
+ /**
75
+ * Configuration for useDropCompensation hook
76
+ */
77
+ export interface UseDropCompensationConfig {
78
+ /** Item ID for stable identity check */
79
+ itemId: string;
80
+ /** Current index in list */
81
+ index: number;
82
+ /** This item's translateY SharedValue (from useDragGesture) */
83
+ translateY: SharedValue<number>;
84
+ /** This item's shiftY SharedValue (from useDragShift) */
85
+ shiftY: SharedValue<number>;
86
+ }
87
+ /**
88
+ * Return value from useDragAnimatedStyle hook
89
+ */
90
+ export interface UseDragAnimatedStyleResult {
91
+ /** Animated style for the dragged item (transform, zIndex, shadow) */
92
+ dragAnimatedStyle: ReturnType<typeof import('react-native-reanimated').useAnimatedStyle>;
93
+ }
94
+ //# sourceMappingURL=drag.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drag.d.ts","sourceRoot":"","sources":["../../src/types/drag.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACxE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,KAAK,QAAQ,MAAM,yBAAyB,CAAC;AAEpD;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,+DAA+D;IAC/D,UAAU,EAAE,MAAM,CAAC;IACnB,2CAA2C;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,+BAA+B;IAC/B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,8DAA8D;IAC9D,iBAAiB,EAAE,MAAM,CAAC;IAC1B,sDAAsD;IACtD,aAAa,EAAE,MAAM,CAAC;IACtB,+CAA+C;IAC/C,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,kCAAkC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,OAAO,EAAE,OAAO,CAAC;IACjB,oCAAoC;IACpC,YAAY,EAAE,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;CAC1C;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,0DAA0D;IAC1D,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3D,wCAAwC;IACxC,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,KAAK,IAAI,CAAC;CACvD;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,+CAA+C;IAC/C,UAAU,EAAE,WAAW,CAAC;IACxB,mDAAmD;IACnD,UAAU,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IACjC,sCAAsC;IACtC,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,sEAAsE;IACtE,MAAM,EAAE,MAAM,CAAC;IACf,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,iDAAiD;IACjD,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAChC,yDAAyD;IACzD,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,sEAAsE;IACtE,iBAAiB,EAAE,UAAU,CAAC,cAAc,yBAAyB,EAAE,gBAAgB,CAAC,CAAC;CAC1F"}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,4 @@
1
+ export * from './animations';
2
+ export * from './drag';
3
+ export * from './list';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC"}
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./animations"), exports);
18
+ __exportStar(require("./drag"), exports);
19
+ __exportStar(require("./list"), exports);