[go: nahoru, domu]

blob: c8c3bc7f220a384709bfc0a9cebc74461b813d06 [file] [log] [blame]
/*
* Copyright 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.compose.material.navigation
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.material.ModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.runtime.saveable.SaveableStateHolder
import androidx.compose.runtime.snapshotFlow
import androidx.navigation.NavBackStackEntry
import androidx.navigation.compose.LocalOwnersProvider
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.drop
/**
* Hosts a [BottomSheetNavigator.Destination]'s [NavBackStackEntry] and its
* [BottomSheetNavigator.Destination.content] and provides a [onSheetDismissed] callback. It also
* shows and hides the [ModalBottomSheetLayout] through the [sheetState] when the sheet content
* enters or leaves the composition.
*
* @param backStackEntry The [NavBackStackEntry] holding the [BottomSheetNavigator.Destination],
* or null if there is no [NavBackStackEntry]
* @param sheetState The [ModalBottomSheetState] used to observe and control the sheet visibility
* @param onSheetDismissed Callback when the sheet has been dismissed. Typically, you'll want to
* pop the back stack here.
*/
@Composable
internal fun ColumnScope.SheetContentHost(
backStackEntry: NavBackStackEntry?,
sheetState: ModalBottomSheetState,
saveableStateHolder: SaveableStateHolder,
onSheetShown: (entry: NavBackStackEntry) -> Unit,
onSheetDismissed: (entry: NavBackStackEntry) -> Unit,
) {
if (backStackEntry != null) {
val currentOnSheetShown by rememberUpdatedState(onSheetShown)
val currentOnSheetDismissed by rememberUpdatedState(onSheetDismissed)
LaunchedEffect(sheetState, backStackEntry) {
snapshotFlow { sheetState.isVisible }
// We are only interested in changes in the sheet's visibility
.distinctUntilChanged()
// distinctUntilChanged emits the initial value which we don't need
.drop(1)
.collect { visible ->
if (visible) {
currentOnSheetShown(backStackEntry)
} else {
currentOnSheetDismissed(backStackEntry)
}
}
}
backStackEntry.LocalOwnersProvider(saveableStateHolder) {
val content =
(backStackEntry.destination as BottomSheetNavigator.Destination).content
content(backStackEntry)
}
}
}