diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml
index fe63bb6..148fdd2 100644
--- a/.idea/kotlinc.xml
+++ b/.idea/kotlinc.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 0ad17cb..8978d23 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,4 +1,3 @@
-
diff --git a/bottom-drawer-scaffold/build.gradle b/bottom-drawer-scaffold/build.gradle
index 2eca6f8..c632605 100644
--- a/bottom-drawer-scaffold/build.gradle
+++ b/bottom-drawer-scaffold/build.gradle
@@ -8,7 +8,7 @@ apply from: '../buildCompose.gradle'
ext {
PUBLISH_GROUP_ID = 'de.charlex.compose'
- PUBLISH_VERSION = '2.0.0-beta03'
+ PUBLISH_VERSION = '2.0.0-rc01'
PUBLISH_ARTIFACT_ID = 'bottom-drawer-scaffold'
}
diff --git a/bottom-drawer-scaffold/src/main/java/de/charlex/compose/bottomdrawerscaffold/BottomDrawerScaffold.kt b/bottom-drawer-scaffold/src/main/java/de/charlex/compose/bottomdrawerscaffold/BottomDrawerScaffold.kt
index a82a8e7..9e1c2da 100644
--- a/bottom-drawer-scaffold/src/main/java/de/charlex/compose/bottomdrawerscaffold/BottomDrawerScaffold.kt
+++ b/bottom-drawer-scaffold/src/main/java/de/charlex/compose/bottomdrawerscaffold/BottomDrawerScaffold.kt
@@ -6,14 +6,14 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.WindowInsets
-import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.exclude
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.requiredHeightIn
import androidx.compose.foundation.layout.statusBars
+import androidx.compose.foundation.layout.systemBars
+import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.BottomSheetScaffold
import androidx.compose.material3.BottomSheetScaffoldState
@@ -21,12 +21,15 @@ import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.FabPosition
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
+import androidx.compose.material3.SheetState
import androidx.compose.material3.SheetValue
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Surface
import androidx.compose.material3.contentColorFor
import androidx.compose.material3.rememberBottomSheetScaffoldState
+import androidx.compose.material3.rememberStandardBottomSheetState
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
@@ -36,17 +39,39 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.layout.onGloballyPositioned
-import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.launch
+
+@Composable
+@ExperimentalMaterial3Api
+fun rememberBottomSheetScaffoldState(
+ bottomSheetState: SheetState = rememberStandardBottomSheetState(),
+ snackbarHostState: SnackbarHostState = remember { SnackbarHostState() },
+ onSheetStateChanged: (SheetValue) -> Unit
+): BottomSheetScaffoldState {
+ val state = remember(bottomSheetState, snackbarHostState) {
+ BottomSheetScaffoldState(
+ bottomSheetState = bottomSheetState,
+ snackbarHostState = snackbarHostState
+ )
+ }
+
+ LaunchedEffect(state.bottomSheetState.currentValue) {
+ onSheetStateChanged(state.bottomSheetState.currentValue)
+ }
+
+ return state
+}
+
@Composable
@ExperimentalMaterial3Api
fun BottomDrawerScaffold(
modifier: Modifier = Modifier,
+ contentWindowInsets: WindowInsets = WindowInsets.systemBars.exclude(WindowInsets.statusBars).exclude(WindowInsets.navigationBars),
bottomSheetScaffoldState: BottomSheetScaffoldState = rememberBottomSheetScaffoldState(),
- topBar: @Composable (() -> Unit)? = null,
+ topBar: (@Composable () -> Unit)? = null,
bottomBar: @Composable (() -> Unit)? = null,
gesturesEnabled: Boolean = true,
drawerModifier: Modifier = Modifier,
@@ -69,7 +94,7 @@ fun BottomDrawerScaffold(
) {
Scaffold(
modifier = modifier,
- contentWindowInsets = WindowInsets.navigationBars.exclude(WindowInsets.statusBars),
+ contentWindowInsets = contentWindowInsets,
topBar = {
topBar?.invoke()
},
@@ -88,78 +113,78 @@ fun BottomDrawerScaffold(
.padding(scaffoldPaddingValues)
) {
val fullHeight = constraints.maxHeight.toFloat()
- val peekHeightPx = with(LocalDensity.current) { drawerPeekHeight.toPx() }
var bottomDrawerHeight by remember { mutableStateOf(fullHeight) }
+ var initialOffset by remember { mutableStateOf(-1f) }
+
+ Surface(
+ color = backgroundColor,
+ contentColor = contentColor
+ ) {
+ Box(Modifier.fillMaxSize()) {
+ content(PaddingValues(bottom = drawerPeekHeight))
- BottomSheetScaffold(
- modifier = Modifier,
- scaffoldState = bottomSheetScaffoldState,
- sheetDragHandle = null,
- sheetSwipeEnabled = drawerGesturesEnabled ?: gesturesEnabled,
- sheetContainerColor = Color.Transparent,
- sheetPeekHeight = drawerPeekHeight + 30.dp,
- sheetTonalElevation = 0.dp,
- sheetShadowElevation = 0.dp,
- snackbarHost = snackbarHost,
- sheetContent = {
- val topPadding = if (topBar == null) {
- WindowInsets.statusBars.asPaddingValues(LocalDensity.current).calculateTopPadding()
- } else {
- 0.dp
- }
- Surface(
- Modifier
- .fillMaxWidth()
- .requiredHeightIn(
- min = drawerPeekHeight
- )
- .padding(
- top = drawerPadding + topPadding,
- start = drawerPadding,
- end = drawerPadding,
- )
- .onGloballyPositioned {
- bottomDrawerHeight = it.size.height.toFloat()
+ Scrim(
+ open = bottomSheetScaffoldState.isExpanded(),
+ onClose = {
+ if (gesturesEnabled) {
+ scope.launch { bottomSheetScaffoldState.collapse() }
}
- .then(
- drawerModifier
- ),
- shape = drawerShape,
- shadowElevation = drawerShadowElevation,
- tonalElevation = drawerTonalElevation,
- color = drawerBackgroundColor,
- contentColor = drawerContentColor,
- content = {
- Column(
- content = {
- drawerContent()
- }
- )
- }
+ },
+ fraction = {
+ calculateFraction(initialOffset, 0f, bottomSheetScaffoldState.bottomSheetState.requireOffset())
+ },
+ color = drawerScrimColor
)
}
+ }
+
+ Box(
+ modifier = if(topBar == null) Modifier.windowInsetsPadding(WindowInsets.statusBars) else Modifier
) {
- Surface(
- color = backgroundColor,
- contentColor = contentColor
- ) {
- Box(Modifier.fillMaxSize()) {
- content(PaddingValues(bottom = drawerPeekHeight))
-
- Scrim(
- open = bottomSheetScaffoldState.isExpanded(),
- onClose = {
- if (gesturesEnabled) {
- scope.launch { bottomSheetScaffoldState.collapse() }
+ BottomSheetScaffold(
+ modifier = Modifier,
+ scaffoldState = bottomSheetScaffoldState,
+ sheetDragHandle = null,
+ sheetSwipeEnabled = drawerGesturesEnabled ?: gesturesEnabled,
+ sheetContainerColor = Color.Transparent,
+ sheetPeekHeight = drawerPeekHeight,
+ sheetTonalElevation = 0.dp,
+ sheetShadowElevation = 0.dp,
+ snackbarHost = snackbarHost,
+ sheetContent = {
+ Surface(
+ Modifier
+ .fillMaxWidth()
+ .padding(
+ top = drawerPadding,
+ start = drawerPadding,
+ end = drawerPadding
+ )
+ .onGloballyPositioned {
+ if(initialOffset == -1f) {
+ initialOffset = bottomSheetScaffoldState.bottomSheetState.requireOffset()
+ }
+ bottomDrawerHeight = it.size.height.toFloat()
}
- },
- fraction = {
- calculateFraction(fullHeight - peekHeightPx, fullHeight - bottomDrawerHeight, bottomSheetScaffoldState.bottomSheetState.requireOffset())
- },
- color = drawerScrimColor
+ .then(
+ drawerModifier
+ ),
+ shape = drawerShape,
+ shadowElevation = drawerShadowElevation,
+ tonalElevation = drawerTonalElevation,
+ color = drawerBackgroundColor,
+ contentColor = drawerContentColor,
+ content = {
+ Column(
+ content = {
+ drawerContent()
+ }
+ )
+ }
)
- }
- }
+ },
+ content = {}
+ )
}
}
}
diff --git a/example/src/main/java/de/charlex/compose/bottomdrawerscaffold/sample/MainActivity.kt b/example/src/main/java/de/charlex/compose/bottomdrawerscaffold/sample/MainActivity.kt
index db22bb4..5bce607 100644
--- a/example/src/main/java/de/charlex/compose/bottomdrawerscaffold/sample/MainActivity.kt
+++ b/example/src/main/java/de/charlex/compose/bottomdrawerscaffold/sample/MainActivity.kt
@@ -1,6 +1,7 @@
package de.charlex.compose.bottomdrawerscaffold.sample
import android.os.Bundle
+import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
@@ -43,12 +44,13 @@ import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.SheetValue
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text
-import androidx.compose.material3.rememberBottomSheetScaffoldState
+import androidx.compose.material3.TopAppBar
+import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
@@ -58,7 +60,6 @@ import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import de.charlex.compose.bottomdrawerscaffold.BottomDrawerScaffold
-import de.charlex.compose.bottomdrawerscaffold.isCollapsed
import de.charlex.compose.bottomdrawerscaffold.toggle
import kotlinx.coroutines.launch
@@ -75,16 +76,23 @@ class MainActivity : ComponentActivity() {
}
}
-@OptIn(ExperimentalFoundationApi::class, ExperimentalMaterial3Api::class,
- ExperimentalLayoutApi::class
-)
+@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun Content() {
MaterialTheme {
val coroutineScope = rememberCoroutineScope()
val snackbarHostState = remember { SnackbarHostState() }
- val bottomSheetScaffoldState = rememberBottomSheetScaffoldState()
+
+ val lazyListState = rememberLazyListState()
+
+ val bottomSheetScaffoldState = de.charlex.compose.bottomdrawerscaffold.rememberBottomSheetScaffoldState {
+ if (it == SheetValue.PartiallyExpanded) {
+ coroutineScope.launch {
+ lazyListState.scrollToItem(0)
+ }
+ }
+ }
BottomDrawerScaffold(
modifier = Modifier,
@@ -102,6 +110,7 @@ fun Content() {
// },
bottomBar = {
BottomAppBar(
+ containerColor = MaterialTheme.colorScheme.errorContainer,
floatingActionButton = {
FloatingActionButton(
onClick = {
@@ -126,22 +135,34 @@ fun Content() {
},
backgroundColor = Color(0xFFF2F2F2),
drawerTonalElevation = 10.dp,
- drawerPeekHeight = 80.dp,
+ drawerPeekHeight = 100.dp,
drawerPadding = 10.dp,
drawerContent = {
- val lazyListState = rememberLazyListState()
- val collapsed = bottomSheetScaffoldState.isCollapsed()
-
- LaunchedEffect(collapsed) {
- if (collapsed) {
- lazyListState.scrollToItem(0)
- }
- }
-
LazyColumn(
modifier = Modifier.fillMaxSize(),
state = lazyListState
) {
+ item {
+ Group(title = "Category A") {
+ RowEntry(icon = Icons.Default.Build, label = "Build the app")
+ RowEntry(icon = Icons.Default.Send, label = "Send a message")
+ RowEntry(icon = Icons.Default.PlayArrow, label = "Play some stuff")
+ RowEntry(icon = Icons.Default.Phone, label = "Call a person")
+ }
+ }
+ item {
+ Group(title = "Other") {
+ RowEntry(icon = Icons.Default.Place, label = "Place or Location")
+ RowEntry(icon = Icons.Default.LocationOn, label = "Some text here")
+ }
+ }
+ item {
+ Group(title = "Setting") {
+ RowEntry(icon = Icons.Default.Email, label = "Email config")
+ RowEntry(icon = Icons.Default.DateRange, label = "Date Range")
+ RowEntry(icon = Icons.Default.ShoppingCart, label = "Subscriptions")
+ }
+ }
item {
Group(title = "Category A") {
RowEntry(icon = Icons.Default.Build, label = "Build the app")
@@ -175,7 +196,7 @@ fun Content() {
modifier = Modifier
.fillMaxWidth()
.height(10.dp)
- .background(color = MaterialTheme.colorScheme.secondaryContainer)
+ .background(color = MaterialTheme.colorScheme.primary)
)
}
}
@@ -193,7 +214,7 @@ fun Content() {
.fillMaxWidth()
.align(Alignment.TopCenter)
.height(10.dp)
- .background(color = MaterialTheme.colorScheme.secondaryContainer)
+ .background(color = MaterialTheme.colorScheme.primary)
)
Text(
modifier = Modifier.align(Alignment.Center),
@@ -205,7 +226,7 @@ fun Content() {
.fillMaxWidth()
.align(Alignment.BottomCenter)
.height(10.dp)
- .background(color = MaterialTheme.colorScheme.secondaryContainer)
+ .background(color = MaterialTheme.colorScheme.primary)
)
}
}
@@ -240,11 +261,11 @@ fun RowEntry(
println("Click on $label")
}
.padding(
- start = 40.dp,
- end = 40.dp,
- top = 10.dp,
- bottom = 10.dp
- ),
+ start = 40.dp,
+ end = 40.dp,
+ top = 10.dp,
+ bottom = 10.dp
+ ),
verticalAlignment = Alignment.CenterVertically
) {
if (icon != null) {
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 155fab6..f5668c5 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -6,14 +6,16 @@ compileSdk = "34"
minSdk = "21"
targetSdk = "33"
-composeBom = "2024.04.00" # https://developer.android.com/jetpack/compose/bom/bom-mapping
-composeCompiler = "1.5.11" # https://developer.android.com/jetpack/androidx/releases/compose-kotlin
-kotlin = "1.9.23" # https://developer.android.com/jetpack/androidx/releases/compose-kotlin
-gradlePlugin = "8.1.4" # https://developer.android.com/build/releases/gradle-plugin
+composeBom = "2024.05.00" # https://developer.android.com/jetpack/compose/bom/bom-mapping
+composeCompiler = "1.5.14" # https://developer.android.com/jetpack/androidx/releases/compose-kotlin
+kotlin = "1.9.24" # https://developer.android.com/jetpack/androidx/releases/compose-kotlin
+gradlePlugin = "8.4.1" # https://developer.android.com/build/releases/gradle-plugin
-activityCompose = "1.8.2"
-coreKtx = "1.12.0"
-ktlint = "0.42.1"
+material3 = "1.3.0-beta02" # https://developer.android.com/build/releases/gradle-plugin
+
+activityCompose = "1.9.0"
+coreKtx = "1.13.1"
+ktlint = "0.49.1"
nexusStaging = "0.30.0"
@@ -22,7 +24,7 @@ compose-bom = { module = "androidx.compose:compose-bom", version.ref = "composeB
compose-ui-ui = { module = "androidx.compose.ui:ui" }
compose-ui-util = { module = "androidx.compose.ui:ui-util" }
compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling" }
-compose-material3-material3 = { module = "androidx.compose.material3:material3" }
+compose-material3-material3 = { module = "androidx.compose.material3:material3", version.ref = "material3" }
core-ktx = { module = "androidx.core:core-ktx", version.ref = "coreKtx" }
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 84e0af4..21607e5 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
#Sun Aug 22 22:07:44 CEST 2021
distributionBase=GRADLE_USER_HOME
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME