react-native-drax 0.11.0-alpha.2 β†’ 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (246) hide show
  1. package/LICENSE.md +1 -1
  2. package/README.md +385 -227
  3. package/lib/module/DebugOverlay.js +121 -0
  4. package/lib/module/DebugOverlay.js.map +1 -0
  5. package/lib/module/Drax.js +36 -0
  6. package/lib/module/Drax.js.map +1 -0
  7. package/lib/module/DraxContext.js +6 -0
  8. package/lib/module/DraxContext.js.map +1 -0
  9. package/lib/module/DraxHandle.js +47 -0
  10. package/lib/module/DraxHandle.js.map +1 -0
  11. package/lib/module/DraxHandleContext.js +11 -0
  12. package/lib/module/DraxHandleContext.js.map +1 -0
  13. package/lib/module/DraxList.js +108 -0
  14. package/lib/module/DraxList.js.map +1 -0
  15. package/lib/module/DraxProvider.js +203 -0
  16. package/lib/module/DraxProvider.js.map +1 -0
  17. package/lib/module/DraxScrollView.js +167 -0
  18. package/lib/module/DraxScrollView.js.map +1 -0
  19. package/lib/module/DraxSubprovider.js +21 -0
  20. package/lib/module/DraxSubprovider.js.map +1 -0
  21. package/lib/module/DraxView.js +348 -0
  22. package/lib/module/DraxView.js.map +1 -0
  23. package/lib/module/HoverLayer.js +152 -0
  24. package/lib/module/HoverLayer.js.map +1 -0
  25. package/lib/module/SortableBoardContainer.js +386 -0
  26. package/lib/module/SortableBoardContainer.js.map +1 -0
  27. package/lib/module/SortableBoardContext.js +6 -0
  28. package/lib/module/SortableBoardContext.js.map +1 -0
  29. package/lib/module/SortableContainer.js +561 -0
  30. package/lib/module/SortableContainer.js.map +1 -0
  31. package/lib/module/SortableItem.js +226 -0
  32. package/lib/module/SortableItem.js.map +1 -0
  33. package/lib/module/SortableItemContext.js +38 -0
  34. package/lib/module/SortableItemContext.js.map +1 -0
  35. package/lib/module/compat/detectVersion.js +19 -0
  36. package/lib/module/compat/detectVersion.js.map +1 -0
  37. package/lib/module/compat/index.js +5 -0
  38. package/lib/module/compat/index.js.map +1 -0
  39. package/lib/module/compat/types.js +4 -0
  40. package/lib/module/compat/types.js.map +1 -0
  41. package/lib/module/compat/useDraxPanGesture.js +94 -0
  42. package/lib/module/compat/useDraxPanGesture.js.map +1 -0
  43. package/lib/module/hooks/index.js +5 -0
  44. package/lib/module/hooks/index.js.map +1 -0
  45. package/lib/module/hooks/useCallbackDispatch.js +681 -0
  46. package/lib/module/hooks/useCallbackDispatch.js.map +1 -0
  47. package/lib/module/hooks/useDragGesture.js +240 -0
  48. package/lib/module/hooks/useDragGesture.js.map +1 -0
  49. package/lib/module/hooks/useDraxContext.js +12 -0
  50. package/lib/module/hooks/useDraxContext.js.map +1 -0
  51. package/lib/module/hooks/useDraxId.js +13 -0
  52. package/lib/module/hooks/useDraxId.js.map +1 -0
  53. package/lib/module/hooks/useDraxMethods.js +73 -0
  54. package/lib/module/hooks/useDraxMethods.js.map +1 -0
  55. package/lib/module/hooks/useDraxScrollHandler.js +97 -0
  56. package/lib/module/hooks/useDraxScrollHandler.js.map +1 -0
  57. package/lib/module/hooks/useSortableBoard.js +37 -0
  58. package/lib/module/hooks/useSortableBoard.js.map +1 -0
  59. package/lib/module/hooks/useSortableList.js +824 -0
  60. package/lib/module/hooks/useSortableList.js.map +1 -0
  61. package/lib/module/hooks/useSpatialIndex.js +283 -0
  62. package/lib/module/hooks/useSpatialIndex.js.map +1 -0
  63. package/lib/module/hooks/useViewStyles.js +158 -0
  64. package/lib/module/hooks/useViewStyles.js.map +1 -0
  65. package/lib/module/hooks/useWebScrollFreeze.js +52 -0
  66. package/lib/module/hooks/useWebScrollFreeze.js.map +1 -0
  67. package/lib/module/index.js +37 -0
  68. package/lib/module/index.js.map +1 -0
  69. package/lib/module/math.js +222 -0
  70. package/lib/module/math.js.map +1 -0
  71. package/lib/module/package.json +1 -0
  72. package/lib/module/params.js +88 -0
  73. package/lib/module/params.js.map +1 -0
  74. package/lib/module/types.js +213 -0
  75. package/lib/module/types.js.map +1 -0
  76. package/lib/typescript/package.json +1 -0
  77. package/lib/typescript/src/DebugOverlay.d.ts +17 -0
  78. package/lib/typescript/src/DebugOverlay.d.ts.map +1 -0
  79. package/lib/typescript/src/Drax.d.ts +28 -0
  80. package/lib/typescript/src/Drax.d.ts.map +1 -0
  81. package/lib/typescript/src/DraxContext.d.ts +3 -0
  82. package/lib/typescript/src/DraxContext.d.ts.map +1 -0
  83. package/lib/typescript/src/DraxHandle.d.ts +25 -0
  84. package/lib/typescript/src/DraxHandle.d.ts.map +1 -0
  85. package/lib/typescript/src/DraxHandleContext.d.ts +12 -0
  86. package/lib/typescript/src/DraxHandleContext.d.ts.map +1 -0
  87. package/lib/typescript/src/DraxList.d.ts +66 -0
  88. package/lib/typescript/src/DraxList.d.ts.map +1 -0
  89. package/lib/typescript/src/DraxProvider.d.ts +4 -0
  90. package/lib/typescript/src/DraxProvider.d.ts.map +1 -0
  91. package/lib/typescript/src/DraxScrollView.d.ts +7 -0
  92. package/lib/typescript/src/DraxScrollView.d.ts.map +1 -0
  93. package/lib/typescript/src/DraxSubprovider.d.ts +4 -0
  94. package/lib/typescript/src/DraxSubprovider.d.ts.map +1 -0
  95. package/lib/typescript/src/DraxView.d.ts +4 -0
  96. package/lib/typescript/src/DraxView.d.ts.map +1 -0
  97. package/lib/typescript/src/HoverLayer.d.ts +38 -0
  98. package/lib/typescript/src/HoverLayer.d.ts.map +1 -0
  99. package/lib/typescript/src/SortableBoardContainer.d.ts +11 -0
  100. package/lib/typescript/src/SortableBoardContainer.d.ts.map +1 -0
  101. package/lib/typescript/src/SortableBoardContext.d.ts +4 -0
  102. package/lib/typescript/src/SortableBoardContext.d.ts.map +1 -0
  103. package/lib/typescript/src/SortableContainer.d.ts +13 -0
  104. package/lib/typescript/src/SortableContainer.d.ts.map +1 -0
  105. package/lib/typescript/src/SortableItem.d.ts +14 -0
  106. package/lib/typescript/src/SortableItem.d.ts.map +1 -0
  107. package/lib/typescript/src/SortableItemContext.d.ts +37 -0
  108. package/lib/typescript/src/SortableItemContext.d.ts.map +1 -0
  109. package/lib/typescript/src/compat/detectVersion.d.ts +2 -0
  110. package/lib/typescript/src/compat/detectVersion.d.ts.map +1 -0
  111. package/lib/typescript/src/compat/index.d.ts +4 -0
  112. package/lib/typescript/src/compat/index.d.ts.map +1 -0
  113. package/lib/typescript/src/compat/types.d.ts +33 -0
  114. package/lib/typescript/src/compat/types.d.ts.map +1 -0
  115. package/lib/typescript/src/compat/useDraxPanGesture.d.ts +8 -0
  116. package/lib/typescript/src/compat/useDraxPanGesture.d.ts.map +1 -0
  117. package/lib/typescript/src/hooks/index.d.ts +3 -0
  118. package/lib/typescript/src/hooks/index.d.ts.map +1 -0
  119. package/lib/typescript/src/hooks/useCallbackDispatch.d.ts +40 -0
  120. package/lib/typescript/src/hooks/useCallbackDispatch.d.ts.map +1 -0
  121. package/lib/typescript/src/hooks/useDragGesture.d.ts +17 -0
  122. package/lib/typescript/src/hooks/useDragGesture.d.ts.map +1 -0
  123. package/lib/typescript/src/hooks/useDraxContext.d.ts +2 -0
  124. package/lib/typescript/src/hooks/useDraxContext.d.ts.map +1 -0
  125. package/{build β†’ lib/typescript/src}/hooks/useDraxId.d.ts +1 -0
  126. package/lib/typescript/src/hooks/useDraxId.d.ts.map +1 -0
  127. package/lib/typescript/src/hooks/useDraxMethods.d.ts +13 -0
  128. package/lib/typescript/src/hooks/useDraxMethods.d.ts.map +1 -0
  129. package/lib/typescript/src/hooks/useDraxScrollHandler.d.ts +27 -0
  130. package/lib/typescript/src/hooks/useDraxScrollHandler.d.ts.map +1 -0
  131. package/lib/typescript/src/hooks/useSortableBoard.d.ts +10 -0
  132. package/lib/typescript/src/hooks/useSortableBoard.d.ts.map +1 -0
  133. package/lib/typescript/src/hooks/useSortableList.d.ts +11 -0
  134. package/lib/typescript/src/hooks/useSortableList.d.ts.map +1 -0
  135. package/lib/typescript/src/hooks/useSpatialIndex.d.ts +22 -0
  136. package/lib/typescript/src/hooks/useSpatialIndex.d.ts.map +1 -0
  137. package/lib/typescript/src/hooks/useViewStyles.d.ts +183 -0
  138. package/lib/typescript/src/hooks/useViewStyles.d.ts.map +1 -0
  139. package/lib/typescript/src/hooks/useWebScrollFreeze.d.ts +14 -0
  140. package/lib/typescript/src/hooks/useWebScrollFreeze.d.ts.map +1 -0
  141. package/lib/typescript/src/index.d.ts +25 -0
  142. package/lib/typescript/src/index.d.ts.map +1 -0
  143. package/lib/typescript/src/math.d.ts +52 -0
  144. package/lib/typescript/src/math.d.ts.map +1 -0
  145. package/{build β†’ lib/typescript/src}/params.d.ts +13 -9
  146. package/lib/typescript/src/params.d.ts.map +1 -0
  147. package/lib/typescript/src/types.d.ts +743 -0
  148. package/lib/typescript/src/types.d.ts.map +1 -0
  149. package/package.json +164 -34
  150. package/src/DebugOverlay.tsx +140 -0
  151. package/src/Drax.ts +33 -0
  152. package/src/DraxContext.ts +8 -0
  153. package/src/DraxHandle.tsx +52 -0
  154. package/src/DraxHandleContext.ts +15 -0
  155. package/src/DraxList.tsx +181 -0
  156. package/src/DraxProvider.tsx +224 -0
  157. package/src/DraxScrollView.tsx +180 -0
  158. package/src/DraxSubprovider.tsx +22 -0
  159. package/src/DraxView.tsx +430 -0
  160. package/src/HoverLayer.tsx +167 -0
  161. package/src/SortableBoardContainer.tsx +439 -0
  162. package/src/SortableBoardContext.ts +6 -0
  163. package/src/SortableContainer.tsx +642 -0
  164. package/src/SortableItem.tsx +264 -0
  165. package/src/SortableItemContext.ts +46 -0
  166. package/src/compat/detectVersion.ts +17 -0
  167. package/src/compat/index.ts +7 -0
  168. package/src/compat/types.ts +35 -0
  169. package/src/compat/useDraxPanGesture.ts +112 -0
  170. package/src/hooks/index.ts +2 -0
  171. package/src/hooks/useCallbackDispatch.tsx +823 -0
  172. package/src/hooks/useDragGesture.ts +273 -0
  173. package/src/hooks/useDraxContext.ts +11 -0
  174. package/src/hooks/useDraxId.ts +11 -0
  175. package/src/hooks/useDraxMethods.ts +71 -0
  176. package/src/hooks/useDraxScrollHandler.ts +121 -0
  177. package/src/hooks/useSortableBoard.ts +44 -0
  178. package/src/hooks/useSortableList.ts +868 -0
  179. package/src/hooks/useSpatialIndex.ts +336 -0
  180. package/src/hooks/useViewStyles.ts +180 -0
  181. package/src/hooks/useWebScrollFreeze.ts +60 -0
  182. package/src/index.ts +110 -0
  183. package/src/math.ts +251 -0
  184. package/src/params.ts +74 -0
  185. package/src/types.ts +919 -0
  186. package/.editorconfig +0 -15
  187. package/.eslintrc.js +0 -4
  188. package/.prettierrc +0 -16
  189. package/CHANGELOG.md +0 -270
  190. package/CODE-OF-CONDUCT.md +0 -85
  191. package/CONTRIBUTING.md +0 -15
  192. package/FUNDING.yml +0 -4
  193. package/build/AllHoverViews.d.ts +0 -0
  194. package/build/AllHoverViews.js +0 -30
  195. package/build/DraxContext.d.ts +0 -2
  196. package/build/DraxContext.js +0 -6
  197. package/build/DraxList.d.ts +0 -8
  198. package/build/DraxList.js +0 -512
  199. package/build/DraxListItem.d.ts +0 -7
  200. package/build/DraxListItem.js +0 -121
  201. package/build/DraxProvider.d.ts +0 -2
  202. package/build/DraxProvider.js +0 -704
  203. package/build/DraxScrollView.d.ts +0 -6
  204. package/build/DraxScrollView.js +0 -136
  205. package/build/DraxSubprovider.d.ts +0 -3
  206. package/build/DraxSubprovider.js +0 -18
  207. package/build/DraxView.d.ts +0 -8
  208. package/build/DraxView.js +0 -93
  209. package/build/HoverView.d.ts +0 -8
  210. package/build/HoverView.js +0 -40
  211. package/build/PanGestureDetector.d.ts +0 -3
  212. package/build/PanGestureDetector.js +0 -49
  213. package/build/hooks/index.d.ts +0 -4
  214. package/build/hooks/index.js +0 -11
  215. package/build/hooks/useContent.d.ts +0 -23
  216. package/build/hooks/useContent.js +0 -212
  217. package/build/hooks/useDraxContext.d.ts +0 -1
  218. package/build/hooks/useDraxContext.js +0 -13
  219. package/build/hooks/useDraxId.js +0 -13
  220. package/build/hooks/useDraxProtocol.d.ts +0 -5
  221. package/build/hooks/useDraxProtocol.js +0 -32
  222. package/build/hooks/useDraxRegistry.d.ts +0 -78
  223. package/build/hooks/useDraxRegistry.js +0 -714
  224. package/build/hooks/useDraxScrollHandler.d.ts +0 -25
  225. package/build/hooks/useDraxScrollHandler.js +0 -89
  226. package/build/hooks/useDraxState.d.ts +0 -10
  227. package/build/hooks/useDraxState.js +0 -132
  228. package/build/hooks/useMeasurements.d.ts +0 -9
  229. package/build/hooks/useMeasurements.js +0 -119
  230. package/build/hooks/useStatus.d.ts +0 -11
  231. package/build/hooks/useStatus.js +0 -96
  232. package/build/index.d.ts +0 -9
  233. package/build/index.js +0 -33
  234. package/build/math.d.ts +0 -22
  235. package/build/math.js +0 -68
  236. package/build/params.js +0 -27
  237. package/build/transform.d.ts +0 -11
  238. package/build/transform.js +0 -59
  239. package/build/types.d.ts +0 -807
  240. package/build/types.js +0 -46
  241. package/docs/concept.md +0 -79
  242. package/docs/images/color-drag-drop.gif +0 -0
  243. package/docs/images/deck-cards.gif +0 -0
  244. package/docs/images/drag-drop-events.jpg +0 -0
  245. package/docs/images/knight-moves.gif +0 -0
  246. package/docs/images/reorderable-list.gif +0 -0
package/README.md CHANGED
@@ -1,291 +1,449 @@
1
1
  # react-native-drax
2
2
 
3
- **A drag-and-drop system for React Native**
3
+ **A drag-and-drop framework for React Native**
4
4
 
5
- *"Not to be confused with react-native-picksaw"*
5
+ [![React Native CLI](https://img.shields.io/badge/-React%20Native%20CLI-282C34?style=flat-square&logo=react&logoColor=61DAFB)](https://reactnative.dev/)
6
+ [![Expo CLI](https://img.shields.io/badge/-Expo%20CLI-282C34?style=flat-square&logo=expo&logoColor=white)](https://expo.dev/)
7
+ [![platforms](https://img.shields.io/badge/platforms-Android%20%7C%20iOS%20%7C%20Web-brightgreen.svg?style=flat-square&colorB=191A17)](https://necolas.github.io/react-native-web/)
8
+ [![GitHub top language](https://img.shields.io/github/languages/top/nuclearpasta/react-native-drax?style=flat-square)](https://github.com/nuclearpasta/react-native-drax/search?l=typescript)
9
+ [![CI](https://github.com/nuclearpasta/react-native-drax/actions/workflows/ci.yml/badge.svg)](https://github.com/nuclearpasta/react-native-drax/actions/workflows/ci.yml)
10
+ [![GitHub license](https://img.shields.io/github/license/nuclearpasta/react-native-drax?style=flat-square)](https://github.com/nuclearpasta/react-native-drax/blob/main/LICENSE.md)
11
+ [![npm version](https://img.shields.io/npm/v/react-native-drax?style=flat-square)](https://www.npmjs.com/package/react-native-drax)
6
12
 
7
- [![npm version](https://badge.fury.io/js/react-native-drax.svg)](https://badge.fury.io/js/react-native-drax)
8
- [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v2.0%20adopted-ff69b4.svg)](CODE-OF-CONDUCT.md)
9
13
 
10
- ## Overview
14
+ [Docs](https://nuclearpasta.com/react-native-drax) | [Live Example](https://nuclearpasta.com/react-native-drax/example)
11
15
 
12
- Drax is a declarative drag-and-drop system for React Native, written in TypeScript. It is designed to be flexible and powerful with the goal of supporting many use cases, while its stock components and default settings should cover the most common scenarios with minimal configuration.
16
+ ## πŸ“– Overview
13
17
 
14
- **Note: We currently only support the latest Expo and React Native versions. Other older version might work just fine, but we won't respond to bug reports or feature requests for them.**
18
+ Drax is a declarative drag-and-drop framework for React Native, written in TypeScript. It supports free-form drag-and-drop, sortable lists and grids, cross-list reorder, drag handles, collision algorithms, and more.
15
19
 
16
- ### Experimental Alpha Version (v0.11.0)
20
+ Built on [Reanimated 4](https://docs.swmansion.com/react-native-reanimated/) and [Gesture Handler 3](https://docs.swmansion.com/react-native-gesture-handler/) with a UI-thread-first architecture for smooth 60fps interactions.
17
21
 
18
- An experimental alpha version is now available that introduces significant updates and breaking changes. This version focuses on:
22
+ **Platforms:** iOS, Android, Web
19
23
 
20
- - Integration with latest React Native Reanimated and React Native Gesture Handler by SoftwareMansion
21
- - Enhanced animation performance and capabilities
22
- - Works with New Architecture
24
+ ### ✨ Highlights
23
25
 
24
- **Installation:** To install the experimental alpha version:
26
+ - πŸ“‹ **List-agnostic sortable** β€” works with FlatList, FlashList, LegendList, or any list component
27
+ - πŸ”€ **Cross-container drag** β€” move items between lists (cross-list reorder)
28
+ - ⚑ **UI-thread hit-testing** β€” spatial index worklet for fast receiver detection
29
+ - ✊ **Drag handles** β€” only the handle starts a drag, the rest scrolls
30
+ - πŸ’₯ **Collision algorithms** β€” center, intersect, or contain
31
+ - πŸ“ **Drag bounds** β€” constrain drags within a view
32
+ - 🎨 **Hover styles** β€” conditional styles based on drag phase and receiver state
33
+ - 🚫 **Drop zone acceptance** β€” accept or reject drops with `acceptsDrag`
34
+ - 🎬 **Animation presets** β€” default, spring, gentle, snappy, none β€” or custom config
35
+ - 🧲 **Snap alignment** β€” snap to 9-point alignment within receivers
36
+ - β™Ώ **Accessibility** β€” auto-generated labels, reduced motion support
37
+ - πŸ“‘ **19 callback events** β€” full drag lifecycle control
38
+ - πŸ—οΈ **New Architecture** compatible (Fabric)
25
39
 
26
- ```bash
27
- # npm
28
- npm install react-native-drax@alpha
40
+ ### πŸ€” Why Drax?
41
+
42
+ | Feature | Drax | reanimated-dnd | sortables |
43
+ |---|:---:|:---:|:---:|
44
+ | Free-form drag & drop | βœ… | βœ… | βž– |
45
+ | Sortable list / grid | βœ… | βœ… | βœ… |
46
+ | Cross-container / cross-list reorder | ⚠️ Experimental | βž– | βž– |
47
+ | List-agnostic (FlatList, FlashList, LegendList) | βœ… | βž– | βž– |
48
+ | Drag handles | βœ… | βœ… | βœ… |
49
+ | Drag state styling | 15 props + inactive | onStateChange | 5 props + hook |
50
+ | Drop indicator | βœ… | βž– | Grid only |
51
+ | UI-thread DnD collision | βœ… | βž– | βž– |
52
+ | Event callbacks | 19 types | ~12 types | ~10 types |
53
+ | Accessibility + reduced motion | βœ… | Manual | Manual |
54
+ | Web support | βœ… | βž– | Partial |
55
+ | Reanimated | 4 | β‰₯ 4.2 | β‰₯ 3 |
56
+
57
+ [See full comparison β†’](https://nuclearpasta.com/react-native-drax#comparison)
58
+
59
+ ## πŸ“¦ Installation
29
60
 
30
- # or yarn
31
- yarn add react-native-drax@alpha
61
+ ```bash
62
+ npm install react-native-drax
63
+ # or
64
+ yarn add react-native-drax
32
65
  ```
33
66
 
34
- You'll also need to ensure you have the required peer dependencies:
67
+ ### πŸ”— Peer Dependencies
35
68
 
36
69
  ```bash
37
- yarn add react-native-reanimated react-native-gesture-handler
70
+ npm install react-native-reanimated react-native-gesture-handler
71
+ ```
72
+
73
+ | Peer Dependency | Version |
74
+ |---|---|
75
+ | `react` | >= 18 |
76
+ | `react-native` | >= 0.68 |
77
+ | `react-native-reanimated` | ^4.0.0 |
78
+ | `react-native-gesture-handler` | >= 2.0.0 (v3 recommended) |
79
+
80
+ ## πŸš€ Quick Start
81
+
82
+ ### πŸ‘‹ Basic Drag-and-Drop
83
+
84
+ ```tsx
85
+ import { DraxProvider, DraxView } from 'react-native-drax';
86
+
87
+ function App() {
88
+ return (
89
+ <DraxProvider>
90
+ <DraxView
91
+ style={{ width: 100, height: 100, backgroundColor: 'blue' }}
92
+ onDragStart={() => console.log('dragging')}
93
+ payload="hello"
94
+ />
95
+ <DraxView
96
+ style={{ width: 100, height: 100, backgroundColor: 'green' }}
97
+ onReceiveDragDrop={({ dragged: { payload } }) => {
98
+ console.log(`received: ${payload}`);
99
+ }}
100
+ />
101
+ </DraxProvider>
102
+ );
103
+ }
38
104
  ```
39
105
 
40
- **Important:** This alpha version contains breaking changes, especially to the `DraxList` component. See the [Alpha Version Breaking Changes](#alpha-version-breaking-changes) section for details.
41
-
42
- *Personal note from Joe: this project is in need of additional [contributors/shepherds](#contributing). I have not been focused on React Native over the past year, and the state of the library has fallen behind the times. At a minimum, it should be updated to use the latest RNGH and take advantage of any fixes and new features in that and RN. I apologize that I do not have the availability to maintain this project to my own high standards and thank everyone who has been understanding of that.*
43
-
44
- #### Contents
45
-
46
- * [Screenshots](#screenshots)
47
- * [Status](#status)
48
- * [Alpha Version Breaking Changes](#alpha-version-breaking-changes)
49
- * [Background](#background)
50
- * [Concept](#concept)
51
- * [Installation](#installation)
52
- * [Usage](#usage)
53
- * [Caveats](#caveats)
54
- * [Examples](#examples)
55
- * [Contributing](#contributing)
56
- * [Code of Conduct](#code-of-conduct)
57
- * [License](#license)
58
- * [Acknowledgments](#acknowledgments)
59
-
60
- <a name="screenshots"></a>
61
- ## Screenshots
62
-
63
- <a href="docs/images/color-drag-drop.gif"><img src="docs/images/color-drag-drop.gif" width="200" alt="Color Drag-and-Drop" /></a>
64
- <a href="docs/images/reorderable-list.gif"><img src="docs/images/reorderable-list.gif" width="200" alt="Reorderable List" /></a>
65
- <a href="docs/images/knight-moves.gif"><img src="docs/images/knight-moves.gif" width="200" alt="Knight Moves" /></a>
66
- <a href="docs/images/deck-cards.gif"><img src="docs/images/deck-cards.gif" width="200" alt="Knight Moves" /></a>
67
-
68
- (Click images to see larger versions.)
69
-
70
- <a name="status"></a>
71
- ## Status
72
-
73
- This library adheres to [Semantic Versioning (semver)](https://semver.org/) and is in its [0.y.z initial development phase](https://semver.org/#how-should-i-deal-with-revisions-in-the-0yz-initial-development-phase). It has been released so that early adopters (such as the project author) can begin to use it in production and identify gaps in the functionality. The API is subject to potentially significant rework until version 1.0.0 is released, and any minor version increment before then may include breaking changes. Documentation and full examples are still being written.
74
-
75
- The author of this library has not had significant availability to work on it for quite a while now, due to higher priority life and work concerns. Newer versions of Drax's major dependencies have been released in that time, and many people have opened issues asking questions about usage and potential features. Relatively small fixes and easy questions are handled reasonably often, but ultimately another round of research, testing, and architecture are what would take this library to the next level of usability. It is not clear when that might happen, but [contributors are welcome](#contributing).
76
-
77
- <a name="alpha-version-breaking-changes"></a>
78
- ## Alpha Version Breaking Changes
79
-
80
- The experimental alpha version (v0.11.0) includes significant updates to modernize the library and improve performance. However, these changes introduce breaking changes, particularly to the `DraxList` component.
81
-
82
- ### DraxList Breaking Changes
83
-
84
- - `renderItem` property signature receives different props than before and has replaced `renderItemContent` and `renderHoverContent`
85
- - Receives incoming external drag items inside the list.
86
- - Added `monitoringExternalDragStyle` prop for styling during incoming external drags
87
- - `parentDraxViewProps` prop for customizing the parent DraxView wrapping the FlatList. You should use this prop if you were using the `style` prop on `DraxList`. (see example below)
88
-
89
- ### DraxListItem Component
90
-
91
- The alpha version introduces a new `DraxListItem` component that works with `DraxList` to simplify implementation of reorderable lists. This component handles animations, measurement caching, and shift calculations internally.
92
-
93
- #### Usage Example
94
-
95
- ```jsx
96
- import { DraxList, DraxListItem } from 'react-native-drax';
97
-
98
- const MyReorderableList = () => (
99
- <DraxList
100
- data={items}
101
- // BREAKING CHANGE: `style` prop is now applied to internal FlatList, not to the parent DraxView
102
- style={styles.list}
103
-
104
- // should use this prop if you were using the `style` prop on `DraxList` on v0.10.3.
105
- parentDraxViewProps={{
106
- style: styles.list,
107
- }}
108
- renderItem={(info, itemProps) => (
109
- <DraxListItem
110
- itemProps={itemProps}
111
- style={styles.listItem}
112
- draggingStyle={styles.itemDragging}
113
- dragReleasedStyle={styles.itemReleased}
114
- // Any other DraxView props
115
- >
116
- <Text>{info.item.text}</Text>
117
- </DraxListItem>
118
- )}
119
- onItemReorder={({fromIndex, toIndex}) => {
120
- // Update your data here
121
- const newData = [...items];
122
- const item = newData.splice(fromIndex, 1)[0];
123
- newData.splice(toIndex, 0, item);
124
- setItems(newData);
125
- }}
126
- />
127
- );
106
+ ### πŸ“‹ Sortable List
107
+
108
+ The simplest way to make a reorderable list:
109
+
110
+ ```tsx
111
+ import { useState } from 'react';
112
+ import { Text, View } from 'react-native';
113
+ import { DraxProvider, DraxList } from 'react-native-drax';
114
+
115
+ function App() {
116
+ const [items, setItems] = useState(['A', 'B', 'C', 'D', 'E']);
117
+
118
+ return (
119
+ <DraxProvider>
120
+ <DraxList
121
+ data={items}
122
+ keyExtractor={(item) => item}
123
+ onReorder={({ data }) => setItems(data)}
124
+ renderItem={({ item }) => (
125
+ <View style={{ padding: 16, backgroundColor: '#eee', margin: 4 }}>
126
+ <Text>{item}</Text>
127
+ </View>
128
+ )}
129
+ />
130
+ </DraxProvider>
131
+ );
132
+ }
128
133
  ```
129
134
 
130
- <a name="background"></a>
131
- ## Background
135
+ `DraxList` is list-agnostic β€” pass any list component via the `component` prop:
132
136
 
133
- To give an idea of the problem this library is trying to solve, here is some informal background:
137
+ ```tsx
138
+ import { FlashList } from '@shopify/flash-list';
139
+
140
+ <DraxList
141
+ component={FlashList}
142
+ data={items}
143
+ keyExtractor={(item) => item.id}
144
+ onReorder={({ data }) => setItems(data)}
145
+ renderItem={({ item }) => <ItemCard item={item} />}
146
+ estimatedItemSize={60}
147
+ />
148
+ ```
134
149
 
135
- > In our React Native application we had a screen which showed a
136
- > FlatList of cards that could be scrolled through or individually
137
- > tapped to view details. We wanted to add the ability for a user
138
- > to long-press a card then drag it into a different position in
139
- > the list; in other words, we needed a reorderable list.
140
- >
141
- > I figured there must already be a library out there that would
142
- > suit our needs. I tried out a few different packages, which each
143
- > looked to have pros and cons, but nothing quite worked right how
144
- > we expected. To complicate things further, our application used
145
- > `react-navigation`, which seemed to conflict with some of them.
146
- >
147
- > We also had future features on our roadmap which would necessitate
148
- > a more generic drag-and-drop solution. I found it a bit odd that,
149
- > although reorderable lists and drag-and-drop have much functional
150
- > overlap, there didn't seem to be a package for React Native which
151
- > did both. It looked like React for the web was a little more mature
152
- > in this arena, but that didn't help us. I asked some other
153
- > developers if they knew of a solid React Native library for this,
154
- > but they agreed that it was a gap in the ecosystem.
155
- >
156
- > I decided to create my own drag-and-drop library, including
157
- > stock components for common behaviors. The goal, first and
158
- > foremost, was to fulfill our draggable reorderable list wish.
159
- > But beyond that, I wanted a robust foundation that could be
160
- > used to flexibly implement various drag-and-drop-related
161
- > solutions. I am sure that there are scenarios I have not
162
- > yet considered, and I am open to input from other people
163
- > who are working in this space.
150
+ ### 🧱 Composable API
164
151
 
165
- <a name="concept"></a>
166
- ## Concept
152
+ For full control, use the composable primitives directly:
153
+
154
+ ```tsx
155
+ import {
156
+ DraxProvider,
157
+ useSortableList,
158
+ SortableContainer,
159
+ SortableItem,
160
+ } from 'react-native-drax';
161
+ import { FlatList } from 'react-native';
162
+
163
+ function App() {
164
+ const [items, setItems] = useState(['A', 'B', 'C', 'D', 'E']);
165
+ const listRef = useRef<FlatList>(null);
166
+
167
+ const sortable = useSortableList({
168
+ data: items,
169
+ keyExtractor: (item) => item,
170
+ onReorder: ({ data }) => setItems(data),
171
+ });
172
+
173
+ return (
174
+ <DraxProvider>
175
+ <SortableContainer sortable={sortable} scrollRef={listRef}>
176
+ <FlatList
177
+ ref={listRef}
178
+ data={sortable.data}
179
+ keyExtractor={sortable.stableKeyExtractor}
180
+ onScroll={sortable.onScroll}
181
+ onContentSizeChange={sortable.onContentSizeChange}
182
+ renderItem={({ item, index }) => (
183
+ <SortableItem sortable={sortable} index={index}>
184
+ <Text>{item}</Text>
185
+ </SortableItem>
186
+ )}
187
+ />
188
+ </SortableContainer>
189
+ </DraxProvider>
190
+ );
191
+ }
192
+ ```
167
193
 
168
- Descriptions of the library's approach, underlying implementation, and drag-and-drop event lifecycle can be found in the [Concept Document](docs/concept.md).
194
+ This pattern works with any list component β€” FlatList, FlashList, LegendList, ScrollView, etc.
169
195
 
170
- <a name="installation"></a>
171
- ## Installation
196
+ ## πŸŽ› Features
172
197
 
173
- First you must have a project using `react-native` version `>=0.62`, including `react-native-gesture-handler` version `>=1.8.0`. For further information on installing the latter, see [that library's documentation](https://software-mansion.github.io/react-native-gesture-handler/docs/getting-started.html).
198
+ ### ✊ Drag Handles
174
199
 
175
- Then simply install Drax with:
200
+ Only the handle area starts a drag β€” the rest of the view scrolls normally:
176
201
 
177
- `yarn add react-native-drax`
202
+ ```tsx
203
+ import { DraxView, DraxHandle } from 'react-native-drax';
204
+
205
+ <DraxView dragHandle>
206
+ <Text>This content scrolls normally</Text>
207
+ <DraxHandle>
208
+ <GripIcon /> {/* Only this starts a drag */}
209
+ </DraxHandle>
210
+ </DraxView>
211
+ ```
178
212
 
179
- or
213
+ ### πŸ“ Drag Bounds
180
214
 
181
- `npm install react-native-drax`
215
+ Constrain a dragged view within a boundary:
182
216
 
183
- There is no Cocoapods or native linking step here. You've already covered those needs with `react-native-gesture-handler`.
217
+ ```tsx
218
+ const boundsRef = useRef<View>(null);
184
219
 
185
- <a name="usage"></a>
186
- ## Usage
220
+ <View ref={boundsRef} style={{ flex: 1 }}>
221
+ <DraxView dragBoundsRef={boundsRef}>
222
+ <Text>I can only be dragged within the parent</Text>
223
+ </DraxView>
224
+ </View>
225
+ ```
187
226
 
188
- ### Basic Usage
227
+ ### πŸ’₯ Collision Algorithms
189
228
 
190
- Import the library components:
229
+ Control how receiver detection works:
191
230
 
192
- ```ts
193
- import { DraxProvider, DraxView } from 'react-native-drax';
231
+ ```tsx
232
+ <DraxView collisionAlgorithm="center" /> {/* hover center inside receiver (default) */}
233
+ <DraxView collisionAlgorithm="intersect" /> {/* any overlap triggers receiving */}
234
+ <DraxView collisionAlgorithm="contain" /> {/* dragged view must be fully inside */}
194
235
  ```
195
236
 
196
- Wrap the area of your app that will use Drax with a `DraxProvider`, and create a couple `DraxView`s, one draggable and one receptive:
237
+ ### 🚫 Drop Zone Acceptance
238
+
239
+ Accept or reject drops conditionally:
197
240
 
198
241
  ```tsx
199
- <DraxProvider>
200
- <View style={styles.container}>
201
- <DraxView
202
- style={styles.draggable}
203
- onDragStart={() => {
204
- console.log('start drag');
205
- }}
206
- payload="world"
207
- />
208
- <DraxView
209
- style={styles.receiver}
210
- onReceiveDragEnter={({ dragged: { payload } }) => {
211
- console.log(`hello ${payload}`);
212
- }}
213
- onReceiveDragExit={({ dragged: { payload } }) => {
214
- console.log(`goodbye ${payload}`);
215
- }}
216
- onReceiveDragDrop={({ dragged: { payload } }) => {
217
- console.log(`received ${payload}`);
218
- }}
219
- />
220
- </View>
221
- </DraxProvider>
242
+ <DraxView
243
+ acceptsDrag={(draggedPayload) => items.length < 5}
244
+ onReceiveDragDrop={({ dragged }) => addItem(dragged.payload)}
245
+ />
246
+ ```
247
+
248
+ ### 🎨 Hover Styles
249
+
250
+ Style the hover layer based on drag state:
251
+
252
+ ```tsx
253
+ <DraxView
254
+ hoverStyle={{ opacity: 0.8 }}
255
+ hoverDraggingWithReceiverStyle={{ borderColor: 'green', borderWidth: 2 }}
256
+ hoverDraggingWithoutReceiverStyle={{ opacity: 0.5 }}
257
+ hoverDragReleasedStyle={{ opacity: 0.3 }}
258
+ />
259
+ ```
260
+
261
+ ### 🧲 Snap Alignment
262
+
263
+ Snap dropped items to specific positions within a receiver:
264
+
265
+ ```tsx
266
+ import { snapToAlignment } from 'react-native-drax';
267
+
268
+ <DraxView
269
+ onReceiveDragDrop={({ dragged, receiver }) =>
270
+ snapToAlignment(receiver, dragged, 'top-left', { x: 8, y: 8 })
271
+ }
272
+ />
273
+ ```
274
+
275
+ Alignments: `center`, `top-left`, `top-center`, `top-right`, `center-left`, `center-right`, `bottom-left`, `bottom-center`, `bottom-right`
276
+
277
+ ### 🎬 Animation Presets
278
+
279
+ ```tsx
280
+ <DraxList animationConfig="spring" /> {/* spring physics */}
281
+ <DraxList animationConfig="gentle" /> {/* soft spring */}
282
+ <DraxList animationConfig="snappy" /> {/* fast spring */}
283
+ <DraxList animationConfig="none" /> {/* instant */}
284
+
285
+ {/* Or custom: */}
286
+ <DraxList animationConfig={{
287
+ useSpring: true,
288
+ springDamping: 15,
289
+ springStiffness: 150,
290
+ springMass: 1,
291
+ }} />
292
+ ```
293
+
294
+ Device reduced motion settings are respected automatically.
295
+
296
+ ### πŸ“‘ Continuous Drag Callbacks
297
+
298
+ ```tsx
299
+ <DraxView
300
+ onDrag={(data) => { /* fires every frame while dragging over empty space */ }}
301
+ onDragOver={(data) => { /* fires every frame while over the same receiver */ }}
302
+ />
222
303
  ```
223
304
 
224
- The styles are provided here for completeness:
225
-
226
- ```ts
227
- const styles = StyleSheet.create({
228
- container: {
229
- flex: 1,
230
- justifyContent: 'center',
231
- alignItems: 'center',
232
- },
233
- draggable: {
234
- width: 100,
235
- height: 100,
236
- backgroundColor: 'blue',
237
- },
238
- receiver: {
239
- width: 100,
240
- height: 100,
241
- backgroundColor: 'green',
242
- },
305
+ ### πŸ”€ Cross-Container Sortable (Experimental)
306
+
307
+ Move items between lists (cross-list reorder):
308
+
309
+ ```tsx
310
+ import {
311
+ useSortableBoard,
312
+ SortableBoardContainer,
313
+ useSortableList,
314
+ SortableContainer,
315
+ SortableItem,
316
+ } from 'react-native-drax';
317
+
318
+ const board = useSortableBoard({
319
+ onTransfer: ({ fromColumnId, toColumnId, fromIndex, toIndex, item }) => {
320
+ // Move item between columns
321
+ },
243
322
  });
323
+
324
+ <SortableBoardContainer board={board}>
325
+ {columns.map((column) => (
326
+ <Column key={column.id} board={board} column={column} />
327
+ ))}
328
+ </SortableBoardContainer>
244
329
  ```
245
330
 
246
- This will give you a blue box which can be dragged around and a green box which it can be dragged into. Watch the console log messages while you drag the blue box around, releasing the drag either in or out of the green box.
331
+ > **Note:** Cross-container drag is experimental. The API may change in future versions.
247
332
 
248
- ### API
333
+ ### 🏷️ Namespace API
249
334
 
250
- *Full API description coming soon*
335
+ For convenience, all components are available under the `Drax` namespace:
336
+
337
+ ```tsx
338
+ import { Drax } from 'react-native-drax';
339
+
340
+ <Drax.Provider>
341
+ <Drax.View draggable>
342
+ <Drax.Handle><GripIcon /></Drax.Handle>
343
+ </Drax.View>
344
+ </Drax.Provider>
345
+ ```
346
+
347
+ ## 🧩 Components
348
+
349
+ | Component | Description |
350
+ |---|---|
351
+ | `DraxProvider` | Context provider β€” wrap your app's drag-and-drop area |
352
+ | `DraxView` | Draggable and/or receptive view with 19 callback events |
353
+ | `DraxList` | List-agnostic sortable list (convenience wrapper) |
354
+ | `DraxHandle` | Drag handle β€” only this area starts a drag |
355
+ | `DraxScrollView` | Scrollable container with auto-scroll during drag |
356
+ | `SortableContainer` | Monitoring wrapper for composable sortable API |
357
+ | `SortableItem` | Per-item wrapper with shift animation |
358
+ | `SortableBoardContainer` | Cross-container board coordinator (experimental) |
359
+
360
+ ## πŸͺ Hooks
361
+
362
+ | Hook | Description |
363
+ |---|---|
364
+ | `useSortableList` | List-agnostic reorder state management |
365
+ | `useSortableBoard` | Cross-container board coordinator (experimental) |
366
+ | `useDraxContext` | Access the Drax context |
367
+ | `useDraxId` | Generate a unique Drax view ID |
368
+
369
+ ## πŸ’‘ Examples
370
+
371
+ The `example/` directory contains an Expo Router app with 10 screens demonstrating all features:
372
+
373
+ | Screen | Features shown |
374
+ |---|---|
375
+ | Color Drag & Drop | Drop acceptance, hover styles, snap alignment |
376
+ | Reorderable List | DraxList, animation presets, auto-scroll |
377
+ | Reorderable Grid | Sortable grid with multi-column layout |
378
+ | Drag Handles | Only the grip icon starts a drag |
379
+ | Drag Bounds | Constrain drag within a view |
380
+ | Collision Modes | Center vs Intersect vs Contain |
381
+ | Cross-List Reorder | FlashList + LegendList + FlatList cross-container drag (experimental) |
382
+ | Knight Moves | Chess knight drag puzzle |
383
+ | Scrolling | Drag from scroll view to drop zone |
384
+ | Stress Test | 100 items in a sortable list |
385
+
386
+ To run the example app:
387
+
388
+ ```bash
389
+ cd example && yarn start
390
+ ```
251
391
 
252
- <a name="caveats"></a>
253
- ## Caveats
392
+ ## πŸ”„ Migration from v0.x
254
393
 
255
- This library has several [known issues and limitations](https://github.com/nuclearpasta/react-native-drax/issues?q=is%3Aissue+is%3Aopen+label%3Areproduced), particularly around the [Android](https://github.com/nuclearpasta/react-native-drax/issues?q=is%3Aissue+is%3Aopen+label%3Aandroid) platform. We hope to address these and improve the library over time. For most use cases, the current functionality is probably fine.
394
+ v1.0.0 is a complete rewrite. Key changes:
256
395
 
257
- This library currently expects React Native >=0.62 and React Native Gesture Handler >=1.8. Due to complexity, we cannot support the use of the library with older versions.
396
+ - **`DraxList` is new** β€” list-agnostic convenience wrapper using the new sortable architecture. The old `DraxList` / `DraxListItem` API from v0.10.x and v0.11.0-alpha is removed.
397
+ - **New sortable architecture** β€” `useSortableList` + `SortableContainer` + `SortableItem` composable API replaces the old array-indexed approach.
398
+ - **Reanimated 4 + Gesture Handler 3** β€” required peer dependencies (Gesture Handler v2 supported via compat layer with reduced performance).
399
+ - **New Architecture (Fabric)** compatible.
258
400
 
259
- <a name="examples"></a>
260
- ## Examples
401
+ ## πŸ“‹ Changelog
261
402
 
262
- A reference application can be found at [`react-native-drax-example`](https://github.com/nuclearpasta/react-native-drax-example) demonstrating several use cases.
403
+ See [CHANGELOG.md](CHANGELOG.md) for a full list of changes.
263
404
 
264
- If you don't want to download and run the sample application, here are two Snack examples:
405
+ ## 🀝 Contributing
265
406
 
266
- - [Basic drag-and-drop](https://snack.expo.io/@lafiosca/react-native-drax---basic-drag-and-drop?platform=ios)
267
- - [Basic reorderable list](https://snack.expo.io/@lafiosca/react-native-drax---basic-reorderable-list?platform=ios)
407
+ Issues, pull requests, and discussion are all welcome. See the [Contribution Guidelines](CONTRIBUTING.md) for details.
268
408
 
269
- Note: these Snack examples will not work in the Web device. You must use an iOS (default) or Android device.
409
+ ## πŸ“œ Code of Conduct
270
410
 
271
- <a name="contributing"></a>
272
- ## Contributing
411
+ This project is released with a [Contributor Code of Conduct](CODE-OF-CONDUCT.md). By participating in this project you agree to abide by its terms.
273
412
 
274
- Issues, pull request, and discussion are all welcome. See the [Contribution Guidelines](CONTRIBUTING.md) for details, and please reach out to [the author](https://github.com/lafiosca) if you would like to participate more significantly.
413
+ ## πŸ† Contributors
275
414
 
276
- <a name="code-of-conduct"></a>
277
- ## Code of Conduct
415
+ Originally created by [Joe Lafiosca](https://github.com/lafiosca). v1.0.0 rewrite led by [Ovidiu Cristescu](https://github.com/LunatiqueCoder).
278
416
 
279
- Please note that this project is released with a [Contributor Code of Conduct](CODE-OF-CONDUCT.md). By participating in this project you agree to abide by its terms.
417
+ Thanks to all contributors who have helped make Drax better:
280
418
 
281
- <a name="license"></a>
282
- ## License
419
+ <!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
420
+ <!-- prettier-ignore-start -->
421
+ <!-- markdownlint-disable -->
422
+ <table>
423
+ <tbody>
424
+ <tr>
425
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/lafiosca"><img src="https://avatars.githubusercontent.com/u/9442662?v=4" width="100px;" alt="Joe Lafiosca"/><br /><sub><b>Joe Lafiosca</b></sub></a><br /><a href="https://github.com/nuclearpasta/react-native-drax/commits?author=lafiosca" title="Code">πŸ’»</a> <a href="https://github.com/nuclearpasta/react-native-drax/commits?author=lafiosca" title="Documentation">πŸ“–</a> <a href="#example-lafiosca" title="Examples">πŸ’‘</a> <a href="#maintenance-lafiosca" title="Maintenance">🚧</a> <a href="#infra-lafiosca" title="Infrastructure">πŸš‡</a></td>
426
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/LunatiqueCoder"><img src="https://avatars.githubusercontent.com/u/55203625?v=4" width="100px;" alt="Ovidiu Cristescu"/><br /><sub><b>Ovidiu Cristescu</b></sub></a><br /><a href="https://github.com/nuclearpasta/react-native-drax/commits?author=LunatiqueCoder" title="Code">πŸ’»</a> <a href="https://github.com/nuclearpasta/react-native-drax/commits?author=LunatiqueCoder" title="Documentation">πŸ“–</a> <a href="#example-LunatiqueCoder" title="Examples">πŸ’‘</a> <a href="#maintenance-LunatiqueCoder" title="Maintenance">🚧</a></td>
427
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/Auticiel"><img src="https://avatars.githubusercontent.com/u/8429221?v=4" width="100px;" alt="FranΓ§ois Dupayrat"/><br /><sub><b>FranΓ§ois Dupayrat</b></sub></a><br /><a href="https://github.com/nuclearpasta/react-native-drax/commits?author=Auticiel" title="Code">πŸ’»</a></td>
428
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/jmarnold"><img src="https://avatars.githubusercontent.com/u/181667?v=4" width="100px;" alt="Josh Arnold"/><br /><sub><b>Josh Arnold</b></sub></a><br /><a href="https://github.com/nuclearpasta/react-native-drax/commits?author=jmarnold" title="Code">πŸ’»</a></td>
429
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/rnz269"><img src="https://avatars.githubusercontent.com/u/20953181?v=4" width="100px;" alt="Rahul Nallappa"/><br /><sub><b>Rahul Nallappa</b></sub></a><br /><a href="https://github.com/nuclearpasta/react-native-drax/commits?author=rnz269" title="Code">πŸ’»</a></td>
430
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/negue"><img src="https://avatars.githubusercontent.com/u/842273?v=4" width="100px;" alt="negue"/><br /><sub><b>negue</b></sub></a><br /><a href="https://github.com/nuclearpasta/react-native-drax/commits?author=negue" title="Documentation">πŸ“–</a></td>
431
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/chrisdrackett"><img src="https://avatars.githubusercontent.com/u/4378?v=4" width="100px;" alt="Chris Drackett"/><br /><sub><b>Chris Drackett</b></sub></a><br /><a href="https://github.com/nuclearpasta/react-native-drax/commits?author=chrisdrackett" title="Code">πŸ’»</a></td>
432
+ </tr>
433
+ <tr>
434
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/sturdynut"><img src="https://avatars.githubusercontent.com/u/8547391?v=4" width="100px;" alt="Matti Salokangas"/><br /><sub><b>Matti Salokangas</b></sub></a><br /><a href="https://github.com/nuclearpasta/react-native-drax/commits?author=sturdynut" title="Code">πŸ’»</a></td>
435
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/afgarcia86"><img src="https://avatars.githubusercontent.com/u/3606053?v=4" width="100px;" alt="Andres Garcia"/><br /><sub><b>Andres Garcia</b></sub></a><br /><a href="https://github.com/nuclearpasta/react-native-drax/commits?author=afgarcia86" title="Code">πŸ’»</a></td>
436
+ </tr>
437
+ </tbody>
438
+ </table>
439
+ <!-- markdownlint-restore -->
440
+ <!-- prettier-ignore-end -->
441
+ <!-- ALL-CONTRIBUTORS-LIST:END -->
283
442
 
284
- This software library is licensed under the [MIT License](LICENSE.md).
443
+ ## πŸ“ƒ License
285
444
 
286
- <a name="acknowledgements"></a>
287
- ## Acknowledgments
445
+ [MIT](LICENSE.md)
288
446
 
289
- The initial version of this library was written by [Joe Lafiosca](https://github.com/lafiosca) over the course of December 2019. Joe would like to give thanks to Nuclear Pasta co-founder Mark Thomas for being patient with the development process. Joe would also like to give thanks to Lena Raine, Tom Jenkinson, Rollie Pemberton, David Minnick, Tim Smith, and Danny Baranowsky for providing most of the coding background music that inspired this work.
447
+ ---
290
448
 
291
- Special thanks go to the folks who have contributed donations toward this project. (If you are a sponsor and would like your name listed here, please let me know! I do not want to make assumptions about people's privacy preferences.)
449
+ Built and maintained using [OpenKit](https://www.openkit.work/).