kotlinkotlin-multiplatformcompose-multiplatformcompose

How to use startTransfer for onDragStart in Jetpack Compose 1.8.0 for Desktop?


The code in https://www.jetbrains.com/help/kotlin-multiplatform-dev/compose-drag-drop.html does not work. It still uses startTransfer(), and in Jetpack Compose 1.8.0 it does not work the same anymore, but I can not find a migration guide.

Previously on Jetpack Compose 1.7.3, this code worked just fine for me.

Does anyone know how to port this 1.8.0? It complains with Unresolved reference 'startTransfer'.

/**
 * Allows to drag the component out into other apps to copy/move/link a file.
 *
 * Note that on 'regular' mouse drag & drop into macOS Finder, it moves the file.
 *
 * @param onTransferCompleted null, when the drag is aborted.
 * @param drawDragDecoration see this for an example:
 *   These are drawn as a visual representation of the component being dragged.
 */
@OptIn(ExperimentalFoundationApi::class, ExperimentalComposeUiApi::class)
fun Modifier.fileDragSource(
    path: Path,
    onTransferCompleted: ((userAction: DragAndDropTransferAction?) -> Unit)? = null,
    drawDragDecoration: (DrawScope.() -> Unit)? = debugDrawDragDecoration()
): Modifier = dragAndDropSource(
    drawDragDecoration = {
        drawDragDecoration?.invoke(this)
    },
) {
    detectDragGestures(
        onDragStart = { offset ->
            startTransfer(
                DragAndDropTransferData(
                    DragAndDropTransferable(
                        PathTransferable(path)
                    ),
                    supportedActions = listOf(
                        DragAndDropTransferAction.Copy,
                        DragAndDropTransferAction.Move,
                        DragAndDropTransferAction.Link,
                    ),
                    onTransferCompleted = { action ->
                        onTransferCompleted?.invoke(action)
                    },
                    dragDecorationOffset = offset
                )
            )
        },
        onDrag = { _, _ -> },
    )
}

Solution

  • The API of dragAndDropSource got a lot cleaner with Compose 1.8.0. You can now simply use this:

    dragAndDropSource(
        drawDragDecoration = {
            drawDragDecoration?.invoke(this)
        },
        transferData = { offset ->
            DragAndDropTransferData(...)
        }
    )
    

    detectDragGestures and startTransfer are now handled internally, you only need to provide the DragAndDropTransferData object. Return null instead to skip starting the transfer.