From 7c9c4dca911add09b0a8354f36556ba8b756dacb Mon Sep 17 00:00:00 2001 From: Ben Trengrove Date: Wed, 11 Dec 2024 07:44:16 +1100 Subject: [PATCH] Remove navigation material --- README.md | 2 +- navigation-material/README.md | 21 - navigation-material/api/current.api | 43 - navigation-material/build.gradle.kts | 57 -- navigation-material/gradle.properties | 19 - .../src/androidTest/AndroidManifest.xml | 17 - .../BottomSheetNavigatorTest.kt | 854 ------------------ .../navigation.material/FakeTests.kt | 57 -- .../NavGraphBuilderTest.kt | 124 --- .../SheetContentHostTest.kt | 225 ----- .../src/main/AndroidManifest.xml | 20 - .../navigation/material/BottomSheet.kt | 66 -- .../material/BottomSheetNavigator.kt | 272 ------ .../ExperimentalMaterialNavigationApi.kt | 21 - .../navigation/material/NavGraphBuilder.kt | 65 -- .../navigation/material/SheetContentHost.kt | 78 -- sample/build.gradle.kts | 1 - sample/src/main/AndroidManifest.xml | 10 - .../material/BottomSheetNavSample.kt | 115 --- settings.gradle.kts | 1 - 20 files changed, 1 insertion(+), 2067 deletions(-) delete mode 100644 navigation-material/README.md delete mode 100644 navigation-material/api/current.api delete mode 100644 navigation-material/build.gradle.kts delete mode 100644 navigation-material/gradle.properties delete mode 100644 navigation-material/src/androidTest/AndroidManifest.xml delete mode 100644 navigation-material/src/androidTest/java/com/google/accompanist/navigation.material/BottomSheetNavigatorTest.kt delete mode 100644 navigation-material/src/androidTest/java/com/google/accompanist/navigation.material/FakeTests.kt delete mode 100644 navigation-material/src/androidTest/java/com/google/accompanist/navigation.material/NavGraphBuilderTest.kt delete mode 100644 navigation-material/src/androidTest/java/com/google/accompanist/navigation.material/SheetContentHostTest.kt delete mode 100644 navigation-material/src/main/AndroidManifest.xml delete mode 100644 navigation-material/src/main/java/com/google/accompanist/navigation/material/BottomSheet.kt delete mode 100644 navigation-material/src/main/java/com/google/accompanist/navigation/material/BottomSheetNavigator.kt delete mode 100644 navigation-material/src/main/java/com/google/accompanist/navigation/material/ExperimentalMaterialNavigationApi.kt delete mode 100644 navigation-material/src/main/java/com/google/accompanist/navigation/material/NavGraphBuilder.kt delete mode 100644 navigation-material/src/main/java/com/google/accompanist/navigation/material/SheetContentHost.kt delete mode 100644 sample/src/main/java/com/google/accompanist/sample/navigation/material/BottomSheetNavSample.kt diff --git a/README.md b/README.md index fd10aa6a5..225b747c8 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ A library providing a collection of utilities for adaptive layouts. ### 🧭✨[Navigation-Animation](./navigation-animation/) (Deprecated) See our [Migration Guide](https://google.github.io/accompanist/navigation-animation/) for migrating to using built in support for animations in Jetpack Navigation Compose. -### 🧭🎨️ [Navigation-Material](./navigation-material/) (Deprecated) +### 🧭🎨️ [Navigation-Material](./navigation-material/) (Deprecated & Removed) See our [Migration Guide](https://google.github.io/accompanist/navigation-material/) for migrating to using built in material-navigation support. ### 🍫 [System UI Controller](./systemuicontroller/) (Deprecated) diff --git a/navigation-material/README.md b/navigation-material/README.md deleted file mode 100644 index 1db43eebc..000000000 --- a/navigation-material/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# Navigation Material for Jetpack Compose - -[![Maven Central](https://img.shields.io/maven-central/v/com.google.accompanist/accompanist-navigation-material)](https://search.maven.org/search?q=g:com.google.accompanist) - -For more information, visit the documentation: https://google.github.io/accompanist/navigation-material - -## Download - -```groovy -repositories { - mavenCentral() -} - -dependencies { - implementation "com.google.accompanist:accompanist-navigation-material:" -} -``` - -Snapshots of the development version are available in [Sonatype's `snapshots` repository][snap]. These are updated on every commit. - - [snap]: https://oss.sonatype.org/content/repositories/snapshots/com/google/accompanist/accompanist-navigation-material/ diff --git a/navigation-material/api/current.api b/navigation-material/api/current.api deleted file mode 100644 index 8954f5cb3..000000000 --- a/navigation-material/api/current.api +++ /dev/null @@ -1,43 +0,0 @@ -// Signature format: 4.0 -package com.google.accompanist.navigation.material { - - public final class BottomSheetKt { - method @Deprecated @androidx.compose.runtime.Composable @com.google.accompanist.navigation.material.ExperimentalMaterialNavigationApi public static void ModalBottomSheetLayout(com.google.accompanist.navigation.material.BottomSheetNavigator bottomSheetNavigator, optional androidx.compose.ui.Modifier modifier, optional androidx.compose.ui.graphics.Shape sheetShape, optional float sheetElevation, optional long sheetBackgroundColor, optional long sheetContentColor, optional long scrimColor, kotlin.jvm.functions.Function0 content); - } - - @Deprecated @androidx.navigation.Navigator.Name("BottomSheetNavigator") @com.google.accompanist.navigation.material.ExperimentalMaterialNavigationApi public final class BottomSheetNavigator extends androidx.navigation.Navigator { - ctor @Deprecated public BottomSheetNavigator(androidx.compose.material.ModalBottomSheetState sheetState); - method @Deprecated public com.google.accompanist.navigation.material.BottomSheetNavigator.Destination createDestination(); - method @Deprecated public com.google.accompanist.navigation.material.BottomSheetNavigatorSheetState getNavigatorSheetState(); - method @Deprecated public kotlin.jvm.functions.Function1 getSheetContent(); - property @Deprecated public final com.google.accompanist.navigation.material.BottomSheetNavigatorSheetState navigatorSheetState; - property @Deprecated public final kotlin.jvm.functions.Function1 sheetContent; - } - - @Deprecated @androidx.navigation.NavDestination.ClassType(Composable::class) public static final class BottomSheetNavigator.Destination extends androidx.navigation.NavDestination implements androidx.navigation.FloatingWindow { - ctor @Deprecated public BottomSheetNavigator.Destination(com.google.accompanist.navigation.material.BottomSheetNavigator navigator, kotlin.jvm.functions.Function2 content); - } - - public final class BottomSheetNavigatorKt { - method @Deprecated @androidx.compose.runtime.Composable @com.google.accompanist.navigation.material.ExperimentalMaterialNavigationApi public static com.google.accompanist.navigation.material.BottomSheetNavigator rememberBottomSheetNavigator(optional androidx.compose.animation.core.AnimationSpec animationSpec); - } - - @Deprecated @androidx.compose.runtime.Stable @com.google.accompanist.navigation.material.ExperimentalMaterialNavigationApi public final class BottomSheetNavigatorSheetState { - ctor @Deprecated public BottomSheetNavigatorSheetState(androidx.compose.material.ModalBottomSheetState sheetState); - method @Deprecated public androidx.compose.material.ModalBottomSheetValue getCurrentValue(); - method @Deprecated public androidx.compose.material.ModalBottomSheetValue getTargetValue(); - method @Deprecated public boolean isVisible(); - property @Deprecated public final androidx.compose.material.ModalBottomSheetValue currentValue; - property @Deprecated public final boolean isVisible; - property @Deprecated public final androidx.compose.material.ModalBottomSheetValue targetValue; - } - - @kotlin.RequiresOptIn(message="This APIs are experimental and may change in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalMaterialNavigationApi { - } - - public final class NavGraphBuilderKt { - method @Deprecated @com.google.accompanist.navigation.material.ExperimentalMaterialNavigationApi public static void bottomSheet(androidx.navigation.NavGraphBuilder, String route, optional java.util.List arguments, optional java.util.List deepLinks, kotlin.jvm.functions.Function2 content); - } - -} - diff --git a/navigation-material/build.gradle.kts b/navigation-material/build.gradle.kts deleted file mode 100644 index f657d430a..000000000 --- a/navigation-material/build.gradle.kts +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2023 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. - */ -@file:Suppress("UnstableApiUsage") - -plugins { - alias(libs.plugins.accompanist.android.library) - alias(libs.plugins.accompanist.android.library.compose) - alias(libs.plugins.accompanist.android.library.published) -} - -android { - namespace = "com.google.accompanist.navigation.material" - - packaging { - // Some of the META-INF files conflict with coroutines-test. Exclude them to enable - // our test APK to build (has no effect on our AARs) - resources { - excludes += listOf("/META-INF/AL2.0", "/META-INF/LGPL2.1") - } - } -} - -dependencies { - api(libs.androidx.navigation.compose) - implementation(libs.compose.foundation.foundation) - implementation(libs.compose.material.material) - implementation(libs.kotlin.coroutines.android) - - // ====================== - // Test dependencies - // ====================== - - androidTestImplementation(project(":internal-testutils")) - androidTestImplementation(libs.androidx.navigation.testing) - - androidTestImplementation(libs.junit) - androidTestImplementation(libs.truth) - - androidTestImplementation(libs.compose.ui.test.junit4) - androidTestImplementation(libs.compose.ui.test.manifest) - androidTestImplementation(libs.compose.foundation.foundation) - androidTestImplementation(libs.androidx.test.runner) - androidTestImplementation(libs.androidx.test.rules) -} diff --git a/navigation-material/gradle.properties b/navigation-material/gradle.properties deleted file mode 100644 index 11627c311..000000000 --- a/navigation-material/gradle.properties +++ /dev/null @@ -1,19 +0,0 @@ -# -# Copyright 2021 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. -# - -POM_ARTIFACT_ID=accompanist-navigation-material -POM_NAME=Accompanist Navigation Material -POM_PACKAGING=aar diff --git a/navigation-material/src/androidTest/AndroidManifest.xml b/navigation-material/src/androidTest/AndroidManifest.xml deleted file mode 100644 index 329f0ddff..000000000 --- a/navigation-material/src/androidTest/AndroidManifest.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - diff --git a/navigation-material/src/androidTest/java/com/google/accompanist/navigation.material/BottomSheetNavigatorTest.kt b/navigation-material/src/androidTest/java/com/google/accompanist/navigation.material/BottomSheetNavigatorTest.kt deleted file mode 100644 index a8ad92875..000000000 --- a/navigation-material/src/androidTest/java/com/google/accompanist/navigation.material/BottomSheetNavigatorTest.kt +++ /dev/null @@ -1,854 +0,0 @@ -/* - * Copyright 2021 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 com.google.accompanist.navigation.material - -import android.os.Bundle -import androidx.activity.OnBackPressedDispatcher -import androidx.activity.compose.LocalOnBackPressedDispatcherOwner -import androidx.compose.animation.core.tween -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.size -import androidx.compose.material.Button -import androidx.compose.material.ExperimentalMaterialApi -import androidx.compose.material.ModalBottomSheetState -import androidx.compose.material.ModalBottomSheetValue -import androidx.compose.material.Text -import androidx.compose.runtime.DisposableEffect -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.testTag -import androidx.compose.ui.test.click -import androidx.compose.ui.test.getUnclippedBoundsInRoot -import androidx.compose.ui.test.junit4.createComposeRule -import androidx.compose.ui.test.onNodeWithTag -import androidx.compose.ui.test.onNodeWithText -import androidx.compose.ui.test.onRoot -import androidx.compose.ui.test.performClick -import androidx.compose.ui.test.performTouchInput -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.height -import androidx.lifecycle.Lifecycle -import androidx.navigation.NavBackStackEntry -import androidx.navigation.NavHostController -import androidx.navigation.compose.NavHost -import androidx.navigation.compose.composable -import androidx.navigation.compose.rememberNavController -import androidx.navigation.testing.TestNavigatorState -import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.filters.LargeTest -import com.google.common.truth.Truth.assertThat -import com.google.common.truth.Truth.assertWithMessage -import kotlinx.coroutines.runBlocking -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith -import kotlin.math.roundToLong - -@Suppress("DEPRECATION") -@LargeTest -@RunWith(AndroidJUnit4::class) -@OptIn(ExperimentalMaterialApi::class, ExperimentalMaterialNavigationApi::class) -internal class BottomSheetNavigatorTest { - - @get:Rule - val composeTestRule = createComposeRule() - - @Test - fun testNavigateAddsDestinationToBackStack(): Unit = runBlocking { - val sheetState = ModalBottomSheetState(ModalBottomSheetValue.Hidden, composeTestRule.density) - val navigatorState = TestNavigatorState() - val navigator = BottomSheetNavigator(sheetState) - - navigator.onAttach(navigatorState) - val entry = navigatorState.createBackStackEntry(navigator.createFakeDestination(), null) - navigator.navigate(listOf(entry), null, null) - - assertWithMessage("The back stack entry has been added to the back stack") - .that(navigatorState.backStack.value) - .containsExactly(entry) - } - - @Test - fun testNavigateAddsDestinationToBackStackAndKeepsPrevious(): Unit = runBlocking { - val sheetState = ModalBottomSheetState(ModalBottomSheetValue.Hidden, composeTestRule.density) - val navigator = BottomSheetNavigator(sheetState) - val navigatorState = TestNavigatorState() - - navigator.onAttach(navigatorState) - val firstEntry = navigatorState.createBackStackEntry(navigator.createFakeDestination(), null) - val secondEntry = navigatorState.createBackStackEntry(navigator.createFakeDestination(), null) - - navigator.navigate(listOf(firstEntry), null, null) - assertWithMessage("The first entry has been added to the back stack") - .that(navigatorState.backStack.value) - .containsExactly(firstEntry) - - navigator.navigate(listOf(secondEntry), null, null) - assertWithMessage( - "The second entry has been added to the back stack and it still " + - "contains the first entry" - ) - .that(navigatorState.backStack.value) - .containsExactly(firstEntry, secondEntry) - .inOrder() - } - - @Test - fun testNavigateComposesDestinationAndDisposesPreviousDestination(): Unit = runBlocking { - val sheetState = ModalBottomSheetState(ModalBottomSheetValue.Hidden, composeTestRule.density) - val navigator = BottomSheetNavigator(sheetState) - val navigatorState = TestNavigatorState() - navigator.onAttach(navigatorState) - - composeTestRule.setContent { - Column { navigator.sheetContent(this) } - } - - var firstDestinationCompositions = 0 - val firstDestinationContentTag = "firstSheetContentTest" - val firstDestination = BottomSheetNavigator.Destination(navigator) { - DisposableEffect(Unit) { - firstDestinationCompositions++ - onDispose { firstDestinationCompositions = 0 } - } - Text("Fake Sheet Content", Modifier.testTag(firstDestinationContentTag)) - } - val firstEntry = navigatorState.createBackStackEntry(firstDestination, null) - - var secondDestinationCompositions = 0 - val secondDestinationContentTag = "secondSheetContentTest" - val secondDestination = BottomSheetNavigator.Destination(navigator) { - DisposableEffect(Unit) { - secondDestinationCompositions++ - onDispose { secondDestinationCompositions = 0 } - } - Box( - Modifier - .size(64.dp) - .testTag(secondDestinationContentTag) - ) - } - val secondEntry = navigatorState.createBackStackEntry(secondDestination, null) - - navigator.navigate(listOf(firstEntry), null, null) - composeTestRule.awaitIdle() - - composeTestRule.onNodeWithTag(firstDestinationContentTag).assertExists() - composeTestRule.onNodeWithTag(secondDestinationContentTag).assertDoesNotExist() - assertWithMessage("First destination should have been composed exactly once") - .that(firstDestinationCompositions).isEqualTo(1) - assertWithMessage("Second destination should not have been composed yet") - .that(secondDestinationCompositions).isEqualTo(0) - - navigator.navigate(listOf(secondEntry), null, null) - composeTestRule.awaitIdle() - - composeTestRule.onNodeWithTag(firstDestinationContentTag).assertDoesNotExist() - composeTestRule.onNodeWithTag(secondDestinationContentTag).assertExists() - assertWithMessage("First destination has not been disposed") - .that(firstDestinationCompositions).isEqualTo(0) - assertWithMessage("Second destination should have been composed exactly once") - .that(secondDestinationCompositions).isEqualTo(1) - } - - @Test - fun testBackStackEntryPoppedAfterManualSheetDismiss(): Unit = runBlocking { - val navigatorState = TestNavigatorState() - val sheetState = ModalBottomSheetState(ModalBottomSheetValue.Hidden, composeTestRule.density) - val navigator = BottomSheetNavigator(sheetState = sheetState) - navigator.onAttach(navigatorState) - - val bodyContentTag = "testBodyContent" - - composeTestRule.setContent { - ModalBottomSheetLayout( - bottomSheetNavigator = navigator, - content = { - Box( - Modifier - .fillMaxSize() - .testTag(bodyContentTag) - ) - } - ) - } - - val destination = BottomSheetNavigator.Destination( - navigator = navigator, - content = { Box(Modifier.height(20.dp)) } - ) - val backStackEntry = navigatorState.createBackStackEntry(destination, null) - navigator.navigate(listOf(backStackEntry), null, null) - composeTestRule.awaitIdle() - - assertWithMessage("Navigated to destination") - .that(navigatorState.backStack.value) - .containsExactly(backStackEntry) - assertWithMessage("Bottom sheet shown") - .that(sheetState.isVisible).isTrue() - - composeTestRule.onNodeWithTag(bodyContentTag).performClick() - composeTestRule.awaitIdle() - assertWithMessage("Sheet should be hidden") - .that(sheetState.isVisible).isFalse() - assertThat(navigatorState.transitionsInProgress.value).isEmpty() - assertWithMessage("Back stack entry should be popped off the back stack") - .that(navigatorState.backStack.value) - .isEmpty() - } - - @Test - fun testSheetShownAfterNavControllerRestoresState() = runBlocking { - lateinit var navController: NavHostController - lateinit var navigator: BottomSheetNavigator - var savedState: Bundle? = null - var compositionState by mutableStateOf(0) - - val sheetState = ModalBottomSheetState(ModalBottomSheetValue.Hidden, composeTestRule.density) - val textInSheetTag = "textInSheet" - - composeTestRule.setContent { - navigator = remember { BottomSheetNavigator(sheetState) } - navController = rememberNavController(navigator) - if (savedState != null) navController.restoreState(savedState) - if (compositionState == 0) { - ModalBottomSheetLayout( - bottomSheetNavigator = navigator - ) { - NavHost(navController, startDestination = "first") { - bottomSheet("first") { - Text("Hello!", Modifier.testTag(textInSheetTag)) - } - } - } - } - } - - savedState = navController.saveState() - - // Dispose the ModalBottomSheetLayout - compositionState = 1 - composeTestRule.awaitIdle() - - composeTestRule.onNodeWithTag(textInSheetTag).assertDoesNotExist() - - // Recompose with the ModalBottomSheetLayout - compositionState = 0 - composeTestRule.awaitIdle() - - assertWithMessage("Destination is first destination") - .that(navController.currentDestination?.route) - .isEqualTo("first") - assertWithMessage("Bottom sheet is visible") - .that(sheetState.isVisible).isTrue() - } - - @Test - fun testNavigateCompletesEntriesTransitions() = runBlocking { - val sheetState = ModalBottomSheetState(ModalBottomSheetValue.Hidden, composeTestRule.density) - val navigator = BottomSheetNavigator(sheetState) - val navigatorState = TestNavigatorState() - - navigator.onAttach(navigatorState) - - composeTestRule.setContent { - ModalBottomSheetLayout( - bottomSheetNavigator = navigator, - content = { Box(Modifier.fillMaxSize()) } - ) - } - - val backStackEntry1 = navigatorState.createBackStackEntry( - navigator.createFakeDestination(), null - ) - val backStackEntry2 = navigatorState.createBackStackEntry( - navigator.createFakeDestination(), null - ) - - navigator.navigate( - entries = listOf(backStackEntry1, backStackEntry2), - navOptions = null, - navigatorExtras = null - ) - - composeTestRule.awaitIdle() - - assertThat(navigatorState.transitionsInProgress.value).doesNotContain(backStackEntry1) - assertThat(navigatorState.transitionsInProgress.value).doesNotContain(backStackEntry2) - assertThat(backStackEntry2.lifecycle.currentState).isEqualTo(Lifecycle.State.RESUMED) - } - - @Test - fun testComposeSheetContentBeforeNavigatorAttached(): Unit = runBlocking { - val sheetState = ModalBottomSheetState(ModalBottomSheetValue.Hidden, composeTestRule.density) - val navigator = BottomSheetNavigator(sheetState) - val navigatorState = TestNavigatorState() - - composeTestRule.setContent { - ModalBottomSheetLayout( - bottomSheetNavigator = navigator, - content = { Box(Modifier.fillMaxSize()) } - ) - } - - // Attach the state only after accessing the navigator's sheetContent in - // ModalBottomSheetLayout - navigator.onAttach(navigatorState) - - val entry = navigatorState.createBackStackEntry( - navigator.createFakeDestination(), null - ) - - navigator.navigate( - entries = listOf(entry), - navOptions = null, - navigatorExtras = null - ) - - composeTestRule.awaitIdle() - - assertWithMessage("The back stack entry has been added to the back stack") - .that(navigatorState.backStack.value) - .containsExactly(entry) - } - - @Test - fun testBackPressedDestroysEntry() { - lateinit var onBackPressedDispatcher: OnBackPressedDispatcher - lateinit var navController: NavHostController - - composeTestRule.setContent { - val bottomSheetNavigator = rememberBottomSheetNavigator() - navController = rememberNavController(bottomSheetNavigator) - onBackPressedDispatcher = - LocalOnBackPressedDispatcherOwner.current?.onBackPressedDispatcher!! - - ModalBottomSheetLayout(bottomSheetNavigator) { - Box(modifier = Modifier.fillMaxSize()) { - NavHost( - navController = navController, - startDestination = "mainScreen" - ) { - - composable( - route = "mainScreen", - content = { - Button(onClick = { navController.navigate("bottomSheet") }) { - Text(text = "open drawer") - } - } - ) - - bottomSheet( - route = "bottomSheet", - content = { - Box(modifier = Modifier.fillMaxSize()) { - Text( - text = "bottomSheet" - ) - } - } - ) - } - } - } - } - - composeTestRule.onNodeWithText("open drawer").performClick() - - lateinit var bottomSheetEntry: NavBackStackEntry - - composeTestRule.runOnIdle { - bottomSheetEntry = navController.currentBackStackEntry!! - onBackPressedDispatcher.onBackPressed() - } - - composeTestRule.runOnIdle { - assertThat(bottomSheetEntry.lifecycle.currentState).isEqualTo(Lifecycle.State.DESTROYED) - } - } - - @Test - fun testSheetContentSizeChangeDuringAnimation_opensSheet_shortSheetToShortSheet() { - lateinit var navigator: BottomSheetNavigator - lateinit var navController: NavHostController - var height: Dp by mutableStateOf(20.dp) - lateinit var sheetNavBackStackEntry: NavBackStackEntry - val homeDestination = "home" - val sheetDestination = "sheet" - - composeTestRule.setContent { - navigator = rememberBottomSheetNavigator() - navController = rememberNavController(navigator) - ModalBottomSheetLayout(navigator) { - NavHost(navController, homeDestination) { - composable(homeDestination) { - Box( - Modifier - .fillMaxSize() - .background(Color.Blue) - ) - } - bottomSheet(sheetDestination) { backStackEntry -> - sheetNavBackStackEntry = backStackEntry - Box( - Modifier - .height(height) - .fillMaxWidth() - .background(Color.Red) - ) - } - } - } - } - - composeTestRule.mainClock.autoAdvance = false - composeTestRule.runOnUiThread { navController.navigate(sheetDestination) } - composeTestRule.mainClock.advanceTimeBy(100) - - assertThat(navigator.transitionsInProgress.value.lastOrNull()) - .isEqualTo(sheetNavBackStackEntry) - - height = (composeTestRule.onRoot().getUnclippedBoundsInRoot().height) / 3 - - composeTestRule.mainClock.autoAdvance = true - composeTestRule.waitForIdle() - assertThat(navigator.navigatorSheetState.isVisible).isTrue() - - assertThat(navigator.transitionsInProgress.value).isEmpty() - - composeTestRule.runOnUiThread { navController.navigate(homeDestination) } - composeTestRule.waitForIdle() - assertThat(navigator.navigatorSheetState.isVisible).isFalse() - } - - @Test - fun testSheetContentSizeChangeDuringAnimation_opensSheet_shortSheetToTallSheet() { - lateinit var navigator: BottomSheetNavigator - lateinit var navController: NavHostController - var height: Dp by mutableStateOf(20.dp) - lateinit var sheetNavBackStackEntry: NavBackStackEntry - val homeDestination = "home" - val sheetDestination = "sheet" - - composeTestRule.setContent { - navigator = rememberBottomSheetNavigator() - navController = rememberNavController(navigator) - ModalBottomSheetLayout(navigator) { - NavHost(navController, homeDestination) { - composable(homeDestination) { - Box(Modifier.fillMaxSize().background(Color.Blue)) - } - bottomSheet(sheetDestination) { backStackEntry -> - sheetNavBackStackEntry = backStackEntry - Box(Modifier.height(height).fillMaxWidth().background(Color.Red)) - } - } - } - } - - composeTestRule.mainClock.autoAdvance = false - composeTestRule.runOnUiThread { navController.navigate(sheetDestination) } - composeTestRule.mainClock.advanceTimeBy(100) - assertThat(navigator.transitionsInProgress.value.lastOrNull()) - .isEqualTo(sheetNavBackStackEntry) - - height = (composeTestRule.onRoot().getUnclippedBoundsInRoot().height) / 0.9f - - composeTestRule.mainClock.autoAdvance = true - composeTestRule.waitForIdle() - assertThat(navigator.navigatorSheetState.isVisible).isTrue() - - assertThat(navigator.transitionsInProgress.value).isEmpty() - - composeTestRule.runOnUiThread { navController.navigate(homeDestination) } - composeTestRule.waitForIdle() - assertThat(navigator.navigatorSheetState.isVisible).isFalse() - } - - @Test - fun testSheetContentSizeChangeDuringAnimation_opensSheet_tallSheetToTallSheet() { - lateinit var navigator: BottomSheetNavigator - lateinit var navController: NavHostController - lateinit var sheetNavBackStackEntry: NavBackStackEntry - var height: Dp by mutableStateOf(0.dp) - val homeDestination = "home" - val sheetDestination = "sheet" - - composeTestRule.setContent { - navigator = rememberBottomSheetNavigator() - navController = rememberNavController(navigator) - ModalBottomSheetLayout(navigator) { - NavHost(navController, homeDestination) { - composable(homeDestination) { - Box(Modifier.fillMaxSize().background(Color.Blue)) - } - bottomSheet(sheetDestination) { backStackEntry -> - sheetNavBackStackEntry = backStackEntry - Box(Modifier.height(height).fillMaxWidth().background(Color.Red)) - } - } - } - } - - val rootHeight = composeTestRule.onRoot().getUnclippedBoundsInRoot().height - height = rootHeight - - composeTestRule.mainClock.autoAdvance = false - composeTestRule.runOnUiThread { navController.navigate(sheetDestination) } - composeTestRule.mainClock.advanceTimeBy(100) - assertThat(navigator.transitionsInProgress.value.lastOrNull()) - .isEqualTo(sheetNavBackStackEntry) - - height = (composeTestRule.onRoot().getUnclippedBoundsInRoot().height) / 0.9f - - composeTestRule.mainClock.autoAdvance = true - composeTestRule.waitForIdle() - assertThat(navigator.navigatorSheetState.isVisible).isTrue() - - assertThat(navigator.transitionsInProgress.value).isEmpty() - - composeTestRule.runOnUiThread { navController.navigate(homeDestination) } - composeTestRule.waitForIdle() - assertThat(navigator.navigatorSheetState.isVisible).isFalse() - } - - @Test - fun testSheetContentSizeChangeDuringAnimation_opensSheet_tallSheetToShortSheet() { - lateinit var navigator: BottomSheetNavigator - lateinit var navController: NavHostController - var height: Dp by mutableStateOf(0.dp) - lateinit var sheetNavBackStackEntry: NavBackStackEntry - val homeDestination = "home" - val sheetDestination = "sheet" - - composeTestRule.setContent { - navigator = rememberBottomSheetNavigator() - navController = rememberNavController(navigator) - ModalBottomSheetLayout(navigator) { - NavHost(navController, homeDestination) { - composable(homeDestination) { - Box(Modifier.fillMaxSize().background(Color.Blue)) - } - bottomSheet(sheetDestination) { backStackEntry -> - sheetNavBackStackEntry = backStackEntry - Box(Modifier.height(height).fillMaxWidth().background(Color.Red)) - } - } - } - } - - val rootHeight = composeTestRule.onRoot().getUnclippedBoundsInRoot().height - height = rootHeight - - composeTestRule.mainClock.autoAdvance = false - composeTestRule.runOnUiThread { navController.navigate(sheetDestination) } - composeTestRule.mainClock.advanceTimeBy(100) - assertThat(navigator.transitionsInProgress.value.lastOrNull()) - .isEqualTo(sheetNavBackStackEntry) - - height = (composeTestRule.onRoot().getUnclippedBoundsInRoot().height) / 3f - - composeTestRule.mainClock.autoAdvance = true - composeTestRule.waitForIdle() - assertThat(navigator.navigatorSheetState.isVisible).isTrue() - - assertThat(navigator.transitionsInProgress.value).isEmpty() - - composeTestRule.runOnUiThread { navController.navigate(homeDestination) } - composeTestRule.waitForIdle() - assertThat(navigator.navigatorSheetState.isVisible).isFalse() - } - - @OptIn(ExperimentalMaterialApi::class) - @Test - fun testPopBackStackHidesSheetWithAnimation() { - val animationDuration = 2000 - val animationSpec = tween(animationDuration) - lateinit var navigator: BottomSheetNavigator - lateinit var navController: NavHostController - - composeTestRule.setContent { - navigator = rememberBottomSheetNavigator(animationSpec) - navController = rememberNavController(navigator) - ModalBottomSheetLayout(navigator) { - NavHost(navController, "first") { - composable("first") { - Box(Modifier.fillMaxSize()) - } - bottomSheet("sheet") { - Box(Modifier.height(200.dp)) - } - } - } - } - - composeTestRule.runOnUiThread { navController.navigate("sheet") } - composeTestRule.waitForIdle() - assertThat(navigator.navigatorSheetState.isVisible).isTrue() - - composeTestRule.mainClock.autoAdvance = false - composeTestRule.runOnUiThread { navController.popBackStack() } - - val firstAnimationTimeBreakpoint = (animationDuration * 0.9).roundToLong() - - composeTestRule.mainClock.advanceTimeBy(firstAnimationTimeBreakpoint) - assertThat(navigator.navigatorSheetState.currentValue) - .isAnyOf(ModalBottomSheetValue.HalfExpanded, ModalBottomSheetValue.Expanded) - assertThat(navigator.navigatorSheetState.targetValue) - .isEqualTo(ModalBottomSheetValue.Hidden) - - composeTestRule.runOnUiThread { navController.navigate("first") } - - composeTestRule.mainClock.autoAdvance = true - composeTestRule.waitForIdle() - assertThat(navigator.navigatorSheetState.currentValue) - .isEqualTo(ModalBottomSheetValue.Hidden) - } - - @Test - fun testTapOnScrimDismissesSheetAndPopsBackStack() { - val animationDuration = 2000 - val animationSpec = tween(animationDuration) - lateinit var navigator: BottomSheetNavigator - lateinit var navController: NavHostController - val sheetLayoutTestTag = "sheetLayout" - val homeDestination = "home" - val sheetDestination = "sheet" - - composeTestRule.setContent { - navigator = rememberBottomSheetNavigator(animationSpec) - navController = rememberNavController(navigator) - ModalBottomSheetLayout(navigator, Modifier.testTag(sheetLayoutTestTag)) { - NavHost(navController, homeDestination) { - composable(homeDestination) { - Box( - Modifier - .fillMaxSize() - .background(Color.Red) - ) - } - bottomSheet(sheetDestination) { - Box( - Modifier - .height(200.dp) - .fillMaxWidth() - .background(Color.Green) - ) { - Text("Hello!") - } - } - } - } - } - - assertThat(navController.currentBackStackEntry?.destination?.route).isEqualTo( - homeDestination - ) - assertThat(navigator.navigatorSheetState.isVisible).isFalse() - - composeTestRule.runOnUiThread { navController.navigate(sheetDestination) } - composeTestRule.waitForIdle() - - assertThat(navController.currentBackStackEntry?.destination?.route).isEqualTo( - sheetDestination - ) - assertThat(navController.currentBackStackEntry?.lifecycle?.currentState).isEqualTo(Lifecycle.State.RESUMED) - assertThat(navigator.navigatorSheetState.isVisible).isTrue() - - composeTestRule.onNodeWithTag(sheetLayoutTestTag) - .performTouchInput { click(position = topCenter) } - - composeTestRule.waitForIdle() - assertThat(navigator.navigatorSheetState.isVisible).isFalse() - } - - @Test - fun testNavigatingFromSheetToSheetDismissesAndThenShowsSheet() { - val animationDuration = 2000 - val animationSpec = tween(animationDuration) - lateinit var navigator: BottomSheetNavigator - lateinit var navController: NavHostController - val sheetLayoutTestTag = "sheetLayout" - val homeDestination = "home" - val firstSheetDestination = "sheet1" - val secondSheetDestination = "sheet2" - - composeTestRule.setContent { - navigator = rememberBottomSheetNavigator(animationSpec) - navController = rememberNavController(navigator) - ModalBottomSheetLayout(navigator, Modifier.testTag(sheetLayoutTestTag)) { - NavHost(navController, homeDestination) { - composable(homeDestination) { - Box( - Modifier - .fillMaxSize() - .background(Color.Red) - ) - } - bottomSheet(firstSheetDestination) { - Box( - Modifier - .height(200.dp) - .fillMaxWidth() - .background(Color.Green) - ) { - Text("Hello!") - } - } - bottomSheet(secondSheetDestination) { - Box( - Modifier - .height(200.dp) - .fillMaxWidth() - .background(Color.Blue) - ) { - Text("Hello!") - } - } - } - } - } - - assertThat(navController.currentBackStackEntry?.destination?.route) - .isEqualTo(homeDestination) - - composeTestRule.runOnUiThread { navController.navigate(firstSheetDestination) } - composeTestRule.waitForIdle() - - assertThat(navController.currentBackStackEntry?.destination?.route) - .isEqualTo(firstSheetDestination) - assertThat(navigator.sheetState.currentValue) - .isAnyOf(ModalBottomSheetValue.HalfExpanded, ModalBottomSheetValue.Expanded) - - composeTestRule.mainClock.autoAdvance = false - composeTestRule.runOnUiThread { navController.navigate(secondSheetDestination) } - - composeTestRule.mainClock.advanceTimeUntil { navigator.sheetState.isAnimationRunning } - composeTestRule.mainClock.advanceTimeBy(animationDuration.toLong()) - composeTestRule.mainClock.advanceTimeByFrame() - - assertThat(navigator.sheetState.currentValue).isEqualTo(ModalBottomSheetValue.Hidden) - - composeTestRule.mainClock.advanceTimeUntil { navigator.sheetState.isAnimationRunning } - composeTestRule.mainClock.advanceTimeBy(animationDuration.toLong()) - composeTestRule.mainClock.advanceTimeByFrame() - - assertThat(navigator.sheetState.currentValue) - .isAnyOf(ModalBottomSheetValue.HalfExpanded, ModalBottomSheetValue.Expanded) - assertThat(navController.currentBackStackEntry?.destination?.route) - .isEqualTo(secondSheetDestination) - - composeTestRule.runOnUiThread { - navController.popBackStack(firstSheetDestination, inclusive = false) - } - composeTestRule.mainClock.advanceTimeBy(animationDuration.toLong()) - composeTestRule.mainClock.advanceTimeByFrame() - - assertThat(navigator.sheetState.currentValue).isEqualTo(ModalBottomSheetValue.Hidden) - - composeTestRule.mainClock.autoAdvance = true - composeTestRule.waitForIdle() - - assertThat(navigator.sheetState.currentValue) - .isAnyOf(ModalBottomSheetValue.HalfExpanded, ModalBottomSheetValue.Expanded) - assertThat(navController.currentBackStackEntry?.destination?.route) - .isEqualTo(firstSheetDestination) - } - - @Test - fun testBackPressWithNestedGraphBehind() { - lateinit var navigator: BottomSheetNavigator - lateinit var navController: NavHostController - lateinit var nestedNavController: NavHostController - lateinit var backDispatcher: OnBackPressedDispatcher - val homeDestination = "home" - val firstSheetDestination = "sheet1" - val firstNestedDestination = "nested1" - val secondNestedDestination = "nested2" - - composeTestRule.setContent { - backDispatcher = LocalOnBackPressedDispatcherOwner.current?.onBackPressedDispatcher!! - navigator = rememberBottomSheetNavigator() - navController = rememberNavController(navigator) - ModalBottomSheetLayout(navigator) { - NavHost(navController, homeDestination) { - composable(homeDestination) { - nestedNavController = rememberNavController() - NavHost(nestedNavController, "nested1") { - composable(firstNestedDestination) { } - composable(secondNestedDestination) { } - } - } - bottomSheet(firstSheetDestination) { - Text("SheetDestination") - } - } - } - } - - assertThat(navController.currentBackStackEntry?.destination?.route) - .isEqualTo(homeDestination) - - composeTestRule.runOnUiThread { - nestedNavController.navigate(secondNestedDestination) - } - composeTestRule.waitForIdle() - - assertThat(navController.currentBackStackEntry?.destination?.route) - .isEqualTo(homeDestination) - assertThat(nestedNavController.currentBackStackEntry?.destination?.route) - .isEqualTo(secondNestedDestination) - - composeTestRule.runOnUiThread { - navController.navigate(firstSheetDestination) - } - composeTestRule.waitForIdle() - - assertThat(navigator.sheetState.currentValue) - .isAnyOf(ModalBottomSheetValue.HalfExpanded, ModalBottomSheetValue.Expanded) - - composeTestRule.runOnUiThread { - backDispatcher.onBackPressed() - } - composeTestRule.waitForIdle() - - assertThat(navController.currentBackStackEntry?.destination?.route) - .isEqualTo(homeDestination) - assertThat(nestedNavController.currentBackStackEntry?.destination?.route) - .isEqualTo(secondNestedDestination) - - assertThat(navigator.sheetState.currentValue).isEqualTo(ModalBottomSheetValue.Hidden) - } - - private fun BottomSheetNavigator.createFakeDestination() = - BottomSheetNavigator.Destination(this) { - Text("Fake Sheet Content") - } - - private val ModalBottomSheetState.isAnimationRunning get() = currentValue != targetValue -} diff --git a/navigation-material/src/androidTest/java/com/google/accompanist/navigation.material/FakeTests.kt b/navigation-material/src/androidTest/java/com/google/accompanist/navigation.material/FakeTests.kt deleted file mode 100644 index 8a898b592..000000000 --- a/navigation-material/src/androidTest/java/com/google/accompanist/navigation.material/FakeTests.kt +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2021 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 com.google.accompanist.navigation.material - -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.JUnit4 - -/** - * Fake tests to help with sharding: https://github.com/android/android-test/issues/973 - */ -@RunWith(JUnit4::class) -class FakeTests { - @Test - fun fake1() = Unit - - @Test - fun fake2() = Unit - - @Test - fun fake3() = Unit - - @Test - fun fake4() = Unit - - @Test - fun fake5() = Unit - - @Test - fun fake6() = Unit - - @Test - fun fake7() = Unit - - @Test - fun fake8() = Unit - - @Test - fun fake9() = Unit - - @Test - fun fake10() = Unit -} diff --git a/navigation-material/src/androidTest/java/com/google/accompanist/navigation.material/NavGraphBuilderTest.kt b/navigation-material/src/androidTest/java/com/google/accompanist/navigation.material/NavGraphBuilderTest.kt deleted file mode 100644 index d1797c889..000000000 --- a/navigation-material/src/androidTest/java/com/google/accompanist/navigation.material/NavGraphBuilderTest.kt +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2021 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 com.google.accompanist.navigation.material - -import android.net.Uri -import androidx.compose.material.ExperimentalMaterialApi -import androidx.compose.material.ModalBottomSheetState -import androidx.compose.material.ModalBottomSheetValue -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.test.junit4.createComposeRule -import androidx.core.net.toUri -import androidx.navigation.NavDeepLinkRequest -import androidx.navigation.compose.NavHost -import androidx.navigation.navArgument -import androidx.navigation.navDeepLink -import androidx.navigation.plusAssign -import androidx.navigation.testing.TestNavHostController -import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.filters.LargeTest -import com.google.common.truth.Truth.assertThat -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith - -@Suppress("DEPRECATION") -@OptIn(ExperimentalMaterialApi::class, ExperimentalMaterialNavigationApi::class) -@LargeTest -@RunWith(AndroidJUnit4::class) -internal class NavGraphBuilderTest { - @get:Rule - val composeTestRule = createComposeRule() - - @Test - fun testCurrentBackStackEntryNavigate() { - lateinit var navController: TestNavHostController - val key = "key" - val arg = "myarg" - composeTestRule.setContent { - navController = TestNavHostController(LocalContext.current) - navController.navigatorProvider += createBottomSheetNavigator() - - NavHost(navController, startDestination = firstRoute) { - bottomSheet(firstRoute) { } - bottomSheet("$secondRoute/{$key}") { } - } - } - - composeTestRule.runOnUiThread { - navController.navigate("$secondRoute/$arg") - assertThat(navController.currentBackStackEntry!!.arguments!!.getString(key)) - .isEqualTo(arg) - } - } - - @Test - fun testDefaultArguments() { - lateinit var navController: TestNavHostController - val key = "key" - val defaultArg = "default" - composeTestRule.setContent { - navController = TestNavHostController(LocalContext.current) - navController.navigatorProvider += createBottomSheetNavigator() - - NavHost(navController, startDestination = firstRoute) { - bottomSheet(firstRoute) { } - bottomSheet( - secondRoute, - arguments = listOf(navArgument(key) { defaultValue = defaultArg }) - ) { } - } - } - - composeTestRule.runOnUiThread { - navController.navigate(secondRoute) - assertThat(navController.currentBackStackEntry!!.arguments!!.getString(key)) - .isEqualTo(defaultArg) - } - } - - @Test - fun testDeepLink() { - lateinit var navController: TestNavHostController - val uriString = "https://www.example.com" - val deeplink = NavDeepLinkRequest.Builder.fromUri(Uri.parse(uriString)).build() - composeTestRule.setContent { - navController = TestNavHostController(LocalContext.current) - navController.navigatorProvider += createBottomSheetNavigator() - - NavHost(navController, startDestination = firstRoute) { - bottomSheet(firstRoute) { } - bottomSheet( - secondRoute, - deepLinks = listOf(navDeepLink { uriPattern = uriString }) - ) { } - } - } - - composeTestRule.runOnUiThread { - navController.navigate(uriString.toUri()) - assertThat(navController.currentBackStackEntry!!.destination.hasDeepLink(deeplink)) - .isTrue() - } - } - - private fun createBottomSheetNavigator() = - BottomSheetNavigator(sheetState = ModalBottomSheetState(ModalBottomSheetValue.Hidden, composeTestRule.density)) -} - -private const val firstRoute = "first" -private const val secondRoute = "second" diff --git a/navigation-material/src/androidTest/java/com/google/accompanist/navigation.material/SheetContentHostTest.kt b/navigation-material/src/androidTest/java/com/google/accompanist/navigation.material/SheetContentHostTest.kt deleted file mode 100644 index 1f199579e..000000000 --- a/navigation-material/src/androidTest/java/com/google/accompanist/navigation.material/SheetContentHostTest.kt +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright 2021 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 com.google.accompanist.navigation.material - -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.ColumnScope -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.height -import androidx.compose.material.ExperimentalMaterialApi -import androidx.compose.material.ModalBottomSheetLayout -import androidx.compose.material.ModalBottomSheetState -import androidx.compose.material.ModalBottomSheetValue -import androidx.compose.material.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.State -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.saveable.rememberSaveableStateHolder -import androidx.compose.runtime.setValue -import androidx.compose.ui.Modifier -import androidx.compose.ui.layout.onPlaced -import androidx.compose.ui.platform.testTag -import androidx.compose.ui.test.junit4.ComposeContentTestRule -import androidx.compose.ui.test.junit4.createComposeRule -import androidx.compose.ui.test.onNodeWithTag -import androidx.compose.ui.test.performClick -import androidx.compose.ui.unit.dp -import androidx.navigation.NavBackStackEntry -import androidx.navigation.testing.TestNavigatorState -import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.filters.LargeTest -import com.google.common.truth.Truth.assertThat -import com.google.common.truth.Truth.assertWithMessage -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.test.runTest -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith - -@Suppress("DEPRECATION") -@LargeTest -@RunWith(AndroidJUnit4::class) -@OptIn( - ExperimentalCoroutinesApi::class, - ExperimentalMaterialApi::class, - ExperimentalMaterialNavigationApi::class -) -internal class SheetContentHostTest { - private val bodyContentTag = "testBodyContent" - - @get:Rule - val composeTestRule = createComposeRule() - - @Test - fun testOnSheetDismissedCalled_ManualDismiss() = runTest { - val sheetState = ModalBottomSheetState(ModalBottomSheetValue.Hidden, composeTestRule.density) - val backStackEntry = createBackStackEntry(sheetState) - - val dismissedBackStackEntries = mutableListOf() - - composeTestRule.setBottomSheetContent( - mutableStateOf(backStackEntry), - sheetState, - onSheetShown = { }, - onSheetDismissed = { entry -> dismissedBackStackEntries.add(entry) } - ) - - assertThat(sheetState.currentValue == ModalBottomSheetValue.Expanded).isTrue() - composeTestRule.onNodeWithTag(bodyContentTag).performClick() - composeTestRule.runOnIdle { - assertWithMessage("Sheet is visible") - .that(sheetState.isVisible).isFalse() - assertWithMessage("Back stack entry should be in the dismissed entries list") - .that(dismissedBackStackEntries) - .containsExactly(backStackEntry) - } - } - - @Test - fun testOnSheetDismissedCalled_initiallyExpanded() = runTest { - val sheetState = ModalBottomSheetState(ModalBottomSheetValue.Expanded, composeTestRule.density) - val backStackEntry = createBackStackEntry(sheetState) - - val dismissedBackStackEntries = mutableListOf() - - composeTestRule.setBottomSheetContent( - mutableStateOf(backStackEntry), - sheetState, - onSheetShown = { }, - onSheetDismissed = { entry -> dismissedBackStackEntries.add(entry) } - ) - - assertThat(sheetState.currentValue == ModalBottomSheetValue.Expanded).isTrue() - composeTestRule.onNodeWithTag(bodyContentTag).performClick() - composeTestRule.runOnIdle { - assertWithMessage("Sheet is not visible") - .that(sheetState.isVisible).isFalse() - assertWithMessage("Back stack entry should be in the dismissed entries list") - .that(dismissedBackStackEntries) - .containsExactly(backStackEntry) - } - } - - @Test - fun testOnSheetShownCalled_onBackStackEntryEnter_shortSheet() = runTest { - val sheetState = ModalBottomSheetState(ModalBottomSheetValue.Hidden, composeTestRule.density) - val backStackEntryState = mutableStateOf(null) - val shownBackStackEntries = mutableListOf() - - composeTestRule.setBottomSheetContent( - backStackEntry = backStackEntryState, - sheetState = sheetState, - onSheetShown = { entry -> shownBackStackEntries.add(entry) }, - onSheetDismissed = { } - ) - - val backStackEntry = createBackStackEntry(sheetState) { - Box(Modifier.height(50.dp)) - } - backStackEntryState.value = backStackEntry - - composeTestRule.runOnIdle { - assertWithMessage("Sheet is visible") - .that(sheetState.isVisible).isTrue() - assertWithMessage("Back stack entry should be in the shown entries list") - .that(shownBackStackEntries) - .containsExactly(backStackEntry) - } - } - - @Test - fun testOnSheetShownCalled_onBackStackEntryEnter_tallSheet() = runTest { - val sheetState = ModalBottomSheetState(ModalBottomSheetValue.Hidden, composeTestRule.density) - val backStackEntryState = mutableStateOf(null) - val shownBackStackEntries = mutableListOf() - - composeTestRule.setBottomSheetContent( - backStackEntry = backStackEntryState, - sheetState = sheetState, - onSheetShown = { entry -> shownBackStackEntries.add(entry) }, - onSheetDismissed = { } - ) - - val backStackEntry = createBackStackEntry(sheetState) { - Box(Modifier.fillMaxSize()) - } - backStackEntryState.value = backStackEntry - - composeTestRule.runOnIdle { - assertWithMessage("Sheet is visible") - .that(sheetState.isVisible).isTrue() - assertWithMessage("Back stack entry should be in the shown entries list") - .that(shownBackStackEntries) - .containsExactly(backStackEntry) - } - } - - private fun ComposeContentTestRule.setBottomSheetContent( - backStackEntry: State, - sheetState: ModalBottomSheetState, - onSheetShown: (NavBackStackEntry) -> Unit, - onSheetDismissed: (NavBackStackEntry) -> Unit - ) { - setContent { - var anchored by remember { mutableStateOf(false) } - val saveableStateHolder = rememberSaveableStateHolder() - ModalBottomSheetLayout( - sheetContent = { - SheetContentHost( - backStackEntry = backStackEntry.value, - sheetState = sheetState, - saveableStateHolder = saveableStateHolder, - onSheetShown = onSheetShown, - onSheetDismissed = onSheetDismissed - ) - }, - sheetState = sheetState, - modifier = Modifier.onPlaced { anchored = true }, - content = { - Box( - Modifier - .fillMaxSize() - .testTag(bodyContentTag) - ) - } - ) - - if (anchored) { - LaunchedEffect(backStackEntry.value) { - if (backStackEntry.value == null) sheetState.hide() else sheetState.show() - } - } - } - } - - private fun createBackStackEntry( - sheetState: ModalBottomSheetState, - sheetContent: @Composable ColumnScope.(NavBackStackEntry) -> Unit = { Text("Fake Sheet Content") } - ): NavBackStackEntry { - val navigatorState = TestNavigatorState() - val navigator = BottomSheetNavigator(sheetState) - navigator.onAttach(navigatorState) - - val destination = BottomSheetNavigator.Destination(navigator, sheetContent) - val backStackEntry = navigatorState.createBackStackEntry(destination, null) - navigator.navigate(listOf(backStackEntry), null, null) - return backStackEntry - } -} diff --git a/navigation-material/src/main/AndroidManifest.xml b/navigation-material/src/main/AndroidManifest.xml deleted file mode 100644 index 928e8bf1f..000000000 --- a/navigation-material/src/main/AndroidManifest.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - diff --git a/navigation-material/src/main/java/com/google/accompanist/navigation/material/BottomSheet.kt b/navigation-material/src/main/java/com/google/accompanist/navigation/material/BottomSheet.kt deleted file mode 100644 index f80ef402b..000000000 --- a/navigation-material/src/main/java/com/google/accompanist/navigation/material/BottomSheet.kt +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2021 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 com.google.accompanist.navigation.material - -import androidx.compose.material.ExperimentalMaterialApi -import androidx.compose.material.MaterialTheme -import androidx.compose.material.ModalBottomSheetDefaults -import androidx.compose.material.ModalBottomSheetLayout -import androidx.compose.material.contentColorFor -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.Shape -import androidx.compose.ui.unit.Dp - -/** - * Helper function to create a [ModalBottomSheetLayout] from a [BottomSheetNavigator]. - * - * @see [ModalBottomSheetLayout] - */ -@Deprecated( - "Migrate to Androidx compose.material.navigation ModalBottomSheetLayout with the same " + - "parameters. To migrate, change import from " + - "com.google.accompanist.navigation.material.ModalBottomSheetLayout to " + - "androidx.compose.material.navigation.ModalBottomSheetLayout." -) -@ExperimentalMaterialNavigationApi -@OptIn(ExperimentalMaterialApi::class) -@Suppress("DEPRECATION") -@Composable -public fun ModalBottomSheetLayout( - bottomSheetNavigator: BottomSheetNavigator, - modifier: Modifier = Modifier, - sheetShape: Shape = MaterialTheme.shapes.large, - sheetElevation: Dp = ModalBottomSheetDefaults.Elevation, - sheetBackgroundColor: Color = MaterialTheme.colors.surface, - sheetContentColor: Color = contentColorFor(sheetBackgroundColor), - scrimColor: Color = ModalBottomSheetDefaults.scrimColor, - content: @Composable () -> Unit -) { - ModalBottomSheetLayout( - sheetState = bottomSheetNavigator.sheetState, - sheetContent = bottomSheetNavigator.sheetContent, - modifier = modifier, - sheetShape = sheetShape, - sheetElevation = sheetElevation, - sheetBackgroundColor = sheetBackgroundColor, - sheetContentColor = sheetContentColor, - scrimColor = scrimColor, - content = content - ) -} diff --git a/navigation-material/src/main/java/com/google/accompanist/navigation/material/BottomSheetNavigator.kt b/navigation-material/src/main/java/com/google/accompanist/navigation/material/BottomSheetNavigator.kt deleted file mode 100644 index 1b663d3e5..000000000 --- a/navigation-material/src/main/java/com/google/accompanist/navigation/material/BottomSheetNavigator.kt +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright 2021 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. - */ - -@file:Suppress("DEPRECATION") - -package com.google.accompanist.navigation.material - -import android.annotation.SuppressLint -import androidx.activity.compose.BackHandler -import androidx.compose.animation.core.AnimationSpec -import androidx.compose.animation.core.SpringSpec -import androidx.compose.foundation.layout.ColumnScope -import androidx.compose.material.ExperimentalMaterialApi -import androidx.compose.material.ModalBottomSheetState -import androidx.compose.material.ModalBottomSheetValue -import androidx.compose.material.rememberModalBottomSheetState -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.Stable -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.produceState -import androidx.compose.runtime.remember -import androidx.compose.runtime.saveable.rememberSaveableStateHolder -import androidx.compose.runtime.setValue -import androidx.navigation.FloatingWindow -import androidx.navigation.NavBackStackEntry -import androidx.navigation.NavDestination -import androidx.navigation.NavOptions -import androidx.navigation.Navigator -import androidx.navigation.NavigatorState -import com.google.accompanist.navigation.material.BottomSheetNavigator.Destination -import kotlinx.coroutines.CancellationException -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.transform - -/** - * The state of a [ModalBottomSheetLayout] that the [BottomSheetNavigator] drives - * - * @param sheetState The sheet state that is driven by the [BottomSheetNavigator] - */ -@Deprecated( - "Migrate to Androidx compose.material.navigation BottomSheetNavigatorSheetState " + - "with the same parameters. To migrate, change import from " + - "com.google.accompanist.navigation.material.BottomSheetNavigatorSheetState to " + - "androidx.compose.material.navigation.BottomSheetNavigatorSheetState." -) -@ExperimentalMaterialNavigationApi -@OptIn(ExperimentalMaterialApi::class) -@Stable -public class BottomSheetNavigatorSheetState(internal val sheetState: ModalBottomSheetState) { - /** - * @see ModalBottomSheetState.isVisible - */ - public val isVisible: Boolean - get() = sheetState.isVisible - - /** - * @see ModalBottomSheetState.currentValue - */ - public val currentValue: ModalBottomSheetValue - get() = sheetState.currentValue - - /** - * @see ModalBottomSheetState.targetValue - */ - public val targetValue: ModalBottomSheetValue - get() = sheetState.targetValue -} - -/** - * Create and remember a [BottomSheetNavigator] - */ -@Deprecated( - "Migrate to Androidx compose.material.navigation rememberBottomSheetNavigator " + - "with the same parameters. To migrate, change import from " + - "com.google.accompanist.navigation.material.rememberBottomSheetNavigator to " + - "androidx.compose.material.navigation.rememberBottomSheetNavigator." -) -@ExperimentalMaterialNavigationApi -@OptIn(ExperimentalMaterialApi::class) -@Composable -public fun rememberBottomSheetNavigator( - animationSpec: AnimationSpec = SpringSpec() -): BottomSheetNavigator { - val sheetState = rememberModalBottomSheetState( - ModalBottomSheetValue.Hidden, - animationSpec = animationSpec - ) - return remember { BottomSheetNavigator(sheetState) } -} - -/** - * Navigator that drives a [ModalBottomSheetState] for use of [ModalBottomSheetLayout]s - * with the navigation library. Every destination using this Navigator must set a valid - * [Composable] by setting it directly on an instantiated [Destination] or calling - * [androidx.navigation.compose.material.bottomSheet]. - * - * The [sheetContent] [Composable] will always host the latest entry of the back stack. When - * navigating from a [BottomSheetNavigator.Destination] to another - * [BottomSheetNavigator.Destination], the content of the sheet will be replaced instead of a - * new bottom sheet being shown. - * - * When the sheet is dismissed by the user, the [state]'s [NavigatorState.backStack] will be popped. - * - * The primary constructor is not intended for public use. Please refer to - * [rememberBottomSheetNavigator] instead. - * - * @param sheetState The [ModalBottomSheetState] that the [BottomSheetNavigator] will use to - * drive the sheet state - */ -@Deprecated( - "Migrate to Androidx compose.material.navigation BottomSheetNavigator " + - "with the same parameters. To migrate, change import from " + - "com.google.accompanist.navigation.material.BottomSheetNavigator to " + - "androidx.compose.material.navigation.BottomSheetNavigator." -) -@ExperimentalMaterialNavigationApi -@OptIn(ExperimentalMaterialApi::class) -@Navigator.Name("BottomSheetNavigator") -public class BottomSheetNavigator( - internal val sheetState: ModalBottomSheetState -) : Navigator() { - - private var attached by mutableStateOf(false) - - /** - * Get the back stack from the [state]. In some cases, the [sheetContent] might be composed - * before the Navigator is attached, so we specifically return an empty flow if we aren't - * attached yet. - */ - private val backStack: StateFlow> - get() = if (attached) { - state.backStack - } else { - MutableStateFlow(emptyList()) - } - - /** - * Get the transitionsInProgress from the [state]. In some cases, the [sheetContent] might be - * composed before the Navigator is attached, so we specifically return an empty flow if we - * aren't attached yet. - */ - internal val transitionsInProgress: StateFlow> - get() = if (attached) { - state.transitionsInProgress - } else { - MutableStateFlow(emptySet()) - } - - /** - * Access properties of the [ModalBottomSheetLayout]'s [ModalBottomSheetState] - */ - public val navigatorSheetState: BottomSheetNavigatorSheetState = BottomSheetNavigatorSheetState(sheetState) - - /** - * A [Composable] function that hosts the current sheet content. This should be set as - * sheetContent of your [ModalBottomSheetLayout]. - */ - public val sheetContent: @Composable ColumnScope.() -> Unit = { - val saveableStateHolder = rememberSaveableStateHolder() - val transitionsInProgressEntries by transitionsInProgress.collectAsState() - - // The latest back stack entry, retained until the sheet is completely hidden - // While the back stack is updated immediately, we might still be hiding the sheet, so - // we keep the entry around until the sheet is hidden - val retainedEntry by produceState( - initialValue = null, - key1 = backStack - ) { - backStack - .transform { backStackEntries -> - // Always hide the sheet when the back stack is updated - // Regardless of whether we're popping or pushing, we always want to hide - // the sheet first before deciding whether to re-show it or keep it hidden - try { - sheetState.hide() - } catch (_: CancellationException) { - // We catch but ignore possible cancellation exceptions as we don't want - // them to bubble up and cancel the whole produceState coroutine - } finally { - emit(backStackEntries.lastOrNull()) - } - } - .collect { - value = it - } - } - - if (retainedEntry != null) { - LaunchedEffect(retainedEntry) { - sheetState.show() - } - - BackHandler { - state.popWithTransition(popUpTo = retainedEntry!!, saveState = false) - } - } - - SheetContentHost( - backStackEntry = retainedEntry, - sheetState = sheetState, - saveableStateHolder = saveableStateHolder, - onSheetShown = { - transitionsInProgressEntries.forEach(state::markTransitionComplete) - }, - onSheetDismissed = { backStackEntry -> - // Sheet dismissal can be started through popBackStack in which case we have a - // transition that we'll want to complete - if (transitionsInProgressEntries.contains(backStackEntry)) { - state.markTransitionComplete(backStackEntry) - } - // If there is no transition in progress, the sheet has been dimissed by the - // user (for example by tapping on the scrim or through an accessibility action) - // In this case, we will immediately pop without a transition as the sheet has - // already been hidden - else { - state.pop(popUpTo = backStackEntry, saveState = false) - } - } - ) - } - - override fun onAttach(state: NavigatorState) { - super.onAttach(state) - attached = true - } - - override fun createDestination(): Destination = Destination( - navigator = this, - content = {} - ) - - @SuppressLint("NewApi") // b/187418647 - override fun navigate( - entries: List, - navOptions: NavOptions?, - navigatorExtras: Extras? - ) { - entries.forEach { entry -> - state.pushWithTransition(entry) - } - } - - override fun popBackStack(popUpTo: NavBackStackEntry, savedState: Boolean) { - state.popWithTransition(popUpTo, savedState) - } - - /** - * [NavDestination] specific to [BottomSheetNavigator] - */ - @NavDestination.ClassType(Composable::class) - public class Destination( - navigator: BottomSheetNavigator, - internal val content: @Composable ColumnScope.(NavBackStackEntry) -> Unit - ) : NavDestination(navigator), FloatingWindow -} diff --git a/navigation-material/src/main/java/com/google/accompanist/navigation/material/ExperimentalMaterialNavigationApi.kt b/navigation-material/src/main/java/com/google/accompanist/navigation/material/ExperimentalMaterialNavigationApi.kt deleted file mode 100644 index 683fd42b9..000000000 --- a/navigation-material/src/main/java/com/google/accompanist/navigation/material/ExperimentalMaterialNavigationApi.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2021 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 com.google.accompanist.navigation.material - -@RequiresOptIn(message = "This APIs are experimental and may change in the future.") -@Retention(AnnotationRetention.BINARY) -public annotation class ExperimentalMaterialNavigationApi diff --git a/navigation-material/src/main/java/com/google/accompanist/navigation/material/NavGraphBuilder.kt b/navigation-material/src/main/java/com/google/accompanist/navigation/material/NavGraphBuilder.kt deleted file mode 100644 index 9b43b38bf..000000000 --- a/navigation-material/src/main/java/com/google/accompanist/navigation/material/NavGraphBuilder.kt +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2021 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 com.google.accompanist.navigation.material - -import android.annotation.SuppressLint -import androidx.compose.foundation.layout.ColumnScope -import androidx.compose.runtime.Composable -import androidx.navigation.NamedNavArgument -import androidx.navigation.NavBackStackEntry -import androidx.navigation.NavDeepLink -import androidx.navigation.NavGraphBuilder -import androidx.navigation.get - -/** - * Add the [content] [Composable] as bottom sheet content to the [NavGraphBuilder] - * - * @param route route for the destination - * @param arguments list of arguments to associate with destination - * @param deepLinks list of deep links to associate with the destinations - * @param content the sheet content at the given destination - */ -@Deprecated( - "Migrate to Androidx compose.material.navigation NavGraphBuilder.bottomSheet with the " + - "same parameters. To migrate, change import from " + - "com.google.accompanist.navigation.material.bottomSheet to " + - "androidx.compose.material.navigation.bottomSheet." -) -@Suppress("DEPRECATION") -@SuppressLint("NewApi") // b/187418647 -@ExperimentalMaterialNavigationApi -public fun NavGraphBuilder.bottomSheet( - route: String, - arguments: List = emptyList(), - deepLinks: List = emptyList(), - content: @Composable ColumnScope.(backstackEntry: NavBackStackEntry) -> Unit -) { - addDestination( - BottomSheetNavigator.Destination( - provider[BottomSheetNavigator::class], - content - ).apply { - this.route = route - arguments.forEach { (argumentName, argument) -> - addArgument(argumentName, argument) - } - deepLinks.forEach { deepLink -> - addDeepLink(deepLink) - } - } - ) -} diff --git a/navigation-material/src/main/java/com/google/accompanist/navigation/material/SheetContentHost.kt b/navigation-material/src/main/java/com/google/accompanist/navigation/material/SheetContentHost.kt deleted file mode 100644 index 0f6a0f927..000000000 --- a/navigation-material/src/main/java/com/google/accompanist/navigation/material/SheetContentHost.kt +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2021 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 com.google.accompanist.navigation.material - -import androidx.compose.foundation.layout.ColumnScope -import androidx.compose.material.ExperimentalMaterialApi -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. - */ -@ExperimentalMaterialNavigationApi -@OptIn(ExperimentalMaterialApi::class) -@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) { - @Suppress("DEPRECATION") - val content = (backStackEntry.destination as BottomSheetNavigator.Destination).content - content(backStackEntry) - } - } -} diff --git a/sample/build.gradle.kts b/sample/build.gradle.kts index 28c512b59..c65a90cda 100644 --- a/sample/build.gradle.kts +++ b/sample/build.gradle.kts @@ -68,7 +68,6 @@ dependencies { implementation(project(":adaptive")) implementation(project(":drawablepainter")) implementation(project(":navigation-animation")) - implementation(project(":navigation-material")) implementation(project(":permissions")) implementation(project(":systemuicontroller")) diff --git a/sample/src/main/AndroidManifest.xml b/sample/src/main/AndroidManifest.xml index 011c09cae..e295acf8a 100644 --- a/sample/src/main/AndroidManifest.xml +++ b/sample/src/main/AndroidManifest.xml @@ -60,16 +60,6 @@ - - - - - - - - val arg = backstackEntry.arguments?.getString("arg") ?: "Missing argument :(" - BottomSheet( - showFeed = { navController.navigate(Destinations.Feed) }, - showAnotherSheet = { - navController.navigate(Destinations.Sheet + "?arg=${UUID.randomUUID()}") - }, - arg = arg - ) - } - } - } -} - -@Composable -private fun HomeScreen(showSheet: () -> Unit, showFeed: () -> Unit) { - Column(Modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally) { - Text("Body") - Button(onClick = showSheet) { - Text("Show sheet!") - } - Button(onClick = showFeed) { - Text("Navigate to Feed") - } - } -} - -@Composable -private fun BottomSheet(showFeed: () -> Unit, showAnotherSheet: () -> Unit, arg: String) { - Column(Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) { - Text("Sheet with arg: $arg") - Button(onClick = showFeed) { - Text("Click me to navigate!") - } - Button(onClick = showAnotherSheet) { - Text("Click me to show another sheet!") - } - } -} diff --git a/settings.gradle.kts b/settings.gradle.kts index c61be1bcc..f678a58fd 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -35,7 +35,6 @@ include(":internal-testutils") include(":appcompat-theme") include(":drawablepainter") include(":navigation-animation") -include(":navigation-material") include(":permissions") include(":permissions-lint") include(":systemuicontroller")