@souscheflabs/reanimated-flashlist 0.3.2 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/AnimatedFlashList.d.ts.map +1 -1
- package/lib/AnimatedFlashList.js +10 -12
- package/lib/AnimatedFlashListItem.d.ts.map +1 -1
- package/lib/AnimatedFlashListItem.js +1 -5
- package/lib/contexts/DragStateContext.d.ts +2 -0
- package/lib/contexts/DragStateContext.d.ts.map +1 -1
- package/lib/contexts/DragStateContext.js +4 -0
- package/lib/hooks/drag/useDragGesture.d.ts.map +1 -1
- package/lib/hooks/drag/useDragGesture.js +8 -6
- package/lib/hooks/drag/useDropCompensation.d.ts.map +1 -1
- package/lib/hooks/drag/useDropCompensation.js +0 -3
- package/lib/types/drag.d.ts +0 -2
- package/lib/types/drag.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/AnimatedFlashList.tsx +11 -12
- package/src/AnimatedFlashListItem.tsx +1 -6
- package/src/contexts/DragStateContext.tsx +7 -0
- package/src/hooks/drag/useDragGesture.ts +7 -5
- package/src/hooks/drag/useDropCompensation.ts +0 -5
- package/src/types/drag.ts +0 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AnimatedFlashList.d.ts","sourceRoot":"","sources":["../src/AnimatedFlashList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAON,MAAM,OAAO,CAAC;AAaf,OAAO,KAAK,EACV,gBAAgB,EAChB,sBAAsB,EACtB,oBAAoB,EAErB,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"AnimatedFlashList.d.ts","sourceRoot":"","sources":["../src/AnimatedFlashList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAON,MAAM,OAAO,CAAC;AAaf,OAAO,KAAK,EACV,gBAAgB,EAChB,sBAAsB,EACtB,oBAAoB,EAErB,MAAM,SAAS,CAAC;AAyYjB,eAAO,MAAM,iBAAiB,EAAyC,CACrE,CAAC,SAAS,gBAAgB,EAE1B,KAAK,EAAE,sBAAsB,CAAC,CAAC,CAAC,GAAG;IAAE,GAAG,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC,oBAAoB,CAAC,CAAA;CAAE,KAClF,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC"}
|
package/lib/AnimatedFlashList.js
CHANGED
|
@@ -46,13 +46,17 @@ const ItemWrapper = react_1.default.memo(function ItemWrapper({ item, index, tot
|
|
|
46
46
|
});
|
|
47
47
|
function InnerFlashList({ data, totalItemsRef, flashListRef, renderItem, keyExtractor, canDrag, dragEnabled, onReorderByDelta, onHapticFeedback, itemHeight, ListFooterComponent, onEndReached, onEndReachedThreshold, onRefresh, refreshing, refreshTintColor, contentContainerStyle, drawDistance = 500, showsVerticalScrollIndicator = true, }) {
|
|
48
48
|
// Get drag state context for scroll tracking
|
|
49
|
-
const { scrollOffset, contentHeight, visibleHeight, listTopY, setListRef } = (0, contexts_1.useDragState)();
|
|
49
|
+
const { scrollOffset, contentHeight, visibleHeight, listTopY, setListRef, totalItems } = (0, contexts_1.useDragState)();
|
|
50
50
|
// Register FlashList ref with drag context for autoscroll
|
|
51
51
|
(0, react_1.useEffect)(() => {
|
|
52
52
|
// Cast to unknown to satisfy the generic constraint
|
|
53
53
|
setListRef(flashListRef.current);
|
|
54
54
|
return () => setListRef(null);
|
|
55
55
|
}, [setListRef, flashListRef]);
|
|
56
|
+
// Sync totalItems SharedValue with data.length for worklet access
|
|
57
|
+
(0, react_1.useEffect)(() => {
|
|
58
|
+
totalItems.value = data.length;
|
|
59
|
+
}, [data.length, totalItems]);
|
|
56
60
|
// Update scroll offset on scroll
|
|
57
61
|
const handleScroll = (0, react_1.useCallback)((event) => {
|
|
58
62
|
scrollOffset.value = event.nativeEvent.contentOffset.y;
|
|
@@ -127,17 +131,11 @@ function AnimatedFlashListInner(props, ref) {
|
|
|
127
131
|
const { data, keyExtractor, renderItem, dragEnabled = false, onReorder, onReorderByNeighbors, canDrag, onHapticFeedback, config, onPrepareLayoutAnimation, ListFooterComponent, onRefresh, refreshing = false, onEndReached, onEndReachedThreshold = 0.5, contentContainerStyle, estimatedItemSize, ...flashListProps } = props;
|
|
128
132
|
// Merge config with defaults
|
|
129
133
|
// Use estimatedItemSize as default itemHeight if not explicitly configured
|
|
130
|
-
const dragConfig = (0, react_1.useMemo)(() => {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
};
|
|
136
|
-
if (__DEV__) {
|
|
137
|
-
console.log(`[AnimatedFlashList] dragConfig.itemHeight=${mergedConfig.itemHeight}, estimatedItemSize=${estimatedItemSize}, config.drag?.itemHeight=${config?.drag?.itemHeight}`);
|
|
138
|
-
}
|
|
139
|
-
return mergedConfig;
|
|
140
|
-
}, [config?.drag, estimatedItemSize]);
|
|
134
|
+
const dragConfig = (0, react_1.useMemo)(() => ({
|
|
135
|
+
...constants_1.DEFAULT_DRAG_CONFIG,
|
|
136
|
+
...config?.drag,
|
|
137
|
+
itemHeight: config?.drag?.itemHeight ?? estimatedItemSize ?? constants_1.DEFAULT_DRAG_CONFIG.itemHeight,
|
|
138
|
+
}), [config?.drag, estimatedItemSize]);
|
|
141
139
|
// Ref to FlashList
|
|
142
140
|
const flashListRef = (0, react_1.useRef)(null);
|
|
143
141
|
// Expose methods to parent via ref
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AnimatedFlashListItem.d.ts","sourceRoot":"","sources":["../src/AnimatedFlashListItem.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAwD,MAAM,OAAO,CAAC;AAY7E,OAAO,KAAK,EACV,gBAAgB,EAChB,sBAAsB,EACtB,kBAAkB,EACnB,MAAM,SAAS,CAAC;AAEjB,UAAU,0BAA0B,CAAC,CAAC,SAAS,gBAAgB;IAC7D,oBAAoB;IACpB,IAAI,EAAE,CAAC,CAAC;IACR,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,4BAA4B;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,aAAa,EAAE,OAAO,CAAC;IACvB,kCAAkC;IAClC,UAAU,EAAE,CAAC,IAAI,EAAE,sBAAsB,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,YAAY,CAAC;IACpE,mCAAmC;IACnC,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3D,wCAAwC;IACxC,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,kBAAkB,KAAK,IAAI,CAAC;CACvD;AAED;;;;;;;;;;GAUG;AACH,iBAAS,0BAA0B,CAAC,CAAC,SAAS,gBAAgB,EAAE,EAC9D,IAAI,EACJ,KAAK,EACL,UAAU,EACV,aAAa,EACb,UAAU,EACV,gBAAgB,EAChB,gBAAgB,GACjB,EAAE,0BAA0B,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,YAAY,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"AnimatedFlashListItem.d.ts","sourceRoot":"","sources":["../src/AnimatedFlashListItem.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAwD,MAAM,OAAO,CAAC;AAY7E,OAAO,KAAK,EACV,gBAAgB,EAChB,sBAAsB,EACtB,kBAAkB,EACnB,MAAM,SAAS,CAAC;AAEjB,UAAU,0BAA0B,CAAC,CAAC,SAAS,gBAAgB;IAC7D,oBAAoB;IACpB,IAAI,EAAE,CAAC,CAAC;IACR,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,4BAA4B;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,aAAa,EAAE,OAAO,CAAC;IACvB,kCAAkC;IAClC,UAAU,EAAE,CAAC,IAAI,EAAE,sBAAsB,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,YAAY,CAAC;IACpE,mCAAmC;IACnC,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3D,wCAAwC;IACxC,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,kBAAkB,KAAK,IAAI,CAAC;CACvD;AAED;;;;;;;;;;GAUG;AACH,iBAAS,0BAA0B,CAAC,CAAC,SAAS,gBAAgB,EAAE,EAC9D,IAAI,EACJ,KAAK,EACL,UAAU,EACV,aAAa,EACb,UAAU,EACV,gBAAgB,EAChB,gBAAgB,GACjB,EAAE,0BAA0B,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,YAAY,GAAG,IAAI,CA8J3D;AAGD,eAAO,MAAM,qBAAqB,EAE7B,OAAO,0BAA0B,CAAC"}
|
|
@@ -50,10 +50,6 @@ const contexts_1 = require("./contexts");
|
|
|
50
50
|
* @internal
|
|
51
51
|
*/
|
|
52
52
|
function AnimatedFlashListItemInner({ item, index, totalItems, isDragEnabled, renderItem, onReorderByDelta, onHapticFeedback, }) {
|
|
53
|
-
// DEBUG: Log renders
|
|
54
|
-
if (__DEV__) {
|
|
55
|
-
console.log(`[AnimatedFlashListItem] RENDER ${item.id} at index=${index}`);
|
|
56
|
-
}
|
|
57
53
|
// Register this item's index in the central registry
|
|
58
54
|
// This handles FlashList's recycling behavior where components may not re-render
|
|
59
55
|
// after data changes, leaving their index props stale
|
|
@@ -72,10 +68,10 @@ function AnimatedFlashListItemInner({ item, index, totalItems, isDragEnabled, re
|
|
|
72
68
|
const animationContext = (0, contexts_1.useListAnimationOptional)();
|
|
73
69
|
// === DRAG HOOKS ===
|
|
74
70
|
// Pan gesture for drag-to-reorder
|
|
71
|
+
// Note: totalItems is now accessed via SharedValue from DragStateContext
|
|
75
72
|
const { panGesture, isDragging, translateY } = (0, hooks_1.useDragGesture)({
|
|
76
73
|
itemId: item.id,
|
|
77
74
|
index,
|
|
78
|
-
totalItems,
|
|
79
75
|
enabled: isDragEnabled,
|
|
80
76
|
containerRef,
|
|
81
77
|
}, {
|
|
@@ -80,6 +80,8 @@ export interface DragStateContextValue {
|
|
|
80
80
|
* Call this from handleDragEnd after onEnd updates the registry.
|
|
81
81
|
*/
|
|
82
82
|
markRegistryUpdated: () => void;
|
|
83
|
+
/** Total number of items in the list (synced from data.length) */
|
|
84
|
+
totalItems: SharedValue<number>;
|
|
83
85
|
}
|
|
84
86
|
/**
|
|
85
87
|
* Hook to access shared drag state from context.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DragStateContext.d.ts","sourceRoot":"","sources":["../../src/contexts/DragStateContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAMZ,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAgC3C;;;;;;;;;GASG;AACH,MAAM,WAAW,qBAAqB;IACpC,2CAA2C;IAC3C,UAAU,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IACjC,oEAAoE;IACpE,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAClC,oFAAoF;IACpF,aAAa,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACnC,iFAAiF;IACjF,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACvC,sEAAsE;IACtE,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAClC,+DAA+D;IAC/D,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAClC,uFAAuF;IACvF,qBAAqB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3C,yEAAyE;IACzE,aAAa,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACnC,qDAAqD;IACrD,aAAa,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACnC,mFAAmF;IACnF,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC9B,4EAA4E;IAC5E,kBAAkB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACxC,yDAAyD;IACzD,UAAU,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IACjC,gFAAgF;IAChF,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAClC,2DAA2D;IAC3D,UAAU,EAAE,CAAC,GAAG,EAAE,YAAY,CAAC,OAAO,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC;IACxD,wEAAwE;IACxE,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7D,6EAA6E;IAC7E,+BAA+B,EAAE,MAAM,IAAI,CAAC;IAC5C,sDAAsD;IACtD,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,iCAAiC;IACjC,MAAM,EAAE,UAAU,CAAC;IACnB;;;;OAIG;IACH,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACvD,mEAAmE;IACnE,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACzD,4CAA4C;IAC5C,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IACrD;;;;OAIG;IACH,sBAAsB,EAAE,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC5D;;;OAGG;IACH,uBAAuB,EAAE,MAAM,IAAI,CAAC;IACpC;;;OAGG;IACH,sBAAsB,EAAE,CACtB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,KACZ,IAAI,CAAC;IACV;;;OAGG;IACH,mBAAmB,EAAE,MAAM,IAAI,CAAC;CACjC;AAID;;;GAGG;AACH,eAAO,MAAM,YAAY,QAAO,qBAM/B,CAAC;AAEF,UAAU,sBAAsB;IAC9B,QAAQ,EAAE,SAAS,CAAC;IACpB,4CAA4C;IAC5C,MAAM,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;CAC9B;AAmDD,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,
|
|
1
|
+
{"version":3,"file":"DragStateContext.d.ts","sourceRoot":"","sources":["../../src/contexts/DragStateContext.tsx"],"names":[],"mappings":"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"}
|
|
@@ -136,6 +136,8 @@ const DragStateProvider = ({ children, config: configOverrides, }) => {
|
|
|
136
136
|
const itemIndexRegistry = (0, react_native_reanimated_1.useSharedValue)({});
|
|
137
137
|
// Snapshot of registry taken at drag start for consistent index lookup during drag
|
|
138
138
|
const dragStartIndexSnapshot = (0, react_native_reanimated_1.useSharedValue)({});
|
|
139
|
+
// Total number of items in the list (synced from data.length by InnerFlashList)
|
|
140
|
+
const totalItems = (0, react_native_reanimated_1.useSharedValue)(0);
|
|
139
141
|
// Timestamp when registry was last updated by onEnd (for protecting against stale overwrites)
|
|
140
142
|
const registryUpdateTimestamp = (0, react_1.useRef)(0);
|
|
141
143
|
// Ref to FlashList for autoscroll operations
|
|
@@ -258,6 +260,7 @@ const DragStateProvider = ({ children, config: configOverrides, }) => {
|
|
|
258
260
|
snapshotRegistryForDrag,
|
|
259
261
|
applyReorderToRegistry,
|
|
260
262
|
markRegistryUpdated,
|
|
263
|
+
totalItems,
|
|
261
264
|
}), [
|
|
262
265
|
isDragging,
|
|
263
266
|
draggedIndex,
|
|
@@ -283,6 +286,7 @@ const DragStateProvider = ({ children, config: configOverrides, }) => {
|
|
|
283
286
|
snapshotRegistryForDrag,
|
|
284
287
|
applyReorderToRegistry,
|
|
285
288
|
markRegistryUpdated,
|
|
289
|
+
totalItems,
|
|
286
290
|
]);
|
|
287
291
|
return (<DragStateContext.Provider value={value}>
|
|
288
292
|
{children}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDragGesture.d.ts","sourceRoot":"","sources":["../../../src/hooks/drag/useDragGesture.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EACV,oBAAoB,EACpB,uBAAuB,EACvB,oBAAoB,EACrB,MAAM,aAAa,CAAC;AAErB;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,oBAAoB,EAC5B,SAAS,EAAE,uBAAuB,GACjC,oBAAoB,
|
|
1
|
+
{"version":3,"file":"useDragGesture.d.ts","sourceRoot":"","sources":["../../../src/hooks/drag/useDragGesture.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EACV,oBAAoB,EACpB,uBAAuB,EACvB,oBAAoB,EACrB,MAAM,aAAa,CAAC;AAErB;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,oBAAoB,EAC5B,SAAS,EAAE,uBAAuB,GACjC,oBAAoB,CA2btB"}
|
|
@@ -35,7 +35,7 @@ const DragStateContext_1 = require("../../contexts/DragStateContext");
|
|
|
35
35
|
* ```
|
|
36
36
|
*/
|
|
37
37
|
function useDragGesture(config, callbacks) {
|
|
38
|
-
const { itemId, index,
|
|
38
|
+
const { itemId, index, enabled, containerRef } = config;
|
|
39
39
|
const { onReorderByDelta, onHapticFeedback } = callbacks;
|
|
40
40
|
// Dev-only guard to warn once if measurement is missing
|
|
41
41
|
const hasWarnedMissingHeight = (0, react_1.useRef)(false);
|
|
@@ -43,7 +43,7 @@ function useDragGesture(config, callbacks) {
|
|
|
43
43
|
const isDragging = (0, react_native_reanimated_1.useSharedValue)(false);
|
|
44
44
|
const translateY = (0, react_native_reanimated_1.useSharedValue)(0);
|
|
45
45
|
// Global drag state for coordinating animations across all items
|
|
46
|
-
const { isDragging: globalIsDragging, draggedIndex, draggedItemId, currentTranslateY, draggedScale, scrollOffset, dragStartScrollOffset, contentHeight, visibleHeight, listTopY, measuredItemHeight, isDropping, scrollToOffset, prepareForLayoutAnimationRender, config: dragConfig, itemIndexRegistry, dragStartIndexSnapshot, dragSequence, markRegistryUpdated, } = (0, DragStateContext_1.useDragState)();
|
|
46
|
+
const { isDragging: globalIsDragging, draggedIndex, draggedItemId, currentTranslateY, draggedScale, scrollOffset, dragStartScrollOffset, contentHeight, visibleHeight, listTopY, measuredItemHeight, isDropping, scrollToOffset, prepareForLayoutAnimationRender, config: dragConfig, itemIndexRegistry, dragStartIndexSnapshot, dragSequence, markRegistryUpdated, totalItems, } = (0, DragStateContext_1.useDragState)();
|
|
47
47
|
// Performance optimization: Track last significant Y position and scroll time
|
|
48
48
|
// to avoid updating on every pixel movement
|
|
49
49
|
const lastSignificantY = (0, react_native_reanimated_1.useSharedValue)(0);
|
|
@@ -82,20 +82,20 @@ function useDragGesture(config, callbacks) {
|
|
|
82
82
|
currentIndex.value = index;
|
|
83
83
|
}, [index, currentIndex]);
|
|
84
84
|
// Store current values in refs for stable gesture callbacks
|
|
85
|
+
// Note: totalItems is now a SharedValue from context, accessed directly in worklets
|
|
85
86
|
const dragContextRef = (0, react_1.useRef)({
|
|
86
|
-
totalItems,
|
|
87
87
|
itemId,
|
|
88
88
|
onReorderByDelta,
|
|
89
89
|
});
|
|
90
90
|
// Keep ref in sync with current values
|
|
91
91
|
dragContextRef.current = {
|
|
92
|
-
totalItems,
|
|
93
92
|
itemId,
|
|
94
93
|
onReorderByDelta,
|
|
95
94
|
};
|
|
96
95
|
// Calculate new position and call reorder callback
|
|
97
96
|
const handleDragEnd = (0, react_1.useCallback)((finalTranslateY) => {
|
|
98
|
-
const {
|
|
97
|
+
const { itemId: currentItemId, onReorderByDelta: reorder, } = dragContextRef.current;
|
|
98
|
+
const total = totalItems.value;
|
|
99
99
|
// Use draggedIndex from context, which was set in onStart using the registry
|
|
100
100
|
// This handles FlashList's recycling where closure-captured index may be stale
|
|
101
101
|
const currentIndex = draggedIndex.value;
|
|
@@ -184,6 +184,7 @@ function useDragGesture(config, callbacks) {
|
|
|
184
184
|
onHapticFeedback,
|
|
185
185
|
dragSequence,
|
|
186
186
|
markRegistryUpdated,
|
|
187
|
+
totalItems,
|
|
187
188
|
]);
|
|
188
189
|
// Stable haptic callback for drag start
|
|
189
190
|
const triggerLightHaptic = (0, react_1.useCallback)(() => {
|
|
@@ -301,7 +302,7 @@ function useDragGesture(config, callbacks) {
|
|
|
301
302
|
// runs on the JS thread, which would cause the new drag's snapshot to have
|
|
302
303
|
// stale indices.
|
|
303
304
|
const currentIdx = draggedIndex.value;
|
|
304
|
-
const total =
|
|
305
|
+
const total = totalItems.value;
|
|
305
306
|
// Use measured item height for accurate position calculations
|
|
306
307
|
// Fall back to config height if measurement failed or not yet available
|
|
307
308
|
const itemHeight = measuredItemHeight.value > 0
|
|
@@ -371,6 +372,7 @@ function useDragGesture(config, callbacks) {
|
|
|
371
372
|
itemId,
|
|
372
373
|
dragStartIndexSnapshot,
|
|
373
374
|
itemIndexRegistry,
|
|
375
|
+
totalItems,
|
|
374
376
|
]);
|
|
375
377
|
return { panGesture, isDragging, translateY };
|
|
376
378
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDropCompensation.d.ts","sourceRoot":"","sources":["../../../src/hooks/drag/useDropCompensation.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAE7D;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,yBAAyB,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"useDropCompensation.d.ts","sourceRoot":"","sources":["../../../src/hooks/drag/useDropCompensation.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAE7D;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,yBAAyB,GAAG,IAAI,CA0I3E"}
|
|
@@ -84,9 +84,6 @@ function useDropCompensation(config) {
|
|
|
84
84
|
}
|
|
85
85
|
else {
|
|
86
86
|
// Normal index change (not during drop): apply compensation
|
|
87
|
-
if (__DEV__) {
|
|
88
|
-
console.log("[DROP-COMP] Non-dragged normal index change - compensating");
|
|
89
|
-
}
|
|
90
87
|
translateY.value = (0, react_native_reanimated_1.withTiming)(compensatedY, {
|
|
91
88
|
duration: constants_1.ANIMATION_TIMING.COMPENSATION_DURATION,
|
|
92
89
|
easing: react_native_reanimated_1.Easing.out(react_native_reanimated_1.Easing.ease),
|
package/lib/types/drag.d.ts
CHANGED
|
@@ -28,8 +28,6 @@ export interface UseDragGestureConfig {
|
|
|
28
28
|
itemId: string;
|
|
29
29
|
/** Current index in list */
|
|
30
30
|
index: number;
|
|
31
|
-
/** Total number of items in the list */
|
|
32
|
-
totalItems: number;
|
|
33
31
|
/** Whether drag is enabled for this item */
|
|
34
32
|
enabled: boolean;
|
|
35
33
|
/** Ref to measure item container */
|
package/lib/types/drag.d.ts.map
CHANGED
|
@@ -1 +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,
|
|
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,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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@souscheflabs/reanimated-flashlist",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"description": "A high-performance animated FlashList with drag-to-reorder and entry/exit animations (New Architecture)",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"module": "lib/index.js",
|
|
@@ -112,7 +112,7 @@ function InnerFlashList<T extends AnimatedListItem>({
|
|
|
112
112
|
showsVerticalScrollIndicator = true,
|
|
113
113
|
}: InnerFlashListProps<T>): React.ReactElement {
|
|
114
114
|
// Get drag state context for scroll tracking
|
|
115
|
-
const { scrollOffset, contentHeight, visibleHeight, listTopY, setListRef } =
|
|
115
|
+
const { scrollOffset, contentHeight, visibleHeight, listTopY, setListRef, totalItems } =
|
|
116
116
|
useDragState();
|
|
117
117
|
|
|
118
118
|
// Register FlashList ref with drag context for autoscroll
|
|
@@ -122,6 +122,11 @@ function InnerFlashList<T extends AnimatedListItem>({
|
|
|
122
122
|
return () => setListRef(null);
|
|
123
123
|
}, [setListRef, flashListRef]);
|
|
124
124
|
|
|
125
|
+
// Sync totalItems SharedValue with data.length for worklet access
|
|
126
|
+
useEffect(() => {
|
|
127
|
+
totalItems.value = data.length;
|
|
128
|
+
}, [data.length, totalItems]);
|
|
129
|
+
|
|
125
130
|
// Update scroll offset on scroll
|
|
126
131
|
const handleScroll = useCallback(
|
|
127
132
|
(event: NativeSyntheticEvent<NativeScrollEvent>) => {
|
|
@@ -285,17 +290,11 @@ function AnimatedFlashListInner<T extends AnimatedListItem>(
|
|
|
285
290
|
// Merge config with defaults
|
|
286
291
|
// Use estimatedItemSize as default itemHeight if not explicitly configured
|
|
287
292
|
const dragConfig = useMemo(
|
|
288
|
-
() => {
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
};
|
|
294
|
-
if (__DEV__) {
|
|
295
|
-
console.log(`[AnimatedFlashList] dragConfig.itemHeight=${mergedConfig.itemHeight}, estimatedItemSize=${estimatedItemSize}, config.drag?.itemHeight=${config?.drag?.itemHeight}`);
|
|
296
|
-
}
|
|
297
|
-
return mergedConfig;
|
|
298
|
-
},
|
|
293
|
+
() => ({
|
|
294
|
+
...DEFAULT_DRAG_CONFIG,
|
|
295
|
+
...config?.drag,
|
|
296
|
+
itemHeight: config?.drag?.itemHeight ?? estimatedItemSize ?? DEFAULT_DRAG_CONFIG.itemHeight,
|
|
297
|
+
}),
|
|
299
298
|
[config?.drag, estimatedItemSize],
|
|
300
299
|
);
|
|
301
300
|
|
|
@@ -53,11 +53,6 @@ function AnimatedFlashListItemInner<T extends AnimatedListItem>({
|
|
|
53
53
|
onReorderByDelta,
|
|
54
54
|
onHapticFeedback,
|
|
55
55
|
}: AnimatedFlashListItemProps<T>): React.ReactElement | null {
|
|
56
|
-
// DEBUG: Log renders
|
|
57
|
-
if (__DEV__) {
|
|
58
|
-
console.log(`[AnimatedFlashListItem] RENDER ${item.id} at index=${index}`);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
56
|
// Register this item's index in the central registry
|
|
62
57
|
// This handles FlashList's recycling behavior where components may not re-render
|
|
63
58
|
// after data changes, leaving their index props stale
|
|
@@ -82,11 +77,11 @@ function AnimatedFlashListItemInner<T extends AnimatedListItem>({
|
|
|
82
77
|
// === DRAG HOOKS ===
|
|
83
78
|
|
|
84
79
|
// Pan gesture for drag-to-reorder
|
|
80
|
+
// Note: totalItems is now accessed via SharedValue from DragStateContext
|
|
85
81
|
const { panGesture, isDragging, translateY } = useDragGesture(
|
|
86
82
|
{
|
|
87
83
|
itemId: item.id,
|
|
88
84
|
index,
|
|
89
|
-
totalItems,
|
|
90
85
|
enabled: isDragEnabled,
|
|
91
86
|
containerRef,
|
|
92
87
|
},
|
|
@@ -123,6 +123,8 @@ export interface DragStateContextValue {
|
|
|
123
123
|
* Call this from handleDragEnd after onEnd updates the registry.
|
|
124
124
|
*/
|
|
125
125
|
markRegistryUpdated: () => void;
|
|
126
|
+
/** Total number of items in the list (synced from data.length) */
|
|
127
|
+
totalItems: SharedValue<number>;
|
|
126
128
|
}
|
|
127
129
|
|
|
128
130
|
const DragStateContext = createContext<DragStateContextValue | null>(null);
|
|
@@ -236,6 +238,9 @@ export const DragStateProvider: React.FC<DragStateProviderProps> = ({
|
|
|
236
238
|
// Snapshot of registry taken at drag start for consistent index lookup during drag
|
|
237
239
|
const dragStartIndexSnapshot = useSharedValue<Record<string, number>>({});
|
|
238
240
|
|
|
241
|
+
// Total number of items in the list (synced from data.length by InnerFlashList)
|
|
242
|
+
const totalItems = useSharedValue(0);
|
|
243
|
+
|
|
239
244
|
// Timestamp when registry was last updated by onEnd (for protecting against stale overwrites)
|
|
240
245
|
const registryUpdateTimestamp = useRef<number>(0);
|
|
241
246
|
|
|
@@ -393,6 +398,7 @@ export const DragStateProvider: React.FC<DragStateProviderProps> = ({
|
|
|
393
398
|
snapshotRegistryForDrag,
|
|
394
399
|
applyReorderToRegistry,
|
|
395
400
|
markRegistryUpdated,
|
|
401
|
+
totalItems,
|
|
396
402
|
}),
|
|
397
403
|
[
|
|
398
404
|
isDragging,
|
|
@@ -419,6 +425,7 @@ export const DragStateProvider: React.FC<DragStateProviderProps> = ({
|
|
|
419
425
|
snapshotRegistryForDrag,
|
|
420
426
|
applyReorderToRegistry,
|
|
421
427
|
markRegistryUpdated,
|
|
428
|
+
totalItems,
|
|
422
429
|
],
|
|
423
430
|
);
|
|
424
431
|
|
|
@@ -55,7 +55,7 @@ export function useDragGesture(
|
|
|
55
55
|
config: UseDragGestureConfig,
|
|
56
56
|
callbacks: UseDragGestureCallbacks,
|
|
57
57
|
): UseDragGestureResult {
|
|
58
|
-
const { itemId, index,
|
|
58
|
+
const { itemId, index, enabled, containerRef } = config;
|
|
59
59
|
const { onReorderByDelta, onHapticFeedback } = callbacks;
|
|
60
60
|
|
|
61
61
|
// Dev-only guard to warn once if measurement is missing
|
|
@@ -86,6 +86,7 @@ export function useDragGesture(
|
|
|
86
86
|
dragStartIndexSnapshot,
|
|
87
87
|
dragSequence,
|
|
88
88
|
markRegistryUpdated,
|
|
89
|
+
totalItems,
|
|
89
90
|
} = useDragState();
|
|
90
91
|
|
|
91
92
|
// Performance optimization: Track last significant Y position and scroll time
|
|
@@ -131,15 +132,14 @@ export function useDragGesture(
|
|
|
131
132
|
}, [index, currentIndex]);
|
|
132
133
|
|
|
133
134
|
// Store current values in refs for stable gesture callbacks
|
|
135
|
+
// Note: totalItems is now a SharedValue from context, accessed directly in worklets
|
|
134
136
|
const dragContextRef = useRef({
|
|
135
|
-
totalItems,
|
|
136
137
|
itemId,
|
|
137
138
|
onReorderByDelta,
|
|
138
139
|
});
|
|
139
140
|
|
|
140
141
|
// Keep ref in sync with current values
|
|
141
142
|
dragContextRef.current = {
|
|
142
|
-
totalItems,
|
|
143
143
|
itemId,
|
|
144
144
|
onReorderByDelta,
|
|
145
145
|
};
|
|
@@ -148,10 +148,10 @@ export function useDragGesture(
|
|
|
148
148
|
const handleDragEnd = useCallback(
|
|
149
149
|
(finalTranslateY: number) => {
|
|
150
150
|
const {
|
|
151
|
-
totalItems: total,
|
|
152
151
|
itemId: currentItemId,
|
|
153
152
|
onReorderByDelta: reorder,
|
|
154
153
|
} = dragContextRef.current;
|
|
154
|
+
const total = totalItems.value;
|
|
155
155
|
|
|
156
156
|
// Use draggedIndex from context, which was set in onStart using the registry
|
|
157
157
|
// This handles FlashList's recycling where closure-captured index may be stale
|
|
@@ -266,6 +266,7 @@ export function useDragGesture(
|
|
|
266
266
|
onHapticFeedback,
|
|
267
267
|
dragSequence,
|
|
268
268
|
markRegistryUpdated,
|
|
269
|
+
totalItems,
|
|
269
270
|
],
|
|
270
271
|
);
|
|
271
272
|
|
|
@@ -416,7 +417,7 @@ export function useDragGesture(
|
|
|
416
417
|
// runs on the JS thread, which would cause the new drag's snapshot to have
|
|
417
418
|
// stale indices.
|
|
418
419
|
const currentIdx = draggedIndex.value;
|
|
419
|
-
const total =
|
|
420
|
+
const total = totalItems.value;
|
|
420
421
|
// Use measured item height for accurate position calculations
|
|
421
422
|
// Fall back to config height if measurement failed or not yet available
|
|
422
423
|
const itemHeight =
|
|
@@ -491,6 +492,7 @@ export function useDragGesture(
|
|
|
491
492
|
itemId,
|
|
492
493
|
dragStartIndexSnapshot,
|
|
493
494
|
itemIndexRegistry,
|
|
495
|
+
totalItems,
|
|
494
496
|
],
|
|
495
497
|
);
|
|
496
498
|
|
|
@@ -110,11 +110,6 @@ export function useDropCompensation(config: UseDropCompensationConfig): void {
|
|
|
110
110
|
translateY.value = 0;
|
|
111
111
|
} else {
|
|
112
112
|
// Normal index change (not during drop): apply compensation
|
|
113
|
-
if (__DEV__) {
|
|
114
|
-
console.log(
|
|
115
|
-
"[DROP-COMP] Non-dragged normal index change - compensating",
|
|
116
|
-
);
|
|
117
|
-
}
|
|
118
113
|
translateY.value = withTiming(compensatedY, {
|
|
119
114
|
duration: ANIMATION_TIMING.COMPENSATION_DURATION,
|
|
120
115
|
easing: Easing.out(Easing.ease),
|
package/src/types/drag.ts
CHANGED
|
@@ -30,8 +30,6 @@ export interface UseDragGestureConfig {
|
|
|
30
30
|
itemId: string;
|
|
31
31
|
/** Current index in list */
|
|
32
32
|
index: number;
|
|
33
|
-
/** Total number of items in the list */
|
|
34
|
-
totalItems: number;
|
|
35
33
|
/** Whether drag is enabled for this item */
|
|
36
34
|
enabled: boolean;
|
|
37
35
|
/** Ref to measure item container */
|