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.
- package/LICENSE.md +1 -1
- package/README.md +385 -227
- package/lib/module/DebugOverlay.js +121 -0
- package/lib/module/DebugOverlay.js.map +1 -0
- package/lib/module/Drax.js +36 -0
- package/lib/module/Drax.js.map +1 -0
- package/lib/module/DraxContext.js +6 -0
- package/lib/module/DraxContext.js.map +1 -0
- package/lib/module/DraxHandle.js +47 -0
- package/lib/module/DraxHandle.js.map +1 -0
- package/lib/module/DraxHandleContext.js +11 -0
- package/lib/module/DraxHandleContext.js.map +1 -0
- package/lib/module/DraxList.js +108 -0
- package/lib/module/DraxList.js.map +1 -0
- package/lib/module/DraxProvider.js +203 -0
- package/lib/module/DraxProvider.js.map +1 -0
- package/lib/module/DraxScrollView.js +167 -0
- package/lib/module/DraxScrollView.js.map +1 -0
- package/lib/module/DraxSubprovider.js +21 -0
- package/lib/module/DraxSubprovider.js.map +1 -0
- package/lib/module/DraxView.js +348 -0
- package/lib/module/DraxView.js.map +1 -0
- package/lib/module/HoverLayer.js +152 -0
- package/lib/module/HoverLayer.js.map +1 -0
- package/lib/module/SortableBoardContainer.js +386 -0
- package/lib/module/SortableBoardContainer.js.map +1 -0
- package/lib/module/SortableBoardContext.js +6 -0
- package/lib/module/SortableBoardContext.js.map +1 -0
- package/lib/module/SortableContainer.js +561 -0
- package/lib/module/SortableContainer.js.map +1 -0
- package/lib/module/SortableItem.js +226 -0
- package/lib/module/SortableItem.js.map +1 -0
- package/lib/module/SortableItemContext.js +38 -0
- package/lib/module/SortableItemContext.js.map +1 -0
- package/lib/module/compat/detectVersion.js +19 -0
- package/lib/module/compat/detectVersion.js.map +1 -0
- package/lib/module/compat/index.js +5 -0
- package/lib/module/compat/index.js.map +1 -0
- package/lib/module/compat/types.js +4 -0
- package/lib/module/compat/types.js.map +1 -0
- package/lib/module/compat/useDraxPanGesture.js +94 -0
- package/lib/module/compat/useDraxPanGesture.js.map +1 -0
- package/lib/module/hooks/index.js +5 -0
- package/lib/module/hooks/index.js.map +1 -0
- package/lib/module/hooks/useCallbackDispatch.js +681 -0
- package/lib/module/hooks/useCallbackDispatch.js.map +1 -0
- package/lib/module/hooks/useDragGesture.js +240 -0
- package/lib/module/hooks/useDragGesture.js.map +1 -0
- package/lib/module/hooks/useDraxContext.js +12 -0
- package/lib/module/hooks/useDraxContext.js.map +1 -0
- package/lib/module/hooks/useDraxId.js +13 -0
- package/lib/module/hooks/useDraxId.js.map +1 -0
- package/lib/module/hooks/useDraxMethods.js +73 -0
- package/lib/module/hooks/useDraxMethods.js.map +1 -0
- package/lib/module/hooks/useDraxScrollHandler.js +97 -0
- package/lib/module/hooks/useDraxScrollHandler.js.map +1 -0
- package/lib/module/hooks/useSortableBoard.js +37 -0
- package/lib/module/hooks/useSortableBoard.js.map +1 -0
- package/lib/module/hooks/useSortableList.js +824 -0
- package/lib/module/hooks/useSortableList.js.map +1 -0
- package/lib/module/hooks/useSpatialIndex.js +283 -0
- package/lib/module/hooks/useSpatialIndex.js.map +1 -0
- package/lib/module/hooks/useViewStyles.js +158 -0
- package/lib/module/hooks/useViewStyles.js.map +1 -0
- package/lib/module/hooks/useWebScrollFreeze.js +52 -0
- package/lib/module/hooks/useWebScrollFreeze.js.map +1 -0
- package/lib/module/index.js +37 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/math.js +222 -0
- package/lib/module/math.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/params.js +88 -0
- package/lib/module/params.js.map +1 -0
- package/lib/module/types.js +213 -0
- package/lib/module/types.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/DebugOverlay.d.ts +17 -0
- package/lib/typescript/src/DebugOverlay.d.ts.map +1 -0
- package/lib/typescript/src/Drax.d.ts +28 -0
- package/lib/typescript/src/Drax.d.ts.map +1 -0
- package/lib/typescript/src/DraxContext.d.ts +3 -0
- package/lib/typescript/src/DraxContext.d.ts.map +1 -0
- package/lib/typescript/src/DraxHandle.d.ts +25 -0
- package/lib/typescript/src/DraxHandle.d.ts.map +1 -0
- package/lib/typescript/src/DraxHandleContext.d.ts +12 -0
- package/lib/typescript/src/DraxHandleContext.d.ts.map +1 -0
- package/lib/typescript/src/DraxList.d.ts +66 -0
- package/lib/typescript/src/DraxList.d.ts.map +1 -0
- package/lib/typescript/src/DraxProvider.d.ts +4 -0
- package/lib/typescript/src/DraxProvider.d.ts.map +1 -0
- package/lib/typescript/src/DraxScrollView.d.ts +7 -0
- package/lib/typescript/src/DraxScrollView.d.ts.map +1 -0
- package/lib/typescript/src/DraxSubprovider.d.ts +4 -0
- package/lib/typescript/src/DraxSubprovider.d.ts.map +1 -0
- package/lib/typescript/src/DraxView.d.ts +4 -0
- package/lib/typescript/src/DraxView.d.ts.map +1 -0
- package/lib/typescript/src/HoverLayer.d.ts +38 -0
- package/lib/typescript/src/HoverLayer.d.ts.map +1 -0
- package/lib/typescript/src/SortableBoardContainer.d.ts +11 -0
- package/lib/typescript/src/SortableBoardContainer.d.ts.map +1 -0
- package/lib/typescript/src/SortableBoardContext.d.ts +4 -0
- package/lib/typescript/src/SortableBoardContext.d.ts.map +1 -0
- package/lib/typescript/src/SortableContainer.d.ts +13 -0
- package/lib/typescript/src/SortableContainer.d.ts.map +1 -0
- package/lib/typescript/src/SortableItem.d.ts +14 -0
- package/lib/typescript/src/SortableItem.d.ts.map +1 -0
- package/lib/typescript/src/SortableItemContext.d.ts +37 -0
- package/lib/typescript/src/SortableItemContext.d.ts.map +1 -0
- package/lib/typescript/src/compat/detectVersion.d.ts +2 -0
- package/lib/typescript/src/compat/detectVersion.d.ts.map +1 -0
- package/lib/typescript/src/compat/index.d.ts +4 -0
- package/lib/typescript/src/compat/index.d.ts.map +1 -0
- package/lib/typescript/src/compat/types.d.ts +33 -0
- package/lib/typescript/src/compat/types.d.ts.map +1 -0
- package/lib/typescript/src/compat/useDraxPanGesture.d.ts +8 -0
- package/lib/typescript/src/compat/useDraxPanGesture.d.ts.map +1 -0
- package/lib/typescript/src/hooks/index.d.ts +3 -0
- package/lib/typescript/src/hooks/index.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useCallbackDispatch.d.ts +40 -0
- package/lib/typescript/src/hooks/useCallbackDispatch.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useDragGesture.d.ts +17 -0
- package/lib/typescript/src/hooks/useDragGesture.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useDraxContext.d.ts +2 -0
- package/lib/typescript/src/hooks/useDraxContext.d.ts.map +1 -0
- package/{build β lib/typescript/src}/hooks/useDraxId.d.ts +1 -0
- package/lib/typescript/src/hooks/useDraxId.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useDraxMethods.d.ts +13 -0
- package/lib/typescript/src/hooks/useDraxMethods.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useDraxScrollHandler.d.ts +27 -0
- package/lib/typescript/src/hooks/useDraxScrollHandler.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useSortableBoard.d.ts +10 -0
- package/lib/typescript/src/hooks/useSortableBoard.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useSortableList.d.ts +11 -0
- package/lib/typescript/src/hooks/useSortableList.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useSpatialIndex.d.ts +22 -0
- package/lib/typescript/src/hooks/useSpatialIndex.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useViewStyles.d.ts +183 -0
- package/lib/typescript/src/hooks/useViewStyles.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useWebScrollFreeze.d.ts +14 -0
- package/lib/typescript/src/hooks/useWebScrollFreeze.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +25 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/math.d.ts +52 -0
- package/lib/typescript/src/math.d.ts.map +1 -0
- package/{build β lib/typescript/src}/params.d.ts +13 -9
- package/lib/typescript/src/params.d.ts.map +1 -0
- package/lib/typescript/src/types.d.ts +743 -0
- package/lib/typescript/src/types.d.ts.map +1 -0
- package/package.json +164 -34
- package/src/DebugOverlay.tsx +140 -0
- package/src/Drax.ts +33 -0
- package/src/DraxContext.ts +8 -0
- package/src/DraxHandle.tsx +52 -0
- package/src/DraxHandleContext.ts +15 -0
- package/src/DraxList.tsx +181 -0
- package/src/DraxProvider.tsx +224 -0
- package/src/DraxScrollView.tsx +180 -0
- package/src/DraxSubprovider.tsx +22 -0
- package/src/DraxView.tsx +430 -0
- package/src/HoverLayer.tsx +167 -0
- package/src/SortableBoardContainer.tsx +439 -0
- package/src/SortableBoardContext.ts +6 -0
- package/src/SortableContainer.tsx +642 -0
- package/src/SortableItem.tsx +264 -0
- package/src/SortableItemContext.ts +46 -0
- package/src/compat/detectVersion.ts +17 -0
- package/src/compat/index.ts +7 -0
- package/src/compat/types.ts +35 -0
- package/src/compat/useDraxPanGesture.ts +112 -0
- package/src/hooks/index.ts +2 -0
- package/src/hooks/useCallbackDispatch.tsx +823 -0
- package/src/hooks/useDragGesture.ts +273 -0
- package/src/hooks/useDraxContext.ts +11 -0
- package/src/hooks/useDraxId.ts +11 -0
- package/src/hooks/useDraxMethods.ts +71 -0
- package/src/hooks/useDraxScrollHandler.ts +121 -0
- package/src/hooks/useSortableBoard.ts +44 -0
- package/src/hooks/useSortableList.ts +868 -0
- package/src/hooks/useSpatialIndex.ts +336 -0
- package/src/hooks/useViewStyles.ts +180 -0
- package/src/hooks/useWebScrollFreeze.ts +60 -0
- package/src/index.ts +110 -0
- package/src/math.ts +251 -0
- package/src/params.ts +74 -0
- package/src/types.ts +919 -0
- package/.editorconfig +0 -15
- package/.eslintrc.js +0 -4
- package/.prettierrc +0 -16
- package/CHANGELOG.md +0 -270
- package/CODE-OF-CONDUCT.md +0 -85
- package/CONTRIBUTING.md +0 -15
- package/FUNDING.yml +0 -4
- package/build/AllHoverViews.d.ts +0 -0
- package/build/AllHoverViews.js +0 -30
- package/build/DraxContext.d.ts +0 -2
- package/build/DraxContext.js +0 -6
- package/build/DraxList.d.ts +0 -8
- package/build/DraxList.js +0 -512
- package/build/DraxListItem.d.ts +0 -7
- package/build/DraxListItem.js +0 -121
- package/build/DraxProvider.d.ts +0 -2
- package/build/DraxProvider.js +0 -704
- package/build/DraxScrollView.d.ts +0 -6
- package/build/DraxScrollView.js +0 -136
- package/build/DraxSubprovider.d.ts +0 -3
- package/build/DraxSubprovider.js +0 -18
- package/build/DraxView.d.ts +0 -8
- package/build/DraxView.js +0 -93
- package/build/HoverView.d.ts +0 -8
- package/build/HoverView.js +0 -40
- package/build/PanGestureDetector.d.ts +0 -3
- package/build/PanGestureDetector.js +0 -49
- package/build/hooks/index.d.ts +0 -4
- package/build/hooks/index.js +0 -11
- package/build/hooks/useContent.d.ts +0 -23
- package/build/hooks/useContent.js +0 -212
- package/build/hooks/useDraxContext.d.ts +0 -1
- package/build/hooks/useDraxContext.js +0 -13
- package/build/hooks/useDraxId.js +0 -13
- package/build/hooks/useDraxProtocol.d.ts +0 -5
- package/build/hooks/useDraxProtocol.js +0 -32
- package/build/hooks/useDraxRegistry.d.ts +0 -78
- package/build/hooks/useDraxRegistry.js +0 -714
- package/build/hooks/useDraxScrollHandler.d.ts +0 -25
- package/build/hooks/useDraxScrollHandler.js +0 -89
- package/build/hooks/useDraxState.d.ts +0 -10
- package/build/hooks/useDraxState.js +0 -132
- package/build/hooks/useMeasurements.d.ts +0 -9
- package/build/hooks/useMeasurements.js +0 -119
- package/build/hooks/useStatus.d.ts +0 -11
- package/build/hooks/useStatus.js +0 -96
- package/build/index.d.ts +0 -9
- package/build/index.js +0 -33
- package/build/math.d.ts +0 -22
- package/build/math.js +0 -68
- package/build/params.js +0 -27
- package/build/transform.d.ts +0 -11
- package/build/transform.js +0 -59
- package/build/types.d.ts +0 -807
- package/build/types.js +0 -46
- package/docs/concept.md +0 -79
- package/docs/images/color-drag-drop.gif +0 -0
- package/docs/images/deck-cards.gif +0 -0
- package/docs/images/drag-drop-events.jpg +0 -0
- package/docs/images/knight-moves.gif +0 -0
- 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
|
|
3
|
+
**A drag-and-drop framework for React Native**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[](https://reactnative.dev/)
|
|
6
|
+
[](https://expo.dev/)
|
|
7
|
+
[](https://necolas.github.io/react-native-web/)
|
|
8
|
+
[](https://github.com/nuclearpasta/react-native-drax/search?l=typescript)
|
|
9
|
+
[](https://github.com/nuclearpasta/react-native-drax/actions/workflows/ci.yml)
|
|
10
|
+
[](https://github.com/nuclearpasta/react-native-drax/blob/main/LICENSE.md)
|
|
11
|
+
[](https://www.npmjs.com/package/react-native-drax)
|
|
6
12
|
|
|
7
|
-
[](https://badge.fury.io/js/react-native-drax)
|
|
8
|
-
[](CODE-OF-CONDUCT.md)
|
|
9
13
|
|
|
10
|
-
|
|
14
|
+
[Docs](https://nuclearpasta.com/react-native-drax) | [Live Example](https://nuclearpasta.com/react-native-drax/example)
|
|
11
15
|
|
|
12
|
-
|
|
16
|
+
## π Overview
|
|
13
17
|
|
|
14
|
-
|
|
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
|
-
|
|
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
|
-
|
|
22
|
+
**Platforms:** iOS, Android, Web
|
|
19
23
|
|
|
20
|
-
|
|
21
|
-
- Enhanced animation performance and capabilities
|
|
22
|
-
- Works with New Architecture
|
|
24
|
+
### β¨ Highlights
|
|
23
25
|
|
|
24
|
-
**
|
|
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
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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
|
-
|
|
31
|
-
|
|
61
|
+
```bash
|
|
62
|
+
npm install react-native-drax
|
|
63
|
+
# or
|
|
64
|
+
yarn add react-native-drax
|
|
32
65
|
```
|
|
33
66
|
|
|
34
|
-
|
|
67
|
+
### π Peer Dependencies
|
|
35
68
|
|
|
36
69
|
```bash
|
|
37
|
-
|
|
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
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
<
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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
|
-
|
|
131
|
-
## Background
|
|
135
|
+
`DraxList` is list-agnostic β pass any list component via the `component` prop:
|
|
132
136
|
|
|
133
|
-
|
|
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
|
-
|
|
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
|
-
|
|
166
|
-
|
|
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
|
-
|
|
194
|
+
This pattern works with any list component β FlatList, FlashList, LegendList, ScrollView, etc.
|
|
169
195
|
|
|
170
|
-
|
|
171
|
-
## Installation
|
|
196
|
+
## π Features
|
|
172
197
|
|
|
173
|
-
|
|
198
|
+
### β Drag Handles
|
|
174
199
|
|
|
175
|
-
|
|
200
|
+
Only the handle area starts a drag β the rest of the view scrolls normally:
|
|
176
201
|
|
|
177
|
-
|
|
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
|
-
|
|
213
|
+
### π Drag Bounds
|
|
180
214
|
|
|
181
|
-
|
|
215
|
+
Constrain a dragged view within a boundary:
|
|
182
216
|
|
|
183
|
-
|
|
217
|
+
```tsx
|
|
218
|
+
const boundsRef = useRef<View>(null);
|
|
184
219
|
|
|
185
|
-
<
|
|
186
|
-
|
|
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
|
-
###
|
|
227
|
+
### π₯ Collision Algorithms
|
|
189
228
|
|
|
190
|
-
|
|
229
|
+
Control how receiver detection works:
|
|
191
230
|
|
|
192
|
-
```
|
|
193
|
-
|
|
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
|
-
|
|
237
|
+
### π« Drop Zone Acceptance
|
|
238
|
+
|
|
239
|
+
Accept or reject drops conditionally:
|
|
197
240
|
|
|
198
241
|
```tsx
|
|
199
|
-
<
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
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
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
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
|
-
|
|
331
|
+
> **Note:** Cross-container drag is experimental. The API may change in future versions.
|
|
247
332
|
|
|
248
|
-
### API
|
|
333
|
+
### π·οΈ Namespace API
|
|
249
334
|
|
|
250
|
-
|
|
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
|
-
|
|
253
|
-
## Caveats
|
|
392
|
+
## π Migration from v0.x
|
|
254
393
|
|
|
255
|
-
|
|
394
|
+
v1.0.0 is a complete rewrite. Key changes:
|
|
256
395
|
|
|
257
|
-
|
|
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
|
-
|
|
260
|
-
## Examples
|
|
401
|
+
## π Changelog
|
|
261
402
|
|
|
262
|
-
|
|
403
|
+
See [CHANGELOG.md](CHANGELOG.md) for a full list of changes.
|
|
263
404
|
|
|
264
|
-
|
|
405
|
+
## π€ Contributing
|
|
265
406
|
|
|
266
|
-
|
|
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
|
-
|
|
409
|
+
## π Code of Conduct
|
|
270
410
|
|
|
271
|
-
|
|
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
|
-
|
|
413
|
+
## π Contributors
|
|
275
414
|
|
|
276
|
-
|
|
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
|
-
|
|
417
|
+
Thanks to all contributors who have helped make Drax better:
|
|
280
418
|
|
|
281
|
-
|
|
282
|
-
|
|
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
|
-
|
|
443
|
+
## π License
|
|
285
444
|
|
|
286
|
-
|
|
287
|
-
## Acknowledgments
|
|
445
|
+
[MIT](LICENSE.md)
|
|
288
446
|
|
|
289
|
-
|
|
447
|
+
---
|
|
290
448
|
|
|
291
|
-
|
|
449
|
+
Built and maintained using [OpenKit](https://www.openkit.work/).
|