@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.
- package/README.md +282 -0
- package/lib/AnimatedFlashList.d.ts +6 -0
- package/lib/AnimatedFlashList.d.ts.map +1 -0
- package/lib/AnimatedFlashList.js +207 -0
- package/lib/AnimatedFlashListItem.d.ts +33 -0
- package/lib/AnimatedFlashListItem.d.ts.map +1 -0
- package/lib/AnimatedFlashListItem.js +155 -0
- package/lib/__tests__/utils/test-utils.d.ts +82 -0
- package/lib/__tests__/utils/test-utils.d.ts.map +1 -0
- package/lib/__tests__/utils/test-utils.js +115 -0
- package/lib/constants/animations.d.ts +39 -0
- package/lib/constants/animations.d.ts.map +1 -0
- package/lib/constants/animations.js +100 -0
- package/lib/constants/drag.d.ts +11 -0
- package/lib/constants/drag.d.ts.map +1 -0
- package/lib/constants/drag.js +47 -0
- package/lib/constants/index.d.ts +3 -0
- package/lib/constants/index.d.ts.map +1 -0
- package/lib/constants/index.js +18 -0
- package/lib/contexts/DragStateContext.d.ts +73 -0
- package/lib/contexts/DragStateContext.d.ts.map +1 -0
- package/lib/contexts/DragStateContext.js +148 -0
- package/lib/contexts/ListAnimationContext.d.ts +104 -0
- package/lib/contexts/ListAnimationContext.d.ts.map +1 -0
- package/lib/contexts/ListAnimationContext.js +184 -0
- package/lib/contexts/index.d.ts +5 -0
- package/lib/contexts/index.d.ts.map +1 -0
- package/lib/contexts/index.js +10 -0
- package/lib/hooks/animations/index.d.ts +9 -0
- package/lib/hooks/animations/index.d.ts.map +1 -0
- package/lib/hooks/animations/index.js +13 -0
- package/lib/hooks/animations/useListEntryAnimation.d.ts +38 -0
- package/lib/hooks/animations/useListEntryAnimation.d.ts.map +1 -0
- package/lib/hooks/animations/useListEntryAnimation.js +90 -0
- package/lib/hooks/animations/useListExitAnimation.d.ts +67 -0
- package/lib/hooks/animations/useListExitAnimation.d.ts.map +1 -0
- package/lib/hooks/animations/useListExitAnimation.js +146 -0
- package/lib/hooks/drag/index.d.ts +20 -0
- package/lib/hooks/drag/index.d.ts.map +1 -0
- package/lib/hooks/drag/index.js +26 -0
- package/lib/hooks/drag/useDragAnimatedStyle.d.ts +33 -0
- package/lib/hooks/drag/useDragAnimatedStyle.d.ts.map +1 -0
- package/lib/hooks/drag/useDragAnimatedStyle.js +61 -0
- package/lib/hooks/drag/useDragGesture.d.ts +30 -0
- package/lib/hooks/drag/useDragGesture.d.ts.map +1 -0
- package/lib/hooks/drag/useDragGesture.js +189 -0
- package/lib/hooks/drag/useDragShift.d.ts +21 -0
- package/lib/hooks/drag/useDragShift.d.ts.map +1 -0
- package/lib/hooks/drag/useDragShift.js +85 -0
- package/lib/hooks/drag/useDropCompensation.d.ts +27 -0
- package/lib/hooks/drag/useDropCompensation.d.ts.map +1 -0
- package/lib/hooks/drag/useDropCompensation.js +90 -0
- package/lib/hooks/index.d.ts +8 -0
- package/lib/hooks/index.d.ts.map +1 -0
- package/lib/hooks/index.js +18 -0
- package/lib/index.d.ts +42 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +69 -0
- package/lib/types/animations.d.ts +71 -0
- package/lib/types/animations.d.ts.map +1 -0
- package/lib/types/animations.js +2 -0
- package/lib/types/drag.d.ts +94 -0
- package/lib/types/drag.d.ts.map +1 -0
- package/lib/types/drag.js +2 -0
- package/lib/types/index.d.ts +4 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/index.js +19 -0
- package/lib/types/list.d.ts +136 -0
- package/lib/types/list.d.ts.map +1 -0
- package/lib/types/list.js +2 -0
- package/package.json +73 -0
- package/src/AnimatedFlashList.tsx +411 -0
- package/src/AnimatedFlashListItem.tsx +212 -0
- package/src/__tests__/components/AnimatedFlashList.test.tsx +365 -0
- package/src/__tests__/components/AnimatedFlashListItem.test.tsx +371 -0
- package/src/__tests__/contexts/DragStateContext.test.tsx +169 -0
- package/src/__tests__/contexts/ListAnimationContext.test.tsx +324 -0
- package/src/__tests__/hooks/useDragAnimatedStyle.test.tsx +118 -0
- package/src/__tests__/hooks/useDragGesture.test.tsx +169 -0
- package/src/__tests__/hooks/useDragShift.test.tsx +94 -0
- package/src/__tests__/hooks/useDropCompensation.test.tsx +182 -0
- package/src/__tests__/hooks/useListEntryAnimation.test.tsx +135 -0
- package/src/__tests__/hooks/useListExitAnimation.test.tsx +175 -0
- package/src/__tests__/utils/test-utils.tsx +159 -0
- package/src/constants/animations.ts +107 -0
- package/src/constants/drag.ts +51 -0
- package/src/constants/index.ts +2 -0
- package/src/contexts/DragStateContext.tsx +197 -0
- package/src/contexts/ListAnimationContext.tsx +302 -0
- package/src/contexts/index.ts +9 -0
- package/src/hooks/animations/index.ts +9 -0
- package/src/hooks/animations/useListEntryAnimation.ts +108 -0
- package/src/hooks/animations/useListExitAnimation.ts +197 -0
- package/src/hooks/drag/index.ts +20 -0
- package/src/hooks/drag/useDragAnimatedStyle.ts +80 -0
- package/src/hooks/drag/useDragGesture.ts +267 -0
- package/src/hooks/drag/useDragShift.ts +119 -0
- package/src/hooks/drag/useDropCompensation.ts +120 -0
- package/src/hooks/index.ts +16 -0
- package/src/index.ts +105 -0
- package/src/types/animations.ts +76 -0
- package/src/types/drag.ts +101 -0
- package/src/types/index.ts +3 -0
- package/src/types/list.ts +178 -0
|
@@ -0,0 +1,155 @@
|
|
|
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.AnimatedFlashListItem = void 0;
|
|
37
|
+
const react_1 = __importStar(require("react"));
|
|
38
|
+
const react_native_reanimated_1 = __importStar(require("react-native-reanimated"));
|
|
39
|
+
const hooks_1 = require("./hooks");
|
|
40
|
+
const contexts_1 = require("./contexts");
|
|
41
|
+
/**
|
|
42
|
+
* Internal item wrapper that provides all animation functionality.
|
|
43
|
+
*
|
|
44
|
+
* This component:
|
|
45
|
+
* 1. Sets up drag gesture and shift animations
|
|
46
|
+
* 2. Sets up entry/exit animations
|
|
47
|
+
* 3. Combines all animated styles
|
|
48
|
+
* 4. Passes everything to the consumer's renderItem function
|
|
49
|
+
*
|
|
50
|
+
* @internal
|
|
51
|
+
*/
|
|
52
|
+
function AnimatedFlashListItemInner({ item, index, totalItems, isDragEnabled, renderItem, onReorderByDelta, onHapticFeedback, }) {
|
|
53
|
+
// Animated ref for measuring item height on drag start
|
|
54
|
+
const containerRef = (0, react_native_reanimated_1.useAnimatedRef)();
|
|
55
|
+
// Track measured height for layout compensation
|
|
56
|
+
const measuredHeightRef = (0, react_1.useRef)(0);
|
|
57
|
+
// List animation context for subscription-triggered animations and layout compensation
|
|
58
|
+
const animationContext = (0, contexts_1.useListAnimationOptional)();
|
|
59
|
+
// === DRAG HOOKS ===
|
|
60
|
+
// Pan gesture for drag-to-reorder
|
|
61
|
+
const { panGesture, isDragging, translateY } = (0, hooks_1.useDragGesture)({
|
|
62
|
+
itemId: item.id,
|
|
63
|
+
index,
|
|
64
|
+
totalItems,
|
|
65
|
+
enabled: isDragEnabled,
|
|
66
|
+
containerRef,
|
|
67
|
+
}, {
|
|
68
|
+
onReorderByDelta,
|
|
69
|
+
onHapticFeedback,
|
|
70
|
+
});
|
|
71
|
+
// Shift animation for non-dragged items
|
|
72
|
+
const { shiftY } = (0, hooks_1.useDragShift)({ itemId: item.id, index });
|
|
73
|
+
// Handle index changes after cache updates (drop compensation)
|
|
74
|
+
(0, hooks_1.useDropCompensation)({ itemId: item.id, index, translateY, shiftY });
|
|
75
|
+
// Animated style for drag transforms
|
|
76
|
+
const { dragAnimatedStyle } = (0, hooks_1.useDragAnimatedStyle)(item.id, isDragging, translateY, shiftY);
|
|
77
|
+
// === ANIMATION HOOKS ===
|
|
78
|
+
// Callbacks for layout compensation (register/unregister exiting items)
|
|
79
|
+
const onExitStart = (0, react_1.useCallback)((exitIndex, height) => {
|
|
80
|
+
animationContext?.registerExitingItem(item.id, exitIndex, height);
|
|
81
|
+
}, [animationContext, item.id]);
|
|
82
|
+
const onExitComplete = (0, react_1.useCallback)(() => {
|
|
83
|
+
animationContext?.unregisterExitingItem(item.id);
|
|
84
|
+
}, [animationContext, item.id]);
|
|
85
|
+
// Exit animation for smooth slide-out (with layout compensation callbacks)
|
|
86
|
+
const { exitAnimatedStyle, triggerExit, resetAnimation } = (0, hooks_1.useListExitAnimation)(item.id, {
|
|
87
|
+
index,
|
|
88
|
+
measuredHeight: measuredHeightRef.current,
|
|
89
|
+
onExitStart,
|
|
90
|
+
onExitComplete,
|
|
91
|
+
});
|
|
92
|
+
// Entry animation for items appearing
|
|
93
|
+
const { entryAnimatedStyle } = (0, hooks_1.useListEntryAnimation)(item.id);
|
|
94
|
+
// Register exit animation trigger (O(1) direct calls from subscriptions)
|
|
95
|
+
(0, react_1.useLayoutEffect)(() => {
|
|
96
|
+
if (!animationContext)
|
|
97
|
+
return;
|
|
98
|
+
animationContext.registerAnimationTrigger(item.id, triggerExit);
|
|
99
|
+
return () => animationContext.unregisterAnimationTrigger(item.id);
|
|
100
|
+
}, [item.id, triggerExit, animationContext]);
|
|
101
|
+
// Track measured height for layout compensation
|
|
102
|
+
const handleLayout = (0, react_1.useCallback)((event) => {
|
|
103
|
+
measuredHeightRef.current = event.nativeEvent.layout.height;
|
|
104
|
+
}, []);
|
|
105
|
+
// Create combined animated style
|
|
106
|
+
const combinedAnimatedStyle = (0, react_1.useMemo)(() => {
|
|
107
|
+
// We can't directly combine animated styles here since they're worklet-based
|
|
108
|
+
// Instead, we'll let the consumer apply them via the render prop
|
|
109
|
+
return {};
|
|
110
|
+
}, []);
|
|
111
|
+
// Create drag handle props
|
|
112
|
+
const dragHandleProps = (0, react_1.useMemo)(() => isDragEnabled
|
|
113
|
+
? {
|
|
114
|
+
gesture: panGesture,
|
|
115
|
+
isDragging,
|
|
116
|
+
}
|
|
117
|
+
: null, [isDragEnabled, panGesture, isDragging]);
|
|
118
|
+
// Trigger exit animation wrapper
|
|
119
|
+
const triggerExitAnimation = (0, react_1.useCallback)((direction, onComplete, preset) => {
|
|
120
|
+
triggerExit(direction, onComplete, preset);
|
|
121
|
+
}, [triggerExit]);
|
|
122
|
+
// Create render info
|
|
123
|
+
const renderInfo = (0, react_1.useMemo)(() => ({
|
|
124
|
+
item,
|
|
125
|
+
index,
|
|
126
|
+
totalItems,
|
|
127
|
+
animatedStyle: combinedAnimatedStyle,
|
|
128
|
+
dragHandleProps,
|
|
129
|
+
isDragging: false, // This is a SharedValue, consumer should use dragHandleProps.isDragging
|
|
130
|
+
isDragEnabled,
|
|
131
|
+
triggerExitAnimation,
|
|
132
|
+
resetExitAnimation: resetAnimation,
|
|
133
|
+
}), [
|
|
134
|
+
item,
|
|
135
|
+
index,
|
|
136
|
+
totalItems,
|
|
137
|
+
combinedAnimatedStyle,
|
|
138
|
+
dragHandleProps,
|
|
139
|
+
isDragEnabled,
|
|
140
|
+
triggerExitAnimation,
|
|
141
|
+
resetAnimation,
|
|
142
|
+
]);
|
|
143
|
+
// Render the item with animations applied
|
|
144
|
+
// The consumer's renderItem gets wrapped in our animated container
|
|
145
|
+
const renderedItem = renderItem(renderInfo);
|
|
146
|
+
return (<react_native_reanimated_1.default.View ref={containerRef} onLayout={handleLayout} style={[
|
|
147
|
+
exitAnimatedStyle,
|
|
148
|
+
entryAnimatedStyle,
|
|
149
|
+
isDragEnabled && dragAnimatedStyle,
|
|
150
|
+
]}>
|
|
151
|
+
{renderedItem}
|
|
152
|
+
</react_native_reanimated_1.default.View>);
|
|
153
|
+
}
|
|
154
|
+
// Memoize to prevent unnecessary re-renders
|
|
155
|
+
exports.AnimatedFlashListItem = react_1.default.memo(AnimatedFlashListItemInner);
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { ReactElement } from 'react';
|
|
2
|
+
import { render, RenderOptions } from '@testing-library/react-native';
|
|
3
|
+
import type { DragConfig } from '../../types';
|
|
4
|
+
/**
|
|
5
|
+
* Custom render options with context configuration
|
|
6
|
+
*/
|
|
7
|
+
interface CustomRenderOptions extends Omit<RenderOptions, 'wrapper'> {
|
|
8
|
+
dragConfig?: Partial<DragConfig>;
|
|
9
|
+
entryAnimationTimeout?: number;
|
|
10
|
+
layoutAnimationDuration?: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Custom render function that wraps components with all necessary providers
|
|
14
|
+
*/
|
|
15
|
+
declare const customRender: (ui: ReactElement, options?: CustomRenderOptions) => ReturnType<typeof render>;
|
|
16
|
+
export * from '@testing-library/react-native';
|
|
17
|
+
export { customRender as render };
|
|
18
|
+
/**
|
|
19
|
+
* Create a mock list item with required id field
|
|
20
|
+
*/
|
|
21
|
+
export interface MockListItem {
|
|
22
|
+
id: string;
|
|
23
|
+
title?: string;
|
|
24
|
+
[key: string]: unknown;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Factory function to create a single mock item
|
|
28
|
+
*/
|
|
29
|
+
export declare const createMockItem: (id: string, overrides?: Partial<MockListItem>) => MockListItem;
|
|
30
|
+
/**
|
|
31
|
+
* Factory function to create multiple mock items
|
|
32
|
+
*/
|
|
33
|
+
export declare const createMockItems: (count: number) => MockListItem[];
|
|
34
|
+
/**
|
|
35
|
+
* Create a mock SharedValue-like object for testing
|
|
36
|
+
*/
|
|
37
|
+
export declare const createMockSharedValue: <T>(initialValue: T) => {
|
|
38
|
+
value: T;
|
|
39
|
+
addListener: jest.Mock<any, any, any>;
|
|
40
|
+
removeListener: jest.Mock<any, any, any>;
|
|
41
|
+
modify: jest.Mock<T, [modifier: (val: T) => T], any>;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Create a mock animated ref for testing
|
|
45
|
+
*/
|
|
46
|
+
export declare const createMockAnimatedRef: <T>(current?: T | null) => {
|
|
47
|
+
current: T | null;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Wait for animations to complete (mock version)
|
|
51
|
+
*/
|
|
52
|
+
export declare const waitForAnimations: (ms?: number) => Promise<void>;
|
|
53
|
+
/**
|
|
54
|
+
* Mock gesture event data for testing drag operations
|
|
55
|
+
*/
|
|
56
|
+
export declare const createMockGestureEvent: (overrides?: Record<string, unknown>) => {
|
|
57
|
+
translationX: number;
|
|
58
|
+
translationY: number;
|
|
59
|
+
velocityX: number;
|
|
60
|
+
velocityY: number;
|
|
61
|
+
absoluteX: number;
|
|
62
|
+
absoluteY: number;
|
|
63
|
+
x: number;
|
|
64
|
+
y: number;
|
|
65
|
+
numberOfPointers: number;
|
|
66
|
+
state: number;
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Mock FlashList ref for testing
|
|
70
|
+
*/
|
|
71
|
+
export declare const createMockFlashListRef: () => {
|
|
72
|
+
scrollToOffset: jest.Mock<any, any, any>;
|
|
73
|
+
scrollToIndex: jest.Mock<any, any, any>;
|
|
74
|
+
scrollToItem: jest.Mock<any, any, any>;
|
|
75
|
+
scrollToEnd: jest.Mock<any, any, any>;
|
|
76
|
+
getScrollOffset: jest.Mock<number, [], any>;
|
|
77
|
+
getScrollableNode: jest.Mock<null, [], any>;
|
|
78
|
+
recordInteraction: jest.Mock<any, any, any>;
|
|
79
|
+
flashScrollIndicators: jest.Mock<any, any, any>;
|
|
80
|
+
prepareForLayoutAnimationRender: jest.Mock<any, any, any>;
|
|
81
|
+
};
|
|
82
|
+
//# sourceMappingURL=test-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-utils.d.ts","sourceRoot":"","sources":["../../../src/__tests__/utils/test-utils.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAGtE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AA+B9C;;GAEG;AACH,UAAU,mBAAoB,SAAQ,IAAI,CAAC,aAAa,EAAE,SAAS,CAAC;IAClE,UAAU,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;IACjC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAClC;AAED;;GAEG;AACH,QAAA,MAAM,YAAY,GAChB,IAAI,YAAY,EAChB,UAAU,mBAAmB,KAC5B,UAAU,CAAC,OAAO,MAAM,CAmB1B,CAAC;AAGF,cAAc,+BAA+B,CAAC;AAG9C,OAAO,EAAE,YAAY,IAAI,MAAM,EAAE,CAAC;AAElC;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;GAEG;AACH,eAAO,MAAM,cAAc,GACzB,IAAI,MAAM,EACV,YAAW,OAAO,CAAC,YAAY,CAAM,KACpC,YAID,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,eAAe,GAAI,OAAO,MAAM,KAAG,YAAY,EACc,CAAC;AAE3E;;GAEG;AACH,eAAO,MAAM,qBAAqB,GAAI,CAAC,EAAG,cAAc,CAAC;;;;0CAItB,CAAC,KAAK,CAAC;CACxC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,qBAAqB,GAAI,CAAC,EAAG,UAAS,CAAC,GAAG,IAAW;;CAEhE,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,iBAAiB,GAAU,WAAQ,KAAG,OAAO,CAAC,IAAI,CAE9D,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,sBAAsB,GAAI,YAAW,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM;;;;;;;;;;;CAY5E,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;CAUjC,CAAC"}
|
|
@@ -0,0 +1,115 @@
|
|
|
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
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
17
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
|
+
};
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.createMockFlashListRef = exports.createMockGestureEvent = exports.waitForAnimations = exports.createMockAnimatedRef = exports.createMockSharedValue = exports.createMockItems = exports.createMockItem = exports.render = void 0;
|
|
21
|
+
const react_1 = __importDefault(require("react"));
|
|
22
|
+
const react_native_1 = require("@testing-library/react-native");
|
|
23
|
+
const DragStateContext_1 = require("../../contexts/DragStateContext");
|
|
24
|
+
const ListAnimationContext_1 = require("../../contexts/ListAnimationContext");
|
|
25
|
+
/**
|
|
26
|
+
* Wrapper component that provides all required contexts for testing
|
|
27
|
+
*/
|
|
28
|
+
const AllProviders = ({ children, dragConfig, entryAnimationTimeout, layoutAnimationDuration, }) => {
|
|
29
|
+
return (<ListAnimationContext_1.ListAnimationProvider entryAnimationTimeout={entryAnimationTimeout} layoutAnimationDuration={layoutAnimationDuration}>
|
|
30
|
+
<DragStateContext_1.DragStateProvider config={dragConfig}>{children}</DragStateContext_1.DragStateProvider>
|
|
31
|
+
</ListAnimationContext_1.ListAnimationProvider>);
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Custom render function that wraps components with all necessary providers
|
|
35
|
+
*/
|
|
36
|
+
const customRender = (ui, options) => {
|
|
37
|
+
const { dragConfig, entryAnimationTimeout, layoutAnimationDuration, ...renderOptions } = options ?? {};
|
|
38
|
+
const Wrapper = ({ children }) => (<AllProviders dragConfig={dragConfig} entryAnimationTimeout={entryAnimationTimeout} layoutAnimationDuration={layoutAnimationDuration}>
|
|
39
|
+
{children}
|
|
40
|
+
</AllProviders>);
|
|
41
|
+
return (0, react_native_1.render)(ui, { wrapper: Wrapper, ...renderOptions });
|
|
42
|
+
};
|
|
43
|
+
exports.render = customRender;
|
|
44
|
+
// Re-export everything
|
|
45
|
+
__exportStar(require("@testing-library/react-native"), exports);
|
|
46
|
+
/**
|
|
47
|
+
* Factory function to create a single mock item
|
|
48
|
+
*/
|
|
49
|
+
const createMockItem = (id, overrides = {}) => ({
|
|
50
|
+
id,
|
|
51
|
+
title: `Item ${id}`,
|
|
52
|
+
...overrides,
|
|
53
|
+
});
|
|
54
|
+
exports.createMockItem = createMockItem;
|
|
55
|
+
/**
|
|
56
|
+
* Factory function to create multiple mock items
|
|
57
|
+
*/
|
|
58
|
+
const createMockItems = (count) => Array.from({ length: count }, (_, i) => (0, exports.createMockItem)(`item-${i + 1}`));
|
|
59
|
+
exports.createMockItems = createMockItems;
|
|
60
|
+
/**
|
|
61
|
+
* Create a mock SharedValue-like object for testing
|
|
62
|
+
*/
|
|
63
|
+
const createMockSharedValue = (initialValue) => ({
|
|
64
|
+
value: initialValue,
|
|
65
|
+
addListener: jest.fn(),
|
|
66
|
+
removeListener: jest.fn(),
|
|
67
|
+
modify: jest.fn((modifier) => modifier(initialValue)),
|
|
68
|
+
});
|
|
69
|
+
exports.createMockSharedValue = createMockSharedValue;
|
|
70
|
+
/**
|
|
71
|
+
* Create a mock animated ref for testing
|
|
72
|
+
*/
|
|
73
|
+
const createMockAnimatedRef = (current = null) => ({
|
|
74
|
+
current,
|
|
75
|
+
});
|
|
76
|
+
exports.createMockAnimatedRef = createMockAnimatedRef;
|
|
77
|
+
/**
|
|
78
|
+
* Wait for animations to complete (mock version)
|
|
79
|
+
*/
|
|
80
|
+
const waitForAnimations = async (ms = 300) => {
|
|
81
|
+
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
82
|
+
};
|
|
83
|
+
exports.waitForAnimations = waitForAnimations;
|
|
84
|
+
/**
|
|
85
|
+
* Mock gesture event data for testing drag operations
|
|
86
|
+
*/
|
|
87
|
+
const createMockGestureEvent = (overrides = {}) => ({
|
|
88
|
+
translationX: 0,
|
|
89
|
+
translationY: 0,
|
|
90
|
+
velocityX: 0,
|
|
91
|
+
velocityY: 0,
|
|
92
|
+
absoluteX: 0,
|
|
93
|
+
absoluteY: 0,
|
|
94
|
+
x: 0,
|
|
95
|
+
y: 0,
|
|
96
|
+
numberOfPointers: 1,
|
|
97
|
+
state: 4, // ACTIVE
|
|
98
|
+
...overrides,
|
|
99
|
+
});
|
|
100
|
+
exports.createMockGestureEvent = createMockGestureEvent;
|
|
101
|
+
/**
|
|
102
|
+
* Mock FlashList ref for testing
|
|
103
|
+
*/
|
|
104
|
+
const createMockFlashListRef = () => ({
|
|
105
|
+
scrollToOffset: jest.fn(),
|
|
106
|
+
scrollToIndex: jest.fn(),
|
|
107
|
+
scrollToItem: jest.fn(),
|
|
108
|
+
scrollToEnd: jest.fn(),
|
|
109
|
+
getScrollOffset: jest.fn(() => 0),
|
|
110
|
+
getScrollableNode: jest.fn(() => null),
|
|
111
|
+
recordInteraction: jest.fn(),
|
|
112
|
+
flashScrollIndicators: jest.fn(),
|
|
113
|
+
prepareForLayoutAnimationRender: jest.fn(),
|
|
114
|
+
});
|
|
115
|
+
exports.createMockFlashListRef = createMockFlashListRef;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { ExitAnimationConfig, EntryAnimationConfig } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Standard cubic bezier easing function for smooth animations
|
|
4
|
+
* Equivalent to CSS ease-in-out with custom curve
|
|
5
|
+
*/
|
|
6
|
+
export declare const standardEasing: import("react-native-reanimated").EasingFunctionFactory;
|
|
7
|
+
/**
|
|
8
|
+
* Default exit animation configuration
|
|
9
|
+
* Used when items are removed/toggled from the list
|
|
10
|
+
*
|
|
11
|
+
* Timeline (300ms total):
|
|
12
|
+
* - 0-300ms: Slide (300px in direction)
|
|
13
|
+
* - 50-300ms: Scale to 0.95
|
|
14
|
+
* - 100-300ms: Fade out
|
|
15
|
+
*/
|
|
16
|
+
export declare const DEFAULT_EXIT_ANIMATION: ExitAnimationConfig;
|
|
17
|
+
/**
|
|
18
|
+
* Fast exit animation for quick actions (checkbox toggles)
|
|
19
|
+
*
|
|
20
|
+
* Timeline (200ms total):
|
|
21
|
+
* - 0-200ms: Slide (200px in direction)
|
|
22
|
+
* - 0-200ms: Fade out (starts immediately)
|
|
23
|
+
* - 0-200ms: Scale to 0.97
|
|
24
|
+
*/
|
|
25
|
+
export declare const FAST_EXIT_ANIMATION: ExitAnimationConfig;
|
|
26
|
+
/**
|
|
27
|
+
* Default entry animation configuration
|
|
28
|
+
* Used when items appear in the list
|
|
29
|
+
*/
|
|
30
|
+
export declare const DEFAULT_ENTRY_ANIMATION: EntryAnimationConfig;
|
|
31
|
+
/**
|
|
32
|
+
* Get exit animation config by preset
|
|
33
|
+
*/
|
|
34
|
+
export declare function getExitAnimationConfig(preset?: 'default' | 'fast', overrides?: Partial<ExitAnimationConfig>): ExitAnimationConfig;
|
|
35
|
+
/**
|
|
36
|
+
* Create a merged entry animation config from defaults and overrides
|
|
37
|
+
*/
|
|
38
|
+
export declare function createEntryAnimationConfig(overrides?: Partial<EntryAnimationConfig>): EntryAnimationConfig;
|
|
39
|
+
//# sourceMappingURL=animations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"animations.d.ts","sourceRoot":"","sources":["../../src/constants/animations.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAE1E;;;GAGG;AACH,eAAO,MAAM,cAAc,yDAAoC,CAAC;AAEhE;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,EAAE,mBAkBpC,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,EAAE,mBAkBjC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,uBAAuB,EAAE,oBAGrC,CAAC;AAEF;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,GAAE,SAAS,GAAG,MAAe,EACnC,SAAS,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,GACvC,mBAAmB,CAWrB;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,SAAS,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,GACxC,oBAAoB,CAOtB"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_ENTRY_ANIMATION = exports.FAST_EXIT_ANIMATION = exports.DEFAULT_EXIT_ANIMATION = exports.standardEasing = void 0;
|
|
4
|
+
exports.getExitAnimationConfig = getExitAnimationConfig;
|
|
5
|
+
exports.createEntryAnimationConfig = createEntryAnimationConfig;
|
|
6
|
+
const react_native_reanimated_1 = require("react-native-reanimated");
|
|
7
|
+
/**
|
|
8
|
+
* Standard cubic bezier easing function for smooth animations
|
|
9
|
+
* Equivalent to CSS ease-in-out with custom curve
|
|
10
|
+
*/
|
|
11
|
+
exports.standardEasing = react_native_reanimated_1.Easing.bezier(0.25, 0.1, 0.25, 1);
|
|
12
|
+
/**
|
|
13
|
+
* Default exit animation configuration
|
|
14
|
+
* Used when items are removed/toggled from the list
|
|
15
|
+
*
|
|
16
|
+
* Timeline (300ms total):
|
|
17
|
+
* - 0-300ms: Slide (300px in direction)
|
|
18
|
+
* - 50-300ms: Scale to 0.95
|
|
19
|
+
* - 100-300ms: Fade out
|
|
20
|
+
*/
|
|
21
|
+
exports.DEFAULT_EXIT_ANIMATION = {
|
|
22
|
+
slide: {
|
|
23
|
+
duration: 300,
|
|
24
|
+
distance: 300,
|
|
25
|
+
},
|
|
26
|
+
fade: {
|
|
27
|
+
delay: 100,
|
|
28
|
+
duration: 200,
|
|
29
|
+
},
|
|
30
|
+
scale: {
|
|
31
|
+
delay: 50,
|
|
32
|
+
duration: 250,
|
|
33
|
+
toValue: 0.95,
|
|
34
|
+
},
|
|
35
|
+
removalDelay: 300,
|
|
36
|
+
layoutAnimation: {
|
|
37
|
+
duration: 200,
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Fast exit animation for quick actions (checkbox toggles)
|
|
42
|
+
*
|
|
43
|
+
* Timeline (200ms total):
|
|
44
|
+
* - 0-200ms: Slide (200px in direction)
|
|
45
|
+
* - 0-200ms: Fade out (starts immediately)
|
|
46
|
+
* - 0-200ms: Scale to 0.97
|
|
47
|
+
*/
|
|
48
|
+
exports.FAST_EXIT_ANIMATION = {
|
|
49
|
+
slide: {
|
|
50
|
+
duration: 200,
|
|
51
|
+
distance: 200,
|
|
52
|
+
},
|
|
53
|
+
fade: {
|
|
54
|
+
delay: 0,
|
|
55
|
+
duration: 200,
|
|
56
|
+
},
|
|
57
|
+
scale: {
|
|
58
|
+
delay: 0,
|
|
59
|
+
duration: 200,
|
|
60
|
+
toValue: 0.97,
|
|
61
|
+
},
|
|
62
|
+
removalDelay: 200,
|
|
63
|
+
layoutAnimation: {
|
|
64
|
+
duration: 150,
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Default entry animation configuration
|
|
69
|
+
* Used when items appear in the list
|
|
70
|
+
*/
|
|
71
|
+
exports.DEFAULT_ENTRY_ANIMATION = {
|
|
72
|
+
fade: { duration: 250 },
|
|
73
|
+
slide: { distance: 50, duration: 300 },
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Get exit animation config by preset
|
|
77
|
+
*/
|
|
78
|
+
function getExitAnimationConfig(preset = 'fast', overrides) {
|
|
79
|
+
const base = preset === 'fast' ? exports.FAST_EXIT_ANIMATION : exports.DEFAULT_EXIT_ANIMATION;
|
|
80
|
+
if (!overrides)
|
|
81
|
+
return base;
|
|
82
|
+
return {
|
|
83
|
+
slide: { ...base.slide, ...overrides.slide },
|
|
84
|
+
fade: { ...base.fade, ...overrides.fade },
|
|
85
|
+
scale: { ...base.scale, ...overrides.scale },
|
|
86
|
+
removalDelay: overrides.removalDelay ?? base.removalDelay,
|
|
87
|
+
layoutAnimation: { ...base.layoutAnimation, ...overrides.layoutAnimation },
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Create a merged entry animation config from defaults and overrides
|
|
92
|
+
*/
|
|
93
|
+
function createEntryAnimationConfig(overrides) {
|
|
94
|
+
if (!overrides)
|
|
95
|
+
return exports.DEFAULT_ENTRY_ANIMATION;
|
|
96
|
+
return {
|
|
97
|
+
fade: { ...exports.DEFAULT_ENTRY_ANIMATION.fade, ...overrides.fade },
|
|
98
|
+
slide: { ...exports.DEFAULT_ENTRY_ANIMATION.slide, ...overrides.slide },
|
|
99
|
+
};
|
|
100
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { DragConfig } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Default drag configuration
|
|
4
|
+
* All values can be overridden via AnimatedFlashList config prop
|
|
5
|
+
*/
|
|
6
|
+
export declare const DEFAULT_DRAG_CONFIG: DragConfig;
|
|
7
|
+
/**
|
|
8
|
+
* Create a merged drag config from defaults and overrides
|
|
9
|
+
*/
|
|
10
|
+
export declare function createDragConfig(overrides?: Partial<DragConfig>): DragConfig;
|
|
11
|
+
//# sourceMappingURL=drag.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drag.d.ts","sourceRoot":"","sources":["../../src/constants/drag.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,UAoCjC,CAAC;AAEF;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,UAAU,CAG5E"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_DRAG_CONFIG = void 0;
|
|
4
|
+
exports.createDragConfig = createDragConfig;
|
|
5
|
+
/**
|
|
6
|
+
* Default drag configuration
|
|
7
|
+
* All values can be overridden via AnimatedFlashList config prop
|
|
8
|
+
*/
|
|
9
|
+
exports.DEFAULT_DRAG_CONFIG = {
|
|
10
|
+
/**
|
|
11
|
+
* Fixed height for list items used in drag calculations.
|
|
12
|
+
* Override this to match your item height + margins
|
|
13
|
+
*/
|
|
14
|
+
itemHeight: 95,
|
|
15
|
+
/**
|
|
16
|
+
* Scale factor applied to dragged item for visual feedback
|
|
17
|
+
*/
|
|
18
|
+
dragScale: 1.03,
|
|
19
|
+
/**
|
|
20
|
+
* Shadow opacity for dragged item (increases from 0.1 to this value)
|
|
21
|
+
*/
|
|
22
|
+
dragShadowOpacity: 0.25,
|
|
23
|
+
/**
|
|
24
|
+
* Vertical margin per item (total margin = 2 * itemVerticalMargin)
|
|
25
|
+
*/
|
|
26
|
+
itemVerticalMargin: 8,
|
|
27
|
+
/**
|
|
28
|
+
* Duration (ms) to hold drag handle before drag activates
|
|
29
|
+
*/
|
|
30
|
+
longPressDuration: 200,
|
|
31
|
+
/**
|
|
32
|
+
* Pixels from viewport edge to trigger autoscroll
|
|
33
|
+
*/
|
|
34
|
+
edgeThreshold: 80,
|
|
35
|
+
/**
|
|
36
|
+
* Maximum scroll speed in pixels per frame at edge
|
|
37
|
+
*/
|
|
38
|
+
maxScrollSpeed: 10,
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Create a merged drag config from defaults and overrides
|
|
42
|
+
*/
|
|
43
|
+
function createDragConfig(overrides) {
|
|
44
|
+
if (!overrides)
|
|
45
|
+
return exports.DEFAULT_DRAG_CONFIG;
|
|
46
|
+
return { ...exports.DEFAULT_DRAG_CONFIG, ...overrides };
|
|
47
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/constants/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
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("./drag"), exports);
|
|
18
|
+
__exportStar(require("./animations"), exports);
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import React, { type ReactNode } from 'react';
|
|
2
|
+
import { type SharedValue } from 'react-native-reanimated';
|
|
3
|
+
import type { FlashListRef } from '@shopify/flash-list';
|
|
4
|
+
import type { DragConfig } from '../types';
|
|
5
|
+
/**
|
|
6
|
+
* Centralized drag state for coordinating animations across list items.
|
|
7
|
+
* All animation values are Reanimated SharedValues for 60fps UI thread performance.
|
|
8
|
+
*
|
|
9
|
+
* Architecture:
|
|
10
|
+
* - Single source of truth for all drag state (no per-item local state)
|
|
11
|
+
* - Dragged item identified by draggedIndex, reads/writes centralized values
|
|
12
|
+
* - Non-dragged items read draggedIndex/currentTranslateY to calculate shift
|
|
13
|
+
* - Scroll state enables viewport-aware hover calculations and autoscroll
|
|
14
|
+
*/
|
|
15
|
+
export interface DragStateContextValue {
|
|
16
|
+
/** Is any item currently being dragged? */
|
|
17
|
+
isDragging: SharedValue<boolean>;
|
|
18
|
+
/** Original index of the item being dragged (-1 if not dragging) */
|
|
19
|
+
draggedIndex: SharedValue<number>;
|
|
20
|
+
/** ID of the item being dragged (for stable identity across FlashList recycling) */
|
|
21
|
+
draggedItemId: SharedValue<string>;
|
|
22
|
+
/** Current Y translation of the dragged item (for calculating hover position) */
|
|
23
|
+
currentTranslateY: SharedValue<number>;
|
|
24
|
+
/** Scale of the dragged item (1.0 = normal, configured = dragging) */
|
|
25
|
+
draggedScale: SharedValue<number>;
|
|
26
|
+
/** Current scroll offset of the list (updated via onScroll) */
|
|
27
|
+
scrollOffset: SharedValue<number>;
|
|
28
|
+
/** Scroll offset when drag started (for scroll delta calculation during autoscroll) */
|
|
29
|
+
dragStartScrollOffset: SharedValue<number>;
|
|
30
|
+
/** Total content height of the list (updated via onContentSizeChange) */
|
|
31
|
+
contentHeight: SharedValue<number>;
|
|
32
|
+
/** Visible viewport height (updated via onLayout) */
|
|
33
|
+
visibleHeight: SharedValue<number>;
|
|
34
|
+
/** Y position of FlashList top on screen (for autoscroll coordinate conversion) */
|
|
35
|
+
listTopY: SharedValue<number>;
|
|
36
|
+
/** Counter incremented on every drag state change to force useDerivedValue re-evaluation */
|
|
37
|
+
dragUpdateTrigger: SharedValue<number>;
|
|
38
|
+
/** Measured height of the dragged item (for dynamic height calculations) */
|
|
39
|
+
measuredItemHeight: SharedValue<number>;
|
|
40
|
+
/** Flag to freeze shift values during drop transition */
|
|
41
|
+
isDropping: SharedValue<boolean>;
|
|
42
|
+
/** Register the FlashList ref for autoscroll operations */
|
|
43
|
+
setListRef: (ref: FlashListRef<unknown> | null) => void;
|
|
44
|
+
/** Scroll the list to a specific offset (for autoscroll during drag) */
|
|
45
|
+
scrollToOffset: (offset: number, animated?: boolean) => void;
|
|
46
|
+
/** Reset drag state after drop animation completes */
|
|
47
|
+
resetDragState: () => void;
|
|
48
|
+
/** Current drag configuration */
|
|
49
|
+
config: DragConfig;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Hook to access shared drag state from context.
|
|
53
|
+
* Must be used within DragStateProvider.
|
|
54
|
+
*/
|
|
55
|
+
export declare const useDragState: () => DragStateContextValue;
|
|
56
|
+
interface DragStateProviderProps {
|
|
57
|
+
children: ReactNode;
|
|
58
|
+
/** Optional drag configuration overrides */
|
|
59
|
+
config?: Partial<DragConfig>;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Provider that creates shared Reanimated values for drag state.
|
|
63
|
+
*
|
|
64
|
+
* These values are shared across all list items:
|
|
65
|
+
* - The dragged item writes to them during drag gestures
|
|
66
|
+
* - Non-dragged items read them to calculate their shift offset
|
|
67
|
+
* - Scroll state enables viewport-aware hover calculations
|
|
68
|
+
*
|
|
69
|
+
* Using SharedValues ensures animations run on the UI thread at 60fps.
|
|
70
|
+
*/
|
|
71
|
+
export declare const DragStateProvider: React.FC<DragStateProviderProps>;
|
|
72
|
+
export {};
|
|
73
|
+
//# sourceMappingURL=DragStateContext.d.ts.map
|
|
@@ -0,0 +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;AAC3E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAG3C;;;;;;;;;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,4FAA4F;IAC5F,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACvC,4EAA4E;IAC5E,kBAAkB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACxC,yDAAyD;IACzD,UAAU,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IACjC,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,sDAAsD;IACtD,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,iCAAiC;IACjC,MAAM,EAAE,UAAU,CAAC;CACpB;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;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CA0G9D,CAAC"}
|