{"id":26266116,"url":"https://github.com/calvin-ll/reorderable","last_synced_at":"2025-05-15T08:11:08.836Z","repository":{"id":208155153,"uuid":"720887699","full_name":"Calvin-LL/Reorderable","owner":"Calvin-LL","description":"Reorder items in Lists and Grids in Jetpack Compose and Compose Multiplatform with drag and drop.","archived":false,"fork":false,"pushed_at":"2025-02-26T08:53:11.000Z","size":12999,"stargazers_count":750,"open_issues_count":16,"forks_count":26,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-11T19:57:53.693Z","etag":null,"topics":["android","compose-multiplatform","drag-and-drop","draggable","grid","jetpack-compose","kotlin","list","reorderable","reorderable-list","reordering"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Calvin-LL.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-11-19T22:16:25.000Z","updated_at":"2025-04-11T03:32:12.000Z","dependencies_parsed_at":"2024-02-21T23:28:22.598Z","dependency_job_id":"312c390e-e600-445a-9da1-3f991a593095","html_url":"https://github.com/Calvin-LL/Reorderable","commit_stats":null,"previous_names":["calvin-ll/reorderable"],"tags_count":35,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Calvin-LL%2FReorderable","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Calvin-LL%2FReorderable/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Calvin-LL%2FReorderable/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Calvin-LL%2FReorderable/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Calvin-LL","download_url":"https://codeload.github.com/Calvin-LL/Reorderable/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254301432,"owners_count":22047904,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","compose-multiplatform","drag-and-drop","draggable","grid","jetpack-compose","kotlin","list","reorderable","reorderable-list","reordering"],"created_at":"2025-03-14T03:16:54.164Z","updated_at":"2025-05-15T08:11:08.818Z","avatar_url":"https://github.com/Calvin-LL.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Reorderable\n\nReorderable is a simple library that allows you to reorder items in [`LazyColumn`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/package-summary#LazyColumn(androidx.compose.ui.Modifier,androidx.compose.foundation.lazy.LazyListState,androidx.compose.foundation.layout.PaddingValues,kotlin.Boolean,androidx.compose.foundation.layout.Arrangement.Vertical,androidx.compose.ui.Alignment.Horizontal,androidx.compose.foundation.gestures.FlingBehavior,kotlin.Boolean,kotlin.Function1)\u003e), [`LazyRow`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/package-summary#LazyRow(androidx.compose.ui.Modifier,androidx.compose.foundation.lazy.LazyListState,androidx.compose.foundation.layout.PaddingValues,kotlin.Boolean,androidx.compose.foundation.layout.Arrangement.Horizontal,androidx.compose.ui.Alignment.Vertical,androidx.compose.foundation.gestures.FlingBehavior,kotlin.Boolean,kotlin.Function1)\u003e), [`LazyVerticalGrid`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/grid/package-summary#LazyVerticalGrid(androidx.compose.foundation.lazy.grid.GridCells,androidx.compose.ui.Modifier,androidx.compose.foundation.lazy.grid.LazyGridState,androidx.compose.foundation.layout.PaddingValues,kotlin.Boolean,androidx.compose.foundation.layout.Arrangement.Vertical,androidx.compose.foundation.layout.Arrangement.Horizontal,androidx.compose.foundation.gestures.FlingBehavior,kotlin.Boolean,kotlin.Function1)\u003e), [`LazyHorizontalGrid`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/grid/package-summary#LazyHorizontalGrid(androidx.compose.foundation.lazy.grid.GridCells,androidx.compose.ui.Modifier,androidx.compose.foundation.lazy.grid.LazyGridState,androidx.compose.foundation.layout.PaddingValues,kotlin.Boolean,androidx.compose.foundation.layout.Arrangement.Horizontal,androidx.compose.foundation.layout.Arrangement.Vertical,androidx.compose.foundation.gestures.FlingBehavior,kotlin.Boolean,kotlin.Function1)\u003e), [`LazyVerticalStaggeredGrid`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/staggeredgrid/package-summary#LazyVerticalStaggeredGrid(androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells,androidx.compose.ui.Modifier,androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridState,androidx.compose.foundation.layout.PaddingValues,kotlin.Boolean,androidx.compose.ui.unit.Dp,androidx.compose.foundation.layout.Arrangement.Horizontal,androidx.compose.foundation.gestures.FlingBehavior,kotlin.Boolean,kotlin.Function1)\u003e), and [`LazyHorizontalStaggeredGrid`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/staggeredgrid/package-summary#LazyHorizontalStaggeredGrid(androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells,androidx.compose.ui.Modifier,androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridState,androidx.compose.foundation.layout.PaddingValues,kotlin.Boolean,androidx.compose.foundation.layout.Arrangement.Vertical,androidx.compose.ui.unit.Dp,androidx.compose.foundation.gestures.FlingBehavior,kotlin.Boolean,kotlin.Function1)\u003e) as well as [`Column`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/package-summary#Column(androidx.compose.ui.Modifier,androidx.compose.foundation.layout.Arrangement.Vertical,androidx.compose.ui.Alignment.Horizontal,kotlin.Function1)\u003e) and [`Row`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/package-summary#Row(androidx.compose.ui.Modifier,androidx.compose.foundation.layout.Arrangement.Horizontal,androidx.compose.ui.Alignment.Vertical,kotlin.Function1)\u003e) in Jetpack Compose and Compose Multiplatform with drag and drop.\n\nThe latest demo app APK can be found in the [releases](https://github.com/Calvin-LL/Reorderable/releases) section under the \"Assets\" section of the latest release.\n\n\u003ctable width=\"100%\" align=\"center\"\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth width=\"50%\"\u003eLazyColumn\u003c/th\u003e\n      \u003cth width=\"50%\"\u003eLazyGrid\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd width=\"50%\"\u003e\n        \u003cimg\n          src=\"lazy-column-demo.webp\"\n          width=\"320\"\n          alt=\"A video showing an item being reordered in a LazyColumn\"\n        /\u003e\n      \u003c/td\u003e\n      \u003ctd width=\"50%\"\u003e\n        \u003cimg\n          src=\"lazy-grid-demo.webp\"\n          width=\"320\"\n          alt=\"A video showing an item being reordered in a LazyGrid\"\n        /\u003e\n      \u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n## Used By\n\n- [Lawnchair](https://github.com/LawnchairLauncher/lawnchair/blob/10889eb9772d5ec05f8ec536db3986ad5d9f4f33/build.gradle#L420) ![GitHub Repo stars](https://img.shields.io/github/stars/LawnchairLauncher/lawnchair?style=flat)\n- [Pocket Casts](https://github.com/Automattic/pocket-casts-android/blob/96cb6c6c3e210800a5fd2365776eee896079e255/gradle/libs.versions.toml#L281) ![GitHub Repo stars](https://img.shields.io/github/stars/Automattic/pocket-casts-android?style=flat)\n- [gkd](https://github.com/gkd-kit/gkd/blob/de140488aa42330d282cc41b92127237308e25f2/gradle/libs.versions.toml#L63) ![GitHub Repo stars](https://img.shields.io/github/stars/gkd-kit/gkd?style=flat)\n- [Mihon](https://github.com/mihonapp/mihon/blob/919607cd06ee45ac667a2fd650d85aaf6ebb9762/gradle/libs.versions.toml#L68) ![GitHub Repo stars](https://img.shields.io/github/stars/mihonapp/mihon?style=flat)\n- [InnerTune](https://github.com/z-huang/InnerTune/blob/ba3a3a0fe9d3499205a7fc91649938091cad75b8/gradle/libs.versions.toml#L34) ![GitHub Repo stars](https://img.shields.io/github/stars/z-huang/InnerTune?style=flat)\n- [ImageToolbox](https://github.com/T8RIN/ImageToolbox/blob/f03ba7e7dd497b215cc14cf80ee4991d42d101a4/gradle/libs.versions.toml#L160) ![GitHub Repo stars](https://img.shields.io/github/stars/T8RIN/ImageToolbox?style=flat)\n- [StreetComplete](https://github.com/streetcomplete/StreetComplete/blob/bcb8b58597c5e55b59b71be3568eed5e6a025e9b/app/build.gradle.kts#L154) ![GitHub Repo stars](https://img.shields.io/github/stars/streetcomplete/StreetComplete?style=flat)\n- [EhViewer](https://github.com/FooIbar/EhViewer/blob/4bb6b0baf69f4e996e1dd0bdb89a7f112819bf02/gradle/libs.versions.toml#L102) ![GitHub Repo stars](https://img.shields.io/github/stars/FooIbar/EhViewer?style=flat)\n- [Twine](https://github.com/msasikanth/twine/blob/841defa05f03c13e56fd331e288f9a5e676862ca/gradle/libs.versions.toml#L124) ![GitHub Repo stars](https://img.shields.io/github/stars/msasikanth/twine?style=flat)\n- [bilimiao](https://github.com/10miaomiao/bilimiao2/blob/b806379206283309defd6d0ef9ad3b575dd46642/bilimiao-compose/build.gradle.kts#L83) ![GitHub Repo stars](https://img.shields.io/github/stars/10miaomiao/bilimiao2?style=flat)\n- [Neo Launcher](https://github.com/NeoApplications/Neo-Launcher/blob/c3788690e31d13249ae70e9db628ed7e9baa86d4/gradle/libs.versions.toml#L112) ![GitHub Repo stars](https://img.shields.io/github/stars/NeoApplications/Neo-Launcher?style=flat)\n- [Stream Chat](https://github.com/GetStream/stream-chat-android/blob/95a3f812991d7fe1e91d7457d125a039aeff704c/buildSrc/src/main/kotlin/io/getstream/chat/android/Dependencies.kt#L217) ![GitHub Repo stars](https://img.shields.io/github/stars/GetStream/stream-chat-android?style=flat)\n- [EinkBro](https://github.com/plateaukao/einkbro/blob/4dfa50fff1ced5035d1be77ef5af55ac165375e6/app/build.gradle.kts#L148) ![GitHub Repo stars](https://img.shields.io/github/stars/plateaukao/einkbro?style=flat)\n\n## Features\n\n- Supports Compose Multiplatform (Android, iOS, Desktop/JVM, Wasm, JS)\n- Supports items of different sizes\n- Some items can be made non-reorderable\n- Supports dragging and animating the first visible item\n- Supports dragging immediately or long press to start dragging\n- Supports section headers and footers\n- Scrolls when dragging to the edge of the screen. (unavailable for [`Column`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/package-summary#Column(androidx.compose.ui.Modifier,androidx.compose.foundation.layout.Arrangement.Vertical,androidx.compose.ui.Alignment.Horizontal,kotlin.Function1)\u003e) and [`Row`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/package-summary#Row(androidx.compose.ui.Modifier,androidx.compose.foundation.layout.Arrangement.Horizontal,androidx.compose.ui.Alignment.Vertical,kotlin.Function1)\u003e)) The scroll speed is based on the distance from the edge of the screen.\n- Uses the new [`Modifier.animateItem`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyItemScope#(androidx.compose.ui.Modifier).animateItem(androidx.compose.animation.core.FiniteAnimationSpec,androidx.compose.animation.core.FiniteAnimationSpec,androidx.compose.animation.core.FiniteAnimationSpec)\u003e) API to animate item movement in [`LazyColumn`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/package-summary#LazyColumn(androidx.compose.ui.Modifier,androidx.compose.foundation.lazy.LazyListState,androidx.compose.foundation.layout.PaddingValues,kotlin.Boolean,androidx.compose.foundation.layout.Arrangement.Vertical,androidx.compose.ui.Alignment.Horizontal,androidx.compose.foundation.gestures.FlingBehavior,kotlin.Boolean,kotlin.Function1)\u003e), [`LazyRow`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/package-summary#LazyRow(androidx.compose.ui.Modifier,androidx.compose.foundation.lazy.LazyListState,androidx.compose.foundation.layout.PaddingValues,kotlin.Boolean,androidx.compose.foundation.layout.Arrangement.Horizontal,androidx.compose.ui.Alignment.Vertical,androidx.compose.foundation.gestures.FlingBehavior,kotlin.Boolean,kotlin.Function1)\u003e), [`LazyVerticalGrid`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/grid/package-summary#LazyVerticalGrid(androidx.compose.foundation.lazy.grid.GridCells,androidx.compose.ui.Modifier,androidx.compose.foundation.lazy.grid.LazyGridState,androidx.compose.foundation.layout.PaddingValues,kotlin.Boolean,androidx.compose.foundation.layout.Arrangement.Vertical,androidx.compose.foundation.layout.Arrangement.Horizontal,androidx.compose.foundation.gestures.FlingBehavior,kotlin.Boolean,kotlin.Function1)\u003e), [`LazyHorizontalGrid`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/grid/package-summary#LazyHorizontalGrid(androidx.compose.foundation.lazy.grid.GridCells,androidx.compose.ui.Modifier,androidx.compose.foundation.lazy.grid.LazyGridState,androidx.compose.foundation.layout.PaddingValues,kotlin.Boolean,androidx.compose.foundation.layout.Arrangement.Horizontal,androidx.compose.foundation.layout.Arrangement.Vertical,androidx.compose.foundation.gestures.FlingBehavior,kotlin.Boolean,kotlin.Function1)\u003e), [`LazyVerticalStaggeredGrid`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/staggeredgrid/package-summary#LazyVerticalStaggeredGrid(androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells,androidx.compose.ui.Modifier,androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridState,androidx.compose.foundation.layout.PaddingValues,kotlin.Boolean,androidx.compose.ui.unit.Dp,androidx.compose.foundation.layout.Arrangement.Horizontal,androidx.compose.foundation.gestures.FlingBehavior,kotlin.Boolean,kotlin.Function1)\u003e), and [`LazyHorizontalStaggeredGrid`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/staggeredgrid/package-summary#LazyHorizontalStaggeredGrid(androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells,androidx.compose.ui.Modifier,androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridState,androidx.compose.foundation.layout.PaddingValues,kotlin.Boolean,androidx.compose.foundation.layout.Arrangement.Vertical,androidx.compose.ui.unit.Dp,androidx.compose.foundation.gestures.FlingBehavior,kotlin.Boolean,kotlin.Function1)\u003e)\n- Supports using a child of an item as the drag handle\n\n## Usage\n\n### Version Catalog\n\nIf you're using Version Catalog, add the following to your `libs.versions.toml` file:\n\n```toml\n[versions]\n#...\nreorderable = \"2.4.3\"\n\n[libraries]\n#...\nreorderable = { module = \"sh.calvin.reorderable:reorderable\", version.ref = \"reorderable\" }\n```\n\nor\n\n```toml\n[libraries]\n#...\nreorderable = { module = \"sh.calvin.reorderable:reorderable\", version = \"2.4.3\" }\n```\n\nthen\n\n```kotlin\ndependencies {\n    // ...\n    implementation(libs.reorderable)\n}\n```\n\n### Gradle\n\nIf you're using Gradle instead, add the following to your `build.gradle` file:\n\n#### Kotlin DSL\n\n```kotlin\ndependencies {\n    implementation(\"sh.calvin.reorderable:reorderable:2.4.3\")\n}\n```\n\n#### Groovy DSL\n\n```groovy\ndependencies {\n    implementation 'sh.calvin.reorderable:reorderable:2.4.3'\n}\n```\n\n### Examples\n\nSee [demo app code](demoApp/composeApp/src/commonMain/kotlin/sh/calvin/reorderable/demo) for more examples.\n\n#### Table of Contents\n\n- [`LazyColumn`](#lazycolumn)\n- [`LazyRow`](#lazyrow)\n- [`LazyVerticalGrid`](#lazyverticalgrid)\n- [`LazyHorizontalGrid`](#lazyhorizontalgrid)\n- [`LazyVerticalStaggeredGrid`](#lazyverticalstaggeredgrid)\n- [`LazyHorizontalStaggeredGrid`](#lazyhorizontalstaggeredgrid)\n- [`Column`](#column)\n- [`Row`](#row)\n- [Accessibility](#accessibility)\n- [FAQ](#faq)\n\n#### `LazyColumn`\n\nFind more examples in [`SimpleReorderableLazyColumnScreen.kt`](demoApp/composeApp/src/commonMain/kotlin/sh/calvin/reorderable/demo/ui/SimpleReorderableLazyColumnScreen.kt), [`SimpleLongPressHandleReorderableLazyColumnScreen.kt`](demoApp/composeApp/src/commonMain/kotlin/sh/calvin/reorderable/demo/ui/SimpleLongPressHandleReorderableLazyColumnScreen.kt) and [`ComplexReorderableLazyColumnScreen.kt`](demoApp/composeApp/src/commonMain/kotlin/sh/calvin/reorderable/demo/ui/ComplexReorderableLazyColumnScreen.kt) in the demo app.\n\n##### Simple Example\n\nTo use this library with [`LazyColumn`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/package-summary#LazyColumn(androidx.compose.ui.Modifier,androidx.compose.foundation.lazy.LazyListState,androidx.compose.foundation.layout.PaddingValues,kotlin.Boolean,androidx.compose.foundation.layout.Arrangement.Vertical,androidx.compose.ui.Alignment.Horizontal,androidx.compose.foundation.gestures.FlingBehavior,kotlin.Boolean,kotlin.Function1)\u003e), follow this basic structure:\n\n```kotlin\nval lazyListState = rememberLazyListState()\nval reorderableLazyListState = rememberReorderableLazyListState(lazyListState) { from, to -\u003e\n    // Update the list\n}\n\nLazyColumn(state = lazyListState) {\n    items(list, key = { /* item key */ }) {\n        ReorderableItem(reorderableLazyListState, key = /* item key */) { isDragging -\u003e\n            // Item content\n\n            IconButton(\n                modifier = Modifier.draggableHandle(),\n                /* ... */\n            )\n        }\n    }\n}\n\n```\n\n##### Complete Example (with haptic feedback)\n\n\u003e [!NOTE]  \n\u003e `val view = LocalView.current` and `View.performHapticFeedback` are only available in Android. Comment out these lines if you are using this library in a multiplatform project.\n\n```kotlin\nval view = LocalView.current\n\nvar list by remember { mutableStateOf(List(100) { \"Item $it\" }) }\nval lazyListState = rememberLazyListState()\nval reorderableLazyListState = rememberReorderableLazyListState(lazyListState) { from, to -\u003e\n    list = list.toMutableList().apply {\n        add(to.index, removeAt(from.index))\n    }\n\n    ViewCompat.performHapticFeedback(\n        view,\n        HapticFeedbackConstantsCompat.SEGMENT_FREQUENT_TICK\n    )\n}\n\nLazyColumn(\n    modifier = Modifier.fillMaxSize(),\n    state = lazyListState,\n    contentPadding = PaddingValues(8.dp),\n    verticalArrangement = Arrangement.spacedBy(8.dp),\n) {\n    items(list, key = { it }) {\n        ReorderableItem(reorderableLazyListState, key = it) { isDragging -\u003e\n            val elevation by animateDpAsState(if (isDragging) 4.dp else 0.dp)\n\n            Surface(shadowElevation = elevation) {\n                Row {\n                    Text(it, Modifier.padding(horizontal = 8.dp))\n                    IconButton(\n                        modifier = Modifier.draggableHandle(\n                            onDragStarted = {\n                                ViewCompat.performHapticFeedback(\n                                    view,\n                                    HapticFeedbackConstantsCompat.GESTURE_START\n                                )\n                            },\n                            onDragStopped = {\n                                ViewCompat.performHapticFeedback(\n                                    view,\n                                    HapticFeedbackConstantsCompat.GESTURE_END\n                                )\n                            },\n                        ),\n                        onClick = {},\n                    ) {\n                        Icon(Icons.Rounded.DragHandle, contentDescription = \"Reorder\")\n                    }\n                }\n            }\n        }\n    }\n}\n```\n\n##### Section Headers and Footers or Multiple Lists\n\nThe `from.index` and `to.index` in `onMove` are the indices of the items in the `LazyColumn`. If you have section headers or footers, you may need to adjust the indices accordingly. For example:\n\n```kotlin\nvar list by remember { mutableStateOf(List(100) { \"Item $it\" }) }\nval lazyListState = rememberLazyListState()\nval reorderableLazyColumnState = rememberReorderableLazyListState(lazyListState) { from, to -\u003e\n    list = list.toMutableList().apply {\n        add(to.index - 1, removeAt(from.index - 1))\n    }\n}\n\nLazyColumn(\n    state = lazyListState,\n    // ...\n) {\n    item {\n        Text(\"Header\")\n    }\n\n    items(list, key = { item -\u003e item.id }) { item -\u003e\n        ReorderableItem(reorderableLazyColumnState, item.id) {\n            // ...\n        }\n    }\n}\n```\n\n##### Passing `Modifier.draggableHandle` to a Child Composable\n\nSince `Modifier.draggableHandle` and `Modifier.longPressDraggableHandle` can only be used in `ReorderableCollectionItemScope`, you may need to pass `ReorderableCollectionItemScope` to a child composable. For example:\n\n```kotlin\n@Composable\nfun List() {\n    // ...\n\n    LazyColumn(state = lazyListState) {\n        items(list, key = { /* item key */ }) {\n            ReorderableItem(reorderableLazyListState, key = /* item key */) { isDragging -\u003e\n                // Item content\n\n                DragHandle(this)\n            }\n        }\n    }\n}\n\n@Composable\nfun DragHandle(scope: ReorderableCollectionItemScope) {\n    IconButton(\n        modifier = with(scope) {\n            Modifier.draggableHandle()\n        },\n        /* ... */\n    )\n}\n```\n\n##### Scroll Trigger Padding\n\nIf your [`LazyColumn`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/package-summary#LazyColumn(androidx.compose.ui.Modifier,androidx.compose.foundation.lazy.LazyListState,androidx.compose.foundation.layout.PaddingValues,kotlin.Boolean,androidx.compose.foundation.layout.Arrangement.Vertical,androidx.compose.ui.Alignment.Horizontal,androidx.compose.foundation.gestures.FlingBehavior,kotlin.Boolean,kotlin.Function1)\u003e) displays under navigation bar or notification bar, you may want to add `scrollThresholdPadding` to `rememberReorderableLazyListState` to move the scroll trigger area out from under the navigation bar or notification bar.\n\n```kotlin\nval reorderableLazyListState = rememberReorderableLazyListState(\n    lazyListState = lazyListState,\n    scrollThresholdPadding = WindowInsets.systemBars.asPaddingValues(),\n) { from, to -\u003e\n    ...\n}\n```\n\n##### Use with [`Card`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#Card(kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.ui.graphics.Shape,androidx.compose.material3.CardColors,androidx.compose.material3.CardElevation,androidx.compose.foundation.BorderStroke,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Function1)\u003e)\n\nIf you want to use the [material3's Clickable Card](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#Card(kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.ui.graphics.Shape,androidx.compose.material3.CardColors,androidx.compose.material3.CardElevation,androidx.compose.foundation.BorderStroke,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Function1)\u003e), you can create a [`MutableInteractionSource`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/interaction/MutableInteractionSource) and pass it to both the [`Card`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#Card(kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.ui.graphics.Shape,androidx.compose.material3.CardColors,androidx.compose.material3.CardElevation,androidx.compose.foundation.BorderStroke,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Function1)\u003e) and the `Modifier.draggableHandle` (or `Modifier.longPressDraggableHandle`), `Modifier.draggableHandle` will emit drag events to the [`MutableInteractionSource`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/interaction/MutableInteractionSource) so that the [`Card`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#Card(kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.ui.graphics.Shape,androidx.compose.material3.CardColors,androidx.compose.material3.CardElevation,androidx.compose.foundation.BorderStroke,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Function1)\u003e) can respond to the drag events:\n\n```kotlin\nval view = LocalView.current\n\nvar list by remember { mutableStateOf(List(100) { \"Item $it\" }) }\nval lazyListState = rememberLazyListState()\nval reorderableLazyListState = rememberReorderableLazyListState(lazyListState) { from, to -\u003e\n    list = list.toMutableList().apply {\n        add(to.index, removeAt(from.index))\n    }\n\n    ViewCompat.performHapticFeedback(\n        view,\n        HapticFeedbackConstantsCompat.SEGMENT_FREQUENT_TICK\n    )\n}\n\nLazyColumn(\n    modifier = Modifier.fillMaxSize(),\n    state = lazyListState,\n    contentPadding = PaddingValues(8.dp),\n    verticalArrangement = Arrangement.spacedBy(8.dp),\n) {\n    items(list, key = { it }) { item -\u003e\n        ReorderableItem(reorderableLazyListState, key = item) {\n            val interactionSource = remember { MutableInteractionSource() }\n\n            Card(\n                onClick = {},\n                interactionSource = interactionSource,\n            ) {\n                Row {\n                    Text(item, Modifier.padding(horizontal = 8.dp))\n                    IconButton(\n                        modifier = Modifier.draggableHandle(\n                            onDragStarted = {\n                                ViewCompat.performHapticFeedback(\n                                    view,\n                                    HapticFeedbackConstantsCompat.GESTURE_START\n                                )\n                            },\n                            onDragStopped = {\n                                ViewCompat.performHapticFeedback(\n                                    view,\n                                    HapticFeedbackConstantsCompat.GESTURE_END\n                                )\n                            },\n                            interactionSource = interactionSource,\n                        ),\n                        onClick = {},\n                    ) {\n                        Icon(Icons.Rounded.DragHandle, contentDescription = \"Reorder\")\n                    }\n                }\n            }\n        }\n    }\n}\n```\n\n#### LazyRow\n\nSee [`SimpleReorderableLazyRowScreen.kt`](demoApp/composeApp/src/commonMain/kotlin/sh/calvin/reorderable/demo/ui/SimpleReorderableLazyRowScreen.kt) and [`ComplexReorderableLazyRowScreen.kt`](demoApp/composeApp/src/commonMain/kotlin/sh/calvin/reorderable/demo/ui/ComplexReorderableLazyRowScreen.kt) in the demo app.\n\n##### Simple Example\n\nTo use this library with [`LazyRow`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/package-summary#LazyRow(androidx.compose.ui.Modifier,androidx.compose.foundation.lazy.LazyListState,androidx.compose.foundation.layout.PaddingValues,kotlin.Boolean,androidx.compose.foundation.layout.Arrangement.Horizontal,androidx.compose.ui.Alignment.Vertical,androidx.compose.foundation.gestures.FlingBehavior,kotlin.Boolean,kotlin.Function1)\u003e), follow this basic structure:\n\n```kotlin\nval lazyListState = rememberLazyListState()\nval reorderableLazyListState = rememberReorderableLazyListState(lazyListState) { from, to -\u003e\n    // Update the list\n}\n\nLazyRow(state = lazyListState) {\n    items(list, key = { /* item key */ }) {\n        ReorderableItem(reorderableLazyListState, key = /* item key */) { isDragging -\u003e\n            // Item content\n\n            IconButton(\n                modifier = Modifier.draggableHandle(),\n                /* ... */\n            )\n        }\n    }\n}\n\n```\n\n##### Complete Example (with haptic feedback)\n\n\u003e [!NOTE]  \n\u003e `val view = LocalView.current` and `View.performHapticFeedback` are only available in Android. Comment out these lines if you are using this library in a multiplatform project.\n\n```kotlin\nval view = LocalView.current\n\nvar list by remember { mutableStateOf(List(100) { \"Item $it\" }) }\nval lazyListState = rememberLazyListState()\nval reorderableLazyListState = rememberReorderableLazyListState(lazyListState) { from, to -\u003e\n    list = list.toMutableList().apply {\n        add(to.index, removeAt(from.index))\n    }\n\n    ViewCompat.performHapticFeedback(\n        view,\n        HapticFeedbackConstantsCompat.SEGMENT_FREQUENT_TICK\n    )\n}\n\nLazyRow(\n    modifier = Modifier.fillMaxSize(),\n    state = lazyListState,\n    contentPadding = PaddingValues(8.dp),\n    horizontalArrangement = Arrangement.spacedBy(8.dp),\n) {\n    items(list, key = { it }) {\n        ReorderableItem(reorderableLazyListState, key = it) { isDragging -\u003e\n            val elevation by animateDpAsState(if (isDragging) 4.dp else 0.dp)\n\n            Surface(shadowElevation = elevation) {\n                Column {\n                    Text(it, Modifier.padding(vertical = 8.dp))\n                    IconButton(\n                        modifier = Modifier.draggableHandle(\n                            onDragStarted = {\n                                ViewCompat.performHapticFeedback(\n                                    view,\n                                    HapticFeedbackConstantsCompat.GESTURE_START\n                                )\n                            },\n                            onDragStopped = {\n                                ViewCompat.performHapticFeedback(\n                                    view,\n                                    HapticFeedbackConstantsCompat.GESTURE_END\n                                )\n                            },\n                        ),\n                        onClick = {},\n                    ) {\n                        Icon(Icons.Rounded.DragHandle, contentDescription = \"Reorder\")\n                    }\n                }\n            }\n        }\n    }\n}\n```\n\n##### Section Headers and Footers or Multiple Lists\n\nThe `from.index` and `to.index` in `onMove` are the indices of the items in the `LazyRow`. If you have section headers or footers, you may need to adjust the indices accordingly. For example:\n\n```kotlin\nvar list by remember { mutableStateOf(List(100) { \"Item $it\" }) }\nval lazyListState = rememberLazyListState()\nval reorderableLazyRowState = rememberReorderableLazyListState(lazyListState) { from, to -\u003e\n    list = list.toMutableList().apply {\n        add(to.index - 1, removeAt(from.index - 1))\n    }\n}\n\nLazyRow(\n    state = lazyListState,\n    // ...\n) {\n    item {\n        Text(\"Header\")\n    }\n\n    items(list, key = { item -\u003e item.id }) { item -\u003e\n        ReorderableItem(reorderableLazyRowState, item.id) {\n            // ...\n        }\n    }\n}\n```\n\n##### Passing `Modifier.draggableHandle` to a Child Composable\n\nSince `Modifier.draggableHandle` and `Modifier.longPressDraggableHandle` can only be used in `ReorderableCollectionItemScope`, you may need to pass `ReorderableCollectionItemScope` to a child composable. For example:\n\n```kotlin\n@Composable\nfun List() {\n    // ...\n\n    LazyRow(state = lazyListState) {\n        items(list, key = { /* item key */ }) {\n            ReorderableItem(reorderableLazyListState, key = /* item key */) { isDragging -\u003e\n                // Item content\n\n                DragHandle(this)\n            }\n        }\n    }\n}\n\n@Composable\nfun DragHandle(scope: ReorderableCollectionItemScope) {\n    IconButton(\n        modifier = with(scope) {\n            Modifier.draggableHandle()\n        },\n        /* ... */\n    )\n}\n```\n\n##### Scroll Trigger Padding\n\nIf your [`LazyRow`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/package-summary#LazyRow(androidx.compose.ui.Modifier,androidx.compose.foundation.lazy.LazyListState,androidx.compose.foundation.layout.PaddingValues,kotlin.Boolean,androidx.compose.foundation.layout.Arrangement.Horizontal,androidx.compose.ui.Alignment.Vertical,androidx.compose.foundation.gestures.FlingBehavior,kotlin.Boolean,kotlin.Function1)\u003e) displays under navigation bar or notification bar, you may want to add `scrollThresholdPadding` to `rememberReorderableLazyListState` to move the scroll trigger area out from under the navigation bar or notification bar.\n\n```kotlin\nval reorderableLazyListState = rememberReorderableLazyListState(\n    lazyListState = lazyListState,\n    scrollThresholdPadding = WindowInsets.systemBars.asPaddingValues(),\n) { from, to -\u003e\n    ...\n}\n```\n\n##### Use with [`Card`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#Card(kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.ui.graphics.Shape,androidx.compose.material3.CardColors,androidx.compose.material3.CardElevation,androidx.compose.foundation.BorderStroke,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Function1)\u003e)\n\nIf you want to use the [material3's Clickable Card](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#Card(kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.ui.graphics.Shape,androidx.compose.material3.CardColors,androidx.compose.material3.CardElevation,androidx.compose.foundation.BorderStroke,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Function1)\u003e), you can create a [`MutableInteractionSource`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/interaction/MutableInteractionSource) and pass it to both the [`Card`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#Card(kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.ui.graphics.Shape,androidx.compose.material3.CardColors,androidx.compose.material3.CardElevation,androidx.compose.foundation.BorderStroke,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Function1)\u003e) and the `Modifier.draggableHandle` (or `Modifier.longPressDraggableHandle`), `Modifier.draggableHandle` will emit drag events to the [`MutableInteractionSource`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/interaction/MutableInteractionSource) so that the [`Card`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#Card(kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.ui.graphics.Shape,androidx.compose.material3.CardColors,androidx.compose.material3.CardElevation,androidx.compose.foundation.BorderStroke,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Function1)\u003e) can respond to the drag events:\n\n```kotlin\nval view = LocalView.current\n\nvar list by remember { mutableStateOf(List(100) { \"Item $it\" }) }\nval lazyListState = rememberLazyListState()\nval reorderableLazyListState = rememberReorderableLazyListState(lazyListState) { from, to -\u003e\n    list = list.toMutableList().apply {\n        add(to.index, removeAt(from.index))\n    }\n\n    ViewCompat.performHapticFeedback(\n        view,\n        HapticFeedbackConstantsCompat.SEGMENT_FREQUENT_TICK\n    )\n}\n\nLazyRow(\n    modifier = Modifier.fillMaxSize(),\n    state = lazyListState,\n    contentPadding = PaddingValues(8.dp),\n    horizontalArrangement = Arrangement.spacedBy(8.dp),\n) {\n    items(list, key = { it }) { item -\u003e\n        ReorderableItem(reorderableLazyListState, key = item) {\n            val interactionSource = remember { MutableInteractionSource() }\n\n            Card(\n                onClick = {},\n                interactionSource = interactionSource,\n            ) {\n                Column {\n                    Text(item, Modifier.padding(vertical = 8.dp))\n                    IconButton(\n                        modifier = Modifier.draggableHandle(\n                            onDragStarted = {\n                                ViewCompat.performHapticFeedback(\n                                    view,\n                                    HapticFeedbackConstantsCompat.GESTURE_START\n                                )\n                            },\n                            onDragStopped = {\n                                ViewCompat.performHapticFeedback(\n                                    view,\n                                    HapticFeedbackConstantsCompat.GESTURE_END\n                                )\n                            },\n                            interactionSource = interactionSource,\n                        ),\n                        onClick = {},\n                    ) {\n                        Icon(Icons.Rounded.DragHandle, contentDescription = \"Reorder\")\n                    }\n                }\n            }\n        }\n    }\n}\n```\n\n#### `LazyVerticalGrid`\n\nFind more examples in [`SimpleReorderableLazyVerticalGridScreen.kt`](demoApp/composeApp/src/commonMain/kotlin/sh/calvin/reorderable/demo/ui/SimpleReorderableLazyVerticalGridScreen.kt) in the demo app.\n\n##### Simple Example\n\nTo use this library with [`LazyVerticalGrid`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/grid/package-summary#LazyVerticalGrid(androidx.compose.foundation.lazy.grid.GridCells,androidx.compose.ui.Modifier,androidx.compose.foundation.lazy.grid.LazyGridState,androidx.compose.foundation.layout.PaddingValues,kotlin.Boolean,androidx.compose.foundation.layout.Arrangement.Vertical,androidx.compose.foundation.layout.Arrangement.Horizontal,androidx.compose.foundation.gestures.FlingBehavior,kotlin.Boolean,kotlin.Function1)\u003e), follow this basic structure:\n\n```kotlin\nval lazyGridState = rememberLazyGridState()\nval reorderableLazyGridState = rememberReorderableLazyGridState(lazyGridState) { from, to -\u003e\n    // Update the list\n}\n\nLazyVerticalGrid(state = lazyGridState) {\n    items(list, key = { /* item key */ }) {\n        ReorderableItem(reorderableLazyGridState, key = /* item key */) { isDragging -\u003e\n            // Item content\n\n            IconButton(\n                modifier = Modifier.draggableHandle(),\n                /* ... */\n            )\n        }\n    }\n}\n\n```\n\n##### Complete Example (with haptic feedback)\n\n\u003e [!NOTE]  \n\u003e `val view = LocalView.current` and `View.performHapticFeedback` are only available in Android. Comment out these lines if you are using this library in a multiplatform project.\n\n```kotlin\nval view = LocalView.current\n\nvar list by remember { mutableStateOf(List(100) { \"Item $it\" }) }\nval lazyGridState = rememberLazyGridState()\nval reorderableLazyGridState = rememberReorderableLazyGridState(lazyGridState) { from, to -\u003e\n    list = list.toMutableList().apply {\n        add(to.index, removeAt(from.index))\n    }\n\n    ViewCompat.performHapticFeedback(\n        view,\n        HapticFeedbackConstantsCompat.SEGMENT_FREQUENT_TICK\n    )\n}\n\nLazyVerticalGrid(\n    columns = GridCells.Adaptive(minSize = 96.dp),\n    modifier = Modifier.fillMaxSize(),\n    state = lazyGridState,\n    contentPadding = PaddingValues(8.dp),\n    verticalArrangement = Arrangement.spacedBy(8.dp),\n    horizontalArrangement = Arrangement.spacedBy(8.dp),\n) {\n    items(list, key = { it }) {\n        ReorderableItem(reorderableLazyGridState, key = it) { isDragging -\u003e\n            val elevation by animateDpAsState(if (isDragging) 4.dp else 0.dp)\n\n            Surface(shadowElevation = elevation) {\n                Row {\n                    Text(it, Modifier.padding(horizontal = 8.dp))\n                    IconButton(\n                        modifier = Modifier.draggableHandle(\n                            onDragStarted = {\n                                ViewCompat.performHapticFeedback(\n                                    view,\n                                    HapticFeedbackConstantsCompat.GESTURE_START\n                                )\n                            },\n                            onDragStopped = {\n                                ViewCompat.performHapticFeedback(\n                                    view,\n                                    HapticFeedbackConstantsCompat.GESTURE_END\n                                )\n                            },\n                        ),\n                        onClick = {},\n                    ) {\n                        Icon(Icons.Rounded.DragHandle, contentDescription = \"Reorder\")\n                    }\n                }\n            }\n        }\n    }\n}\n```\n\n##### Section Headers and Footers or Multiple Lists\n\nThe `from.index` and `to.index` in `onMove` are the indices of the items in the `LazyVerticalGrid`. If you have section headers or footers, you may need to adjust the indices accordingly. For example:\n\n```kotlin\nvar list by remember { mutableStateOf(List(100) { \"Item $it\" }) }\nval lazyGridState = rememberLazyGridState()\nval reorderableLazyGridState = rememberReorderableLazyGridState(lazyGridState) { from, to -\u003e\n    list = list.toMutableList().apply {\n        add(to.index - 1, removeAt(from.index - 1))\n    }\n}\n\nLazyVerticalGrid(\n    state = lazyGridState,\n    // ...\n) {\n    item {\n        Text(\"Header\")\n    }\n\n    items(list, key = { item -\u003e item.id }) { item -\u003e\n        ReorderableItem(reorderableLazyGridState, item.id) {\n            // ...\n        }\n    }\n}\n```\n\n##### Passing `Modifier.draggableHandle` to a Child Composable\n\nSince `Modifier.draggableHandle` and `Modifier.longPressDraggableHandle` can only be used in `ReorderableCollectionItemScope`, you may need to pass `ReorderableCollectionItemScope` to a child composable. For example:\n\n```kotlin\n@Composable\nfun Grid() {\n    // ...\n\n    LazyVerticalGrid(state = lazyGridState) {\n        items(Grid, key = { /* item key */ }) {\n            ReorderableItem(reorderableLazyGridState, key = /* item key */) { isDragging -\u003e\n                // Item content\n\n                DragHandle(this)\n            }\n        }\n    }\n}\n\n@Composable\nfun DragHandle(scope: ReorderableCollectionItemScope) {\n    IconButton(\n        modifier = with(scope) {\n            Modifier.draggableHandle()\n        },\n        /* ... */\n    )\n}\n```\n\n##### Scroll Trigger Padding\n\nIf your [`LazyVerticalGrid`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/grid/package-summary#LazyVerticalGrid(androidx.compose.foundation.lazy.grid.GridCells,androidx.compose.ui.Modifier,androidx.compose.foundation.lazy.grid.LazyGridState,androidx.compose.foundation.layout.PaddingValues,kotlin.Boolean,androidx.compose.foundation.layout.Arrangement.Vertical,androidx.compose.foundation.layout.Arrangement.Horizontal,androidx.compose.foundation.gestures.FlingBehavior,kotlin.Boolean,kotlin.Function1)\u003e) displays under navigation bar or notification bar, you may want to add `scrollThresholdPadding` to `rememberReorderableLazyGridState` to move the scroll trigger area out from under the navigation bar or notification bar.\n\n```kotlin\nval reorderableLazyGridState = rememberReorderableLazyGridState(\n    lazyGridState = lazyGridState,\n    scrollThresholdPadding = WindowInsets.systemBars.asPaddingValues(),\n) { from, to -\u003e\n    ...\n}\n```\n\n##### Use with [`Card`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#Card(kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.ui.graphics.Shape,androidx.compose.material3.CardColors,androidx.compose.material3.CardElevation,androidx.compose.foundation.BorderStroke,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Function1)\u003e)\n\nIf you want to use the [material3's Clickable Card](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#Card(kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.ui.graphics.Shape,androidx.compose.material3.CardColors,androidx.compose.material3.CardElevation,androidx.compose.foundation.BorderStroke,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Function1)\u003e), you can create a [`MutableInteractionSource`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/interaction/MutableInteractionSource) and pass it to both the [`Card`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#Card(kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.ui.graphics.Shape,androidx.compose.material3.CardColors,androidx.compose.material3.CardElevation,androidx.compose.foundation.BorderStroke,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Function1)\u003e) and the `Modifier.draggableHandle` (or `Modifier.longPressDraggableHandle`), `Modifier.draggableHandle` will emit drag events to the [`MutableInteractionSource`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/interaction/MutableInteractionSource) so that the [`Card`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#Card(kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.ui.graphics.Shape,androidx.compose.material3.CardColors,androidx.compose.material3.CardElevation,androidx.compose.foundation.BorderStroke,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Function1)\u003e) can respond to the drag events:\n\n```kotlin\nval view = LocalView.current\n\nvar list by remember { mutableStateOf(List(100) { \"Item $it\" }) }\nval lazyGridState = rememberLazyGridState()\nval reorderableLazyGridState = rememberReorderableLazyGridState(lazyGridState) { from, to -\u003e\n    list = list.toMutableList().apply {\n        add(to.index, removeAt(from.index))\n    }\n\n    ViewCompat.performHapticFeedback(\n        view,\n        HapticFeedbackConstantsCompat.SEGMENT_FREQUENT_TICK\n    )\n}\n\nLazyVerticalGrid(\n    columns = GridCells.Adaptive(minSize = 96.dp),\n    modifier = Modifier.fillMaxSize(),\n    state = lazyGridState,\n    contentPadding = PaddingValues(8.dp),\n    verticalArrangement = Arrangement.spacedBy(8.dp),\n    horizontalArrangement = Arrangement.spacedBy(8.dp),\n) {\n    items(list, key = { it }) { item -\u003e\n        ReorderableItem(reorderableLazyGridState, key = item) {\n            val interactionSource = remember { MutableInteractionSource() }\n\n            Card(\n                onClick = {},\n                interactionSource = interactionSource,\n            ) {\n                Row {\n                    Text(item, Modifier.padding(horizontal = 8.dp))\n                    IconButton(\n                        modifier = Modifier.draggableHandle(\n                            onDragStarted = {\n                                ViewCompat.performHapticFeedback(\n                                    view,\n                                    HapticFeedbackConstantsCompat.GESTURE_START\n                                )\n                            },\n                            onDragStopped = {\n                                ViewCompat.performHapticFeedback(\n                                    view,\n                                    HapticFeedbackConstantsCompat.GESTURE_END\n                                )\n                            },\n                            interactionSource = interactionSource,\n                        ),\n                        onClick = {},\n                    ) {\n                        Icon(Icons.Rounded.DragHandle, contentDescription = \"Reorder\")\n                    }\n                }\n            }\n        }\n    }\n}\n```\n\n#### `LazyHorizontalGrid`\n\nFind more examples in [`SimpleReorderableLazyHorizontalGridScreen.kt`](demoApp/composeApp/src/commonMain/kotlin/sh/calvin/reorderable/demo/ui/SimpleReorderableLazyHorizontalGridScreen.kt) in the demo app.\n\n##### Simple Example\n\nTo use this library with [`LazyHorizontalGrid`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/grid/package-summary#LazyHorizontalGrid(androidx.compose.foundation.lazy.grid.GridCells,androidx.compose.ui.Modifier,androidx.compose.foundation.lazy.grid.LazyStaggeredGridState,androidx.compose.foundation.layout.PaddingValues,kotlin.Boolean,androidx.compose.foundation.layout.Arrangement.Horizontal,androidx.compose.foundation.layout.Arrangement.Vertical,androidx.compose.foundation.gestures.FlingBehavior,kotlin.Boolean,kotlin.Function1)\u003e), follow this basic structure:\n\n```kotlin\nval lazyGridState = rememberLazyGridState()\nval reorderableLazyGridState = rememberReorderableLazyGridState(lazyGridState) { from, to -\u003e\n    // Update the list\n}\n\nLazyHorizontalGrid(state = lazyGridState) {\n    items(list, key = { /* item key */ }) {\n        ReorderableItem(reorderableLazyGridState, key = /* item key */) { isDragging -\u003e\n            // Item content\n\n            IconButton(\n                modifier = Modifier.draggableHandle(),\n                /* ... */\n            )\n        }\n    }\n}\n\n```\n\n##### Complete Example (with haptic feedback)\n\n\u003e [!NOTE]  \n\u003e `val view = LocalView.current` and `View.performHapticFeedback` are only available in Android. Comment out these lines if you are using this library in a multiplatform project.\n\n```kotlin\nval view = LocalView.current\n\nvar list by remember { mutableStateOf(List(100) { \"Item $it\" }) }\nval lazyGridState = rememberLazyGridState()\nval reorderableLazyGridState = rememberReorderableLazyGridState(lazyGridState) { from, to -\u003e\n    list = list.toMutableList().apply {\n        add(to.index, removeAt(from.index))\n    }\n\n    ViewCompat.performHapticFeedback(\n        view,\n        HapticFeedbackConstantsCompat.SEGMENT_FREQUENT_TICK\n    )\n}\n\nLazyHorizontalGrid(\n    rows = GridCells.Adaptive(minSize = 96.dp),\n    modifier = Modifier.fillMaxSize(),\n    state = lazyGridState,\n    contentPadding = PaddingValues(8.dp),\n    verticalArrangement = Arrangement.spacedBy(8.dp),\n    horizontalArrangement = Arrangement.spacedBy(8.dp),\n) {\n    items(list, key = { it }) {\n        ReorderableItem(reorderableLazyGridState, key = it) { isDragging -\u003e\n            val elevation by animateDpAsState(if (isDragging) 4.dp else 0.dp)\n\n            Surface(shadowElevation = elevation) {\n                Row {\n                    Text(it, Modifier.padding(horizontal = 8.dp))\n                    IconButton(\n                        modifier = Modifier.draggableHandle(\n                            onDragStarted = {\n                                ViewCompat.performHapticFeedback(\n                                    view,\n                                    HapticFeedbackConstantsCompat.GESTURE_START\n                                )\n                            },\n                            onDragStopped = {\n                                ViewCompat.performHapticFeedback(\n                                    view,\n                                    HapticFeedbackConstantsCompat.GESTURE_END\n                                )\n                            },\n                        ),\n                        onClick = {},\n                    ) {\n                        Icon(Icons.Rounded.DragHandle, contentDescription = \"Reorder\")\n                    }\n                }\n            }\n        }\n    }\n}\n```\n\n##### Section Headers and Footers or Multiple Lists\n\nThe `from.index` and `to.index` in `onMove` are the indices of the items in the `LazyHorizontalGrid`. If you have section headers or footers, you may need to adjust the indices accordingly. For example:\n\n```kotlin\nvar list by remember { mutableStateOf(List(100) { \"Item $it\" }) }\nval lazyGridState = rememberLazyGridState()\nval reorderableLazyGridState = rememberReorderableLazyGridState(lazyGridState) { from, to -\u003e\n    list = list.toMutableList().apply {\n        add(to.index - 1, removeAt(from.index - 1))\n    }\n}\n\nLazyHorizontalGrid(\n    state = lazyGridState,\n    // ...\n) {\n    item {\n        Text(\"Header\")\n    }\n\n    items(list, key = { item -\u003e item.id }) { item -\u003e\n        ReorderableItem(reorderableLazyGridState, item.id) {\n            // ...\n        }\n    }\n}\n```\n\n##### Passing `Modifier.draggableHandle` to a Child Composable\n\nSince `Modifier.draggableHandle` and `Modifier.longPressDraggableHandle` can only be used in `ReorderableCollectionItemScope`, you may need to pass `ReorderableCollectionItemScope` to a child composable. For example:\n\n```kotlin\n@Composable\nfun Grid() {\n    // ...\n\n    LazyHorizontalGrid(state = lazyGridState) {\n        items(Grid, key = { /* item key */ }) {\n            ReorderableItem(reorderableLazyGridState, key = /* item key */) { isDragging -\u003e\n                // Item content\n\n                DragHandle(this)\n            }\n        }\n    }\n}\n\n@Composable\nfun DragHandle(scope: ReorderableCollectionItemScope) {\n    IconButton(\n        modifier = with(scope) {\n            Modifier.draggableHandle()\n        },\n        /* ... */\n    )\n}\n```\n\n##### Scroll Trigger Padding\n\nIf your [`LazyHorizontalGrid`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/grid/package-summary#LazyHorizontalGrid(androidx.compose.foundation.lazy.grid.GridCells,androidx.compose.ui.Modifier,androidx.compose.foundation.lazy.grid.LazyStaggeredGridState,androidx.compose.foundation.layout.PaddingValues,kotlin.Boolean,androidx.compose.foundation.layout.Arrangement.Horizontal,androidx.compose.foundation.layout.Arrangement.Vertical,androidx.compose.foundation.gestures.FlingBehavior,kotlin.Boolean,kotlin.Function1)\u003e) displays under navigation bar or notification bar, you may want to add `scrollThresholdPadding` to `rememberReorderableLazyGridState` to move the scroll trigger area out from under the navigation bar or notification bar.\n\n```kotlin\nval reorderableLazyGridState = rememberReorderableLazyGridState(\n    lazyGridState = lazyGridState,\n    scrollThresholdPadding = WindowInsets.systemBars.asPaddingValues(),\n) { from, to -\u003e\n    ...\n}\n```\n\n##### Use with [`Card`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#Card(kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.ui.graphics.Shape,androidx.compose.material3.CardColors,androidx.compose.material3.CardElevation,androidx.compose.foundation.BorderStroke,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Function1)\u003e)\n\nIf you want to use the [material3's Clickable Card](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#Card(kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.ui.graphics.Shape,androidx.compose.material3.CardColors,androidx.compose.material3.CardElevation,androidx.compose.foundation.BorderStroke,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Function1)\u003e), you can create a [`MutableInteractionSource`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/interaction/MutableInteractionSource) and pass it to both the [`Card`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#Card(kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.ui.graphics.Shape,androidx.compose.material3.CardColors,androidx.compose.material3.CardElevation,androidx.compose.foundation.BorderStroke,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Function1)\u003e) and the `Modifier.draggableHandle` (or `Modifier.longPressDraggableHandle`), `Modifier.draggableHandle` will emit drag events to the [`MutableInteractionSource`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/interaction/MutableInteractionSource) so that the [`Card`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#Card(kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.ui.graphics.Shape,androidx.compose.material3.CardColors,androidx.compose.material3.CardElevation,androidx.compose.foundation.BorderStroke,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Function1)\u003e) can respond to the drag events:\n\n```kotlin\nval view = LocalView.current\n\nvar list by remember { mutableStateOf(List(100) { \"Item $it\" }) }\nval lazyGridState = rememberLazyGridState()\nval reorderableLazyGridState = rememberReorderableLazyGridState(lazyGridState) { from, to -\u003e\n    list = list.toMutableList().apply {\n        add(to.index, removeAt(from.index))\n    }\n\n    ViewCompat.performHapticFeedback(\n        view,\n        HapticFeedbackConstantsCompat.SEGMENT_FREQUENT_TICK\n    )\n}\n\nLazyHorizontalGrid(\n    rows = GridCells.Adaptive(minSize = 96.dp),\n    modifier = Modifier.fillMaxSize(),\n    state = lazyGridState,\n    contentPadding = PaddingValues(8.dp),\n    verticalArrangement = Arrangement.spacedBy(8.dp),\n    horizontalArrangement = Arrangement.spacedBy(8.dp),\n) {\n    items(list, key = { it }) { item -\u003e\n        ReorderableItem(reorderableLazyGridState, key = item) {\n            val interactionSource = remember { MutableInteractionSource() }\n\n            Card(\n                onClick = {},\n                interactionSource = interactionSource,\n            ) {\n                Row {\n                    Text(item, Modifier.padding(horizontal = 8.dp))\n                    IconButton(\n                        modifier = Modifier.draggableHandle(\n                            onDragStarted = {\n                                ViewCompat.performHapticFeedback(\n                                    view,\n                                    HapticFeedbackConstantsCompat.GESTURE_START\n                                )\n                            },\n                            onDragStopped = {\n                                ViewCompat.performHapticFeedback(\n                                    view,\n                                    HapticFeedbackConstantsCompat.GESTURE_END\n                                )\n                            },\n                            interactionSource = interactionSource,\n                        ),\n                        onClick = {},\n                    ) {\n                        Icon(Icons.Rounded.DragHandle, contentDescription = \"Reorder\")\n                    }\n                }\n            }\n        }\n    }\n}\n```\n\n#### `LazyVerticalStaggeredGrid`\n\nFind more examples in [`SimpleReorderableLazyVerticalStaggeredGridScreen.kt`](demoApp/composeApp/src/commonMain/kotlin/sh/calvin/reorderable/demo/ui/SimpleReorderableLazyVerticalStaggeredGridScreen.kt) in the demo app.\n\n##### Simple Example\n\nTo use this library with [`LazyVerticalStaggeredGrid`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/staggeredgrid/package-summary#LazyVerticalStaggeredGrid(androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells,androidx.compose.ui.Modifier,androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridState,androidx.compose.foundation.layout.PaddingValues,kotlin.Boolean,androidx.compose.ui.unit.Dp,androidx.compose.foundation.layout.Arrangement.Horizontal,androidx.compose.foundation.gestures.FlingBehavior,kotlin.Boolean,kotlin.Function1)\u003e), follow this basic structure:\n\n```kotlin\nval lazyStaggeredGridState = rememberLazyStaggeredGridState()\nval reorderableLazyStaggeredGridState = rememberReorderableLazyStaggeredGridState(lazyStaggeredGridState) { from, to -\u003e\n    // Update the list\n}\n\nLazyVerticalStaggeredGrid(state = lazyStaggeredGridState) {\n    items(list, key = { /* item key */ }) {\n        ReorderableItem(reorderableLazyStaggeredGridState, key = /* item key */) { isDragging -\u003e\n            // Item content\n\n            IconButton(\n                modifier = Modifier.draggableHandle(),\n                /* ... */\n            )\n        }\n    }\n}\n\n```\n\n##### Complete Example (with haptic feedback)\n\n\u003e [!NOTE]  \n\u003e `val view = LocalView.current` and `View.performHapticFeedback` are only available in Android. Comment out these lines if you are using this library in a multiplatform project.\n\n```kotlin\nval view = LocalView.current\n\nvar list by remember { mutableStateOf(List(100) { \"Item $it\" }) }\nval lazyStaggeredGridState = rememberLazyStaggeredGridState()\nval reorderableLazyStaggeredGridState = rememberReorderableLazyStaggeredGridState(lazyStaggeredGridState) { from, to -\u003e\n    list = list.toMutableList().apply {\n        add(to.index, removeAt(from.index))\n    }\n\n    ViewCompat.performHapticFeedback(\n        view,\n        HapticFeedbackConstantsCompat.SEGMENT_FREQUENT_TICK\n    )\n}\n\nLazyVerticalStaggeredGrid(\n    columns = StaggeredGridCells.Adaptive(minSize = 96.dp),\n    modifier = Modifier.fillMaxSize(),\n    state = lazyStaggeredGridState,\n    contentPadding = PaddingValues(8.dp),\n    verticalItemSpacing = 8.dp,\n    horizontalArrangement = Arrangement.spacedBy(8.dp),\n) {\n    items(list, key = { it }) {\n        ReorderableItem(reorderableLazyStaggeredGridState, key = it) { isDragging -\u003e\n            val elevation by animateDpAsState(if (isDragging) 4.dp else 0.dp)\n\n            Surface(shadowElevation = elevation) {\n                Row {\n                    Text(it, Modifier.padding(horizontal = 8.dp))\n                    IconButton(\n                        modifier = Modifier.draggableHandle(\n                            onDragStarted = {\n                                ViewCompat.performHapticFeedback(\n                                    view,\n                                    HapticFeedbackConstantsCompat.GESTURE_START\n                                )\n                            },\n                            onDragStopped = {\n                                ViewCompat.performHapticFeedback(\n                                    view,\n                                    HapticFeedbackConstantsCompat.GESTURE_END\n                                )\n                            },\n                        ),\n                        onClick = {},\n                    ) {\n                        Icon(Icons.Rounded.DragHandle, contentDescription = \"Reorder\")\n                    }\n                }\n            }\n        }\n    }\n}\n```\n\n##### Section Headers and Footers or Multiple Lists\n\nThe `from.index` and `to.index` in `onMove` are the indices of the items in the `LazyVerticalStaggeredGrid`. If you have section headers or footers, you may need to adjust the indices accordingly. For example:\n\n```kotlin\nvar list by remember { mutableStateOf(List(100) { \"Item $it\" }) }\nval lazyStaggeredGridState = rememberLazyStaggeredGridState()\nval reorderableLazyStaggeredGridState = rememberReorderableLazyStaggeredGridState(lazyStaggeredGridState) { from, to -\u003e\n    list = list.toMutableList().apply {\n        add(to.index - 1, removeAt(from.index - 1))\n    }\n}\n\nLazyVerticalStaggeredGrid(\n    state = lazyStaggeredGridState,\n    // ...\n) {\n    item {\n        Text(\"Header\")\n    }\n\n    items(list, key = { item -\u003e item.id }) { item -\u003e\n        ReorderableItem(reorderableLazyStaggeredGridState, item.id) {\n            // ...\n        }\n    }\n}\n```\n\n##### Passing `Modifier.draggableHandle` to a Child Composable\n\nSince `Modifier.draggableHandle` and `Modifier.longPressDraggableHandle` can only be used in `ReorderableCollectionItemScope`, you may need to pass `ReorderableCollectionItemScope` to a child composable. For example:\n\n```kotlin\n@Composable\nfun Grid() {\n    // ...\n\n    LazyVerticalStaggeredGrid(state = lazyStaggeredGridState) {\n        items(list, key = { /* item key */ }) {\n            ReorderableItem(reorderableLazyStaggeredGridState, key = /* item key */) { isDragging -\u003e\n                // Item content\n\n                DragHandle(this)\n            }\n        }\n    }\n}\n\n@Composable\nfun DragHandle(scope: ReorderableCollectionItemScope) {\n    IconButton(\n        modifier = with(scope) {\n            Modifier.draggableHandle()\n        },\n        /* ... */\n    )\n}\n```\n\n##### Scroll Trigger Padding\n\nIf your [`LazyVerticalStaggeredGrid`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/staggeredgrid/package-summary#LazyVerticalStaggeredGrid(androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells,androidx.compose.ui.Modifier,androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridState,androidx.compose.foundation.layout.PaddingValues,kotlin.Boolean,androidx.compose.ui.unit.Dp,androidx.compose.foundation.layout.Arrangement.Horizontal,androidx.compose.foundation.gestures.FlingBehavior,kotlin.Boolean,kotlin.Function1)\u003e) displays under navigation bar or notification bar, you may want to add `scrollThresholdPadding` to `rememberReorderableLazyStaggeredGridState` to move the scroll trigger area out from under the navigation bar or notification bar.\n\n```kotlin\nval reorderableLazyStaggeredGridState = rememberReorderableLazyStaggeredGridState(\n    lazyStaggeredGridState = lazyStaggeredGridState,\n    scrollThresholdPadding = WindowInsets.systemBars.asPaddingValues(),\n) { from, to -\u003e\n    ...\n}\n```\n\n##### Use with [`Card`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#Card(kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.ui.graphics.Shape,androidx.compose.material3.CardColors,androidx.compose.material3.CardElevation,androidx.compose.foundation.BorderStroke,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Function1)\u003e)\n\nIf you want to use the [material3's Clickable Card](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#Card(kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.ui.graphics.Shape,androidx.compose.material3.CardColors,androidx.compose.material3.CardElevation,androidx.compose.foundation.BorderStroke,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Function1)\u003e), you can create a [`MutableInteractionSource`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/interaction/MutableInteractionSource) and pass it to both the [`Card`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#Card(kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.ui.graphics.Shape,androidx.compose.material3.CardColors,androidx.compose.material3.CardElevation,androidx.compose.foundation.BorderStroke,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Function1)\u003e) and the `Modifier.draggableHandle` (or `Modifier.longPressDraggableHandle`), `Modifier.draggableHandle` will emit drag events to the [`MutableInteractionSource`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/interaction/MutableInteractionSource) so that the [`Card`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#Card(kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.ui.graphics.Shape,androidx.compose.material3.CardColors,androidx.compose.material3.CardElevation,androidx.compose.foundation.BorderStroke,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Function1)\u003e) can respond to the drag events:\n\n```kotlin\nval view = LocalView.current\n\nvar list by remember { mutableStateOf(List(100) { \"Item $it\" }) }\nval lazyStaggeredGridState = rememberLazyStaggeredGridState()\nval reorderableLazyStaggeredGridState = rememberReorderableLazyStaggeredGridState(lazyStaggeredGridState) { from, to -\u003e\n    list = list.toMutableList().apply {\n        add(to.index, removeAt(from.index))\n    }\n\n    ViewCompat.performHapticFeedback(\n        view,\n        HapticFeedbackConstantsCompat.SEGMENT_FREQUENT_TICK\n    )\n}\n\nLazyVerticalStaggeredGrid(\n    columns = StaggeredGridCells.Adaptive(minSize = 96.dp),\n    modifier = Modifier.fillMaxSize(),\n    state = lazyStaggeredGridState,\n    contentPadding = PaddingValues(8.dp),\n    verticalItemSpacing = 8.dp,\n    horizontalArrangement = Arrangement.spacedBy(8.dp),\n) {\n    items(list, key = { it }) { item -\u003e\n        ReorderableItem(reorderableLazyStaggeredGridState, key = item) {\n            val interactionSource = remember { MutableInteractionSource() }\n\n            Card(\n                onClick = {},\n                interactionSource = interactionSource,\n            ) {\n                Row {\n                    Text(item, Modifier.padding(horizontal = 8.dp))\n                    IconButton(\n                        modifier = Modifier.draggableHandle(\n                            onDragStarted = {\n                                ViewCompat.performHapticFeedback(\n                                    view,\n                                    HapticFeedbackConstantsCompat.GESTURE_START\n                                )\n                            },\n                            onDragStopped = {\n                                ViewCompat.performHapticFeedback(\n                                    view,\n                                    HapticFeedbackConstantsCompat.GESTURE_END\n                                )\n                            },\n                            interactionSource = interactionSource,\n                        ),\n                        onClick = {},\n                    ) {\n                        Icon(Icons.Rounded.DragHandle, contentDescription = \"Reorder\")\n                    }\n                }\n            }\n        }\n    }\n}\n```\n\n#### `LazyHorizontalStaggeredGrid`\n\nFind more examples in [`SimpleReorderableLazyHorizontalStaggeredGridScreen.kt`](demoApp/composeApp/src/commonMain/kotlin/sh/calvin/reorderable/demo/ui/SimpleReorderableLazyHorizontalStaggeredGridScreen.kt) in the demo app.\n\n##### Simple Example\n\nTo use this library with [`LazyHorizontalStaggeredGrid`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/staggeredgrid/package-summary#LazyHorizontalStaggeredGrid(androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells,androidx.compose.ui.Modifier,androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridState,androidx.compose.foundation.layout.PaddingValues,kotlin.Boolean,androidx.compose.foundation.layout.Arrangement.Vertical,androidx.compose.ui.unit.Dp,androidx.compose.foundation.gestures.FlingBehavior,kotlin.Boolean,kotlin.Function1)\u003e), follow this basic structure:\n\n```kotlin\nval lazyStaggeredGridState = rememberLazyStaggeredGridState()\nval reorderableLazyStaggeredGridState = rememberReorderableLazyStaggeredGridState(lazyStaggeredGridState) { from, to -\u003e\n    // Update the list\n}\n\nLazyHorizontalStaggeredGrid(state = lazyStaggeredGridState) {\n    items(list, key = { /* item key */ }) {\n        ReorderableItem(reorderableLazyStaggeredGridState, key = /* item key */) { isDragging -\u003e\n            // Item content\n\n            IconButton(\n                modifier = Modifier.draggableHandle(),\n                /* ... */\n            )\n        }\n    }\n}\n\n```\n\n##### Complete Example (with haptic feedback)\n\n\u003e [!NOTE]  \n\u003e `val view = LocalView.current` and `View.performHapticFeedback` are only available in Android. Comment out these lines if you are using this library in a multiplatform project.\n\n```kotlin\nval view = LocalView.current\n\nvar list by remember { mutableStateOf(List(100) { \"Item $it\" }) }\nval lazyStaggeredGridState = rememberLazyStaggeredGridState()\nval reorderableLazyStaggeredGridState = rememberReorderableLazyStaggeredGridState(lazyStaggeredGridState) { from, to -\u003e\n    list = list.toMutableList().apply {\n        add(to.index, removeAt(from.index))\n    }\n\n    ViewCompat.performHapticFeedback(\n        view,\n        HapticFeedbackConstantsCompat.SEGMENT_FREQUENT_TICK\n    )\n}\n\nLazyHorizontalStaggeredGrid(\n    rows = StaggeredGridCells.Adaptive(minSize = 96.dp),\n    modifier = Modifier.fillMaxSize(),\n    state = lazyStaggeredGridState,\n    contentPadding = PaddingValues(8.dp),\n    verticalArrangement = Arrangement.spacedBy(8.dp),\n    horizontalItemSpacing = 8.dp,\n) {\n    items(list, key = { it }) {\n        ReorderableItem(reorderableLazyStaggeredGridState, key = it) { isDragging -\u003e\n            val elevation by animateDpAsState(if (isDragging) 4.dp else 0.dp)\n\n            Surface(shadowElevation = elevation) {\n                Row {\n                    Text(it, Modifier.padding(horizontal = 8.dp))\n                    IconButton(\n                        modifier = Modifier.draggableHandle(\n                            onDragStarted = {\n                                ViewCompat.performHapticFeedback(\n                                    view,\n                                    HapticFeedbackConstantsCompat.GESTURE_START\n                                )\n                            },\n                            onDragStopped = {\n                                ViewCompat.performHapticFeedback(\n                                    view,\n                                    HapticFeedbackConstantsCompat.GESTURE_END\n                                )\n                            },\n                        ),\n                        onClick = {},\n                    ) {\n                        Icon(Icons.Rounded.DragHandle, contentDescription = \"Reorder\")\n                    }\n                }\n            }\n        }\n    }\n}\n```\n\n##### Section Headers and Footers or Multiple Lists\n\nThe `from.index` and `to.index` in `onMove` are the indices of the items in the `LazyHorizontalStaggeredGrid`. If you have section headers or footers, you may need to adjust the indices accordingly. For example:\n\n```kotlin\nvar list by remember { mutableStateOf(List(100) { \"Item $it\" }) }\nval lazyStaggeredGridState = rememberLazyStaggeredGridState()\nval reorderableLazyStaggeredGridState = rememberReorderableLazyStaggeredGridState(lazyStaggeredGridState) { from, to -\u003e\n    list = list.toMutableList().apply {\n        add(to.index - 1, removeAt(from.index - 1))\n    }\n}\n\nLazyHorizontalStaggeredGrid(\n    state = lazyStaggeredGridState,\n    // ...\n) {\n    item {\n        Text(\"Header\")\n    }\n\n    items(list, key = { item -\u003e item.id }) { item -\u003e\n        ReorderableItem(reorderableLazyStaggeredGridState, item.id) {\n            // ...\n        }\n    }\n}\n```\n\n##### Passing `Modifier.draggableHandle` to a Child Composable\n\nSince `Modifier.draggableHandle` and `Modifier.longPressDraggableHandle` can only be used in `ReorderableCollectionItemScope`, you may need to pass `ReorderableCollectionItemScope` to a child composable. For example:\n\n```kotlin\n@Composable\nfun Grid() {\n    // ...\n\n    LazyHorizontalStaggeredGrid(state = lazyStaggeredGridState) {\n        items(list, key = { /* item key */ }) {\n            ReorderableItem(reorderableLazyStaggeredGridState, key = /* item key */) { isDragging -\u003e\n                // Item content\n\n                DragHandle(this)\n            }\n        }\n    }\n}\n\n@Composable\nfun DragHandle(scope: ReorderableCollectionItemScope) {\n    IconButton(\n        modifier = with(scope) {\n            Modifier.draggableHandle()\n        },\n        /* ... */\n    )\n}\n```\n\n##### Scroll Trigger Padding\n\nIf your [`LazyHorizontalStaggeredGrid`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/staggeredgrid/package-summary#LazyHorizontalStaggeredGrid(androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells,androidx.compose.ui.Modifier,androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridState,androidx.compose.foundation.layout.PaddingValues,kotlin.Boolean,androidx.compose.foundation.layout.Arrangement.Vertical,androidx.compose.ui.unit.Dp,androidx.compose.foundation.gestures.FlingBehavior,kotlin.Boolean,kotlin.Function1)\u003e) displays under navigation bar or notification bar, you may want to add `scrollThresholdPadding` to `rememberReorderableLazyStaggeredGridState` to move the scroll trigger area out from under the navigation bar or notification bar.\n\n```kotlin\nval reorderableLazyStaggeredGridState = rememberReorderableLazyStaggeredGridState(\n    lazyStaggeredGridState = lazyStaggeredGridState,\n    scrollThresholdPadding = WindowInsets.systemBars.asPaddingValues(),\n) { from, to -\u003e\n    ...\n}\n```\n\n##### Use with [`Card`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#Card(kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.ui.graphics.Shape,androidx.compose.material3.CardColors,androidx.compose.material3.CardElevation,androidx.compose.foundation.BorderStroke,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Function1)\u003e)\n\nIf you want to use the [material3's Clickable Card](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#Card(kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.ui.graphics.Shape,androidx.compose.material3.CardColors,androidx.compose.material3.CardElevation,androidx.compose.foundation.BorderStroke,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Function1)\u003e), you can create a [`MutableInteractionSource`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/interaction/MutableInteractionSource) and pass it to both the [`Card`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#Card(kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.ui.graphics.Shape,androidx.compose.material3.CardColors,androidx.compose.material3.CardElevation,androidx.compose.foundation.BorderStroke,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Function1)\u003e) and the `Modifier.draggableHandle` (or `Modifier.longPressDraggableHandle`), `Modifier.draggableHandle` will emit drag events to the [`MutableInteractionSource`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/interaction/MutableInteractionSource) so that the [`Card`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#Card(kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.ui.graphics.Shape,androidx.compose.material3.CardColors,androidx.compose.material3.CardElevation,androidx.compose.foundation.BorderStroke,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Function1)\u003e) can respond to the drag events:\n\n```kotlin\nval view = LocalView.current\n\nvar list by remember { mutableStateOf(List(100) { \"Item $it\" }) }\nval lazyStaggeredGridState = rememberLazyStaggeredGridState()\nval reorderableLazyStaggeredGridState = rememberReorderableLazyStaggeredGridState(lazyStaggeredGridState) { from, to -\u003e\n    list = list.toMutableList().apply {\n        add(to.index, removeAt(from.index))\n    }\n\n    ViewCompat.performHapticFeedback(\n        view,\n        HapticFeedbackConstantsCompat.SEGMENT_FREQUENT_TICK\n    )\n}\n\nLazyHorizontalStaggeredGrid(\n    rows = StaggeredGridCells.Adaptive(minSize = 96.dp),\n    modifier = Modifier.fillMaxSize(),\n    state = lazyStaggeredGridState,\n    contentPadding = PaddingValues(8.dp),\n    verticalArrangement = Arrangement.spacedBy(8.dp),\n    horizontalItemSpacing = 8.dp,\n) {\n    items(list, key = { it }) { item -\u003e\n        ReorderableItem(reorderableLazyStaggeredGridState, key = item) {\n            val interactionSource = remember { MutableInteractionSource() }\n\n            Card(\n                onClick = {},\n                interactionSource = interactionSource,\n            ) {\n                Row {\n                    Text(item, Modifier.padding(horizontal = 8.dp))\n                    IconButton(\n                        modifier = Modifier.draggableHandle(\n                            onDragStarted = {\n                                ViewCompat.performHapticFeedback(\n                                    view,\n                                    HapticFeedbackConstantsCompat.GESTURE_START\n                                )\n                            },\n                            onDragStopped = {\n                                ViewCompat.performHapticFeedback(\n                                    view,\n                                    HapticFeedbackConstantsCompat.GESTURE_END\n                                )\n                            },\n                            interactionSource = interactionSource,\n                        ),\n                        onClick = {},\n                    ) {\n                        Icon(Icons.Rounded.DragHandle, contentDescription = \"Reorder\")\n                    }\n                }\n            }\n        }\n    }\n}\n```\n\n#### `Column`\n\nFind more examples in [`ReorderableColumnScreen.kt`](demoApp/composeApp/src/commonMain/kotlin/sh/calvin/reorderable/demo/ui/ReorderableColumnScreen.kt) and [`LongPressHandleReorderableColumnScreen.kt`](demoApp/composeApp/src/commonMain/kotlin/sh/calvin/reorderable/demo/ui/LongPressHandleReorderableColumnScreen.kt) in the demo app.\n\n##### Simple Example\n\nTo use this library with [`Column`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/package-summary#Column(androidx.compose.ui.Modifier,androidx.compose.foundation.layout.Arrangement.Vertical,androidx.compose.ui.Alignment.Horizontal,kotlin.Function1)\u003e), follow this basic structure:\n\n```kotlin\nReorderableColumn(\n    list = list,\n    onSettle = { fromIndex, toIndex -\u003e\n        // Update the list\n    },\n) { index, item, isDragging -\u003e\n    key(item.id) {\n        // Item content\n\n        IconButton(modifier = Modifier.draggableHandle(), /* ... */)\n    }\n}\n```\n\n##### Complete Example (with haptic feedback)\n\n\u003e [!NOTE]  \n\u003e `val view = LocalView.current` and `View.performHapticFeedback` are only available in Android. Comment out these lines if you are using this library in a multiplatform project.\n\n```kotlin\nval view = LocalView.current\n\nvar list by remember { mutableStateOf(List(4) { \"Item $it\" }) }\n\nReorderableColumn(\n    modifier = Modifier\n        .fillMaxSize()\n        .padding(8.dp),\n    list = list,\n    onSettle = { fromIndex, toIndex -\u003e\n        list = list.toMutableList().apply {\n            add(toIndex, removeAt(fromIndex))\n        }\n    },\n    onMove = {\n        ViewCompat.performHapticFeedback(\n            view,\n            HapticFeedbackConstantsCompat.SEGMENT_FREQUENT_TICK\n        )\n    },\n    verticalArrangement = Arrangement.spacedBy(8.dp),\n) { _, item, isDragging -\u003e\n    key(item) {\n        val elevation by animateDpAsState(if (isDragging) 4.dp else 0.dp)\n\n        Surface(shadowElevation = elevation) {\n            Row {\n                Text(item, Modifier.padding(horizontal = 8.dp))\n                IconButton(\n                    modifier = Modifier.draggableHandle(\n                        onDragStarted = {\n                            ViewCompat.performHapticFeedback(\n                                view,\n                                HapticFeedbackConstantsCompat.GESTURE_START\n                            )\n                        },\n                        onDragStopped = {\n                            ViewCompat.performHapticFeedback(\n                                view,\n                                HapticFeedbackConstantsCompat.GESTURE_END\n                            )\n                        },\n                    ),\n                    onClick = {},\n                ) {\n                    Icon(Icons.Rounded.DragHandle, contentDescription = \"Reorder\")\n                }\n            }\n        }\n    }\n}\n```\n\n##### Passing `Modifier.draggableHandle` to a Child Composable\n\nSince `Modifier.draggableHandle` and `Modifier.longPressDraggableHandle` can only be used in `ReorderableScope`, you may need to pass `ReorderableScope` to a child composable. For example:\n\n```kotlin\n@Composable\nfun List() {\n    // ...\n\n    ReorderableColumn(\n        list = list,\n        onSettle = { fromIndex, toIndex -\u003e\n            // Update the list\n        },\n    ) { index, item, isDragging -\u003e\n        key(item.id) {\n            // Item content\n\n            DragHandle(this)\n        }\n    }\n}\n\n@Composable\nfun DragHandle(scope: ReorderableScope) {\n    IconButton(modifier = with(scope) { Modifier.draggableHandle() }, /* ... */)\n}\n```\n\n##### Use with [`Card`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#Card(kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.ui.graphics.Shape,androidx.compose.material3.CardColors,androidx.compose.material3.CardElevation,androidx.compose.foundation.BorderStroke,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Function1)\u003e)\n\nIf you want to use the [material3's Clickable Card](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#Card(kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.ui.graphics.Shape,androidx.compose.material3.CardColors,androidx.compose.material3.CardElevation,androidx.compose.foundation.BorderStroke,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Function1)\u003e), you can create a [`MutableInteractionSource`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/interaction/MutableInteractionSource) and pass it to both the [`Card`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#Card(kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.ui.graphics.Shape,androidx.compose.material3.CardColors,androidx.compose.material3.CardElevation,androidx.compose.foundation.BorderStroke,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Function1)\u003e) and the `Modifier.draggableHandle` (or `Modifier.longPressDraggableHandle`), `Modifier.draggableHandle` will emit drag events to the [`MutableInteractionSource`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/interaction/MutableInteractionSource) so that the [`Card`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#Card(kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.ui.graphics.Shape,androidx.compose.material3.CardColors,androidx.compose.material3.CardElevation,androidx.compose.foundation.BorderStroke,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Function1)\u003e) can respond to the drag events:\n\n```kotlin\nval view = LocalView.current\n\nvar list by remember { mutableStateOf(List(4) { \"Item $it\" }) }\n\nReorderableColumn(\n    modifier = Modifier\n        .fillMaxSize()\n        .padding(8.dp),\n    list = list,\n    onSettle = { fromIndex, toIndex -\u003e\n        list = list.toMutableList().apply {\n            add(toIndex, removeAt(fromIndex))\n        }\n    },\n    onMove = {\n        ViewCompat.performHapticFeedback(\n            view,\n            HapticFeedbackConstantsCompat.SEGMENT_FREQUENT_TICK\n        )\n    },\n    verticalArrangement = Arrangement.spacedBy(8.dp),\n) { _, item, _ -\u003e\n    key(item) {\n        val interactionSource = remember { MutableInteractionSource() }\n\n        Card(\n            onClick = {},\n            interactionSource = interactionSource,\n        ) {\n            Row {\n                Text(item, Modifier.padding(horizontal = 8.dp))\n                IconButton(\n                    modifier = Modifier.draggableHandle(\n                        onDragStarted = {\n                            ViewCompat.performHapticFeedback(\n                                view,\n                                HapticFeedbackConstantsCompat.GESTURE_START\n                            )\n                        },\n                        onDragStopped = {\n                            ViewCompat.performHapticFeedback(\n                                view,\n                                HapticFeedbackConstantsCompat.GESTURE_END\n                            )\n                        },\n                        interactionSource = interactionSource,\n                    ),\n                    onClick = {},\n                ) {\n                    Icon(Icons.Rounded.DragHandle, contentDescription = \"Reorder\")\n                }\n            }\n        }\n    }\n}\n```\n\n#### `Row`\n\nSee [`ReorderableRowScreen.kt`](demoApp/composeApp/src/commonMain/kotlin/sh/calvin/reorderable/demo/ui/ReorderableRowScreen.kt) in the demo app.\n\n##### Simple Example\n\nTo use this library with [`Row`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/package-summary#Row(androidx.compose.ui.Modifier,androidx.compose.foundation.layout.Arrangement.Horizontal,androidx.compose.ui.Alignment.Vertical,kotlin.Function1)\u003e), follow this basic structure:\n\n```kotlin\nReorderableRow(\n    list = list,\n    onSettle = { fromIndex, toIndex -\u003e\n        // Update the list\n    },\n) { index, item, isDragging -\u003e\n    key(item.id) {\n        // Item content\n\n        IconButton(modifier = Modifier.draggableHandle(), /* ... */)\n    }\n}\n```\n\n##### Complete Example (with haptic feedback)\n\n\u003e [!NOTE]  \n\u003e `val view = LocalView.current` and `View.performHapticFeedback` are only available in Android. Comment out these lines if you are using this library in a multiplatform project.\n\n```kotlin\nval view = LocalView.current\n\nvar list by remember { mutableStateOf(List(4) { \"Item $it\" }) }\n\nReorderableRow(\n    modifier = Modifier\n        .fillMaxSize()\n        .padding(8.dp),\n    list = list,\n    onSettle = { fromIndex, toIndex -\u003e\n        list = list.toMutableList().apply {\n            add(toIndex, removeAt(fromIndex))\n        }\n    },\n    onMove = {\n        ViewCompat.performHapticFeedback(\n            view,\n            HapticFeedbackConstantsCompat.SEGMENT_FREQUENT_TICK\n        )\n    },\n    verticalArrangement = Arrangement.spacedBy(8.dp),\n) { _, item, isDragging -\u003e\n    key(item) {\n        val elevation by animateDpAsState(if (isDragging) 4.dp else 0.dp)\n\n        Surface(shadowElevation = elevation) {\n            Column {\n                Text(item, Modifier.padding(vertical = 8.dp))\n                IconButton(\n                    modifier = Modifier.draggableHandle(\n                        onDragStarted = {\n                            ViewCompat.performHapticFeedback(\n                                view,\n                                HapticFeedbackConstantsCompat.GESTURE_START\n                            )\n                        },\n                        onDragStopped = {\n                            ViewCompat.performHapticFeedback(\n                                view,\n                                HapticFeedbackConstantsCompat.GESTURE_END\n                            )\n                        },\n                    ),\n                    onClick = {},\n                ) {\n                    Icon(Icons.Rounded.DragHandle, contentDescription = \"Reorder\")\n                }\n            }\n        }\n    }\n}\n```\n\n##### Passing `Modifier.draggableHandle` to a Child Composable\n\nSince `Modifier.draggableHandle` and `Modifier.longPressDraggableHandle` can only be used in `ReorderableScope`, you may need to pass `ReorderableScope` to a child composable. For example:\n\n```kotlin\n@Composable\nfun List() {\n    // ...\n\n    ReorderableRow(\n        list = list,\n        onSettle = { fromIndex, toIndex -\u003e\n            // Update the list\n        },\n    ) { index, item, isDragging -\u003e\n        key(item.id) {\n            // Item content\n\n            DragHandle(this)\n        }\n    }\n}\n\n@Composable\nfun DragHandle(scope: ReorderableScope) {\n    IconButton(modifier = with(scope) { Modifier.draggableHandle() }, /* ... */)\n}\n```\n\n##### Use with [`Card`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#Card(kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.ui.graphics.Shape,androidx.compose.material3.CardColors,androidx.compose.material3.CardElevation,androidx.compose.foundation.BorderStroke,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Function1)\u003e)\n\nIf you want to use the [material3's Clickable Card](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#Card(kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.ui.graphics.Shape,androidx.compose.material3.CardColors,androidx.compose.material3.CardElevation,androidx.compose.foundation.BorderStroke,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Function1)\u003e), you can create a [`MutableInteractionSource`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/interaction/MutableInteractionSource) and pass it to both the [`Card`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#Card(kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.ui.graphics.Shape,androidx.compose.material3.CardColors,androidx.compose.material3.CardElevation,androidx.compose.foundation.BorderStroke,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Function1)\u003e) and the `Modifier.draggableHandle` (or `Modifier.longPressDraggableHandle`), `Modifier.draggableHandle` will emit drag events to the [`MutableInteractionSource`](https://developer.android.com/reference/kotlin/androidx/compose/foundation/interaction/MutableInteractionSource) so that the [`Card`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#Card(kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.ui.graphics.Shape,androidx.compose.material3.CardColors,androidx.compose.material3.CardElevation,androidx.compose.foundation.BorderStroke,androidx.compose.foundation.interaction.MutableInteractionSource,kotlin.Function1)\u003e) can respond to the drag events:\n\n```kotlin\nval view = LocalView.current\n\nvar list by remember { mutableStateOf(List(4) { \"Item $it\" }) }\n\nReorderableRow(\n    modifier = Modifier\n        .fillMaxSize()\n        .padding(8.dp),\n    list = list,\n    onSettle = { fromIndex, toIndex -\u003e\n        list = list.toMutableList().apply {\n            add(toIndex, removeAt(fromIndex))\n        }\n    },\n    onMove = {\n        ViewCompat.performHapticFeedback(\n            view,\n            HapticFeedbackConstantsCompat.SEGMENT_FREQUENT_TICK\n        )\n    },\n    verticalArrangement = Arrangement.spacedBy(8.dp),\n) { _, item, _ -\u003e\n    key(item) {\n        val interactionSource = remember { MutableInteractionSource() }\n\n        Card(\n            onClick = {},\n            interactionSource = interactionSource,\n        ) {\n            Column {\n                Text(item, Modifier.padding(vertical = 8.dp))\n                IconButton(\n                    modifier = Modifier.draggableHandle(\n                        onDragStarted = {\n                            ViewCompat.performHapticFeedback(\n                                view,\n                                HapticFeedbackConstantsCompat.GESTURE_START\n                            )\n                        },\n                        onDragStopped = {\n                            ViewCompat.performHapticFeedback(\n                                view,\n                                HapticFeedbackConstantsCompat.GESTURE_END\n                            )\n                        },\n                        interactionSource = interactionSource,\n                    ),\n                    onClick = {},\n                ) {\n                    Icon(Icons.Rounded.DragHandle, contentDescription = \"Reorder\")\n                }\n            }\n        }\n    }\n}\n```\n\n#### Accessibility\n\nSee the demo app for examples of how to make the reorderable list accessible.\n\nIf the items in the list do not contain any button besides the drag handle, I recommend adding \"Move Up\"/\"Move Down\"/\"Move Left\"/\"Move Right\" actions to the TalkBack menu in each item via [`SemanticsPropertyReceiver.customActions`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/ui/semantics/package-summary#(androidx.compose.ui.semantics.SemanticsPropertyReceiver).customActions()\u003e) and applying [`Modifier.clearAndSetSemantics`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/ui/semantics/package-summary#(androidx.compose.ui.Modifier).clearAndSetSemantics(kotlin.Function1)\u003e) to the drag handle button to make the drag handle button not focusable for TalkBack. For more information, see [Key steps to improve Compose accessibility](https://developer.android.com/develop/ui/compose/accessibility/key-steps#custom-actions).\n\n#### FAQ\n\n##### When `onMove` is called to move items, the dragging item flickers/jumps/flashes.\n\n\u003e [!NOTE]  \n\u003e This assumes you're using version 2.0.3 or later of this library.\n\nThe `onMove` function expects the list to be updated before it returns. If the list is updated after `onMove` returns, the dragging item will flicker. To fix this, update the list before returning from `onMove`.\n\n```kotlin\nval reorderableLazyXXXXState = rememberReorderableLazyXXXXState(listState) { from, to -\u003e\n    // do NOT wrap the updateList call in `launch`\n    updateList(from, to)\n}\n\nsuspend fun updateList(from: Int, to: Int) {\n    // long update operation\n}\n```\n\nIf you can't keep the list update inside `onMove`, you can use a channel to communicate between `onMove` and the list update composition. Here's an example:\n\n```kotlin\nval listUpdatedChannel = remember { Channel\u003cUnit\u003e() }\nval reorderableLazyXXXXState = rememberReorderableLazyXXXXState(listState) { from, to -\u003e\n    // clear the channel\n    listUpdatedChannel.tryReceive()\n\n    // update the list\n\n    // wait for the list to be updated\n    listUpdatedChannel.receive()\n}\n\nLaunchedEffect(list) {\n    // notify the list is updated\n    listUpdatedChannel.trySend(Unit)\n}\n```\n\n## API\n\n### [`LazyColumn`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/package-summary#LazyColumn(androidx.compose.ui.Modifier,androidx.compose.foundation.lazy.LazyListState,androidx.compose.foundation.layout.PaddingValues,kotlin.Boolean,androidx.compose.foundation.layout.Arrangement.Vertical,androidx.compose.ui.Alignment.Horizontal,androidx.compose.foundation.gestures.FlingBehavior,kotlin.Boolean,kotlin.Function1)\u003e) / [`LazyRow`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/package-summary#LazyRow(androidx.compose.ui.Modifier,androidx.compose.foundation.lazy.LazyListState,androidx.compose.foundation.layout.PaddingValues,kotlin.Boolean,androidx.compose.foundation.layout.Arrangement.Horizontal,androidx.compose.ui.Alignment.Vertical,androidx.compose.foundation.gestures.FlingBehavior,kotlin.Boolean,kotlin.Function1)\u003e)\n\n- [`rememberReorderableLazyListState`](reorderable/src/commonMain/kotlin/sh/calvin/reorderable/ReorderableLazyList.kt)\n- [`ReorderableItem`](reorderable/src/commonMain/kotlin/sh/calvin/reorderable/ReorderableLazyList.kt)\n- [`Modifier.draggableHandle`](reorderable/src/commonMain/kotlin/sh/calvin/reorderable/ReorderableLazyCollection.kt)\n- [`Modifier.longPressDraggableHandle`](reorderable/src/commonMain/kotlin/sh/calvin/reorderable/ReorderableLazyCollection.kt)\n\n### [`LazyVerticalGrid`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/grid/package-summary#LazyVerticalGrid(androidx.compose.foundation.lazy.grid.GridCells,androidx.compose.ui.Modifier,androidx.compose.foundation.lazy.grid.LazyGridState,androidx.compose.foundation.layout.PaddingValues,kotlin.Boolean,androidx.compose.foundation.layout.Arrangement.Vertical,androidx.compose.foundation.layout.Arrangement.Horizontal,androidx.compose.foundation.gestures.FlingBehavior,kotlin.Boolean,kotlin.Function1)\u003e) / [`LazyHorizontalGrid`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/grid/package-summary#LazyHorizontalGrid(androidx.compose.foundation.lazy.grid.GridCells,androidx.compose.ui.Modifier,androidx.compose.foundation.lazy.grid.LazyGridState,androidx.compose.foundation.layout.PaddingValues,kotlin.Boolean,androidx.compose.foundation.layout.Arrangement.Horizontal,androidx.compose.foundation.layout.Arrangement.Vertical,androidx.compose.foundation.gestures.FlingBehavior,kotlin.Boolean,kotlin.Function1)\u003e)\n\n- [`rememberReorderableLazyGridState`](reorderable/src/commonMain/kotlin/sh/calvin/reorderable/ReorderableLazyGrid.kt)\n- [`ReorderableItem`](reorderable/src/commonMain/kotlin/sh/calvin/reorderable/ReorderableLazyGrid.kt)\n- [`Modifier.draggableHandle`](reorderable/src/commonMain/kotlin/sh/calvin/reorderable/ReorderableLazyCollection.kt)\n- [`Modifier.longPressDraggableHandle`](reorderable/src/commonMain/kotlin/sh/calvin/reorderable/ReorderableLazyCollection.kt)\n\n### [`LazyVerticalStaggeredGrid`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/staggeredgrid/package-summary#LazyVerticalStaggeredGrid(androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells,androidx.compose.ui.Modifier,androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridState,androidx.compose.foundation.layout.PaddingValues,kotlin.Boolean,androidx.compose.ui.unit.Dp,androidx.compose.foundation.layout.Arrangement.Horizontal,androidx.compose.foundation.gestures.FlingBehavior,kotlin.Boolean,kotlin.Function1)\u003e) / [`LazyHorizontalStaggeredGrid`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/staggeredgrid/package-summary#LazyHorizontalStaggeredGrid(androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells,androidx.compose.ui.Modifier,androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridState,androidx.compose.foundation.layout.PaddingValues,kotlin.Boolean,androidx.compose.foundation.layout.Arrangement.Vertical,androidx.compose.ui.unit.Dp,androidx.compose.foundation.gestures.FlingBehavior,kotlin.Boolean,kotlin.Function1)\u003e)\n\n- [`rememberReorderableLazyStaggeredGridState`](reorderable/src/commonMain/kotlin/sh/calvin/reorderable/ReorderableLazyStaggeredGrid.kt)\n- [`ReorderableItem`](reorderable/src/commonMain/kotlin/sh/calvin/reorderable/ReorderableLazyStaggeredGrid.kt)\n- [`Modifier.draggableHandle`](reorderable/src/commonMain/kotlin/sh/calvin/reorderable/ReorderableLazyCollection.kt)\n- [`Modifier.longPressDraggableHandle`](reorderable/src/commonMain/kotlin/sh/calvin/reorderable/ReorderableLazyCollection.kt)\n\n### [`Column`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/package-summary#Column(androidx.compose.ui.Modifier,androidx.compose.foundation.layout.Arrangement.Vertical,androidx.compose.ui.Alignment.Horizontal,kotlin.Function1)\u003e) / [`Row`](\u003chttps://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/package-summary#Row(androidx.compose.ui.Modifier,androidx.compose.foundation.layout.Arrangement.Horizontal,androidx.compose.ui.Alignment.Vertical,kotlin.Function1)\u003e)\n\n- [`ReorderableColumn`](reorderable/src/commonMain/kotlin/sh/calvin/reorderable/demo/ReorderableList.kt)\n- [`ReorderableRow`](reorderable/src/commonMain/kotlin/sh/calvin/reorderable/demo/ReorderableList.kt)\n- [`Modifier.draggableHandle`](reorderable/src/commonMain/kotlin/sh/calvin/reorderable/demo/ReorderableList.kt)\n- [`Modifier.longPressDraggableHandle`](reorderable/src/commonMain/kotlin/sh/calvin/reorderable/demo/ReorderableList.kt)\n\n## Running the demo app\n\nTo run the Android demo app, open the project in Android Studio and run the app.\n\nTo run the iOS demo app, open the iosApp project i","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcalvin-ll%2Freorderable","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcalvin-ll%2Freorderable","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcalvin-ll%2Freorderable/lists"}