Skip to content

MohamedRejeb/compose-dnd

Repository files navigation

Compose DND

A library that allows you to easily add drag and drop functionality to your Jetpack Compose or Compose Multiplatform projects.

Kotlin Compose Apache-2.0 BuildPassing Maven Central

Compose DND thumbnail

Features

  • Drag and Drop -- Drag items from one location and drop them onto designated targets
  • Reorder Lists -- Reorder items within a list using drag and drop gestures
  • Auto Scroll -- Automatically scroll containers when dragging items near edges
  • Drop Strategies -- Choose from multiple built-in strategies to determine which drop target receives the dragged item
  • Drag Handle -- Restrict the drag gesture to a specific handle area within the item
  • Axis Lock -- Constrain dragging to the horizontal or vertical axis
  • Conditional Drop -- Control which drop targets accept which dragged items
  • Drop Animation -- Smooth spring-based animations when items are dropped
  • Custom Drag Shadow -- Provide a custom composable to display while an item is being dragged

Platform Support

Platform Supported
Android Yes
iOS Yes
Desktop Yes
Web (JS) Yes
Web (WASM) Yes

Installation

Maven Central

Version Compatibility

Kotlin version Compose version Compose DND version
2.3.20 1.10.3 0.5.0

Add the following dependency to your module build.gradle.kts file:

implementation("com.mohamedrejeb.dnd:compose-dnd:0.5.0")

For Kotlin Multiplatform projects, add the dependency to your commonMain source set:

kotlin {
    sourceSets {
        commonMain.dependencies {
            implementation("com.mohamedrejeb.dnd:compose-dnd:0.5.0")
        }
    }
}

Usage

Drag and Drop

Create a DragAndDropState and wrap your content with DragAndDropContainer:

val dragAndDropState = rememberDragAndDropState<String>()

DragAndDropContainer(
    state = dragAndDropState,
) {
    DraggableItem(
        state = dragAndDropState,
        key = "item-1",
        data = "Hello",
    ) {
        Text("Drag me")
    }

    Box(
        modifier = Modifier
            .dropTarget(
                key = "target-1",
                state = dragAndDropState,
                onDrop = { state ->
                    println("Dropped: ${state.data}")
                },
            )
    ) {
        Text("Drop here")
    }
}

Reorder List

Create a ReorderState and use ReorderableItem which is both draggable and a drop target:

val reorderState = rememberReorderState<String>()

ReorderContainer(
    state = reorderState,
) {
    LazyColumn {
        items(items, key = { it }) { item ->
            ReorderableItem(
                state = reorderState,
                key = item,
                data = item,
                onDrop = {},
                onDragEnter = { state ->
                    items = items.toMutableList().apply {
                        val index = indexOf(item)
                        if (index == -1) return@ReorderableItem
                        remove(state.data)
                        add(index, state.data)
                    }
                },
            ) {
                Text(item)
            }
        }
    }
}

Enable/Disable Drag and Drop

Toggle drag and drop at the container level:

DragAndDropContainer(
    state = dragAndDropState,
    enabled = false,
) { }

Or for a specific item:

DraggableItem(
    state = dragAndDropState,
    key = "item-1",
    data = "Hello",
    enabled = false,
) { }

For more details and advanced features (auto scroll, drop strategies, drag handles, axis lock), check out the documentation and the sample project.

Contribution

If you've found an error in this library, please file an issue.

Feel free to help out by sending a pull request.

Code of Conduct

Find this library useful?

Support it by joining stargazers for this repository.

Also, follow me on GitHub for more libraries!

You can always

License

Copyright 2023 Mohamed Rejeb

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.