Skip to content

Commit 98a9e9d

Browse files
feat: onDragMove prop (#324)
This pull request introduces the `onDragMove` callback to the sortable components, allowing for more granular control and feedback during drag operations. The key changes include adding the `onDragMove` callback to various components, updating type definitions, and documenting the new callback. ### Callback Integration: * [`example/app/src/examples/SortableFlex/features/CallbacksExample.tsx`](diffhunk://#diff-909e9ac37b95e3b1e1de1bbac752161e284101aa59ff16a835ec2ff60370c24dR14): Added `onDragMove` callback and integrated it into the `CallbacksExample` component. [[1]](diffhunk://#diff-909e9ac37b95e3b1e1de1bbac752161e284101aa59ff16a835ec2ff60370c24dR14) [[2]](diffhunk://#diff-909e9ac37b95e3b1e1de1bbac752161e284101aa59ff16a835ec2ff60370c24dR42-R48) [[3]](diffhunk://#diff-909e9ac37b95e3b1e1de1bbac752161e284101aa59ff16a835ec2ff60370c24dR62) * [`example/app/src/examples/SortableGrid/features/CallbacksExample.tsx`](diffhunk://#diff-e33ed4a677abd501d9340a3814a5001ab07d7b208f855caa1cd3760af9a4fc88R13): Added `onDragMove` callback and integrated it into the `CallbacksExample` component. [[1]](diffhunk://#diff-e33ed4a677abd501d9340a3814a5001ab07d7b208f855caa1cd3760af9a4fc88R13) [[2]](diffhunk://#diff-e33ed4a677abd501d9340a3814a5001ab07d7b208f855caa1cd3760af9a4fc88R42-R48) [[3]](diffhunk://#diff-e33ed4a677abd501d9340a3814a5001ab07d7b208f855caa1cd3760af9a4fc88R70) ### Type Definitions: * [`packages/react-native-sortables/src/types/props/shared.ts`](diffhunk://#diff-544f2eb90180c2dd21d666753ae5105128f3b522247fc9868e93bf516c72f1b8R8): Added `DragMoveCallback` and `DragMoveParams` type definitions, and updated `SortableCallbacks` to include the new `onDragMove` callback. [[1]](diffhunk://#diff-544f2eb90180c2dd21d666753ae5105128f3b522247fc9868e93bf516c72f1b8R8) [[2]](diffhunk://#diff-544f2eb90180c2dd21d666753ae5105128f3b522247fc9868e93bf516c72f1b8R136-R145) [[3]](diffhunk://#diff-544f2eb90180c2dd21d666753ae5105128f3b522247fc9868e93bf516c72f1b8R180-R185) [[4]](diffhunk://#diff-544f2eb90180c2dd21d666753ae5105128f3b522247fc9868e93bf516c72f1b8R204-R208) ### Component Updates: * [`packages/react-native-sortables/src/constants/props.ts`](diffhunk://#diff-09a936c481316c018f0c31756ee59f904d5906ac2013ed97131ca1926b7699ccR64): Added `onDragMove` to the default shared props. * [`packages/react-native-sortables/src/providers/SharedProvider.tsx`](diffhunk://#diff-b91ba790038255caebcc4ae026433dab840df2ed341d09bb3f58b75eff1416faR60): Integrated `onDragMove` into the `SharedProvider` component. [[1]](diffhunk://#diff-b91ba790038255caebcc4ae026433dab840df2ed341d09bb3f58b75eff1416faR60) [[2]](diffhunk://#diff-b91ba790038255caebcc4ae026433dab840df2ed341d09bb3f58b75eff1416faR104) * [`packages/react-native-sortables/src/providers/shared/DragProvider.ts`](diffhunk://#diff-c764e053814b2d438bc15e419a151ba1aac64acbac7bcdeb8646047a6f8b845fL48-R48): Integrated `onDragMove` into the `DragProvider` component and ensured it is called during drag operations. [[1]](diffhunk://#diff-c764e053814b2d438bc15e419a151ba1aac64acbac7bcdeb8646047a6f8b845fL48-R48) [[2]](diffhunk://#diff-c764e053814b2d438bc15e419a151ba1aac64acbac7bcdeb8646047a6f8b845fR105) [[3]](diffhunk://#diff-c764e053814b2d438bc15e419a151ba1aac64acbac7bcdeb8646047a6f8b845fR389-R396)## Description
1 parent bd1ad0a commit 98a9e9d

File tree

7 files changed

+64
-3
lines changed

7 files changed

+64
-3
lines changed

example/app/src/examples/SortableFlex/features/CallbacksExample.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { useCallback } from 'react';
22
import { useSharedValue } from 'react-native-reanimated';
33
import Sortable, {
44
type DragEndCallback,
5+
type DragMoveCallback,
56
type DragStartCallback,
67
type OrderChangeCallback
78
} from 'react-native-sortables';
@@ -38,6 +39,13 @@ export default function CallbacksExample() {
3839
[text]
3940
);
4041

42+
const onDragMove = useCallback<DragMoveCallback>(
43+
params => {
44+
text.value = `onDragMove:${formatCallbackParams(params)}`;
45+
},
46+
[text]
47+
);
48+
4149
return (
4250
<Screen includeNavBarHeight>
4351
<Stagger wrapperStye={index => (index === 0 ? flex.fill : {})}>
@@ -51,6 +59,7 @@ export default function CallbacksExample() {
5159
columnGap={spacing.sm}
5260
rowGap={spacing.xs}
5361
onDragEnd={onDragEnd}
62+
onDragMove={onDragMove}
5463
onDragStart={onDragStart}
5564
onOrderChange={onOrderChange}>
5665
{DATA.map(item => (

example/app/src/examples/SortableGrid/features/CallbacksExample.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { useCallback } from 'react';
22
import { useSharedValue } from 'react-native-reanimated';
33
import Sortable, {
44
type DragEndCallback,
5+
type DragMoveCallback,
56
type DragStartCallback,
67
type OrderChangeCallback,
78
type SortableGridRenderItem
@@ -38,6 +39,13 @@ export default function CallbacksExample() {
3839
[text]
3940
);
4041

42+
const onDragMove = useCallback<DragMoveCallback>(
43+
params => {
44+
text.value = `onDragMove:${formatCallbackParams(params)}`;
45+
},
46+
[text]
47+
);
48+
4149
const renderItem = useCallback<SortableGridRenderItem<(typeof DATA)[number]>>(
4250
({ item }) => <GridCard>{item}</GridCard>,
4351
[]
@@ -59,6 +67,7 @@ export default function CallbacksExample() {
5967
renderItem={renderItem}
6068
rowGap={spacing.xs}
6169
onDragEnd={onDragEnd}
70+
onDragMove={onDragMove}
6271
onDragStart={onDragStart}
6372
onOrderChange={onOrderChange}
6473
/>

packages/react-native-sortables/src/constants/props.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ export const DEFAULT_SHARED_PROPS = {
6060
itemExiting: IS_WEB ? null : SortableItemExiting,
6161
itemsLayout: IS_WEB ? null : LinearTransition,
6262
itemsLayoutTransitionMode: 'all',
63+
onDragMove: undefined,
6364
onDragStart: undefined,
6465
onOrderChange: undefined,
6566
overDrag: 'both',

packages/react-native-sortables/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ export type { SortableHandleProps, SortableLayerProps } from './components';
1414
export * from './constants/layoutAnimations';
1515
export type {
1616
DragEndCallback,
17+
DragMoveCallback,
1718
DragStartCallback,
18-
DragStartParams,
1919
DropIndicatorComponentProps,
2020
OrderChangeCallback,
2121
OrderChangeParams,

packages/react-native-sortables/src/providers/SharedProvider.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ export default function SharedProvider({
5757
hapticsEnabled,
5858
itemKeys,
5959
onDragEnd,
60+
onDragMove,
6061
onDragStart,
6162
onOrderChange,
6263
overDrag,
@@ -100,6 +101,7 @@ export default function SharedProvider({
100101
hapticsEnabled={hapticsEnabled}
101102
overDrag={overDrag}
102103
onDragEnd={onDragEnd}
104+
onDragMove={onDragMove}
103105
onDragStart={onDragStart}
104106
onOrderChange={onOrderChange}
105107
/>

packages/react-native-sortables/src/providers/shared/DragProvider.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,14 @@ type DragProviderProps = PropsWithChildren<
4545
const { DragProvider, useDragContext } = createProvider('Drag')<
4646
DragProviderProps,
4747
DragContextType
48-
>(({ hapticsEnabled, onDragEnd, onDragStart, onOrderChange, overDrag }) => {
48+
>(({
49+
hapticsEnabled,
50+
onDragEnd,
51+
onDragMove,
52+
onDragStart,
53+
onOrderChange,
54+
overDrag
55+
}) => {
4956
const {
5057
activationAnimationDuration,
5158
activationState,
@@ -102,6 +109,7 @@ const { DragProvider, useDragContext } = createProvider('Drag')<
102109
// function is not memoized
103110
const stableOnDragStart = useJSStableCallback(onDragStart);
104111
const stableOnDragEnd = useJSStableCallback(onDragEnd);
112+
const stableOnDragMove = useJSStableCallback(onDragMove);
105113
const stableOnOrderChange = useJSStableCallback(onOrderChange);
106114

107115
// ACTIVE ITEM POSITION UPDATER
@@ -385,6 +393,14 @@ const { DragProvider, useDragContext } = createProvider('Drag')<
385393
return;
386394
}
387395

396+
if (activeItemKey.value) {
397+
stableOnDragMove({
398+
fromIndex: dragStartIndex.value,
399+
key: activeItemKey.value,
400+
touchData: touch
401+
});
402+
}
403+
388404
if (activationState.value === DragActivationState.TOUCHED) {
389405
if (!touchStartTouch.value) {
390406
fail();
@@ -412,7 +428,9 @@ const { DragProvider, useDragContext } = createProvider('Drag')<
412428
activeItemKey,
413429
currentTouch,
414430
dragActivationFailOffset,
415-
touchStartTouch
431+
touchStartTouch,
432+
dragStartIndex,
433+
stableOnDragMove
416434
]
417435
);
418436

packages/react-native-sortables/src/types/props/shared.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { ComponentType } from 'react';
22
import type { ViewStyle } from 'react-native';
3+
import type { TouchData } from 'react-native-gesture-handler';
34
import type { AnimatedRef, SharedValue } from 'react-native-reanimated';
45

56
import type { Vector } from '../layout/shared';
@@ -132,6 +133,16 @@ export type DragStartParams = {
132133
fromIndex: number;
133134
};
134135

136+
/** Parameters provided when an item is being dragged. */
137+
export type DragMoveParams = {
138+
/** Unique identifier of the dragged item */
139+
key: string;
140+
/** Original index of the dragged item */
141+
fromIndex: number;
142+
/** Touch data */
143+
touchData: TouchData;
144+
};
145+
135146
/** Parameters provided when drag gesture completes and item is dropped */
136147
export type DragEndParams = {
137148
/** Unique identifier of the dragged item */
@@ -166,6 +177,12 @@ export type OrderChangeParams = {
166177
*/
167178
export type DragStartCallback = (params: DragStartParams) => void;
168179

180+
/**
181+
* Callback function called when the item is being dragged
182+
* @param params - Parameters for the drag move event
183+
*/
184+
export type DragMoveCallback = (params: DragMoveParams) => void;
185+
169186
/**
170187
* Callback function called when the item drag ends
171188
* @param params - Parameters for the drag end event
@@ -184,6 +201,11 @@ export type SortableCallbacks = {
184201
*/
185202
onDragStart?: DragStartCallback;
186203

204+
/** Called multiple times during dragging when an item is being dragged.
205+
* @param params Parameters for the drag move event
206+
*/
207+
onDragMove?: DragMoveCallback;
208+
187209
/** Called once when the drag gesture ends.
188210
* You can use this callback to update items order in state.
189211
* @param params Parameters for the drag end event

0 commit comments

Comments
 (0)