@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,119 @@
1
+ import {
2
+ useSharedValue,
3
+ useDerivedValue,
4
+ useAnimatedReaction,
5
+ withTiming,
6
+ Easing,
7
+ } from 'react-native-reanimated';
8
+ import { useDragState } from '../../contexts/DragStateContext';
9
+ import type { UseDragShiftConfig, UseDragShiftResult } from '../../types';
10
+
11
+ /**
12
+ * Hook that calculates shift animation for non-dragged items.
13
+ *
14
+ * When an item is being dragged, other items need to shift up or down
15
+ * to make room for the dragged item at its new position. This hook
16
+ * calculates the target shift based on:
17
+ * - The current drag position (from context)
18
+ * - The scroll delta (accounting for autoscroll)
19
+ * - The item's index relative to the dragged item
20
+ *
21
+ * The shift is animated with timing for smooth transitions.
22
+ *
23
+ * @example
24
+ * ```tsx
25
+ * const { shiftY } = useDragShift({ itemId: item.id, index });
26
+ * // Use shiftY.value in animated style
27
+ * ```
28
+ */
29
+ export function useDragShift(config: UseDragShiftConfig): UseDragShiftResult {
30
+ const { itemId, index } = config;
31
+
32
+ // Global drag state for coordinating animations across all items
33
+ const {
34
+ isDragging: globalIsDragging,
35
+ draggedIndex,
36
+ draggedItemId,
37
+ currentTranslateY,
38
+ scrollOffset,
39
+ dragStartScrollOffset,
40
+ dragUpdateTrigger,
41
+ measuredItemHeight,
42
+ isDropping,
43
+ config: dragConfig,
44
+ } = useDragState();
45
+
46
+ // Shift animation SharedValue
47
+ const shiftY = useSharedValue(0);
48
+
49
+ // Calculate target shift using useDerivedValue
50
+ const targetShiftY = useDerivedValue(() => {
51
+ 'worklet';
52
+ // Force re-evaluation on every drag state change
53
+ // eslint-disable-next-line @typescript-eslint/no-unused-expressions
54
+ dragUpdateTrigger.value;
55
+
56
+ // During drop transition, freeze shift values
57
+ if (isDropping.value) {
58
+ return shiftY.value;
59
+ }
60
+
61
+ const currentDraggedIndex = draggedIndex.value;
62
+ const isDraggingNow = globalIsDragging.value;
63
+ const translateYNow = currentTranslateY.value;
64
+ const currentDraggedItemId = draggedItemId.value;
65
+
66
+ // If I'm the dragged item, no shift needed
67
+ if (currentDraggedItemId === itemId) return 0;
68
+
69
+ // If not dragging, reset to 0
70
+ if (!isDraggingNow) return 0;
71
+
72
+ // Use dynamically measured height + margins, or fall back to config
73
+ const itemHeight =
74
+ measuredItemHeight.value > 0
75
+ ? measuredItemHeight.value + dragConfig.itemVerticalMargin
76
+ : dragConfig.itemHeight;
77
+
78
+ // Calculate effective translateY including scroll delta
79
+ const scrollDelta = scrollOffset.value - dragStartScrollOffset.value;
80
+ const effectiveTranslateY = translateYNow + scrollDelta;
81
+
82
+ // Calculate which index the dragged item is hovering over
83
+ const offset =
84
+ effectiveTranslateY > 0 ? 0.2 : effectiveTranslateY < 0 ? -0.2 : 0;
85
+ const hoveredIndex =
86
+ currentDraggedIndex + Math.round(effectiveTranslateY / itemHeight + offset);
87
+
88
+ // Moving DOWN: items between original and hovered positions shift UP
89
+ if (hoveredIndex > currentDraggedIndex) {
90
+ if (index > currentDraggedIndex && index <= hoveredIndex) {
91
+ return -itemHeight;
92
+ }
93
+ }
94
+ // Moving UP: items between hovered and original positions shift DOWN
95
+ else if (hoveredIndex < currentDraggedIndex) {
96
+ if (index < currentDraggedIndex && index >= hoveredIndex) {
97
+ return itemHeight;
98
+ }
99
+ }
100
+
101
+ return 0;
102
+ }, [index, itemId]);
103
+
104
+ // Animate shift when target changes
105
+ useAnimatedReaction(
106
+ () => targetShiftY.value,
107
+ (target, prev) => {
108
+ 'worklet';
109
+ if (target !== prev) {
110
+ shiftY.value = withTiming(target, {
111
+ duration: 100,
112
+ easing: Easing.out(Easing.ease),
113
+ });
114
+ }
115
+ },
116
+ );
117
+
118
+ return { shiftY };
119
+ }
@@ -0,0 +1,120 @@
1
+ import { useLayoutEffect } from 'react';
2
+ import {
3
+ useSharedValue,
4
+ useAnimatedReaction,
5
+ withTiming,
6
+ Easing,
7
+ } from 'react-native-reanimated';
8
+ import { useRecyclingState } from '@shopify/flash-list';
9
+ import { useDragState } from '../../contexts/DragStateContext';
10
+ import type { UseDropCompensationConfig } from '../../types';
11
+
12
+ /**
13
+ * Hook that handles index change compensation after drag reorder.
14
+ *
15
+ * When an item is dropped and the data updates, React re-renders with new indices.
16
+ * This causes a visual jump because items suddenly have different positions.
17
+ * This hook compensates by:
18
+ * 1. Detecting index changes (via useRecyclingState for FlashList recycling)
19
+ * 2. Adjusting translateY to compensate for the position delta
20
+ * 3. Animating the dragged item back to 0 (settle animation)
21
+ * 4. Resetting global drag state after animation completes
22
+ * 5. Resetting shiftY on UI thread via useAnimatedReaction
23
+ *
24
+ * useLayoutEffect runs synchronously before paint to prevent visual flash.
25
+ *
26
+ * @example
27
+ * ```tsx
28
+ * useDropCompensation({
29
+ * itemId: item.id,
30
+ * index,
31
+ * translateY,
32
+ * shiftY,
33
+ * });
34
+ * ```
35
+ */
36
+ export function useDropCompensation(config: UseDropCompensationConfig): void {
37
+ const { itemId, index, translateY, shiftY } = config;
38
+
39
+ // Track index on UI thread for synchronized shift reset
40
+ const indexShared = useSharedValue(index);
41
+
42
+ // Global drag state
43
+ const {
44
+ isDragging: globalIsDragging,
45
+ draggedIndex,
46
+ draggedItemId,
47
+ measuredItemHeight,
48
+ isDropping,
49
+ dragUpdateTrigger,
50
+ config: dragConfig,
51
+ } = useDragState();
52
+
53
+ // Use FlashList's useRecyclingState for automatic reset on view recycling
54
+ const [prevIndex, setPrevIndex] = useRecyclingState(index, [itemId]);
55
+
56
+ // Handle index changes after data updates (drop compensation)
57
+ useLayoutEffect(() => {
58
+ if (index !== prevIndex) {
59
+ // Compensate for index change by adjusting translateY
60
+ const indexDelta = index - prevIndex;
61
+ const heightDelta = indexDelta * dragConfig.itemHeight;
62
+
63
+ // Check if this is the dragged item completing its drop
64
+ const isTheDraggedItem = draggedItemId.value === itemId;
65
+
66
+ // Compensate translateY for position change
67
+ const compensatedY = translateY.value - heightDelta;
68
+
69
+ if (isTheDraggedItem) {
70
+ // Dragged item: animate smoothly to 0 from compensated position
71
+ translateY.value = compensatedY;
72
+ translateY.value = withTiming(
73
+ 0,
74
+ { duration: 150, easing: Easing.out(Easing.ease) },
75
+ finished => {
76
+ 'worklet';
77
+ if (finished) {
78
+ // Reset ALL global state after settle animation
79
+ isDropping.value = false;
80
+ globalIsDragging.value = false;
81
+ draggedIndex.value = -1;
82
+ draggedItemId.value = '';
83
+ measuredItemHeight.value = 0;
84
+ dragUpdateTrigger.value = withTiming(dragUpdateTrigger.value + 1, {
85
+ duration: 1,
86
+ });
87
+ }
88
+ },
89
+ );
90
+ } else if (Math.abs(translateY.value) > 1) {
91
+ // Non-dragged item: just compensate without animation
92
+ translateY.value = compensatedY;
93
+ }
94
+
95
+ // Update tracked index
96
+ setPrevIndex(index);
97
+ }
98
+ // eslint-disable-next-line react-hooks/exhaustive-deps
99
+ }, [index, prevIndex, translateY, setPrevIndex, itemId]);
100
+
101
+ // Sync JS index to SharedValue for UI thread access
102
+ useLayoutEffect(() => {
103
+ indexShared.value = index;
104
+ }, [index, indexShared]);
105
+
106
+ // Reset shiftY on UI thread when index changes
107
+ useAnimatedReaction(
108
+ () => indexShared.value,
109
+ (currentIndex, prevIdx) => {
110
+ 'worklet';
111
+ if (
112
+ prevIdx !== null &&
113
+ currentIndex !== prevIdx &&
114
+ Math.abs(shiftY.value) > 1
115
+ ) {
116
+ shiftY.value = 0;
117
+ }
118
+ },
119
+ );
120
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Hooks for AnimatedFlashList
3
+ *
4
+ * Re-exports all hooks for both drag and animation functionality.
5
+ */
6
+
7
+ // Drag hooks
8
+ export {
9
+ useDragGesture,
10
+ useDragShift,
11
+ useDragAnimatedStyle,
12
+ useDropCompensation,
13
+ } from './drag';
14
+
15
+ // Animation hooks
16
+ export { useListExitAnimation, useListEntryAnimation } from './animations';
package/src/index.ts ADDED
@@ -0,0 +1,105 @@
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
+
36
+ // Main component
37
+ export { AnimatedFlashList } from './AnimatedFlashList';
38
+ export { AnimatedFlashListItem } from './AnimatedFlashListItem';
39
+
40
+ // Contexts (for advanced usage)
41
+ export {
42
+ DragStateProvider,
43
+ useDragState,
44
+ ListAnimationProvider,
45
+ useListAnimation,
46
+ useListAnimationOptional,
47
+ } from './contexts';
48
+
49
+ // Hooks (for advanced/custom implementations)
50
+ export {
51
+ // Drag hooks
52
+ useDragGesture,
53
+ useDragShift,
54
+ useDragAnimatedStyle,
55
+ useDropCompensation,
56
+ // Animation hooks
57
+ useListExitAnimation,
58
+ useListEntryAnimation,
59
+ } from './hooks';
60
+
61
+ // Constants (for customization)
62
+ export {
63
+ DEFAULT_DRAG_CONFIG,
64
+ createDragConfig,
65
+ DEFAULT_EXIT_ANIMATION,
66
+ FAST_EXIT_ANIMATION,
67
+ DEFAULT_ENTRY_ANIMATION,
68
+ getExitAnimationConfig,
69
+ createEntryAnimationConfig,
70
+ standardEasing,
71
+ } from './constants';
72
+
73
+ // Types
74
+ export type {
75
+ // List types
76
+ AnimatedListItem,
77
+ AnimatedFlashListProps,
78
+ AnimatedFlashListRef,
79
+ AnimatedFlashListConfig,
80
+ AnimatedRenderItemInfo,
81
+ DragHandleProps,
82
+ // Drag types
83
+ DragConfig,
84
+ UseDragGestureConfig,
85
+ UseDragGestureCallbacks,
86
+ UseDragGestureResult,
87
+ UseDragShiftConfig,
88
+ UseDragShiftResult,
89
+ UseDropCompensationConfig,
90
+ UseDragAnimatedStyleResult,
91
+ // Animation types
92
+ AnimationDirection,
93
+ ExitAnimationPreset,
94
+ ExitAnimationConfig,
95
+ EntryAnimationConfig,
96
+ PendingEntryAnimation,
97
+ ExitAnimationTrigger,
98
+ HapticFeedbackType,
99
+ } from './types';
100
+
101
+ // Context types
102
+ export type {
103
+ DragStateContextValue,
104
+ ListAnimationContextValue,
105
+ } from './contexts';
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Animation direction for entry/exit animations
3
+ * 1 = forward/right, -1 = backward/left
4
+ */
5
+ export type AnimationDirection = 1 | -1;
6
+
7
+ /**
8
+ * Animation preset type for exit animations
9
+ * - 'default': Standard exit animation (for swipe/delete actions)
10
+ * - 'fast': Quick exit animation (for checkbox toggles)
11
+ */
12
+ export type ExitAnimationPreset = 'default' | 'fast';
13
+
14
+ /**
15
+ * Haptic feedback types that can be triggered during animations
16
+ */
17
+ export type HapticFeedbackType = 'light' | 'medium' | 'heavy' | 'selection';
18
+
19
+ /**
20
+ * Configuration for exit animations
21
+ */
22
+ export interface ExitAnimationConfig {
23
+ slide: {
24
+ duration: number;
25
+ distance: number;
26
+ };
27
+ fade: {
28
+ delay: number;
29
+ duration: number;
30
+ };
31
+ scale: {
32
+ delay: number;
33
+ duration: number;
34
+ toValue: number;
35
+ };
36
+ removalDelay: number;
37
+ layoutAnimation: {
38
+ duration: number;
39
+ };
40
+ }
41
+
42
+ /**
43
+ * Configuration for entry animations
44
+ */
45
+ export interface EntryAnimationConfig {
46
+ fade: { duration: number };
47
+ slide: { distance: number; 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
+ /**
60
+ * Exit animation trigger function type
61
+ */
62
+ export type ExitAnimationTrigger = (
63
+ direction: AnimationDirection,
64
+ onComplete: () => void,
65
+ preset?: ExitAnimationPreset,
66
+ ) => void;
67
+
68
+ /**
69
+ * Info about an item currently exiting (for layout compensation)
70
+ */
71
+ export interface ExitingItemInfo {
72
+ itemId: string;
73
+ index: number;
74
+ height: number;
75
+ timestamp: number;
76
+ }
@@ -0,0 +1,101 @@
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
+ /**
6
+ * Configuration for drag behavior
7
+ */
8
+ export interface DragConfig {
9
+ /** Fixed height for list items (used for drag calculations) */
10
+ itemHeight: number;
11
+ /** Scale factor applied to dragged item */
12
+ dragScale: number;
13
+ /** Shadow opacity for dragged item */
14
+ dragShadowOpacity: number;
15
+ /** Vertical margin per item */
16
+ itemVerticalMargin: number;
17
+ /** Duration (ms) to hold drag handle before drag activates */
18
+ longPressDuration: number;
19
+ /** Pixels from viewport edge to trigger autoscroll */
20
+ edgeThreshold: number;
21
+ /** Maximum scroll speed in pixels per frame */
22
+ maxScrollSpeed: number;
23
+ }
24
+
25
+ /**
26
+ * Configuration for useDragGesture hook
27
+ */
28
+ export interface UseDragGestureConfig {
29
+ /** Item ID for stable identity */
30
+ itemId: string;
31
+ /** Current index in list */
32
+ index: number;
33
+ /** Total number of items in the list */
34
+ totalItems: number;
35
+ /** Whether drag is enabled for this item */
36
+ enabled: boolean;
37
+ /** Ref to measure item container */
38
+ containerRef: AnimatedRef<Animated.View>;
39
+ }
40
+
41
+ /**
42
+ * Callbacks for drag gesture events
43
+ */
44
+ export interface UseDragGestureCallbacks {
45
+ /** Called when reorder should occur (with index delta) */
46
+ onReorderByDelta?: (itemId: string, delta: number) => void;
47
+ /** Optional haptic feedback callback */
48
+ onHapticFeedback?: (type: 'light' | 'medium') => void;
49
+ }
50
+
51
+ /**
52
+ * Return value from useDragGesture hook
53
+ */
54
+ export interface UseDragGestureResult {
55
+ /** The pan gesture to attach to drag handle */
56
+ panGesture: GestureType;
57
+ /** Whether this item is currently being dragged */
58
+ isDragging: SharedValue<boolean>;
59
+ /** Current translateY of this item */
60
+ translateY: SharedValue<number>;
61
+ }
62
+
63
+ /**
64
+ * Configuration for useDragShift hook
65
+ */
66
+ export interface UseDragShiftConfig {
67
+ /** Item ID for identity check (to skip shift for the dragged item) */
68
+ itemId: string;
69
+ /** Current index in list */
70
+ index: number;
71
+ }
72
+
73
+ /**
74
+ * Return value from useDragShift hook
75
+ */
76
+ export interface UseDragShiftResult {
77
+ /** Animated shift value for non-dragged items */
78
+ shiftY: SharedValue<number>;
79
+ }
80
+
81
+ /**
82
+ * Configuration for useDropCompensation hook
83
+ */
84
+ export interface UseDropCompensationConfig {
85
+ /** Item ID for stable identity check */
86
+ itemId: string;
87
+ /** Current index in list */
88
+ index: number;
89
+ /** This item's translateY SharedValue (from useDragGesture) */
90
+ translateY: SharedValue<number>;
91
+ /** This item's shiftY SharedValue (from useDragShift) */
92
+ shiftY: SharedValue<number>;
93
+ }
94
+
95
+ /**
96
+ * Return value from useDragAnimatedStyle hook
97
+ */
98
+ export interface UseDragAnimatedStyleResult {
99
+ /** Animated style for the dragged item (transform, zIndex, shadow) */
100
+ dragAnimatedStyle: ReturnType<typeof import('react-native-reanimated').useAnimatedStyle>;
101
+ }
@@ -0,0 +1,3 @@
1
+ export * from './animations';
2
+ export * from './drag';
3
+ export * from './list';