Draggable Types
Complete type definitions for draggable components and hooks.
Enums
DraggableState
Represents the different states a draggable item can be in.
enum DraggableState {
/** Item is at rest in its original or dropped position */
IDLE = "IDLE",
/** Item is currently being dragged by the user */
DRAGGING = "DRAGGING",
/** Item has been successfully dropped on a valid drop zone */
DROPPED = "DROPPED",
}
Usage Example
import { DraggableState } from 'react-native-reanimated-dnd';
const handleStateChange = (state: DraggableState) => {
switch (state) {
case DraggableState.IDLE:
console.log('Item is at rest');
break;
case DraggableState.DRAGGING:
console.log('Item is being dragged');
break;
case DraggableState.DROPPED:
console.log('Item was successfully dropped');
break;
}
};
Type Aliases
AnimationFunction
Custom animation function type for controlling how draggable items animate.
type AnimationFunction = (toValue: number) => number;
Parameters
toValue
(number
): The target value to animate to
Returns
number
: The animated value (typically from withSpring, withTiming, etc.)
Example
import { withTiming, Easing } from 'react-native-reanimated';
const customAnimation: AnimationFunction = (toValue) => {
'worklet';
return withTiming(toValue, {
duration: 500,
easing: Easing.bounce
});
};
CollisionAlgorithm
Collision detection algorithms for determining when a draggable overlaps with a droppable.
type CollisionAlgorithm = "center" | "intersect" | "contain";
Values
center
: Collision detected when the center point of the draggable is over the droppableintersect
: Collision detected when any part of the draggable overlaps with the droppable (default)contain
: Collision detected when the entire draggable is contained within the droppable
Usage Examples
// For precise dropping, use center collision
const preciseDraggable = useDraggable({
data: myData,
collisionAlgorithm: 'center'
});
// For easy dropping, use intersect (default)
const easyDraggable = useDraggable({
data: myData,
collisionAlgorithm: 'intersect'
});
// For strict containment, use contain
const strictDraggable = useDraggable({
data: myData,
collisionAlgorithm: 'contain'
});
Interfaces
UseDraggableOptions<TData>
Configuration options for the useDraggable hook.
interface UseDraggableOptions<TData = unknown> {
data: TData;
draggableId?: string;
dragDisabled?: boolean;
onDragStart?: (data: TData) => void;
onDragEnd?: (data: TData) => void;
onDragging?: (payload: DraggingPayload<TData>) => void;
onStateChange?: (state: DraggableState) => void;
animationFunction?: AnimationFunction;
dragBoundsRef?: React.RefObject<Animated.View | View>;
dragAxis?: "x" | "y" | "both";
collisionAlgorithm?: CollisionAlgorithm;
children?: React.ReactNode;
handleComponent?: React.ComponentType<any>;
}
Properties
data
- Type:
TData
- Required: Yes
- Description: Data payload associated with this draggable item. This data is passed to drop handlers when the item is successfully dropped.
const data = { id: '1', name: 'Task 1', priority: 'high' };
draggableId
- Type:
string
- Required: No
- Description: Unique identifier for this draggable item. If not provided, one will be generated automatically.
dragDisabled
- Type:
boolean
- Default:
false
- Description: Whether dragging is disabled for this item. When true, the item cannot be dragged.
onDragStart
- Type:
(data: TData) => void
- Required: No
- Description: Callback fired when dragging starts.
const handleDragStart = (data) => {
console.log('Started dragging:', data.name);
setIsDragging(true);
};
onDragEnd
- Type:
(data: TData) => void
- Required: No
- Description: Callback fired when dragging ends (regardless of whether it was dropped successfully).
const handleDragEnd = (data) => {
console.log('Finished dragging:', data.name);
setIsDragging(false);
};
onDragging
- Type:
(payload: DraggingPayload<TData>) => void
- Required: No
- Description: Callback fired continuously while dragging. Useful for real-time feedback.
const handleDragging = ({ x, y, tx, ty, itemData }) => {
const currentX = x + tx;
const currentY = y + ty;
console.log(`${itemData.name} is at (${currentX}, ${currentY})`);
};
onStateChange
- Type:
(state: DraggableState) => void
- Required: No
- Description: Callback fired when the draggable state changes.
const handleStateChange = (state) => {
if (state === DraggableState.DROPPED) {
showSuccessMessage();
}
};
animationFunction
- Type:
AnimationFunction
- Required: No
- Description: Custom animation function for controlling how the item animates when dropped. If not provided, uses default spring animation.
const bounceAnimation = (toValue) => {
'worklet';
return withTiming(toValue, {
duration: 600,
easing: Easing.bounce
});
};
dragBoundsRef
- Type:
React.RefObject<Animated.View | View>
- Required: No
- Description: Reference to a View that defines the dragging boundaries. The draggable item will be constrained within this view's bounds.
const boundsRef = useRef<View>(null);
return (
<View ref={boundsRef} style={styles.container}>
<Draggable dragBoundsRef={boundsRef} data={data}>
<Text>Bounded draggable</Text>
</Draggable>
</View>
);
dragAxis
- Type:
"x" | "y" | "both"
- Default:
"both"
- Description: Constrains dragging to a specific axis.
// Horizontal slider
const horizontalDraggable = useDraggable({
data: sliderData,
dragAxis: 'x'
});
// Vertical slider
const verticalDraggable = useDraggable({
data: sliderData,
dragAxis: 'y'
});
collisionAlgorithm
- Type:
CollisionAlgorithm
- Default:
"intersect"
- Description: Algorithm used for collision detection with drop zones.
UseDraggableReturn
Return value from the useDraggable hook.
interface UseDraggableReturn {
animatedViewProps: {
style: AnimatedStyle<ViewStyle>;
onLayout: (event: LayoutChangeEvent) => void;
};
gesture: GestureType;
state: DraggableState;
animatedViewRef: ReturnType<typeof useAnimatedRef<Animated.View>>;
hasHandle: boolean;
}
Properties
animatedViewProps
- Type:
{ style: AnimatedStyle<ViewStyle>; onLayout: (event: LayoutChangeEvent) => void; }
- Description: Props to spread on the animated view that will be draggable. Contains the animated style and layout handler.
gesture
- Type:
GestureType
- Description: Gesture object to attach to GestureDetector for handling drag interactions. Only used when no handle is present (entire component is draggable).
state
- Type:
DraggableState
- Description: Current state of the draggable item.
animatedViewRef
- Type:
ReturnType<typeof useAnimatedRef<Animated.View>>
- Description: Animated ref for the draggable view. Used internally for measurements.
hasHandle
- Type:
boolean
- Description: Whether this draggable has a handle component. When true, only the handle can initiate dragging. When false, the entire component is draggable.
DraggingPayload<TData>
Payload object passed to the onDragging callback.
interface DraggingPayload<TData = unknown> {
x: number; // Original X position
y: number; // Original Y position
tx: number; // Current X translation
ty: number; // Current Y translation
itemData: TData; // Data associated with the draggable item
}
Properties
x
: Original X position of the itemy
: Original Y position of the itemtx
: Current X translation from original positionty
: Current Y translation from original positionitemData
: The data associated with the draggable item
DraggableContextValue
Context value for draggable components (used internally).
interface DraggableContextValue {
gesture: any;
state: DraggableState;
}
DraggableProps<TData>
Props for the Draggable component.
interface DraggableProps<TData = unknown> extends UseDraggableOptions<TData> {
style?: StyleProp<ViewStyle>;
children: React.ReactNode;
onStateChange?: (state: DraggableState) => void;
}
Properties
style
- Type:
StyleProp<ViewStyle>
- Required: No
- Description: Style to apply to the draggable container.
children
- Type:
React.ReactNode
- Required: Yes
- Description: The content to render inside the draggable.
onStateChange
- Type:
(state: DraggableState) => void
- Required: No
- Description: Callback fired when the draggable state changes.
DraggableHandleProps
Props for the DraggableHandle component.
interface DraggableHandleProps {
children: React.ReactNode;
style?: StyleProp<ViewStyle>;
}
Properties
children
- Type:
React.ReactNode
- Required: Yes
- Description: The content to render inside the handle.
style
- Type:
StyleProp<ViewStyle>
- Required: No
- Description: Optional style to apply to the handle.
Usage Examples
Basic Draggable
import { useDraggable, DraggableState } from 'react-native-reanimated-dnd';
interface TaskData {
id: string;
title: string;
priority: 'low' | 'medium' | 'high';
}
function TaskItem({ task }: { task: TaskData }) {
const { animatedViewProps, gesture, state } = useDraggable({
data: task,
onDragStart: (data) => console.log('Started dragging:', data.title),
onDragEnd: (data) => console.log('Finished dragging:', data.title),
onStateChange: (state) => {
if (state === DraggableState.DROPPED) {
showSuccessAnimation();
}
}
});
return (
<GestureDetector gesture={gesture}>
<Animated.View {...animatedViewProps}>
<Text>{task.title}</Text>
<Text>Priority: {task.priority}</Text>
</Animated.View>
</GestureDetector>
);
}
Draggable with Handle
import { Draggable, DraggableHandle } from 'react-native-reanimated-dnd';
function TaskCard({ task }: { task: TaskData }) {
return (
<Draggable data={task}>
<View style={styles.card}>
<DraggableHandle style={styles.handle}>
<Icon name="drag-handle" size={20} />
</DraggableHandle>
<View style={styles.content}>
<Text>{task.title}</Text>
<Text>{task.description}</Text>
</View>
</View>
</Draggable>
);
}
Bounded Draggable
function BoundedDraggable() {
const boundsRef = useRef<View>(null);
return (
<View ref={boundsRef} style={styles.container}>
<Draggable
data={{ id: '1', name: 'Bounded Item' }}
dragBoundsRef={boundsRef}
dragAxis="x"
>
<View style={styles.slider}>
<Text>Drag me horizontally</Text>
</View>
</Draggable>
</View>
);
}
Custom Animation
import { withSpring, withTiming, Easing } from 'react-native-reanimated';
const customBounce: AnimationFunction = (toValue) => {
'worklet';
return withSpring(toValue, {
damping: 10,
stiffness: 100,
mass: 1,
});
};
const customTiming: AnimationFunction = (toValue) => {
'worklet';
return withTiming(toValue, {
duration: 800,
easing: Easing.elastic(2),
});
};
function AnimatedDraggable() {
return (
<Draggable
data={{ id: '1' }}
animationFunction={customBounce}
>
<Text>Bouncy draggable</Text>
</Draggable>
);
}
See Also
- Draggable Component - Component documentation
- useDraggable Hook - Hook documentation
- Droppable Types - Related droppable types
- Context Types - Context-related types