### iOS Setup: Run pod install
Source: https://reanimated-dnd-docs.vercel.app/docs/getting-started/installation
Navigate to the 'ios' directory and run 'pod install' to set up native dependencies for iOS.
```bash
cd ios && pod install
```
--------------------------------
### Basic Sortable List Setup
Source: https://reanimated-dnd-docs.vercel.app/docs/hooks/useSortableList
Demonstrates the basic setup of a sortable list using the useSortableList hook. This example shows how to manage a list of tasks and reorder them.
```typescript
function BasicTaskList() {
const [tasks, setTasks] = useState([
{ id: "1", title: "Task 1", priority: "high" },
{ id: "2", title: "Task 2", priority: "medium" },
{ id: "3", title: "Task 3", priority: "low" },
]);
const sortableListProps = useSortableList({
data: tasks,
itemHeight: 80,
});
const {
scrollViewRef,
dropProviderRef,
handleScroll,
handleScrollEnd,
contentHeight,
getItemProps,
} = sortableListProps;
const handleReorder = useCallback((id: string, from: number, to: number) => {
setTasks((prevTasks) => {
const newTasks = [...prevTasks];
const [movedTask] = newTasks.splice(from, 1);
newTasks.splice(to, 0, movedTask);
return newTasks;
});
}, []);
return (
My Tasks
{tasks.length} items
{tasks.map((task, index) => {
const itemProps = getItemProps(task, index);
return (
);
})}
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#f8f9fa",
},
header: {
padding: 20,
backgroundColor: "white",
borderBottomWidth: 1,
borderBottomColor: "#e5e7eb",
},
title: {
fontSize: 24,
fontWeight: "bold",
color: "#1f2937",
},
subtitle: {
fontSize: 14,
color: "#6b7280",
marginTop: 4,
},
scrollView: {
flex: 1,
},
});
```
--------------------------------
### Multi-Zone Setup with Capacity Limits
Source: https://reanimated-dnd-docs.vercel.app/docs/context/DropProvider
This example demonstrates a file organizer component using DropProvider. It sets up multiple droppable zones (folders) each with a maximum file capacity. Files can be dragged between zones, and the UI updates to reflect the new locations, with visual feedback for capacity limits.
```javascript
function FileOrganizer() {
const [files, setFiles] = useState(initialFiles);
const [folders, setFolders] = useState([
{ id: "documents", name: "Documents", maxFiles: 10 },
{ id: "images", name: "Images", maxFiles: 20 },
{ id: "videos", name: "Videos", maxFiles: 5 },
]);
const moveFileToFolder = useCallback((file, folderId) => {
setFiles((prev) =>
prev.map((f) => (f.id === file.id ? { ...f, folderId } : f))
);
}, []);
return (
{
// Update file locations based on drops
Object.entries(droppedItems).forEach(([fileId, { droppableId }]) => {
const file = files.find((f) => f.id === fileId);
if (file && file.folderId !== droppableId) {
moveFileToFolder(file, droppableId);
}
});
}}
>
{/* File List */}
Files
{files
.filter((file) => !file.folderId)
.map((file) => (
))}
{/* Folder Drop Zones */}
{folders.map((folder) => {
const folderFiles = files.filter((f) => f.folderId === folder.id);
const isAtCapacity = folderFiles.length >= folder.maxFiles;
return (
{
if (!isAtCapacity) {
moveFileToFolder(file, folder.id);
showToast(`${file.name} moved to ${folder.name}`);
} else {
showError(`${folder.name} is full!`);
}
}}
activeStyle={{
backgroundColor: isAtCapacity ? "#fee2e2" : "#dcfce7",
borderColor: isAtCapacity ? "#ef4444" : "#22c55e",
}}
>
);
})}
);
}
```
--------------------------------
### Basic Grid Setup with useGridSortableList
Source: https://reanimated-dnd-docs.vercel.app/docs/api/hooks/useGridSortableList
A complete example of setting up a sortable grid using the useGridSortableList hook. This includes initializing the hook, rendering SortableGridItem components, and handling drop events to reorder items.
```javascript
import { useGridSortableList } from "react-native-reanimated-dnd";
import { SortableGridItem } from "react-native-reanimated-dnd";
import { DropProvider } from "react-native-reanimated-dnd";
import { GestureHandlerRootView } from "react-native-gesture-handler";
import Animated from "react-native-reanimated";
interface GridItem {
id: string;
label: string;
emoji: string;
color: string;
}
function CustomGrid() {
const [items, setItems] = useState([
{ id: "1", label: "Music", emoji: "music", color: "#FF3B30" },
{ id: "2", label: "Games", emoji: "games", color: "#FF9500" },
{ id: "3", label: "Camera", emoji: "camera", color: "#FFCC00" },
{ id: "4", label: "Art", emoji: "art", color: "#34C759" },
{ id: "5", label: "Books", emoji: "books", color: "#007AFF" },
{ id: "6", label: "Power", emoji: "power", color: "#5856D6" },
]);
const {
scrollViewRef,
dropProviderRef,
handleScroll,
handleScrollEnd,
contentWidth,
contentHeight,
getItemProps,
} = useGridSortableList({
data: items,
dimensions: {
columns: 3,
itemWidth: 100,
itemHeight: 100,
columnGap: 12,
rowGap: 12,
},
});
return (
{items.map((item, index) => {
const itemProps = getItemProps(item, index);
return (
{
if (allPositions) {
const entries = Object.entries(allPositions);
entries.sort((a, b) => a[1].index - b[1].index);
const reordered = entries
.map(([itemId]) => items.find((d) => d.id === itemId))
.filter(Boolean) as GridItem[];
setItems(reordered);
}
}}
>
{item.emoji}
{item.label}
);
})}
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
},
scrollView: {
flex: 1,
},
gridItem: {
flex: 1,
borderRadius: 16,
justifyContent: "center",
alignItems: "center",
},
emoji: {
fontSize: 28,
marginBottom: 4,
},
label: {
fontSize: 12,
fontWeight: "600",
color: "#fff",
},
});
```
--------------------------------
### Basic Droppable Usage
Source: https://reanimated-dnd-docs.vercel.app/docs/components/droppable
Demonstrates the fundamental setup of a Droppable component, including the required `onDrop` callback and rendering child content. This is the starting point for creating any drop zone.
```javascript
import { Droppable } from "react-native-reanimated-dnd";
function MyDropZone() {
const handleDrop = (data) => {
console.log("Item dropped:", data);
// Handle the dropped item - update state, make API calls, etc.
};
return (
Drop items here
);
}
```
--------------------------------
### File Manager Setup
Source: https://reanimated-dnd-docs.vercel.app/docs/getting-started/setup-provider
Implement DropProvider for a file manager. Supports drag start, end, and updates to file structure. Utilizes a ref for imperative control like requesting position updates.
```javascript
import React, { useState, useRef } from "react";
import { GestureHandlerRootView } from "react-native-gesture-handler";
import { DropProvider, DropProviderRef } from "react-native-reanimated-dnd";
interface FileItem {
id: string;
name: string;
type: "file" | "folder";
size: number;
}
function FileManager() {
const [files, setFiles] = useState([]);
const [selectedFiles, setSelectedFiles] = useState>(new Set());
const dropProviderRef = useRef(null);
const handleFileOperation = useCallback(
(operation: string, fileId: string) => {
// Trigger position update after file operations
setTimeout(() => {
dropProviderRef.current?.requestPositionUpdate();
}, 100);
},
[]
);
return (
{
console.log(`Started dragging: ${file.name}`);
setSelectedFiles(new Set([file.id]));
}}
onDragEnd={(file: FileItem) => {
console.log(`Finished dragging: ${file.name}`);
}}
onDroppedItemsUpdate={(droppedItems) => {
// Update file organization
updateFileStructure(droppedItems);
}}
>
);
}
```
--------------------------------
### Example onDragStart Callback
Source: https://reanimated-dnd-docs.vercel.app/docs/api/types/sortable-types
Callback function executed when dragging begins for an item. Logs the start event, sets the dragging item state, and triggers haptic feedback.
```typescript
const handleDragStart = (id: string, position: number) => {
console.log(`Started dragging item ${id} from position ${position}`);
setDraggingItem(id);
hapticFeedback();
};
```
--------------------------------
### Verify Installation with a Test Component
Source: https://reanimated-dnd-docs.vercel.app/docs/getting-started/installation
Create this component to confirm successful installation. It includes draggable and droppable elements.
```javascript
import React from "react";
import { View, Text, StyleSheet } from "react-native";
import { GestureHandlerRootView } from "react-native-gesture-handler";
import {
DropProvider,
Draggable,
Droppable,
} from "react-native-reanimated-dnd";
export default function InstallationTest() {
return (
Installation Test
Drag me!
console.log("Dropped:", data)}>
Drop here!
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#f5f5f5",
},
content: {
flex: 1,
padding: 20,
justifyContent: "center",
alignItems: "center",
},
title: {
fontSize: 24,
fontWeight: "bold",
marginBottom: 40,
color: "#333",
},
draggable: {
width: 100,
height: 100,
backgroundColor: "#4CAF50",
borderRadius: 10,
justifyContent: "center",
alignItems: "center",
marginBottom: 40,
},
droppable: {
width: 200,
height: 100,
backgroundColor: "#2196F3",
borderRadius: 10,
justifyContent: "center",
alignItems: "center",
borderWidth: 2,
borderStyle: "dashed",
borderColor: "#1976D2",
},
});
```
--------------------------------
### onDragStart Callback Example
Source: https://reanimated-dnd-docs.vercel.app/docs/api/types/draggable-types
Callback function executed when dragging starts. Logs the item's name and sets a dragging state.
```typescript
const handleDragStart = (data) => {
console.log("Started dragging:", data.name);
setIsDragging(true);
};
```
--------------------------------
### Basic useGridSortable Setup
Source: https://reanimated-dnd-docs.vercel.app/docs/api/hooks/useGridSortable
This snippet shows the fundamental setup for using the useGridSortable hook. It demonstrates how to obtain the `animatedStyle` and `panGestureHandler` and apply them to an `Animated.View` component wrapped in a `GestureDetector`.
```javascript
import { GestureDetector } from "react-native-gesture-handler";
const { animatedStyle, panGestureHandler } = useGridSortable(options);
return (
Grid item content
);
```
--------------------------------
### Basic Draggable Component Example
Source: https://reanimated-dnd-docs.vercel.app/docs/api/hooks/useDraggable
Demonstrates a simple draggable component using useDraggable, including drag start and end event logging.
```javascript
import { useDraggable, DraggableState } from "react-native-reanimated-dnd";
import { GestureDetector } from "react-native-gesture-handler";
import Animated from "react-native-reanimated";
function BasicDraggable() {
const { animatedViewProps, gesture, state } = useDraggable({
data: { id: "1", name: "Draggable Item" },
onDragStart: (data) => console.log("Started dragging:", data.name),
onDragEnd: (data) => console.log("Finished dragging:", data.name),
});
return (
Drag me!
State: {state}
);
}
```
--------------------------------
### Install Type Definitions
Source: https://reanimated-dnd-docs.vercel.app/docs/getting-started/installation
Install the latest type definitions for React and React Native if using TypeScript.
```bash
npm install @types/react @types/react-native
```
--------------------------------
### onMove Callback Example
Source: https://reanimated-dnd-docs.vercel.app/docs/api/types/grid-types
Example of how to implement the onMove callback to log an item's position change.
```typescript
const handleMove = (id: string, from: number, to: number) => {
console.log(`Item ${id} moved from position ${from} to ${to}`);
};
```
--------------------------------
### Task Management App Setup
Source: https://reanimated-dnd-docs.vercel.app/docs/getting-started/setup-provider
Integrate DropProvider for a task management app. Handles drag start, end, and updates to task order. Requires GestureHandlerRootView and DropProvider.
```javascript
import React, { useState, useCallback } from "react";
import { View, ScrollView } from "react-native";
import { GestureHandlerRootView } from "react-native-gesture-handler";
import { DropProvider } from "react-native-reanimated-dnd";
interface Task {
id: string;
title: string;
status: "todo" | "in-progress" | "done";
priority: "low" | "medium" | "high";
}
function TaskManagementApp() {
const [tasks, setTasks] = useState([]);
const [draggedTask, setDraggedTask] = useState(null);
const handleDragStart = useCallback((data: Task) => {
setDraggedTask(data);
// Add visual feedback
hapticFeedback();
}, []);
const handleDragEnd = useCallback((data: Task) => {
setDraggedTask(null);
// Clean up visual feedback
}, []);
const handleDroppedItemsUpdate = useCallback(
(droppedItems) => {
// Sync dropped items with your state management
syncTasksWithDroppedItems(droppedItems);
// Save to backend
saveTasks(tasks);
// Analytics
analytics.track("tasks_reordered", {
totalTasks: tasks.length,
droppedCount: Object.keys(droppedItems).length,
});
},
[tasks]
);
return (
{
// Real-time position tracking
updateDragPreview(itemData, tx, ty);
}}
>
);
}
```
--------------------------------
### Droppable Alignment Examples
Source: https://reanimated-dnd-docs.vercel.app/docs/components/droppable
Provides examples of how to use the `dropAlignment` prop to position dropped items. Shows 'center', 'top-left', and 'bottom-center' alignments.
```javascript
// Center alignment (default)
// Top-left corner positioning
// Bottom edge, centered horizontally
```
--------------------------------
### Basic Sortable Grid Usage Example
Source: https://reanimated-dnd-docs.vercel.app/docs/api/components/sortable-grid
A complete example demonstrating how to set up and use the SortableGrid component with custom item rendering, reordering logic, and basic styling.
```jsx
import {
SortableGrid,
SortableGridItem,
SortableGridRenderItemProps,
GridOrientation,
} from "react-native-reanimated-dnd";
interface GridItem {
id: string;
label: string;
color: string;
emoji: string;
}
function AppGrid() {
const [items, setItems] = useState([
{ id: "1", label: "Music", color: "#FF3B30", emoji: "music" },
{ id: "2", label: "Games", color: "#FF9500", emoji: "games" },
{ id: "3", label: "Camera", color: "#FFCC00", emoji: "camera" },
{ id: "4", label: "Art", color: "#34C759", emoji: "art" },
{ id: "5", label: "Books", color: "#007AFF", emoji: "books" },
{ id: "6", label: "Power", color: "#5856D6", emoji: "power" },
]);
const dimensions = useMemo(
() => ({
columns: 3,
itemWidth: 100,
itemHeight: 100,
columnGap: 12,
rowGap: 12,
}),
[]
);
const renderItem = useCallback(
({ item, id, positions, ...props }: SortableGridRenderItemProps) => (
{
if (allPositions) {
const entries = Object.entries(allPositions);
entries.sort((a, b) => a[1].index - b[1].index);
const reordered = entries
.map(([itemId]) => items.find((d) => d.id === itemId))
.filter(Boolean) as GridItem[];
setItems(reordered);
}
}}
>
{item.emoji}
{item.label}
),
[items]
);
return (
My Apps
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
},
header: {
fontSize: 24,
fontWeight: "bold",
padding: 16,
},
grid: {
flex: 1,
},
gridContent: {
padding: 16,
},
gridItem: {
flex: 1,
borderRadius: 16,
justifyContent: "center",
alignItems: "center",
},
emoji: {
fontSize: 28,
marginBottom: 4,
},
label: {
fontSize: 12,
fontWeight: "600",
color: "#fff",
},
});
```
--------------------------------
### Complete React Native Reanimated DnD Example
Source: https://reanimated-dnd-docs.vercel.app/docs/getting-started/quick-start
A full example demonstrating draggable items and a drop zone with state management and alerts on drop.
```javascript
import React, { useState } from "react";
import { View, Text, StyleSheet, Alert } from "react-native";
import { GestureHandlerRootView } from "react-native-gesture-handler";
import {
DropProvider,
Draggable,
Droppable,
} from "react-native-reanimated-dnd";
interface Item {
id: string;
title: string;
color: string;
}
export default function QuickStartExample() {
const [items] = useState- ([
{ id: "1", title: "Item 1", color: "#FF6B6B" },
{ id: "2", title: "Item 2", color: "#4ECDC4" },
{ id: "3", title: "Item 3", color: "#45B7D1" },
]);
const handleDrop = (data: Item) => {
Alert.alert("Success!", `${data.title} was dropped!`);
};
return (
Quick Start Example
{/* Draggable Items */}
{items.map((item) => (
{item.title}
))}
{/* Drop Zone */}
Drop items here
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#f5f5f5",
},
content: {
flex: 1,
padding: 20,
},
title: {
fontSize: 24,
fontWeight: "bold",
textAlign: "center",
marginBottom: 30,
color: "#333",
},
itemsContainer: {
flexDirection: "row",
justifyContent: "space-around",
marginBottom: 50,
},
draggableItem: {
width: 80,
height: 80,
borderRadius: 40,
justifyContent: "center",
alignItems: "center",
shadowColor: "#000",
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.25,
shadowRadius: 4,
elevation: 5,
},
itemText: {
color: "white",
fontWeight: "bold",
fontSize: 12,
textAlign: "center",
},
dropZone: {
height: 150,
backgroundColor: "#e0e0e0",
borderWidth: 2,
borderColor: "#999",
borderStyle: "dashed",
borderRadius: 10,
justifyContent: "center",
alignItems: "center",
},
dropZoneText: {
fontSize: 18,
color: "#666",
fontWeight: "500",
},
});
```
--------------------------------
### Install React Native Reanimated DnD with yarn
Source: https://reanimated-dnd-docs.vercel.app/docs/getting-started/installation
Use this command to install the main package using yarn.
```bash
yarn add react-native-reanimated-dnd
```
--------------------------------
### iOS Pod Install and Deintegration
Source: https://reanimated-dnd-docs.vercel.app/docs/guides/troubleshooting
After installing or upgrading the library, run `pod deintegrate` followed by `pod install` in the `ios` directory to resolve potential issues.
```bash
cd ios
pod deintegrate
pod install
cd ..
```
--------------------------------
### Install React Native Reanimated DnD with npm
Source: https://reanimated-dnd-docs.vercel.app/docs/getting-started/installation
Use this command to install the main package using npm.
```bash
npm install react-native-reanimated-dnd
```
--------------------------------
### Content Width Calculation Example
Source: https://reanimated-dnd-docs.vercel.app/docs/hooks/useHorizontalSortableList
Illustrates how the hook calculates the total content width based on item dimensions, gaps, and padding. The example shows a manual calculation for verification.
```javascript
// For 5 items with width 120, gap 10, padding 16:
// contentWidth = (5 * 120) + (4 * 10) + (2 * 16) = 672px
const { contentWidth } = useHorizontalSortableList({
data: items, // 5 items
itemWidth: 120, // Each item is 120px wide
gap: 10, // 10px gap between items
paddingHorizontal: 16, // 16px padding on each side
});
console.log(contentWidth); // 672
```
--------------------------------
### Handle Active Change Callback Example
Source: https://reanimated-dnd-docs.vercel.app/docs/api/types/droppable-types
Example of a callback function for onActiveChange. It plays a hover sound and sets a highlighted state when an item starts hovering, and resets the highlighted state when hovering stops.
```typescript
const handleActiveChange = (isActive: boolean) => {
if (isActive) {
playHoverSound();
setHighlighted(true);
} else {
setHighlighted(false);
}
};
```
--------------------------------
### Full Basic Grid Sortable Item Example
Source: https://reanimated-dnd-docs.vercel.app/docs/api/hooks/useGridSortable
A comprehensive example demonstrating a sortable grid cell component. It integrates `useGridSortable` with `react-native-gesture-handler` and `react-native-reanimated` to enable drag-and-drop functionality, including callbacks for move and drag start events, and conditional styling.
```javascript
import { useGridSortable } from "react-native-reanimated-dnd";
import { GestureDetector } from "react-native-gesture-handler";
import Animated from "react-native-reanimated";
function SortableGridCell({ item, positions, ...sortableProps }) {
const { animatedStyle, panGestureHandler, isMoving } = useGridSortable({
id: item.id,
positions,
...sortableProps,
onMove: (id, from, to) => {
console.log(`Item ${id} moved from ${from} to ${to}`);
},
onDragStart: (id, position) => {
console.log(`Started dragging item ${id} at position ${position}`);
hapticFeedback();
},
});
return (
{item.emoji}
{item.label}
);
}
const styles = StyleSheet.create({
gridCell: {
flex: 1,
borderRadius: 16,
justifyContent: "center",
alignItems: "center",
},
dragging: {
opacity: 0.9,
},
emoji: {
fontSize: 28,
marginBottom: 4,
},
label: {
fontSize: 12,
fontWeight: "600",
color: "#fff",
},
});
```
--------------------------------
### Basic Drag and Drop Example
Source: https://reanimated-dnd-docs.vercel.app/docs/examples/basic-drag-drop
This example shows how to set up two droppable zones and two draggable items. It utilizes GestureHandlerRootView and DropProvider for gesture handling and drop zone management. Alerts are triggered on successful drops.
```javascript
import React, { useRef } from "react";
import { View, Text, StyleSheet, Alert } from "react-native";
import { GestureHandlerRootView } from "react-native-gesture-handler";
import {
DropProvider,
Draggable,
Droppable,
} from "react-native-reanimated-dnd";
interface DraggableItemData {
id: string;
label: string;
backgroundColor: string;
}
export function BasicDragDropExample() {
return (
Basic Drag & Drop
Drag the items to different zones to see basic interactions
{/* Drop Zones */}
droppableId="zone-alpha"
onDrop={(data) =>
Alert.alert("Drop!", `"${data.label}" dropped on Zone Alpha`)
}
style={styles.dropZone}
activeStyle={styles.activeDropZone}
>
Zone Alpha
Basic Drop Zone
droppableId="zone-beta"
onDrop={(data) =>
Alert.alert("Drop!", `"${data.label}" dropped on Zone Beta`)
}
style={[styles.dropZone, styles.dropZoneBeta]}
activeStyle={styles.activeDropZone}
>
Zone Beta
Another Drop Zone
{/* Draggable Items */}
data={{
id: "basic-item-1",
label: "Draggable Item 1",
backgroundColor: "#a2d2ff",
}}
style={[styles.draggable, { backgroundColor: "#a2d2ff" }]}
onDragStart={(data) =>
console.log("Started dragging:", data.label)
}
onDragEnd={(data) =>
console.log("Finished dragging:", data.label)
}
>
Item 1
Drag me!
data={{
id: "basic-item-2",
label: "Draggable Item 2",
backgroundColor: "#bde0fe",
}}
style={[styles.draggable, { backgroundColor: "#bde0fe" }]}
onDragStart={(data) =>
console.log("Started dragging:", data.label)
}
onDragEnd={(data) =>
console.log("Finished dragging:", data.label)
}
>
Item 2
Drag me too!
{/* Info */}
Basic draggable with default spring animation
Standard drag and drop behavior with visual feedback
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#000000",
},
content: {
flex: 1,
padding: 20,
},
title: {
fontSize: 24,
fontWeight: "bold",
color: "#FFFFFF",
textAlign: "center",
marginBottom: 8,
},
subtitle: {
fontSize: 15,
color: "#8E8E93",
textAlign: "center",
marginBottom: 30,
lineHeight: 22,
},
dropZoneArea: {
flexDirection: "row",
justifyContent: "space-around",
marginBottom: 40,
gap: 16,
},
dropZone: {
flex: 1,
height: 120,
borderWidth: 2,
borderStyle: "dashed",
borderColor: "#58a6ff",
backgroundColor: "rgba(88, 166, 255, 0.08)",
borderRadius: 16,
justifyContent: "center",
alignItems: "center",
padding: 16,
},
dropZoneBeta: {
// This style is incomplete in the source, but included as is.
},
activeDropZone: {
borderColor: "#007aff",
backgroundColor: "rgba(0, 122, 255, 0.15)",
},
draggableItemsArea: {
flexDirection: "column",
gap: 16,
marginBottom: 40,
},
draggable: {
height: 80,
borderRadius: 16,
justifyContent: "center",
alignItems: "center",
padding: 16,
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
},
cardContent: {
alignItems: "center",
},
cardLabel: {
fontSize: 16,
fontWeight: "bold",
color: "#FFFFFF",
},
cardHint: {
fontSize: 12,
color: "#CCCCCC",
},
infoContainer: {
gap: 12,
},
infoItem: {
flexDirection: "row",
alignItems: "center",
gap: 8,
},
infoIndicator: {
width: 12,
height: 12,
borderRadius: 6,
},
infoText: {
fontSize: 14,
color: "#FFFFFF",
flex: 1,
},
});
```
--------------------------------
### Bounded Dragging Example in React Native
Source: https://reanimated-dnd-docs.vercel.app/docs/examples/bounded-dragging
This example shows how to create draggable items that are constrained within a defined boundary. It includes setup for GestureHandlerRootView, DropProvider, Draggable, and Droppable components. Custom logic can be added to the onDragging callback for boundary enforcement.
```typescript
import React, { useState } from "react";
import { View, Text, StyleSheet } from "react-native";
import { GestureHandlerRootView } from "react-native-gesture-handler";
import {
DropProvider,
Draggable,
Droppable,
} from "react-native-reanimated-dnd";
interface BoundedItemData {
id: string;
label: string;
color: string;
}
export function BoundedDraggingExample() {
const [items] = useState([
{ id: "1", label: "Bounded Item 1", color: "#ff6b6b" },
{ id: "2", label: "Bounded Item 2", color: "#4ecdc4" },
]);
return (
Bounded Dragging
Items are constrained within the boundary areas
{/* Boundary Area */}
Drag Boundary
{/* Draggable items within boundary */}
data={items[0]}
style={[styles.draggable, { backgroundColor: items[0].color }]}
onDragging={({ x, y, tx, ty }) => {
// Custom boundary logic can be implemented here
console.log(`Item at position: ${x + tx}, ${y + ty}`);
}}
>
{items[0].label}
Drag within bounds
data={items[1]}
style={[styles.draggable, { backgroundColor: items[1].color }]}
onDragging={({ x, y, tx, ty }) => {
console.log(`Item at position: ${x + tx}, ${y + ty}`);
}}
>
{items[1].label}
Stay in boundary
{/* Drop Zone Outside Boundary */}
droppableId="outside-boundary"
onDrop={(data) =>
console.log(`${data.label} dropped outside boundary`)
}
style={styles.dropZone}
activeStyle={styles.activeDropZone}
>
Drop Zone
Outside boundary
{/* Info */}
Boundary Implementation:
• Use container views to define visual boundaries
• Implement
custom logic in onDragging callbacks
• Combine with drop
zones for controlled interactions
• Style boundaries to
provide clear visual feedback
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#000000",
},
content: {
flex: 1,
padding: 20,
},
title: {
fontSize: 24,
fontWeight: "bold",
color: "#FFFFFF",
textAlign: "center",
marginBottom: 8,
},
subtitle: {
fontSize: 15,
color: "#8E8E93",
textAlign: "center",
marginBottom: 30,
lineHeight: 22,
},
boundaryContainer: {
marginBottom: 40,
},
boundaryTitle: {
fontSize: 16,
fontWeight: "600",
color: "#FFFFFF",
marginBottom: 12,
textAlign: "center",
},
boundary: {
height: 300,
backgroundColor: "#1a1a1a",
borderRadius: 16,
borderWidth: 2,
borderColor: "#58a6ff",
borderStyle: "dashed",
padding: 20,
position: "relative",
},
draggable: {
width: 120,
height: 80,
borderRadius: 12,
position: "absolute",
shadowColor: "#000",
shadowOffset: { width: 0, height: 4 },
shadowOpacity: 0.3,
shadowRadius: 6,
elevation: 8,
},
itemContent: {
flex: 1,
justifyContent: "center",
alignItems: "center",
padding: 8,
},
itemLabel: {
fontSize: 14,
fontWeight: "bold",
color: "#FFFFFF",
marginBottom: 4,
textAlign: "center",
},
itemHint: {
fontSize: 10,
color: "rgba(255, 255, 255, 0.8)",
textAlign: "center",
},
dropZoneArea: {
alignItems: "center",
marginBottom: 30,
},
dropZone: {
width: "60%",
height: 100,
},
activeDropZone: {
backgroundColor: "#333333",
borderColor: "#007AFF",
borderWidth: 2,
},
dropZoneText: {
fontSize: 18,
fontWeight: "bold",
color: "#FFFFFF",
textAlign: "center",
marginTop: 10,
},
dropZoneSubtext: {
fontSize: 12,
color: "#8E8E93",
textAlign: "center",
marginTop: 5,
},
infoContainer: {
marginTop: 20,
padding: 15,
backgroundColor: "#2c2c2e",
borderRadius: 10,
},
infoTitle: {
fontSize: 16,
fontWeight: "bold",
color: "#FFFFFF",
marginBottom: 10,
},
infoText: {
fontSize: 14,
color: "#E5E5EA",
lineHeight: 20,
},
});
```
--------------------------------
### Multi-Alignment Drop Zones Example
Source: https://reanimated-dnd-docs.vercel.app/docs/api/hooks/useDroppable
Demonstrates how to create multiple drop zones with different alignment configurations. Each zone can be configured with specific drop alignments and offsets.
```javascript
function AlignmentDemo() {
const alignments = [
"top-left",
"top-center",
"top-right",
"center-left",
"center",
"center-right",
"bottom-left",
"bottom-center",
"bottom-right",
];
return (
{alignments.map((alignment) => {
const { viewProps, isActive } = useDroppable({
onDrop: (data) => console.log(`Dropped at ${alignment}:`, data),
dropAlignment: alignment,
dropOffset: { x: 5, y: 5 },
activeStyle: {
backgroundColor: "rgba(59, 130, 246, 0.2)",
borderColor: "#3b82f6",
},
});
return (
{alignment}
{isActive && Active}
);
})}
);
}
```
--------------------------------
### Draggable Component Example
Source: https://reanimated-dnd-docs.vercel.app/docs/examples/basic-drag-drop
Create draggable items by using the Draggable component. It accepts data payloads and provides callbacks for drag start and end events.
```jsx
console.log("Drag started:", data)}
onDragEnd={(data) => console.log("Drag ended:", data)>
Drag me!
```