- Notifications
You must be signed in to change notification settings - Fork3
⚡ Google Photos style drag-to-select multi-selection to a LazyGrid for Compose multiplatform
License
jordond/drag-select-compose
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
This is a Compose Multiplatform library that allows you to easily implement a "Google Photos"-stylemulti-selection in your Compose apps.
You can run the demo atdemo.dragselectcompose.com and view the KDocs atdocs.dragselectcompose.com
This library is written for Compose Multiplatform, and can be used on the following platforms:
- Android
- iOS
- JVM (Desktop)
- JavaScript/wasm (Browser)
This library was inspired bythisarticleandthegist.
As well as thedrag-select-recyclerviewlibrary.
You can add this library to your project using Gradle.
To add to a single platform like Android, add the dependency to your app levelbuild.gradle.ktsfile:
dependencies {// Includes the core functionality along with all of the optional modules implementation("com.dragselectcompose:dragselect:3.1.0")// Or use the modules you want// Core functionality implementation("com.dragselectcompose:core:3.1.0")// Optional extensions for adding semantics and toggle Modifiers to Grid items implementation("com.dragselectcompose:extensions:3.1.0")// Optional wrappers around LazyGrid that implement the selection UI for you implementation("com.dragselectcompose:grid:3.1.0")}To add to a multiplatform project, add the dependency to the common source-set:
kotlin { sourceSets { commonMain { dependencies {// Includes the core functionality along with all of the optional modules implementation("com.dragselectcompose:dragselect:3.1.0")// Or use the modules you want// Core functionality implementation("com.dragselectcompose:core:3.1.0")// Optional extensions for adding semantics and toggle Modifiers to Grid items implementation("com.dragselectcompose:extensions:3.1.0")// Optional wrappers around LazyGrid that implement the selection UI for you implementation("com.dragselectcompose:grid:3.1.0") } } }}For the supported platforms, see the badges at the top of the README.
[versions]dragselectcompose ="3.1.0"[libraries]dragselect = {module ="com.dragselectcompose:dragselect",version.ref ="dragselectcompose" }dragselect-core = {module ="com.dragselectcompose:core",version.ref ="dragselectcompose" }dragselect-extensions = {module ="com.dragselectcompose:extensions",version.ref ="dragselectcompose" }dragselect-grid = {module ="com.dragselectcompose:grid",version.ref ="dragselectcompose" }
The:core artifact provides aModifier extension for adding a drag-to-select functionality toyourLazyGrid:
fun <Item> Modifier.gridDragSelect(items:List<Item>,state:DragSelectState<Item>,enableAutoScroll:Boolean = true,autoScrollThreshold:Float? = null,enableHaptics:Boolean = true,hapticFeedback:HapticFeedback? = null,):Modifier
It provides the following functionality:
- Adds a long-press drag gesture to select items.
- Maintains a list of selected items.
- Expose a
inSelectionMode: Booleanwhich you can use to display an unselected state. - If
enableAutoScrollistruethen the list will start to scroll when reaching the top or bottomof the list. - Will trigger a "long-press" haptics if
enableHapticsistrue.
Note: By default selected items will be compared using an equality check. If your item is notadata class you must implementequals andhashCode for your item. Or you can pass a lambdatorememberDragSelectState to compare your items:
val dragSelectState= rememberDragSelectState<Foo>(compareSelector= { it.someProperty })
You can then useDragSelectState to render your list of items:
data classModel(valid:Int,valtitle:String,valimageUrl:String,)@ComposeablefunMyGrid(models:List<Model>) {val dragSelectState= rememberDragSelectState<Model>()LazyVerticalGrid( columns=GridCells.Adaptive(minSize=128.dp), state= dragSelectState.lazyGridState, verticalArrangement=Arrangement.spacedBy(3.dp), horizontalArrangement=Arrangement.spacedBy(3.dp), modifier=Modifier.gridDragSelect( items= models, state= dragSelectState, ), ) { items(models, key= { it.id }) { model->val isSelected by remember { derivedStateOf { dragSelectState.isSelected(model) } }val inSelectionMode= dragSelectState.inSelectionMode// Define your Model Composeable and use `isSelected` or `inSelectionMode` } }}
You can see a full basic exampleinBasicDragSelectPhotoGrid.
Included in the:dragselectcompose and:extensions artifact are a couple extensions onModiferto easily add support for accessibility semantics and toggling selection while the Grid is inselection mode.
Modifier.dragSelectSemantics()- Adds a long click semantics to the modifier for accessibility.
Modifier.dragSelectToggleable()- Allows you to toggle the item when the Grid is in Selection Mode.
Modifier.dragSelectToggleableItem()- Combines the above two extensions.
@ComposeablefunMyGrid(models:List<Model>) {val dragSelectState= rememberDragSelectState<Model>()LazyVerticalGrid(// ... ) { items(models, key= { it.id }) { model->// Add semantics and toggleable modifiersMyItemContent( item= model, modifier=Modifier.dragSelectToggleable( state= dragSelectState, item= model, ), ) } }}
You can see a full extensions exampleinExtensionsDragSelectPhotoGrid.
Included in the:grid artifact is a "all-inclusive" drag-select experience. It includes wrappersaroundLazyHorizontalGrid andLazyVerticalGrid that takes care of addingtheModifier.gridDragSelect.
When usingLazyDragSelectVerticalGrid orLazyDragSelectHorizontalGrid thecontent() is scopedto a custom scope that provides a helper composable for handling the selection indicator, andanimating the padding.
Here is a quick example:
@ComposeablefunMyGrid(models:List<Model>) {val dragSelectState= rememberDragSelectState<Model>()LazyDragSelectVerticalGrid( columns=GridCells.Adaptive(minSize=128.dp), items= models, state= dragSelectState, ) { items(key= { it.id }) { model->SelectableItem(item= model) {// Your Composeable for your item } } }}
Now your item will have an animated padding and clipped shape when selected. As well as displayingindicator icons when the grid is in selection mode, and the item is selected or not.
See the documentation forLazyDragSelectVerticalGrid andSelectableItem for all the options youcan customize.
You can see a full exampleinLazyDragSelectPhotoGrid
To run a demo for the library you can look inside of/demo to see a standard Android application,and a Compose Multiplatform application.
A demo app is included in the:demo:android module, run it by following these steps:
git clone git@github.com:jordond/drag-select-compose.git drag-select-composecd drag-select-compose./gradlew assembleReleaseThen install thedemo/android/build/outputs/apk/release/demo-release.apk file on your device.
The demo is inside of:demo:kmm module. In order to run it you should have the latest version ofAndroid Studio installed.
Check outthe README for more information.
SeeLICENSE
About
⚡ Google Photos style drag-to-select multi-selection to a LazyGrid for Compose multiplatform
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Uh oh!
There was an error while loading.Please reload this page.
Contributors4
Uh oh!
There was an error while loading.Please reload this page.
