|
1 | | -# Compose Drag And Drop |
| 1 | +# Compose DND |
2 | 2 |
|
3 | | -Compose DND is a library that allows you to easily add drag and drop functionality to your Jetpack Compose or Compose Multiplatform projects. |
| 3 | +A library that allows you to easily add drag and drop functionality to your Jetpack Compose or Compose Multiplatform projects. |
4 | 4 |
|
5 | | - |
6 | | -[](http://kotlinlang.org) |
7 | | -[](https://github.com/MohamedRejeb) |
| 5 | +[](http://kotlinlang.org) |
| 6 | +[](https://www.jetbrains.com/lp/compose-multiplatform) |
8 | 7 | [](https://opensource.org/licenses/Apache-2.0) |
9 | 8 | [](https://github.com/MohamedRejeb/compose-dnd/actions) |
10 | | -[](https://search.maven.org/search?q=g:%22com.mohamedrejeb.dnd%22%20AND%20a:%compose-dnd%22) |
| 9 | +[](https://search.maven.org/search?q=g:%22com.mohamedrejeb.dnd%22%20AND%20a:%22compose-dnd%22) |
11 | 10 |
|
12 | 11 |  |
13 | 12 |
|
14 | | -## Installation |
| 13 | +## Features |
15 | 14 |
|
16 | | -[](https://search.maven.org/search?q=g:%22com.mohamedrejeb.dnd%22%20AND%20a:%compose-dnd%22) |
| 15 | +- **Drag and Drop** -- Drag items from one location and drop them onto designated targets |
| 16 | +- **Reorder Lists** -- Reorder items within a list using drag and drop gestures |
| 17 | +- **Auto Scroll** -- Automatically scroll containers when dragging items near edges |
| 18 | +- **Drop Strategies** -- Choose from multiple built-in strategies to determine which drop target receives the dragged item |
| 19 | +- **Drag Handle** -- Restrict the drag gesture to a specific handle area within the item |
| 20 | +- **Axis Lock** -- Constrain dragging to the horizontal or vertical axis |
| 21 | +- **Conditional Drop** -- Control which drop targets accept which dragged items |
| 22 | +- **Drop Animation** -- Smooth spring-based animations when items are dropped |
| 23 | +- **Custom Drag Shadow** -- Provide a custom composable to display while an item is being dragged |
17 | 24 |
|
18 | | -Add the following dependency to your module `build.gradle.kts` file: |
| 25 | +## Platform Support |
19 | 26 |
|
20 | | -```kotlin |
21 | | -implementation("com.mohamedrejeb.dnd:compose-dnd:0.3.0") |
22 | | -``` |
| 27 | +| Platform | Supported | |
| 28 | +|------------|-----------| |
| 29 | +| Android | Yes | |
| 30 | +| iOS | Yes | |
| 31 | +| Desktop | Yes | |
| 32 | +| Web (JS) | Yes | |
| 33 | +| Web (WASM) | Yes | |
23 | 34 |
|
24 | | -## Usage |
| 35 | +## Installation |
25 | 36 |
|
26 | | -### Drag and Drop |
| 37 | +[](https://search.maven.org/search?q=g:%22com.mohamedrejeb.dnd%22%20AND%20a:%22compose-dnd%22) |
27 | 38 |
|
28 | | -To implement drag and drop functionality: |
29 | | -- Create a `DragAndDropState` with `rememberDragAndDropState`. |
| 39 | +### Version Compatibility |
30 | 40 |
|
31 | | -```kotlin |
32 | | -val dragAndDropState = rememberDragAndDropState() |
33 | | -``` |
34 | | -<br> |
| 41 | +| Kotlin version | Compose version | Compose DND version | |
| 42 | +|----------------|-----------------|---------------------| |
| 43 | +| 2.3.20 | 1.10.3 | 0.5.0 | |
35 | 44 |
|
36 | | -- Add `DragAndDropContainer` composable which will wrap the draggable items. |
| 45 | +Add the following dependency to your module `build.gradle.kts` file: |
37 | 46 |
|
38 | 47 | ```kotlin |
39 | | -DragAndDropContainer( |
40 | | - state = dragAndDropState, |
41 | | -) { |
42 | | - |
43 | | -} |
| 48 | +implementation("com.mohamedrejeb.dnd:compose-dnd:0.5.0") |
44 | 49 | ``` |
45 | | -<br> |
46 | 50 |
|
47 | | -- Add `DraggableItem` composable for each draggable item. |
| 51 | +For Kotlin Multiplatform projects, add the dependency to your `commonMain` source set: |
48 | 52 |
|
49 | 53 | ```kotlin |
50 | | -DraggableItem( |
51 | | - state = dragAndDropState, |
52 | | - key = task.id, // Unique key for each draggable item |
53 | | - data = task, // Data to be passed to the drop target |
54 | | -) { |
55 | | - |
| 54 | +kotlin { |
| 55 | + sourceSets { |
| 56 | + commonMain.dependencies { |
| 57 | + implementation("com.mohamedrejeb.dnd:compose-dnd:0.5.0") |
| 58 | + } |
| 59 | + } |
56 | 60 | } |
57 | 61 | ``` |
58 | | -<br> |
59 | 62 |
|
60 | | -- Add `Modifier.dropTarget` for each drop target. |
| 63 | +## Usage |
| 64 | + |
| 65 | +### Drag and Drop |
| 66 | + |
| 67 | +Create a `DragAndDropState` and wrap your content with `DragAndDropContainer`: |
61 | 68 |
|
62 | 69 | ```kotlin |
63 | | -Modifier.dropTarget( |
| 70 | +val dragAndDropState = rememberDragAndDropState<String>() |
| 71 | + |
| 72 | +DragAndDropContainer( |
64 | 73 | state = dragAndDropState, |
65 | | - key = task.id, // Unique key for each drop target |
66 | | - onDrop = { state -> // Data passed from the draggable item |
67 | | - // Handle drop |
| 74 | +) { |
| 75 | + DraggableItem( |
| 76 | + state = dragAndDropState, |
| 77 | + key = "item-1", |
| 78 | + data = "Hello", |
| 79 | + ) { |
| 80 | + Text("Drag me") |
68 | 81 | } |
69 | | -) |
70 | | -``` |
71 | 82 |
|
72 | | -> For more details, check out the [sample](https://github.com/MohamedRejeb/compose-dnd/tree/main/sample/common/src/commonMain/kotlin) |
| 83 | + Box( |
| 84 | + modifier = Modifier |
| 85 | + .dropTarget( |
| 86 | + key = "target-1", |
| 87 | + state = dragAndDropState, |
| 88 | + onDrop = { state -> |
| 89 | + println("Dropped: ${state.data}") |
| 90 | + }, |
| 91 | + ) |
| 92 | + ) { |
| 93 | + Text("Drop here") |
| 94 | + } |
| 95 | +} |
| 96 | +``` |
73 | 97 |
|
74 | 98 | ### Reorder List |
75 | 99 |
|
76 | | -To implement reorder list functionality: |
77 | | - |
78 | | -- Create a `ReorderState` with `rememberReorderState`. |
| 100 | +Create a `ReorderState` and use `ReorderableItem` which is both draggable and a drop target: |
79 | 101 |
|
80 | 102 | ```kotlin |
81 | | -val reorderState = rememberReorderState() |
82 | | -``` |
83 | | -<br> |
84 | | - |
85 | | -- Add `ReorderContainer` composable which will wrap the reorderable items. |
| 103 | +val reorderState = rememberReorderState<String>() |
86 | 104 |
|
87 | | -```kotlin |
88 | 105 | ReorderContainer( |
89 | 106 | state = reorderState, |
90 | 107 | ) { |
91 | | - |
92 | | -} |
93 | | -``` |
94 | | -<br> |
95 | | - |
96 | | -- Add `ReorderableItem` composable for each reorderable item. |
97 | | - |
98 | | -```kotlin |
99 | | -ReorderableItem( |
100 | | - state = reorderState, |
101 | | - key = task.id, // Unique key for each reorderable item |
102 | | - data = task, // Data to be passed to the drop target |
103 | | - onDrop = { state -> // Data passed from the draggable item |
104 | | - // Handle drop |
| 108 | + LazyColumn { |
| 109 | + items(items, key = { it }) { item -> |
| 110 | + ReorderableItem( |
| 111 | + state = reorderState, |
| 112 | + key = item, |
| 113 | + data = item, |
| 114 | + onDrop = {}, |
| 115 | + onDragEnter = { state -> |
| 116 | + items = items.toMutableList().apply { |
| 117 | + val index = indexOf(item) |
| 118 | + if (index == -1) return@ReorderableItem |
| 119 | + remove(state.data) |
| 120 | + add(index, state.data) |
| 121 | + } |
| 122 | + }, |
| 123 | + ) { |
| 124 | + Text(item) |
| 125 | + } |
| 126 | + } |
105 | 127 | } |
106 | | -) { |
107 | | - |
108 | 128 | } |
109 | 129 | ``` |
110 | 130 |
|
111 | | -The `ReorderableItem` composable is at the same time a `DraggableItem` and a `dropTarget`. <br><br> |
112 | | - |
113 | | -> For more details, check out the [sample](https://github.com/MohamedRejeb/compose-dnd/tree/main/sample/common/src/commonMain/kotlin) |
114 | | -
|
115 | | - |
116 | 131 | ### Enable/Disable Drag and Drop |
117 | 132 |
|
118 | | -If you want to enable/disable drag and drop functionality, you can use the `enabled` parameter in the `DragAndDropContainer` and `ReorderContainer` composable. |
| 133 | +Toggle drag and drop at the container level: |
119 | 134 |
|
120 | 135 | ```kotlin |
121 | 136 | DragAndDropContainer( |
122 | 137 | state = dragAndDropState, |
123 | | - enabled = false |
124 | | -) { |
125 | | - |
126 | | -} |
| 138 | + enabled = false, |
| 139 | +) { } |
127 | 140 | ``` |
128 | 141 |
|
129 | | -```kotlin |
130 | | -ReorderContainer( |
131 | | - state = reorderState, |
132 | | - enabled = false |
133 | | -) { |
134 | | - |
135 | | -} |
136 | | -``` |
137 | | - |
138 | | -> This will disable the drag and drop functionality for all the draggable items. |
139 | | -
|
140 | | -If you want to disable drag and drop for a specific item, you can use the `enabled` parameter in the `DraggableItem` and `ReorderableItem` composable. |
| 142 | +Or for a specific item: |
141 | 143 |
|
142 | 144 | ```kotlin |
143 | 145 | DraggableItem( |
144 | 146 | state = dragAndDropState, |
145 | | - key = task.id, |
146 | | - data = task, |
147 | | - enabled = false |
148 | | -) { |
149 | | - |
150 | | -} |
| 147 | + key = "item-1", |
| 148 | + data = "Hello", |
| 149 | + enabled = false, |
| 150 | +) { } |
151 | 151 | ``` |
152 | 152 |
|
153 | | -```kotlin |
154 | | -ReorderableItem( |
155 | | - state = reorderState, |
156 | | - key = task.id, |
157 | | - data = task, |
158 | | - onDrop = { state -> |
159 | | - // Handle drop |
160 | | - }, |
161 | | - enabled = false |
162 | | -) { |
163 | | - |
164 | | -} |
165 | | -``` |
| 153 | +> For more details and advanced features (auto scroll, drop strategies, drag handles, axis lock), check out the [documentation](https://mohamedrejeb.github.io/compose-dnd/) and the [sample project](https://github.com/MohamedRejeb/compose-dnd/tree/main/sample/common/src/commonMain/kotlin). |
166 | 154 |
|
167 | 155 | ## Contribution |
168 | | -If you've found an error in this sample, please file an issue. <br> |
169 | | -Feel free to help out by sending a pull request :heart:. |
| 156 | + |
| 157 | +If you've found an error in this library, please file an [issue](https://github.com/MohamedRejeb/compose-dnd/issues). |
| 158 | + |
| 159 | +Feel free to help out by sending a pull request. |
170 | 160 |
|
171 | 161 | [Code of Conduct](https://github.com/MohamedRejeb/compose-dnd/blob/main/CODE_OF_CONDUCT.md) |
172 | 162 |
|
173 | | -## Find this library useful? :heart: |
174 | | -Support it by joining __[stargazers](https://github.com/MohamedRejeb/compose-dnd/stargazers)__ for this repository. :star: <br> |
175 | | -Also, __[follow me](https://github.com/MohamedRejeb)__ on GitHub for more libraries! 🤩 |
| 163 | +## Find this library useful? |
| 164 | + |
| 165 | +Support it by joining [stargazers](https://github.com/MohamedRejeb/compose-dnd/stargazers) for this repository. |
| 166 | + |
| 167 | +Also, [follow me](https://github.com/MohamedRejeb) on GitHub for more libraries! |
176 | 168 |
|
177 | 169 | You can always <a href="https://www.buymeacoffee.com/MohamedRejeb"><img src="https://img.buymeacoffee.com/button-api/?text=Buy me a coffee&emoji=&slug=MohamedRejeb&button_colour=FFDD00&font_colour=000000&font_family=Cookie&outline_colour=000000&coffee_colour=ffffff"></a> |
178 | 170 |
|
179 | | -# License |
| 171 | +## License |
| 172 | + |
180 | 173 | ``` |
181 | 174 | Copyright 2023 Mohamed Rejeb |
182 | 175 |
|
|
0 commit comments