UNPKG

react-native-reanimated-dnd

Version:

A powerful drag-and-drop library for React Native using Reanimated 3

979 lines (786 loc) โ€ข 26.6 kB
# React Native Reanimated DnD ๐ŸŽฏ <p align="center"> <img src="https://github.com/user-attachments/assets/dba6226e-c407-4a12-9feb-e8f588d6c1e3" alt="React Native Reanimated DnD Demo" style="max-width: 100%; width: 100%;" /> </p> <div align="center"> **A drag-and-drop library that _finally_ works on React Native** โœจ _Powerful, performant, and built for the modern React Native developer_ [![npm version](https://badge.fury.io/js/react-native-reanimated-dnd.svg)](https://badge.fury.io/js/react-native-reanimated-dnd) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/) [![React Native](https://img.shields.io/badge/React%20Native-0.60+-green.svg)](https://reactnative.dev/) <br /> <a href="https://www.npmjs.com/package/react-native-reanimated-dnd" target="_blank"> <img src="https://img.shields.io/badge/๐Ÿ“ฆ%20View%20on%20NPM-cb3837?style=for-the-badge&logo=npm&logoColor=white&labelColor=1e293b&fontSize=24" alt="NPM Package" height="36"/> </a> <a href="https://react-native-reanimated-dnd.netlify.app/" target="_blank"> <img src="https://img.shields.io/badge/๐Ÿ“–%20Read%20the%20Docs-4f46e5?style=for-the-badge&logo=gitbook&logoColor=white&labelColor=1e293b&color=6366f1&fontSize=24" alt="Documentation" height="36"/> </a> <a href="#-interactive-examples" target="_blank"> <img src="https://img.shields.io/badge/๐Ÿ“ฑ%20Try%20Live%20Demo-fcba03?style=for-the-badge&logo=expo&logoColor=white&labelColor=1e293b&fontSize=24" alt="Live Demo" height="36"/> </a> </div> --- ## ๐Ÿš€ Why This Library? After countless attempts with drag-and-drop solutions that don't work or are simply outdated, this is something that _finally_ works. And it is not just another DnD library, but a **complete ecosystem** built from the ground up for React Native, offering a **best-in-class developer experience** and **production-ready performance**. **Highly feature-packed** with every interaction pattern you'll ever need, yet **simple enough** to get started in minutes. Built for developers who demand both power and simplicity. ## โœจ Features - ๐Ÿš€ **High Performance** - Built with Reanimated 3 for buttery-smooth 60fps animations - ๐Ÿ—๏ธ **Full RN Fabric Support** - Works seamlessly with both New Architecture and Old Architecture - ๐Ÿ“ฆ **Expo Compatible** - Zero configuration needed, works out of the box with Expo - ๐Ÿชถ **Tiny Bundle Size** - Only 70kb unpacked size, won't bloat your app - ๐ŸŽฏ **Flexible API** - From simple drag-and-drop to complex sortable lists - ๐Ÿ“ฑ **React Native First** - Designed specifically for mobile, not ported from web - ๐Ÿ”ง **TypeScript Ready** - Full type safety with comprehensive definitions - ๐ŸŽจ **Infinitely Customizable** - Every animation, behavior, and style is configurable - ๐Ÿ“ฆ **Complete Component Suite** - Draggable, Droppable, Sortable, and more - ๐ŸŽช **Smart Collision Detection** - Multiple algorithms (center, intersect, contain) - ๐Ÿ“œ **Sortable Lists** - Drag and drop to sort a Vertical List, also supports Automatic scrolling for out of screen dragging - ๐ŸŽญ **Drag Handles** - Precise control with dedicated drag areas - ๐ŸŽฌ **Custom Animations** - Spring, timing, or bring your own animation functions - ๐Ÿ“ **Pixel-Perfect Positioning** - 9-point alignment system with custom offsets - ๐Ÿ“ฆ **Boundary Constraints** - Keep draggables within specific areas - โšก **State Management** - Complete lifecycle tracking and callbacks - ๐ŸŽฏ **Developer Experience** - Intuitive APIs, helpful warnings, and extensive examples ## ๐Ÿ“ฑ Interactive Examples **See it in action!** A comprehensive example app with **15 interactive demos** showcasing every feature and use case. <div align="center"> ### ๐ŸŽฎ Try the Example App <table> <tr> <td align="center" width="50%"> **๐Ÿ“ฑ Scan & Play** <img src="https://github.com/user-attachments/assets/80f923f6-7c5f-42e9-9817-7770ee27a70b" alt="Expo QR Code" width="200" height="200" /> _Scan with your camera or Expo Go app_ </td> <td align="center" width="50%"> **๐Ÿš€ Quick Start** 1. Install [Expo Go](https://expo.dev/client) on your phone 2. Scan the QR code with your camera 3. Open the link in Expo Go 4. Explore 15 interactive examples! **Or browse the code:** [**๐Ÿ“‚ View Example App โ†’**](./example-app/README.md) </td> </tr> </table> ### ๐Ÿ“š Complete Documentation <a href="https://react-native-reanimated-dnd.netlify.app/" target="_blank"> <img src="https://img.shields.io/badge/๐Ÿ“–%20Documentation-Visit%20Docs-4f46e5?style=for-the-badge&logo=gitbook&logoColor=white&labelColor=1e293b" alt="Documentation" /> </a> _Comprehensive guides, API reference, and interactive examples_ </div> The example app includes: - ๐ŸŽต **Sortable Music Queue** - Complete list reordering with handles - ๐ŸŽฏ **Collision Detection** - Different algorithms in action - ๐ŸŽฌ **Custom Animations** - Spring, timing, and easing variations - ๐Ÿ“ฆ **Boundary Constraints** - Axis-locked and bounded dragging - โœจ **Visual Feedback** - Active styles and state management - โš™๏ธ **Advanced Patterns** - Custom implementations and hooks ## ๐ŸŽฌ Video Showcase **See the library in action** with these demos showcasing some of the key features and use cases. <div align="center"> <table> <tr> <td align="center" width="50%"> ### ๐Ÿ“‹ Sortable Lists _Drag and drop to reorder items with smooth animations_ https://github.com/user-attachments/assets/1cd1929c-724b-4dda-a916-f3e69f917f7b **Features:** Auto-scrolling โ€ข Drag handles โ€ข Smooth transitions </td> <td align="center" width="50%"> ### ๐ŸŽฏ Collision Detection _Multiple algorithms for precise drop targeting_ https://github.com/user-attachments/assets/379040d7-8489-430b-bae4-3fcbde34264e **Algorithms:** Center โ€ข Intersect โ€ข Contain </td> </tr> <tr> <td align="center" width="50%"> ### ๐ŸŽช Drag Handles _Precise control with dedicated drag areas_ https://github.com/user-attachments/assets/ec051d5b-8ba0-41b7-86ae-379de26a97dd **Features:** Touch-friendly โ€ข Visual feedback โ€ข Accessibility </td> <td align="center" width="50%"> ### ๐Ÿ“ฆ Bounded Dragging _Constrain movement within specific boundaries_ https://github.com/user-attachments/assets/7bd5045b-47c4-4d9b-a0c5-eb89122ec9c0 **Constraints:** Axis-locked โ€ข Container bounds โ€ข Custom limits </td> </tr> <tr> <td align="center" width="50%"> ### โœจ Active Drop Styles _Visual feedback during drag operations_ https://github.com/user-attachments/assets/3b8a3d00-38ad-4532-bd42-173037ea61b9 **Feedback:** Hover states โ€ข Drop zones โ€ข Visual cues </td> <td align="center" width="50%"> ### ๐Ÿ”„ State Management _Complete lifecycle tracking and callbacks_ https://github.com/user-attachments/assets/da5e526f-f2d2-4dc5-96b5-3fecc4faf57a **States:** Idle โ€ข Dragging โ€ข Animating โ€ข Dropped </td> </tr> </table> </div> ## ๐Ÿš€ Installation ```bash npm install react-native-reanimated-dnd ``` ### Peer Dependencies ```bash npm install react-native-reanimated react-native-gesture-handler ``` Follow the setup guides: - [React Native Reanimated](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/installation) - [React Native Gesture Handler](https://docs.swmansion.com/react-native-gesture-handler/docs/installation) ## ๐Ÿƒโ€โ™‚๏ธ Quick Start ### Basic Draggable ```tsx import React from "react"; import { View, Text, StyleSheet } from "react-native"; import { GestureHandlerRootView } from "react-native-gesture-handler"; import { Draggable, DropProvider } from "react-native-reanimated-dnd"; export default function App() { return ( <GestureHandlerRootView style={styles.container}> <DropProvider> <View style={styles.content}> <Draggable data={{ id: "1", title: "Drag me!" }}> <View style={styles.draggableItem}> <Text style={styles.itemText}>๐ŸŽฏ Drag me around!</Text> </View> </Draggable> </View> </DropProvider> </GestureHandlerRootView> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: "#000000", }, content: { flex: 1, padding: 20, justifyContent: "center", alignItems: "center", }, draggableItem: { padding: 20, backgroundColor: "#1C1C1E", borderRadius: 12, borderWidth: 1, borderColor: "#3A3A3C", shadowColor: "#000", shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.25, shadowRadius: 4, elevation: 3, }, itemText: { color: "#FFFFFF", fontSize: 16, fontWeight: "600", textAlign: "center", }, }); ``` ### Drag & Drop with Multiple Zones ```tsx import React from "react"; import { Alert, StyleSheet, Text, View } from "react-native"; import { GestureHandlerRootView } from "react-native-gesture-handler"; import { Draggable, Droppable, DropProvider, } from "react-native-reanimated-dnd"; export default function DragDropExample() { const handleDrop = (data: any, zoneId: string) => { Alert.alert("Item Dropped", `"${data.title}" dropped in ${zoneId}`); }; return ( <GestureHandlerRootView style={styles.container}> <DropProvider> <View style={styles.content}> {/* Drop Zones */} <View style={styles.dropZonesSection}> <Text style={styles.sectionTitle}>Drop Zones</Text> <Droppable onDrop={(data) => handleDrop(data, "Zone 1")} activeStyle={styles.dropZoneActive} style={styles.droppable} > <View style={[styles.dropZoneBlue, styles.dropZone]}> <Text style={styles.dropZoneText}>๐ŸŽฏ Zone 1</Text> <Text style={styles.dropZoneSubtext}>Drop here</Text> </View> </Droppable> <Droppable onDrop={(data) => handleDrop(data, "Zone 2")} activeStyle={styles.dropZoneActive} style={styles.droppable} > <View style={[styles.dropZone, styles.dropZoneGreen]}> <Text style={styles.dropZoneText}>๐ŸŽฏ Zone 2</Text> <Text style={styles.dropZoneSubtext}>Drop here</Text> </View> </Droppable> </View> {/* Draggable Item */} <View style={styles.draggableSection}> <Text style={styles.sectionTitle}>Draggable Item</Text> <Draggable data={{ id: "1", title: "Task Item" }}> <View style={styles.draggableItem}> <Text style={styles.itemText}>๐Ÿ“ฆ Drag me to a zone</Text> </View> </Draggable> </View> </View> </DropProvider> </GestureHandlerRootView> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: "#000000", }, content: { flex: 1, padding: 20, justifyContent: "space-between", }, sectionTitle: { color: "#FFFFFF", fontSize: 18, fontWeight: "700", marginBottom: 20, textAlign: "center", }, draggableSection: { alignItems: "center", paddingVertical: 40, }, draggableItem: { padding: 20, backgroundColor: "#1C1C1E", borderRadius: 12, borderWidth: 1, borderColor: "#3A3A3C", shadowColor: "#000", shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.25, shadowRadius: 4, elevation: 3, }, itemText: { color: "#FFFFFF", fontSize: 16, fontWeight: "600", textAlign: "center", }, dropZonesSection: { flex: 1, paddingVertical: 40, }, droppable: { marginBottom: 20, overflow: "hidden", borderRadius: 16, }, dropZone: { height: 140, borderWidth: 2, borderStyle: "dashed", borderRadius: 16, justifyContent: "center", alignItems: "center", padding: 20, }, dropZoneBlue: { borderColor: "#58a6ff", backgroundColor: "rgba(88, 166, 255, 0.08)", }, dropZoneGreen: { borderColor: "#3fb950", backgroundColor: "rgba(63, 185, 80, 0.08)", }, dropZoneActive: { backgroundColor: "rgba(255, 255, 255, 0.1)", borderStyle: "solid", transform: [{ scale: 1.02 }], }, dropZoneText: { color: "#FFFFFF", fontSize: 18, fontWeight: "600", textAlign: "center", marginBottom: 8, }, dropZoneSubtext: { color: "#8E8E93", fontSize: 14, textAlign: "center", }, }); ``` ### Sortable List ```tsx import React, { useCallback, useState } from "react"; import { StyleSheet, Text, View } from "react-native"; import { GestureHandlerRootView } from "react-native-gesture-handler"; import { Sortable, SortableItem, SortableRenderItemProps, } from "react-native-reanimated-dnd"; interface Task { id: string; title: string; completed: boolean; } export default function SortableExample() { const [tasks, setTasks] = useState<Task[]>([ { id: "1", title: "Learn React Native", completed: false }, { id: "2", title: "Build an app", completed: false }, { id: "3", title: "Deploy to store", completed: true }, { id: "4", title: "Celebrate success", completed: false }, ]); const renderTask = useCallback( (props: SortableRenderItemProps<Task>) => { const { item, id, positions, lowerBound, autoScrollDirection, itemsCount, itemHeight, } = props; return ( <SortableItem key={id} data={item} id={id} positions={positions} lowerBound={lowerBound} autoScrollDirection={autoScrollDirection} itemsCount={itemsCount} itemHeight={itemHeight} onMove={(itemId, from, to) => { const newTasks = [...tasks]; const [movedTask] = newTasks.splice(from, 1); newTasks.splice(to, 0, movedTask); setTasks(newTasks); }} style={styles.taskItem} > <View style={styles.taskContent}> <View style={styles.taskInfo}> <Text style={styles.taskTitle}>{item.title}</Text> <Text style={styles.taskStatus}> {item.completed ? "โœ… Completed" : "โณ Pending"} </Text> </View> {/* Drag Handle */} <SortableItem.Handle style={styles.dragHandle}> <View style={styles.dragIconContainer}> <View style={styles.dragColumn}> <View style={styles.dragDot} /> <View style={styles.dragDot} /> <View style={styles.dragDot} /> </View> <View style={styles.dragColumn}> <View style={styles.dragDot} /> <View style={styles.dragDot} /> <View style={styles.dragDot} /> </View> </View> </SortableItem.Handle> </View> </SortableItem> ); }, [tasks] ); return ( <GestureHandlerRootView style={styles.container}> <View style={styles.header}> <Text style={styles.headerTitle}>๐Ÿ“‹ My Tasks</Text> <Text style={styles.headerSubtitle}>Drag to reorder</Text> </View> <Sortable data={tasks} renderItem={renderTask} itemHeight={80} style={styles.list} /> </GestureHandlerRootView> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: "#000000", }, header: { padding: 20, paddingBottom: 16, borderBottomWidth: 1, borderBottomColor: "#2C2C2E", }, headerTitle: { color: "#FFFFFF", fontSize: 24, fontWeight: "700", marginBottom: 4, }, headerSubtitle: { color: "#8E8E93", fontSize: 14, }, list: { flex: 1, backgroundColor: "#000000", marginTop: 20, paddingHorizontal: 20, borderRadius: 20, overflow: "hidden", }, taskItem: { height: 80, backgroundColor: "transparent", }, taskContent: { flex: 1, flexDirection: "row", alignItems: "center", paddingHorizontal: 20, backgroundColor: "#1C1C1E", borderWidth: 1, borderColor: "#3A3A3C", }, taskInfo: { flex: 1, paddingRight: 16, }, taskTitle: { color: "#FFFFFF", fontSize: 16, fontWeight: "600", marginBottom: 4, }, taskStatus: { color: "#8E8E93", fontSize: 14, }, dragHandle: { padding: 12, borderRadius: 8, backgroundColor: "rgba(255, 255, 255, 0.05)", }, dragIconContainer: { flexDirection: "row", alignItems: "center", gap: 3, }, dragColumn: { flexDirection: "column", gap: 2, }, dragDot: { width: 3, height: 3, borderRadius: 1.5, backgroundColor: "#6D6D70", }, }); ``` ## ๐Ÿ“š API Reference ### Components #### `<Draggable>` Makes any component draggable with extensive customization options. ```tsx <Draggable data={any} // Data associated with the item onDragStart={(data) => void} // Called when dragging starts onDragEnd={(data) => void} // Called when dragging ends onDragging={(position) => void} // Called during dragging onStateChange={(state) => void} // Called on state changes dragDisabled={boolean} // Disable dragging collisionAlgorithm="center|intersect|contain" // Collision detection method dragAxis="x|y|both" // Constrain movement axis dragBoundsRef={RefObject} // Boundary container reference animationFunction={(toValue) => Animation} // Custom animation function style={StyleProp<ViewStyle>} // Component styling > {children} </Draggable> ``` #### `<Droppable>` Creates drop zones with visual feedback and capacity management. ```tsx <Droppable onDrop={(data) => void} // Called when item is dropped onActiveChange={(isActive) => void} // Called on hover state change dropDisabled={boolean} // Disable drop functionality dropAlignment="top-left|center|bottom-right|..." // Drop positioning dropOffset={{ x: number, y: number }} // Position offset activeStyle={StyleProp<ViewStyle>} // Style when active capacity={number} // Maximum items allowed droppableId={string} // Unique identifier > {children} </Droppable> ``` #### `<Sortable>` High-level component for sortable lists with auto-scrolling. ```tsx <Sortable data={Array<{ id: string }>} // Array of items to render renderItem={(props) => ReactNode} // Render function for items itemHeight={number} // Height of each item itemKeyExtractor={(item) => string} // Custom key extractor style={StyleProp<ViewStyle>} // List container style contentContainerStyle={StyleProp<ViewStyle>} // Content container style /> ``` #### `<SortableItem>` Individual item within a sortable list with gesture handling. ```tsx <SortableItem id={string} // Unique identifier data={any} // Item data positions={SharedValue} // Position tracking onMove={(id, from, to) => void} // Called when item moves onDragStart={(id, position) => void} // Called when dragging starts onDrop={(id, position) => void} // Called when item is dropped onDragging={(id, overItemId, y) => void} // Called during dragging style={StyleProp<ViewStyle>} // Item styling animatedStyle={StyleProp<AnimatedStyle>} // Animated styling > {children} </SortableItem> ``` ### Hooks #### `useDraggable(options)` Core hook for implementing draggable functionality. #### `useDroppable(options)` Core hook for implementing droppable functionality. #### `useSortable(options)` Hook for individual sortable items with position management. #### `useSortableList(options)` Hook for managing entire sortable lists with auto-scrolling. ### Context #### `<DropProvider>` Required context provider that manages global drag-and-drop state. ```tsx <DropProvider>{/* All draggable and droppable components */}</DropProvider> ``` ### Types & Enums #### `DraggableState` ```tsx enum DraggableState { IDLE = "idle", DRAGGING = "dragging", ANIMATING = "animating", } ``` #### `CollisionAlgorithm` ```tsx type CollisionAlgorithm = "center" | "intersect" | "contain"; ``` #### `DropAlignment` ```tsx type DropAlignment = | "top-left" | "top-center" | "top-right" | "center-left" | "center" | "center-right" | "bottom-left" | "bottom-center" | "bottom-right"; ``` ## ๐ŸŽจ Advanced Usage ### Custom Animations ```tsx import { withTiming, withSpring, Easing } from "react-native-reanimated"; // Smooth timing animation const smoothAnimation = (toValue) => { "worklet"; return withTiming(toValue, { duration: 300, easing: Easing.bezier(0.25, 0.1, 0.25, 1), }); }; // Spring animation const springAnimation = (toValue) => { "worklet"; return withSpring(toValue, { damping: 15, stiffness: 150, }); }; <Draggable animationFunction={springAnimation}>{/* content */}</Draggable>; ``` ### Collision Detection Strategies ```tsx // Precise center-point collision <Draggable collisionAlgorithm="center"> {/* Requires center point to be over drop zone */} </Draggable> // Forgiving intersection collision (default) <Draggable collisionAlgorithm="intersect"> {/* Any overlap triggers collision */} </Draggable> // Strict containment collision <Draggable collisionAlgorithm="contain"> {/* Entire draggable must be within drop zone */} </Draggable> ``` ### Drag Handles ```tsx <SortableItem id={item.id} {...props}> <View style={styles.itemContainer}> <Text>{item.title}</Text> {/* Only this handle area can initiate dragging */} <SortableItem.Handle style={styles.dragHandle}> <View style={styles.handleIcon}> <View style={styles.dot} /> <View style={styles.dot} /> <View style={styles.dot} /> </View> </SortableItem.Handle> </View> </SortableItem> ``` ### Bounded Dragging ```tsx const containerRef = useRef<View>(null); <View ref={containerRef} style={styles.container}> <Draggable data={data} dragBoundsRef={containerRef} dragAxis="x" // Constrain to horizontal movement > {/* content */} </Draggable> </View>; ``` ### Drop Zone Capacity ```tsx <Droppable capacity={3} onDrop={(data) => { if (currentItems.length < 3) { addItem(data); } }} activeStyle={{ backgroundColor: currentItems.length < 3 ? "#e8f5e8" : "#ffe8e8", }} > <Text>Drop Zone ({currentItems.length}/3)</Text> </Droppable> ``` ## ๐Ÿƒโ€โ™‚๏ธ Running the Example App 1. Clone the repository: ```bash git clone https://github.com/entropyconquers/react-native-reanimated-dnd.git cd react-native-reanimated-dnd ``` 2. Install dependencies: ```bash npm install cd example-app npm install ``` 3. Run the example app: ```bash # iOS npx expo run:ios # Android npx expo run:android ``` The example app includes all 15 interactive examples showcasing every feature of the library. ## ๐Ÿ—บ๏ธ Project Roadmap I am constantly working to improve React Native Reanimated DnD. Here's what's coming next: ### ๐ŸŽฏ Next Release (v2.0.0) **Focus: Enhanced Functionality & Bug Fixes** - ๐Ÿ› **Bug Fixes & Issues Resolution** - Address existing reported issues - Performance optimizations - Gesture handling improvements - API Improvements - ๐Ÿ“ **Sortable Grids** - 2D grid drag-and-drop support - Flexible grid layouts (2x2, 3x3, custom) - Smart auto-positioning and gap management - Responsive grid behavior - โ†”๏ธ **Horizontal Sortable Lists** - Full horizontal scrolling support - Auto-scroll for out-of-view items - Customizable scroll behavior - ๐Ÿช† **Nested Sortable Lists** - Multi-level hierarchy support - Collapse/expand functionality - Parent-child relationship management - Tree-like data structure handling - ๐Ÿ“‹ **Kanban Board Support** - Cross-list dragging capabilities - Multiple column support - Inter-list item transfer - Board-level state management ### ๐Ÿ’ก Community Requests Vote on features you'd like to see by raising an issue. **Have an idea?** [Open a feature request](https://github.com/entropyconquers/react-native-reanimated-dnd/issues/new?assignees=&labels=enhancement&template=feature_request.md) and let me know! ## ๐Ÿค Contributing Contributions are always welcome! We believe in building this library together with the community. **Ways to contribute:** - ๐Ÿ› Report bugs and issues - โœจ Suggest new features - ๐Ÿ”ง Submit pull requests - ๐Ÿ“š Improve documentation - ๐Ÿงช Write tests - ๐Ÿ’ฌ Help others in discussions Please see our [**Contributing Guide**](CONTRIBUTING.md) for detailed information on: - Setting up the development environment - Code style guidelines - Pull request process - Testing requirements - Community guidelines ## ๐Ÿ“„ License MIT ยฉ [Vishesh Raheja](https://github.com/entropyconquers) ## ๐Ÿ™ Acknowledgments - Built with [React Native Reanimated](https://docs.swmansion.com/react-native-reanimated/) for smooth 60fps animations - Gesture handling powered by [React Native Gesture Handler](https://docs.swmansion.com/react-native-gesture-handler/) - Inspired by the React ecosystem's drag-and-drop libraries - Special thanks to the React Native community for feedback and contributions ## โ˜• Support the Project <div align="center"> <body> If this library has helped you build amazing apps, consider supporting its development! </br></br> <a href="https://www.buymeacoffee.com/entropyconquers" target="_blank"> <img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me a Coffee" style="height: 60px; width: 217px;"> </a> </br> </br> Your support helps maintain and improve this library for the entire React Native community! ๐Ÿš€ </body> </html> </div> <br/> --- <div align="center"> **Made with โค๏ธ for the React Native community** [โญ Star on GitHub](https://github.com/entropyconquers/react-native-reanimated-dnd) โ€ข [๐Ÿ“ฑ Try the Demo](https://github.com/entropyconquers/react-native-reanimated-dnd/tree/main/example-app) โ€ข [๐Ÿ“– Documentation](https://github.com/entropyconquers/react-native-reanimated-dnd#readme) </div>