### Start Expo Web App from Example
Source: https://github.com/nuclearpasta/react-native-drax/blob/main/docs-site/docs/guides/web-support.mdx
Navigate to the example directory and start the Expo application with web support to test your setup. This verifies that web support is correctly configured.
```bash
cd example && npx expo start --web
```
--------------------------------
### Install Dependencies
Source: https://github.com/nuclearpasta/react-native-drax/blob/main/CLAUDE.md
Navigate to the example directory and install dependencies using yarn.
```bash
cd example && yarn start
```
--------------------------------
### Minimal Drag and Drop Example
Source: https://github.com/nuclearpasta/react-native-drax/blob/main/docs-site/docs/getting-started.mdx
A basic 'Hello World' example demonstrating a draggable element and a drop receiver using DraxProvider and DraxView. Ensure your app is wrapped in GestureHandlerRootView.
```tsx
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { DraxProvider, DraxView } from 'react-native-drax';
import { StyleSheet, Text } from 'react-native';
export default function App() {
return (
console.log('Started dragging!')}
payload="hello"
>
Drag me
{
console.log(`Received: ${dragged.payload}`);
}}
>
Drop here
);
}
const styles = StyleSheet.create({
draggable: {
width: 100,
height: 100,
backgroundColor: '#cf5f34',
borderRadius: 8,
justifyContent: 'center',
alignItems: 'center',
margin: 20,
},
receiver: {
width: 150,
height: 150,
backgroundColor: '#2a9d8f',
borderRadius: 8,
justifyContent: 'center',
alignItems: 'center',
margin: 20,
},
});
```
--------------------------------
### Start Expo Web App
Source: https://github.com/nuclearpasta/react-native-drax/blob/main/docs-site/docs/guides/web-support.mdx
Use this command to start your Expo application with web support enabled. Ensure Reanimated and Gesture Handler are configured for web in your babel.config.js.
```bash
npx expo start --web
```
--------------------------------
### 9-Point Alignment Examples
Source: https://github.com/nuclearpasta/react-native-drax/blob/main/docs-site/docs/guides/snap-alignment.mdx
Demonstrates snapping to predefined positions like 'top-left', 'center', and 'bottom-right'.
```tsx
snapToAlignment(receiver, dragged, 'top-left')
```
```tsx
snapToAlignment(receiver, dragged, 'center')
```
```tsx
snapToAlignment(receiver, dragged, 'bottom-right')
```
--------------------------------
### Install Peer Dependencies
Source: https://github.com/nuclearpasta/react-native-drax/blob/main/docs-site/docs/getting-started.mdx
Install the required peer dependencies, react-native-reanimated and react-native-gesture-handler, using npm.
```bash
npm install react-native-reanimated react-native-gesture-handler
```
--------------------------------
### Basic Usage
Source: https://github.com/nuclearpasta/react-native-drax/blob/main/docs-site/docs/api/components/drax-list.mdx
Example of how to use the DraxList component with essential props.
```APIDOC
```tsx
item.id}
onReorder={({ data }) => setItems(data)}
renderItem={({ item }) => }
/>
```
```
--------------------------------
### Color Drag & Drop Example
Source: https://github.com/nuclearpasta/react-native-drax/blob/main/docs-site/docs/examples/index.mdx
Demonstrates free-form drag and drop with drop acceptance, hover styles, and snap alignment. This example is useful for implementing basic drag and drop interactions.
```typescript
import React from "react";
import { View, Text, StyleSheet } from "react-native";
import { DraxProvider, DraxView, DraxLayout } from "react-native-drax";
const ColorDragDrop = () => {
return (
console.log("Dragging red...")}
onDragEnd={() => console.log("Dropped red.")}
>
Drag Me
console.log("Received drag enter:", dragData)
}
onReceiveDragLeave={({ dragData }) =>
console.log("Received drag leave:", dragData)
}
onReceiveDrop={({ dragData }) => {
console.log("Received drop:", dragData);
// Handle drop logic here
}}
>
Drop Here
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#f0f0f0",
},
box: {
width: 100,
height: 100,
justifyContent: "center",
alignItems: "center",
margin: 20,
borderRadius: 10,
},
red: {
backgroundColor: "red",
},
targetBox: {
backgroundColor: "lightgray",
borderWidth: 2,
borderColor: "darkgray",
},
draggingBox: {
opacity: 0.5,
},
draggedBox: {
backgroundColor: "blue",
opacity: 0.8,
},
hoveringBox: {
backgroundColor: "lightblue",
},
text: {
color: "white",
fontWeight: "bold",
},
});
export default ColorDragDrop;
```
--------------------------------
### Install React Native Drax with yarn
Source: https://github.com/nuclearpasta/react-native-drax/blob/main/docs-site/docs/getting-started.mdx
Use this command to install the react-native-drax package using yarn.
```bash
yarn add react-native-drax
```
--------------------------------
### Install React Native Drax with npm
Source: https://github.com/nuclearpasta/react-native-drax/blob/main/docs-site/docs/getting-started.mdx
Use this command to install the react-native-drax package using npm.
```bash
npm install react-native-drax
```
--------------------------------
### Basic Drag-and-Drop Example
Source: https://github.com/nuclearpasta/react-native-drax/blob/main/README.md
A simple implementation of drag-and-drop using DraxProvider and DraxView. Configure `onDragStart` for drag initiation and `onReceiveDragDrop` to handle dropped payloads.
```tsx
import { DraxProvider, DraxView } from 'react-native-drax';
function App() {
return (
console.log('dragging')}
payload="hello"
/>
{
console.log(`received: ${payload}`);
}}
/>
);
}
```
--------------------------------
### Basic DraxProvider Usage
Source: https://github.com/nuclearpasta/react-native-drax/blob/main/docs-site/docs/api/components/drax-provider.mdx
Wrap your drag-and-drop components with DraxProvider to enable drag-and-drop functionality. This example shows a basic setup with DraxView components.
```tsx
```
--------------------------------
### Mixed-Size Grid Example
Source: https://github.com/nuclearpasta/react-native-drax/blob/main/docs-site/docs/examples/index.mdx
Demonstrates a grid layout where items can have different spans using `getItemSpan` and `packGrid`. This is useful for creating visually diverse grid UIs.
```typescript
import React, { useState } from "react";
import { View, Text, StyleSheet, Dimensions } from "react-native";
import { DraxProvider, DraxGrid, DraxLayout } from "react-native-drax";
const numColumns = 4;
const screenWidth = Dimensions.get("window").width;
const initialItems = [
{ id: "1", text: "1", span: { row: 1, col: 1 } },
{ id: "2", text: "2", span: { row: 1, col: 2 } },
{ id: "3", text: "3", span: { row: 1, col: 1 } },
{ id: "4", text: "4", span: { row: 2, col: 1 } },
{ id: "5", text: "5", span: { row: 1, col: 3 } },
{ id: "6", text: "6", span: { row: 1, col: 1 } },
{ id: "7", text: "7", span: { row: 2, col: 1 } },
{ id: "8", text: "8", span: { row: 1, col: 1 } },
{ id: "9", text: "9", span: { row: 1, col: 2 } },
];
const MixedSizeGrid = () => {
const [items, setItems] = useState(initialItems);
const handleDragEnd = ({ from, to }) => {
if (from === to) return;
const newItems = [...items];
const [movedItem] = newItems.splice(from, 1);
newItems.splice(to, 0, movedItem);
setItems(newItems);
};
const getItemSpan = (item) => item.span;
return (
item.id}
numColumns={numColumns}
getItemSpan={getItemSpan}
renderItem={({ item, drag, dragStyle, dragActivatedStyle, dragDropStyle }) => (
{item.text}
)}
onDragEnd={handleDragEnd}
animationDuration={300}
/>
);
};
const styles = StyleSheet.create({
item: {
justifyContent: "center",
alignItems: "center",
margin: 5,
borderRadius: 5,
overflow: "hidden",
},
itemText: {
color: "white",
fontSize: 18,
fontWeight: "bold",
},
});
export default MixedSizeGrid;
```
--------------------------------
### React Native Drax Collision Modes Example
Source: https://github.com/nuclearpasta/react-native-drax/blob/main/docs-site/docs/examples/collision-modes.mdx
This example demonstrates the 'center', 'intersect', and 'contain' collision algorithms. It shows how each algorithm affects when a drop zone becomes active and accepts a drop. Requires DraxProvider at the root.
```tsx
import {
useState
} from 'react';
import {
StyleSheet,
View,
Text
} from 'react-native';
import {
useSafeAreaInsets
} from 'react-native-safe-area-context';
import {
DraxProvider,
DraxView,
type CollisionAlgorithm,
} from 'react-native-drax';
function DraggableBlock() {
return (
Drag me
);
}
function DropZone({
algorithm,
label,
testID,
}: {
algorithm: CollisionAlgorithm;
label: string;
testID: string;
}) {
const [count, setCount] = useState(0);
const [isReceiving, setIsReceiving] = useState(false);
return (
setIsReceiving(true)}
onReceiveDragExit={() => setIsReceiving(false)}
onReceiveDragDrop={() => {
setCount((c) => c + 1);
setIsReceiving(false);
}}
receivingStyle={styles.receiving}
>
{label}
{algorithm}
Drops: {count}
);
}
export default function CollisionModes() {
const insets = useSafeAreaInsets();
return (
Each drop zone uses a different collision algorithm. Notice how
"intersect" activates as soon as any edge overlaps, "center"
requires the dragged item's center to be inside, and "contain"
needs the entire item inside.
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f5f5f5',
},
header: {
padding: 16,
},
headerText: {
fontSize: 14,
fontStyle: 'italic',
textAlign: 'center',
color: '#666',
},
draggableRow: {
alignItems: 'center',
paddingVertical: 24,
},
draggable: {
width: 100,
height: 100,
borderRadius: 12,
backgroundColor: '#6366f1',
justifyContent: 'center',
alignItems: 'center',
},
draggableText: {
color: '#fff',
fontWeight: '600',
fontSize: 16,
},
dragging: {
opacity: 0.3,
},
hoverDragging: {
shadowColor: '#000',
shadowOpacity: 0.3,
shadowRadius: 8,
shadowOffset: { width: 0, height: 4 },
},
zonesRow: {
flexDirection: 'row',
justifyContent: 'space-evenly',
paddingHorizontal: 8,
flex: 1,
},
dropZone: {
flex: 1,
marginHorizontal: 6,
backgroundColor: '#e5e7eb',
borderRadius: 12,
borderWidth: 2,
borderColor: '#d1d5db',
justifyContent: 'center',
alignItems: 'center',
borderStyle: 'dashed',
},
dropZoneActive: {
backgroundColor: '#dcfce7',
borderColor: '#22c55e',
},
receiving: {
borderColor: '#22c55e',
borderStyle: 'solid',
},
dropLabel: {
fontSize: 18,
fontWeight: '700',
color: '#374151',
},
dropAlgorithm: {
fontSize: 13,
color: '#6b7280',
marginTop: 4,
},
dropCount: {
fontSize: 14,
fontWeight: '600',
color: '#059669',
marginTop: 8,
},
});
```
--------------------------------
### Basic ScrollView Example
Source: https://github.com/nuclearpasta/react-native-drax/blob/main/docs-site/docs/examples/scrolling.mdx
Demonstrates a basic ScrollView component for displaying scrollable content. Ensure you have imported ScrollView from 'react-native'.
```javascript
import React from 'react';
import { ScrollView, View, Text, StyleSheet } from 'react-native';
const App = () => (
Scroll me!
{/* Add more content here to make it scrollable */}
End of content
);
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: 20,
},
text: {
fontSize: 24,
fontWeight: 'bold',
textAlign: 'center',
marginVertical: 20,
},
});
export default App;
```
--------------------------------
### Install react-native-drax
Source: https://github.com/nuclearpasta/react-native-drax/blob/main/README.md
Install the react-native-drax package using npm or yarn. Ensure peer dependencies like react-native-reanimated and react-native-gesture-handler are also installed.
```bash
npm install react-native-drax
# or
yarn add react-native-drax
```
```bash
npm install react-native-reanimated react-native-gesture-handler
```
--------------------------------
### Basic DraxView Setup
Source: https://github.com/nuclearpasta/react-native-drax/blob/main/docs-site/docs/guides/drag-and-drop.mdx
Set up a DraxProvider and two DraxViews to enable basic drag-and-drop functionality. One view is draggable with a payload, and the other is a receiver that logs the dropped payload.
```tsx
import { DraxProvider, DraxView } from 'react-native-drax';
{/* This view can be dragged */}
console.log('Drag started')}
/>
{/* This view receives drops */}
{
console.log('Dropped:', dragged.payload);
}}
/>
```
--------------------------------
### Drax Namespace Usage Example
Source: https://github.com/nuclearpasta/react-native-drax/blob/main/docs-site/docs/api/utilities/drax-namespace.mdx
Example demonstrating how to use components imported via the Drax namespace in a React Native component.
```APIDOC
## Usage
```tsx
import { Drax } from 'react-native-drax';
function App() {
return (
Content
);
}
```
```
--------------------------------
### Basic Cross-List Board Setup
Source: https://github.com/nuclearpasta/react-native-drax/blob/main/docs-site/docs/guides/cross-container-drag.mdx
Sets up the main board component for cross-container drag-and-drop. It uses `useSortableBoard` to manage transfers between columns and `SortableBoardContainer` to provide context. The `onTransfer` callback handles updating the state when an item is moved between columns.
```tsx
import {
DraxProvider,
useSortableBoard,
SortableBoardContainer,
useSortableList,
SortableContainer,
SortableItem,
} from 'react-native-drax';
function CrossListBoard() {
const [columns, setColumns] = useState(initialColumns);
const board = useSortableBoard({
keyExtractor: (item) => item.id,
onTransfer: ({ item, fromContainerId, toContainerId, fromIndex, toIndex }) => {
setColumns((prev) => {
const next = { ...prev };
// Remove from source
next[fromContainerId] = prev[fromContainerId].filter((_, i) => i !== fromIndex);
// Insert into target
next[toContainerId] = [
...prev[toContainerId].slice(0, toIndex),
item,
...prev[toContainerId].slice(toIndex),
];
return next;
});
},
});
return (
{Object.entries(columns).map(([colId, items]) => (
))}
);
}
```
--------------------------------
### Basic Bounded Dragging Setup
Source: https://github.com/nuclearpasta/react-native-drax/blob/main/docs-site/docs/guides/drag-bounds.mdx
Use `dragBoundsRef` to specify a parent `View` that will act as the boundary for the `DraxView`. Ensure the `DraxProvider` wraps the components.
```tsx
import { useRef } from 'react';
import { View } from 'react-native';
import { DraxProvider, DraxView } from 'react-native-drax';
function BoundedDrag() {
const boundsRef = useRef(null);
return (
I stay inside the box
);
}
```
--------------------------------
### Comparing Bounded vs Free Dragging
Source: https://github.com/nuclearpasta/react-native-drax/blob/main/docs-site/docs/guides/drag-bounds.mdx
This example demonstrates two `DraxView` components within the same boundary. One is constrained by `dragBoundsRef`, while the other is not and can be dragged freely.
```tsx
{/* This stays inside */}
Bounded
{/* This can go anywhere */}
Free
```
--------------------------------
### Cross-Container Sortable Example
Source: https://github.com/nuclearpasta/react-native-drax/blob/main/README.md
Demonstrates how to move items between lists using the experimental cross-container sortable API. Requires `onTransfer` callback for handling item movement logic.
```tsx
import {
useSortableBoard,
SortableBoardContainer,
useSortableList,
SortableContainer,
SortableItem,
} from 'react-native-drax';
const board = useSortableBoard({
onTransfer: ({ fromColumnId, toColumnId, fromIndex, toIndex, item }) => {
// Move item between columns
},
});
{columns.map((column) => (
))}
```
--------------------------------
### Styling ScrollView Content
Source: https://github.com/nuclearpasta/react-native-drax/blob/main/docs-site/docs/examples/scrolling.mdx
Shows how to apply styles to the content within a ScrollView. This example includes styles for the container, description, and bucket elements.
```javascript
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
borderTopColor: '#d0d0d0',
borderTopWidth: 1,
padding: 20,
},
description: {
fontSize: 16,
fontStyle: 'italic',
marginBottom: 20,
},
bucket: {
width: 180,
height: 120,
backgroundColor: '#d0d0d0',
borderColor: '#000000',
borderWidth: 3,
borderRadius: 4,
justifyContent: 'center',
alignItems: 'center',
},
bucketReceiving: {
backgroundColor: '#ffffd0',
},
});
```
--------------------------------
### Cross-List Reorder Example
Source: https://github.com/nuclearpasta/react-native-drax/blob/main/docs-site/docs/examples/index.mdx
Enables drag and drop between different list types (FlashList, LegendList, FlatList) within the same container. This showcases advanced cross-container drag and drop capabilities.
```typescript
import React, { useState } from "react";
import { View, Text, StyleSheet } from "react-native";
import { DraxProvider, DraxView, DraxLayout } from "react-native-drax";
// Assuming FlashList, LegendList, and FlatList are imported from their respective libraries
// Placeholder components for demonstration purposes
const FlashList = ({ data, renderItem, keyExtractor }) => (
{data.map((item) => (
{renderItem({ item })}
))}
);
const LegendList = ({ data, renderItem, keyExtractor }) => (
{data.map((item) => (
{renderItem({ item })}
))}
);
const FlatList = ({ data, renderItem, keyExtractor }) => (
{data.map((item) => (
{renderItem({ item })}
))}
);
const initialItems1 = [{ id: "1", text: "Item 1" }, { id: "2", text: "Item 2" }];
const initialItems2 = [{ id: "3", text: "Item 3" }, { id: "4", text: "Item 4" }];
const initialItems3 = [{ id: "5", text: "Item 5" }, { id: "6", text: "Item 6" }];
const CrossListReorder = () => {
const [items1, setItems1] = useState(initialItems1);
const [items2, setItems2] = useState(initialItems2);
const [items3, setItems3] = useState(initialItems3);
const handleDragEnd = (source, destination) => {
// Logic to move item from source list to destination list
console.log("Drag ended from:", source, "to:", destination);
// This would involve updating the state of the respective lists
};
return (
{
handleDragEnd(event.dragged.data, { listId: "list1" });
}}
>
item.id}
renderItem={({ item }) => (
{item.text}
)}
/>
{
handleDragEnd(event.dragged.data, { listId: "list2" });
}}
>
item.id}
renderItem={({ item }) => (
{item.text}
)}
/>
{
handleDragEnd(event.dragged.data, { listId: "list3" });
}}
>
item.id}
renderItem={({ item }) => (
{item.text}
)}
/>
);
};
const styles = StyleSheet.create({
container: {
flexDirection: "row",
justifyContent: "space-around",
padding: 10,
},
listContainer: {
flex: 1,
margin: 5,
borderWidth: 1,
borderColor: "#ccc",
padding: 10,
},
listItem: {
backgroundColor: "#e0e0e0",
padding: 15,
marginVertical: 5,
borderRadius: 5,
},
draggingItem: {
opacity: 0.5,
backgroundColor: "lightblue",
},
});
export default CrossListReorder;
```
--------------------------------
### Snap Alignment with Offset
Source: https://github.com/nuclearpasta/react-native-drax/blob/main/docs-site/docs/guides/snap-alignment.mdx
Apply pixel offsets to the snap position for added padding. This example adds an 8-pixel offset to both X and Y coordinates for 'top-left' alignment.
```tsx
snapToAlignment(receiver.measurements, dragged.measurements, 'top-left', { x: 8, y: 8 })
```
--------------------------------
### Scrolling Example
Source: https://github.com/nuclearpasta/react-native-drax/blob/main/docs-site/docs/examples/index.mdx
Demonstrates `DraxScrollView` for drag and drop interactions within a scrollable container. Includes auto-scroll functionality and the ability to drag items while scrolling.
```typescript
import React, { useState } from "react";
import { View, Text, StyleSheet } from "react-native";
import { DraxProvider, DraxScrollView, DraxView, DraxLayout } from "react-native-drax";
const initialItems = [
{ id: "1", text: "Item 1" },
{ id: "2", text: "Item 2" },
{ id: "3", text: "Item 3" },
{ id: "4", text: "Item 4" },
{ id: "5", text: "Item 5" },
{ id: "6", text: "Item 6" },
{ id: "7", text: "Item 7" },
{ id: "8", text: "Item 8" },
];
const Scrolling = () => {
const [items, setItems] = useState(initialItems);
const handleDragEnd = ({ from, to }) => {
if (from === to) return;
const newItems = [...items];
const [movedItem] = newItems.splice(from, 1);
newItems.splice(to, 0, movedItem);
setItems(newItems);
};
return (
{items.map((item, index) => (
i.id === item.id)) ? styles.draggingItem : null]}
dragStyle={styles.draggingItem}
onDragEnd={handleDragEnd}
draggedStyle={styles.draggedItem}
>
{item.text}
))}
);
};
const styles = StyleSheet.create({
scrollView: {
flex: 1,
backgroundColor: "#f0f0f0",
},
contentContainer: {
paddingVertical: 20,
},
item: {
backgroundColor: "#673AB7",
padding: 20,
marginVertical: 8,
marginHorizontal: 16,
borderRadius: 5,
justifyContent: "center",
alignItems: "center",
height: 100, // Ensure items have height for scrolling
},
itemText: {
color: "white",
fontSize: 18,
},
draggingItem: {
opacity: 0.5,
backgroundColor: "#9575CD",
},
draggedItem: {
// Style for the item after it has been dropped
backgroundColor: "#304FFE",
},
});
export default Scrolling;
```
--------------------------------
### Full-Screen Monitor Example
Source: https://github.com/nuclearpasta/react-native-drax/blob/main/docs-site/docs/guides/continuous-callbacks.mdx
Use a DraxView as a full-screen monitor to track drag events. Set `monitoring` to true and `draggable`/`receptive` to false to enable monitoring mode. Callbacks like `onMonitorDragStart`, `onMonitorDragOver`, and `onMonitorDragDrop` provide detailed event data.
```tsx
{
console.log(`Drag started: ${dragged.id}`);
}}
onMonitorDragOver={({ dragged, receiver, monitorOffset }) => {
console.log(`At offset: ${monitorOffset.x}, ${monitorOffset.y}`);
if (receiver) {
console.log(`Over receiver: ${receiver.id}`);
}
}}
onMonitorDragDrop={({ dragged, receiver }) => {
console.log(`Dropped ${dragged.id} onto ${receiver.id}`);
}}
>
Drag me
Drop here
```
--------------------------------
### DraxList Drag Lifecycle Callbacks
Source: https://github.com/nuclearpasta/react-native-drax/blob/main/docs-site/docs/guides/sortable-list.mdx
Provides examples of using `onDragStart`, `onDragPositionChange`, and `onDragEnd` callbacks to track and react to the different stages of the drag-and-drop lifecycle. This allows for custom animations or logging.
```tsx
item}
onReorder={({ data }) => setItems(data)}
onDragStart={({ index, item }) => {
console.log(`Started dragging "${item}" at index ${index}`);
}}
onDragPositionChange={({ index, toIndex, previousIndex }) => {
console.log(`Position changed: ${previousIndex} → ${toIndex}`);
}}
onDragEnd={({ index, toIndex, cancelled }) => {
console.log(`Drag ended at ${toIndex}, cancelled: ${cancelled}`);
}}
renderItem={({ item }) => }
/>
```
--------------------------------
### Reorderable Grid Example
Source: https://github.com/nuclearpasta/react-native-drax/blob/main/docs-site/docs/examples/index.mdx
Implements a sortable grid layout with multiple columns using Drax. This is suitable for applications requiring a grid interface where items can be rearranged.
```typescript
import React, { useState } from "react";
import { View, Text, StyleSheet, Dimensions } from "react-native";
import { DraxProvider, DraxGrid, DraxLayout } from "react-native-drax";
const numColumns = 3;
const screenWidth = Dimensions.get("window").width;
const itemSize = screenWidth / numColumns - 20; // Adjust for margins
const initialItems = [
{ id: "1", text: "1" },
{ id: "2", text: "2" },
{ id: "3", text: "3" },
{ id: "4", text: "4" },
{ id: "5", text: "5" },
{ id: "6", text: "6" },
{ id: "7", text: "7" },
{ id: "8", text: "8" },
{ id: "9", text: "9" },
];
const ReorderableGrid = () => {
const [items, setItems] = useState(initialItems);
const handleDragEnd = ({ from, to }) => {
if (from === to) return;
const newItems = [...items];
const [movedItem] = newItems.splice(from, 1);
newItems.splice(to, 0, movedItem);
setItems(newItems);
};
return (
item.id}
numColumns={numColumns}
renderItem={({ item, drag, dragStyle, dragActivatedStyle, dragDropStyle }) => (
{item.text}
)}
onDragEnd={handleDragEnd}
animationDuration={300}
autoscrollSpeed={5}
/>
);
};
const styles = StyleSheet.create({
item: {
backgroundColor: "#2196F3",
justifyContent: "center",
alignItems: "center",
margin: 10,
borderRadius: 5,
},
itemText: {
color: "white",
fontSize: 24,
fontWeight: "bold",
},
});
export default ReorderableGrid;
```
--------------------------------
### Collision Modes Example
Source: https://github.com/nuclearpasta/react-native-drax/blob/main/docs-site/docs/examples/index.mdx
Explores different collision detection modes: 'center', 'intersect', and 'contain'. This allows for precise control over when a drop is considered valid based on overlapping areas.
```typescript
import React from "react";
import { View, Text, StyleSheet } from "react-native";
import { DraxProvider, DraxView, DraxLayout } from "react-native-drax";
const CollisionModes = () => {
return (
Drag Me
console.log("Center collision drop:", dragData)
}
>
Center
console.log("Intersect collision drop:", dragData)
}
>
Intersect
console.log("Contain collision drop:", dragData)
}
>
Contain
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#f0f0f0",
},
box: {
width: 100,
height: 100,
justifyContent: "center",
alignItems: "center",
borderRadius: 10,
position: "absolute",
},
red: {
backgroundColor: "red",
},
targetBox: {
backgroundColor: "lightgray",
borderWidth: 2,
borderColor: "darkgray",
},
targetsContainer: {
position: "relative",
width: 400,
height: 200,
marginTop: 100,
},
draggingBox: {
opacity: 0.5,
},
text: {
color: "white",
fontWeight: "bold",
},
});
export default CollisionModes;
```
--------------------------------
### Drag Handles with Sortable List
Source: https://github.com/nuclearpasta/react-native-drax/blob/main/docs-site/docs/examples/drag-handles.mdx
This example demonstrates a sortable list where only the grip icon initiates a drag. The rest of the item's content remains tappable and scrollable. It utilizes `DraxProvider`, `SortableContainer`, `SortableItem`, and `DraxHandle` components.
```tsx
import { useRef, useState } from 'react';
import { StyleSheet, View, Text, FlatList } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import Icon from '@expo/vector-icons/MaterialCommunityIcons';
import {
DraxProvider,
DraxHandle,
SortableContainer,
SortableItem,
useSortableList,
} from 'react-native-drax';
const COLORS = ['#ffcccc', '#ccffcc', '#ccccff', '#ffffcc', '#ffccff', '#ccffff'];
const ITEMS = Array.from({ length: 20 }, (_, i) => ({
id: `item-${i}`,
label: `Item ${i + 1}`,
color: COLORS[i % COLORS.length]!,
}));
export default function DragHandles() {
const [data, setData] = useState(ITEMS);
const listRef = useRef>(null);
const insets = useSafeAreaInsets();
const sortable = useSortableList({
data,
keyExtractor: (item) => item.id,
onReorder: ({ data: newData }) => setData(newData),
});
return (
Only the grip icon on the left starts a drag. Tapping or swiping
the item content scrolls normally.
(
{item.label}
)}
/>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
header: {
padding: 12,
alignItems: 'center',
},
headerText: {
fontSize: 14,
fontStyle: 'italic',
textAlign: 'center',
color: '#666',
},
item: {
flexDirection: 'row',
alignItems: 'center',
marginHorizontal: 8,
marginVertical: 3,
borderRadius: 8,
height: 56,
},
handle: {
width: 44,
height: 56,
justifyContent: 'center',
alignItems: 'center',
},
itemText: {
fontSize: 16,
flex: 1,
},
dragging: {
opacity: 0,
},
});
```
--------------------------------
### Sortable List with FlashList
Source: https://github.com/nuclearpasta/react-native-drax/blob/main/docs-site/docs/guides/composable-api.mdx
Integrates the Composable API with Shopify's `FlashList` for optimized performance. The setup is similar to `FlatList`, requiring the same `sortable` props to be wired correctly.
```tsx
import { FlashList } from '@shopify/flash-list';
(
)}
/>
```