Skip to content

Commit feb85e5

Browse files
committed
docs: add detailed usage examples for reorderableItem and draggableItem modifiers and update DropTarget documentation
1 parent d7f11cf commit feb85e5

2 files changed

Lines changed: 74 additions & 1 deletion

File tree

docs/drag-and-drop/overview.md

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ Compose DND provides a declarative API for adding drag and drop functionality to
44

55
- `DragAndDropState` -- Holds the state for all drag and drop operations.
66
- `DragAndDropContainer` -- A container that wraps all draggable items and drop targets.
7-
- `DraggableItem` -- Makes a composable draggable.
7+
- `DraggableItem` composable -- Makes a composable draggable (wrapper approach).
8+
- `draggableItem` modifier -- Makes a composable draggable (modifier approach, less boilerplate).
89
- `dropTarget` modifier -- Marks a composable as a drop target.
910

1011
## Creating DragAndDropState
@@ -91,6 +92,32 @@ Inside `DraggableItem`'s content lambda, you have access to `DraggableItemScope`
9192
- `key: Any` -- The key of this item.
9293
- `isDragging: Boolean` -- Whether this item is currently being dragged.
9394

95+
## draggableItem Modifier
96+
97+
As an alternative to the `DraggableItem` composable wrapper, you can use the `Modifier.draggableItem` modifier directly. This reduces boilerplate by eliminating the wrapper composable.
98+
99+
```kotlin
100+
val isDragging = dragAndDropState.isDragging("item-1")
101+
102+
Text(
103+
text = "Drag me",
104+
modifier = Modifier
105+
.graphicsLayer { alpha = if (isDragging) 0f else 1f }
106+
.draggableItem(
107+
state = dragAndDropState,
108+
key = "item-1",
109+
data = "Hello World",
110+
draggableContent = {
111+
Text("Drag me") // Content shown as drag shadow
112+
},
113+
)
114+
)
115+
```
116+
117+
The `draggableItem` modifier accepts the same parameters as `DraggableItem` (except `content`, which is the composable it's applied to). The `draggableContent` parameter is required — it defines what the drag shadow looks like.
118+
119+
Use `DragAndDropState.isDragging(key)` to check if a specific item is being dragged.
120+
94121
## Drop Target
95122

96123
Use the `Modifier.dropTarget` extension to mark any composable as a drop target.
@@ -127,6 +154,7 @@ Box(
127154
| `dropAlignment` | `Alignment` | `Alignment.Center` | Alignment of the dropped item within the target for the drop animation. |
128155
| `dropOffset` | `Offset` | `Offset.Zero` | Additional offset for the drop animation position. |
129156
| `dropAnimationEnabled`| `Boolean` | `true` | Whether to animate the drop. If `false`, the drop callback fires immediately. |
157+
| `canDrop` | `Boolean` | `true` | Whether this target accepts drops. When `false`, dragged items cannot hover over or be dropped on this target. Can read `state.draggedItem?.data` to validate dynamically. |
130158
| `onDrop` | `(DraggedItemState<T>) -> Unit` | `{}` | Called when an item is dropped on this target. |
131159
| `onDragEnter` | `(DraggedItemState<T>) -> Unit` | `{}` | Called when a dragged item enters this target. |
132160
| `onDragExit` | `(DraggedItemState<T>) -> Unit` | `{}` | Called when a dragged item exits this target. |

docs/drag-and-drop/reorder.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,3 +204,48 @@ private fun ItemCard(
204204

205205
!!! tip
206206
Use `graphicsLayer { alpha = if (isDragging) 0f else 1f }` to hide the original item while it is being dragged, so only the drag shadow is visible.
207+
208+
## reorderableItem Modifier
209+
210+
As an alternative to the `ReorderableItem` composable wrapper, you can use the `Modifier.reorderableItem` modifier. This combines `draggableItem` and `dropTarget` into a single modifier and reduces boilerplate.
211+
212+
```kotlin
213+
val dndState = rememberDragAndDropState<String>()
214+
215+
DragAndDropContainer(state = dndState) {
216+
LazyColumn(
217+
verticalArrangement = Arrangement.spacedBy(12.dp),
218+
) {
219+
items(items, key = { it }) { item ->
220+
val isDragging = dndState.isDragging(item)
221+
222+
ItemCard(
223+
text = item,
224+
modifier = Modifier
225+
.graphicsLayer { alpha = if (isDragging) 0f else 1f }
226+
.reorderableItem(
227+
key = item,
228+
data = item,
229+
state = dndState,
230+
onDragEnter = { state ->
231+
items = items.toMutableList().apply {
232+
val index = indexOf(item)
233+
if (index != -1) {
234+
remove(state.data)
235+
add(index, state.data)
236+
}
237+
}
238+
},
239+
draggableContent = {
240+
ItemCard(text = item, isDragShadow = true)
241+
},
242+
)
243+
.fillMaxWidth(),
244+
)
245+
}
246+
}
247+
}
248+
```
249+
250+
!!! note
251+
When using the modifier API, use `rememberDragAndDropState` and `DragAndDropContainer` directly instead of `rememberReorderState` and `ReorderContainer`. Use `DragAndDropState.isDragging(key)` to check drag state.

0 commit comments

Comments
 (0)