From 52d472d125cc4f7d0c7b3f06081a01d4ec084044 Mon Sep 17 00:00:00 2001 From: Adetunji Dahunsi Date: Sun, 18 May 2025 00:24:29 -0400 Subject: [PATCH 1/6] Fixes for shared elements on nav UI elements --- sample/android/build.gradle.kts | 1 + .../com/tunjid/demo/common/ui/DemoApp.kt | 3 - .../tunjid/demo/common/ui/PaneNavigation.kt | 84 +++++++++++-------- 3 files changed, 48 insertions(+), 40 deletions(-) diff --git a/sample/android/build.gradle.kts b/sample/android/build.gradle.kts index b53fd89..7dfc9cc 100644 --- a/sample/android/build.gradle.kts +++ b/sample/android/build.gradle.kts @@ -37,6 +37,7 @@ android { getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" ) + signingConfig = signingConfigs.getByName("debug") } } } diff --git a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/DemoApp.kt b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/DemoApp.kt index 6d79122..4b0cc06 100644 --- a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/DemoApp.kt +++ b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/DemoApp.kt @@ -109,7 +109,6 @@ fun App( sharedTransitionScope = this ) } - appState.movableSharedElementHostState = movableSharedElementHostState MultiPaneDisplay( modifier = Modifier .fillMaxSize(), @@ -241,8 +240,6 @@ class AppState( private val navigationRepository: NavigationRepository = NavigationRepository, ) { - internal lateinit var movableSharedElementHostState: MovableSharedElementHostState - private val navigationState = mutableStateOf( navigationRepository.navigationStateFlow.value ) diff --git a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PaneNavigation.kt b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PaneNavigation.kt index 8c042e6..891e2d6 100644 --- a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PaneNavigation.kt +++ b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PaneNavigation.kt @@ -27,6 +27,7 @@ import androidx.compose.animation.slideInHorizontally import androidx.compose.animation.slideInVertically import androidx.compose.animation.slideOutHorizontally import androidx.compose.animation.slideOutVertically +import androidx.compose.foundation.layout.Box import androidx.compose.material3.Icon import androidx.compose.material3.NavigationBar import androidx.compose.material3.NavigationBarItem @@ -39,9 +40,8 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.layout.layout import com.tunjid.demo.common.ui.data.SampleDestination -import com.tunjid.treenav.compose.moveablesharedelement.rememberPaneMovableSharedElementScope -import com.tunjid.treenav.compose.rememberPaneMovableElementSharedTransitionScope import com.tunjid.treenav.compose.threepane.ThreePane import com.tunjid.treenav.compose.threepane.ThreePaneMovableElementSharedTransitionScope import com.tunjid.treenav.current @@ -55,17 +55,19 @@ fun PaneScaffoldState.PaneNavigationBar( enterTransition = enterTransition, exitTransition = exitTransition, canShow = canShowBottomNavigation, - content = { - val finalModifier = modifier - .navigationSharedElement( - sharedContentState = rememberSharedContentState(BottomNavSharedElementKey), + content = content@{ + Box( + modifier = modifier + .navigationSharedElement( + sharedContentState = rememberSharedContentState(BottomNavSharedElementKey), + ) + ) { + if (canUseMovableContent) LocalAppState.current.movableNavigationBar( + this@content, + Modifier.fillMaxConstraints() ) - - if (canUseMovableContent) LocalAppState.current.movableNavigationBar( - this, - finalModifier - ) - else PaneNavigationBar(finalModifier) + else PaneNavigationBar(Modifier.fillMaxConstraints()) + } } ) @@ -78,17 +80,19 @@ fun PaneScaffoldState.PaneNavigationRail( enterTransition = enterTransition, exitTransition = exitTransition, canShow = canShowNavRail, - content = { - val finalModifier = modifier - .navigationSharedElement( - sharedContentState = rememberSharedContentState(NavRailSharedElementKey), + content = content@{ + Box( + modifier = modifier + .navigationSharedElement( + sharedContentState = rememberSharedContentState(NavRailSharedElementKey), + ) + ) { + if (canUseMovableContent) LocalAppState.current.movableNavigationRail( + this@content, + Modifier.fillMaxConstraints() ) - - if (canUseMovableContent) LocalAppState.current.movableNavigationRail( - this, - finalModifier - ) - else PaneNavigationRail(finalModifier) + else PaneNavigationRail(Modifier.fillMaxConstraints()) + } } ) @@ -157,19 +161,9 @@ private fun PaneScaffoldState.withUpdatedPaneScaffoldNavigationState( canShow: Boolean, content: @Composable NavigationBarState.() -> Unit ) { - val appState = LocalAppState.current - - val paneMovableElementSharedTransitionScope = - rememberPaneMovableElementSharedTransitionScope( - paneSharedTransitionScope = this, - movableSharedElementScope = rememberPaneMovableSharedElementScope( - movableSharedElementHostState = appState.movableSharedElementHostState - ), - ) - val state = remember { NavigationBarState( - delegate = paneMovableElementSharedTransitionScope, + delegate = this, enterTransition = enterTransition, exitTransition = exitTransition, canShow = canShow, @@ -185,7 +179,7 @@ private fun PaneScaffoldState.withUpdatedPaneScaffoldNavigationState( @Stable internal class NavigationBarState( - private val delegate: ThreePaneMovableElementSharedTransitionScope, + private val delegate: PaneScaffoldState, enterTransition: EnterTransition, exitTransition: ExitTransition, canShow: Boolean, @@ -195,7 +189,7 @@ internal class NavigationBarState( var canShow by mutableStateOf(canShow) val canUseMovableContent - get() = when { + get() = canShow && when { isActive && isPreviewingBack && paneState.pane == ThreePane.TransientPrimary -> true isActive && !isPreviewingBack && paneState.pane == ThreePane.Primary -> true else -> false @@ -208,13 +202,29 @@ internal class NavigationBarState( @OptIn(ExperimentalSharedTransitionApi::class) fun Modifier.navigationSharedElement( sharedContentState: SharedTransitionScope.SharedContentState, - ) = sharedElement( + ) = sharedElementWithCallerManagedVisibility( sharedContentState = sharedContentState, - animatedVisibilityScope = delegate, + visible = canShow && delegate.isActive, zIndexInOverlay = NavigationSharedElementZIndex, ) } +private fun Modifier.fillMaxConstraints() = + layout { measurable, constraints -> + val placeable = measurable.measure( + constraints.copy( + minWidth = constraints.maxWidth, + maxHeight = constraints.maxHeight + ) + ) + layout( + width = placeable.width, + height = placeable.height + ) { + placeable.place(0, 0) + } + } + private data object BottomNavSharedElementKey private data object NavRailSharedElementKey From 510812a4f058fb4becf2a1b609c0c64d9add1197 Mon Sep 17 00:00:00 2001 From: Adetunji Dahunsi Date: Sun, 18 May 2025 00:59:39 -0400 Subject: [PATCH 2/6] Remove unnecessary animations --- .../kotlin/com/tunjid/demo/common/ui/PaneNavigation.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PaneNavigation.kt b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PaneNavigation.kt index 891e2d6..45b3fb8 100644 --- a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PaneNavigation.kt +++ b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PaneNavigation.kt @@ -77,8 +77,8 @@ fun PaneScaffoldState.PaneNavigationRail( enterTransition: EnterTransition = slideInHorizontally(initialOffsetX = { -it }), exitTransition: ExitTransition = slideOutHorizontally(targetOffsetX = { -it }), ) = withUpdatedPaneScaffoldNavigationState( - enterTransition = enterTransition, - exitTransition = exitTransition, + enterTransition = if (canShowNavRail) enterTransition else EnterTransition.None, + exitTransition = if (canShowNavRail) exitTransition else ExitTransition.None, canShow = canShowNavRail, content = content@{ Box( From adfb6671d7321f999a77a85017e99550408c116a Mon Sep 17 00:00:00 2001 From: Adetunji Dahunsi Date: Sun, 18 May 2025 08:48:05 -0400 Subject: [PATCH 3/6] Simplify use of movable navigation elements --- .../com/tunjid/demo/common/ui/DemoApp.kt | 12 +- .../tunjid/demo/common/ui/PaneNavigation.kt | 228 +++++------------- .../com/tunjid/demo/common/ui/PaneScaffold.kt | 17 +- 3 files changed, 86 insertions(+), 171 deletions(-) diff --git a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/DemoApp.kt b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/DemoApp.kt index 4b0cc06..c2680c4 100644 --- a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/DemoApp.kt +++ b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/DemoApp.kt @@ -48,7 +48,7 @@ import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.Stable import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue -import androidx.compose.runtime.movableContentWithReceiverOf +import androidx.compose.runtime.movableContentOf import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.mutableStateOf @@ -67,28 +67,28 @@ import com.tunjid.composables.backpreview.backPreview import com.tunjid.composables.splitlayout.SplitLayout import com.tunjid.composables.splitlayout.SplitLayoutState import com.tunjid.demo.common.ui.AppState.Companion.rememberMultiPaneDisplayState +import com.tunjid.demo.common.ui.avatar.avatarPaneEntry import com.tunjid.demo.common.ui.chat.chatPaneEntry import com.tunjid.demo.common.ui.chatrooms.chatRoomPaneEntry import com.tunjid.demo.common.ui.data.NavigationRepository import com.tunjid.demo.common.ui.data.SampleDestination import com.tunjid.demo.common.ui.me.mePaneEntry -import com.tunjid.demo.common.ui.avatar.avatarPaneEntry import com.tunjid.demo.common.ui.profile.profilePaneEntry import com.tunjid.treenav.MultiStackNav import com.tunjid.treenav.compose.MultiPaneDisplay import com.tunjid.treenav.compose.MultiPaneDisplayScope import com.tunjid.treenav.compose.MultiPaneDisplayState import com.tunjid.treenav.compose.moveablesharedelement.MovableSharedElementHostState -import com.tunjid.treenav.compose.threepane.ThreePane import com.tunjid.treenav.compose.multiPaneDisplayBackstack +import com.tunjid.treenav.compose.threepane.ThreePane import com.tunjid.treenav.compose.threepane.transforms.backPreviewTransform import com.tunjid.treenav.compose.threepane.transforms.threePanedAdaptiveTransform import com.tunjid.treenav.compose.threepane.transforms.threePanedMovableSharedElementTransform import com.tunjid.treenav.compose.transforms.Transform import com.tunjid.treenav.compose.transforms.paneModifierTransform -import com.tunjid.treenav.requireCurrent import com.tunjid.treenav.pop import com.tunjid.treenav.popToRoot +import com.tunjid.treenav.requireCurrent import com.tunjid.treenav.switch import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -275,12 +275,12 @@ class AppState( ) internal val movableNavigationBar = - movableContentWithReceiverOf { modifier -> + movableContentOf { modifier -> PaneNavigationBar(modifier) } internal val movableNavigationRail = - movableContentWithReceiverOf { modifier -> + movableContentOf { modifier -> PaneNavigationRail(modifier) } diff --git a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PaneNavigation.kt b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PaneNavigation.kt index 45b3fb8..95a0672 100644 --- a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PaneNavigation.kt +++ b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PaneNavigation.kt @@ -22,28 +22,18 @@ import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.EnterTransition import androidx.compose.animation.ExitTransition import androidx.compose.animation.ExperimentalSharedTransitionApi -import androidx.compose.animation.SharedTransitionScope import androidx.compose.animation.slideInHorizontally import androidx.compose.animation.slideInVertically import androidx.compose.animation.slideOutHorizontally import androidx.compose.animation.slideOutVertically -import androidx.compose.foundation.layout.Box import androidx.compose.material3.Icon import androidx.compose.material3.NavigationBar import androidx.compose.material3.NavigationBarItem import androidx.compose.material3.NavigationRail import androidx.compose.material3.NavigationRailItem import androidx.compose.runtime.Composable -import androidx.compose.runtime.Stable -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.layout.layout import com.tunjid.demo.common.ui.data.SampleDestination -import com.tunjid.treenav.compose.threepane.ThreePane -import com.tunjid.treenav.compose.threepane.ThreePaneMovableElementSharedTransitionScope import com.tunjid.treenav.current @Composable @@ -51,181 +41,93 @@ fun PaneScaffoldState.PaneNavigationBar( modifier: Modifier = Modifier, enterTransition: EnterTransition = slideInVertically(initialOffsetY = { it }), exitTransition: ExitTransition = slideOutVertically(targetOffsetY = { it }), -) = withUpdatedPaneScaffoldNavigationState( - enterTransition = enterTransition, - exitTransition = exitTransition, - canShow = canShowBottomNavigation, - content = content@{ - Box( - modifier = modifier - .navigationSharedElement( - sharedContentState = rememberSharedContentState(BottomNavSharedElementKey), - ) - ) { - if (canUseMovableContent) LocalAppState.current.movableNavigationBar( - this@content, - Modifier.fillMaxConstraints() - ) - else PaneNavigationBar(Modifier.fillMaxConstraints()) - } - } -) - -@Composable -fun PaneScaffoldState.PaneNavigationRail( - modifier: Modifier = Modifier, - enterTransition: EnterTransition = slideInHorizontally(initialOffsetX = { -it }), - exitTransition: ExitTransition = slideOutHorizontally(targetOffsetX = { -it }), -) = withUpdatedPaneScaffoldNavigationState( - enterTransition = if (canShowNavRail) enterTransition else EnterTransition.None, - exitTransition = if (canShowNavRail) exitTransition else ExitTransition.None, - canShow = canShowNavRail, - content = content@{ - Box( - modifier = modifier - .navigationSharedElement( - sharedContentState = rememberSharedContentState(NavRailSharedElementKey), - ) - ) { - if (canUseMovableContent) LocalAppState.current.movableNavigationRail( - this@content, - Modifier.fillMaxConstraints() - ) - else PaneNavigationRail(Modifier.fillMaxConstraints()) - } - } -) - -@Composable -internal fun NavigationBarState.PaneNavigationBar( - modifier: Modifier = Modifier, ) { - val appState = LocalAppState.current AnimatedVisibility( - modifier = modifier, - visible = canShow, + modifier = modifier + .sharedElementWithCallerManagedVisibility( + sharedContentState = rememberSharedContentState(NavigationBarSharedElementKey), + visible = isActive && canUseMovableNavigationBar, + zIndexInOverlay = NavigationSharedElementZIndex, + ), + visible = canShowNavigationBar, enter = enterTransition, exit = exitTransition, content = { - NavigationBar { - SampleDestination.NavTabs.entries.forEach { item -> - NavigationBarItem( - icon = { - Icon( - imageVector = item.icon, - contentDescription = item.title, - ) - }, - selected = item == appState.currentNavigation.current, - onClick = { appState.setTab(item) } - ) - } - } - }, + val appState = LocalAppState.current + if (canUseMovableNavigationBar) appState.movableNavigationBar(Modifier) + else appState.PaneNavigationBar(Modifier) + } ) } @Composable -internal fun NavigationBarState.PaneNavigationRail( +fun PaneScaffoldState.PaneNavigationRail( modifier: Modifier = Modifier, + enterTransition: EnterTransition = slideInHorizontally(initialOffsetX = { -it }), + exitTransition: ExitTransition = slideOutHorizontally(targetOffsetX = { -it }), ) { - val appState = LocalAppState.current AnimatedVisibility( - modifier = modifier, - visible = canShow, - enter = enterTransition, - exit = exitTransition, - content = { - NavigationRail { - SampleDestination.NavTabs.entries.forEach { item -> - NavigationRailItem( - selected = item == appState.currentNavigation.current, - icon = { - Icon( - imageVector = item.icon, - contentDescription = item.title, - ) - }, - onClick = { appState.setTab(item) } - ) - } - } - } - ) + modifier = modifier + .sharedElementWithCallerManagedVisibility( + sharedContentState = rememberSharedContentState(NavigationRailSharedElementKey), + visible = isActive && canUseMovableNavigationRail, + zIndexInOverlay = NavigationSharedElementZIndex, + ), + visible = canShowNavigationRail, + enter = if (canShowNavigationRail) enterTransition else EnterTransition.None, + exit = if (canShowNavigationRail) exitTransition else ExitTransition.None, + ) { + val appState = LocalAppState.current + if (canUseMovableNavigationRail) appState.movableNavigationRail(Modifier) + else appState.PaneNavigationRail(Modifier) + } } @Composable -private fun PaneScaffoldState.withUpdatedPaneScaffoldNavigationState( - enterTransition: EnterTransition, - exitTransition: ExitTransition, - canShow: Boolean, - content: @Composable NavigationBarState.() -> Unit +internal fun AppState.PaneNavigationBar( + modifier: Modifier = Modifier ) { - val state = remember { - NavigationBarState( - delegate = this, - enterTransition = enterTransition, - exitTransition = exitTransition, - canShow = canShow, - ) - }.also { - it.enterTransition = enterTransition - it.exitTransition = exitTransition - it.canShow = canShow - } - - state.content() -} - -@Stable -internal class NavigationBarState( - private val delegate: PaneScaffoldState, - enterTransition: EnterTransition, - exitTransition: ExitTransition, - canShow: Boolean, -) : ThreePaneMovableElementSharedTransitionScope by delegate { - var enterTransition by mutableStateOf(enterTransition) - var exitTransition by mutableStateOf(exitTransition) - var canShow by mutableStateOf(canShow) - - val canUseMovableContent - get() = canShow && when { - isActive && isPreviewingBack && paneState.pane == ThreePane.TransientPrimary -> true - isActive && !isPreviewingBack && paneState.pane == ThreePane.Primary -> true - else -> false + NavigationBar( + modifier = modifier + ) { + SampleDestination.NavTabs.entries.forEach { item -> + NavigationBarItem( + icon = { + Icon( + imageVector = item.icon, + contentDescription = item.title, + ) + }, + selected = item == currentNavigation.current, + onClick = { setTab(item) } + ) } - - private val isPreviewingBack: Boolean - get() = paneState.adaptations.contains(ThreePane.PrimaryToTransient) - - - @OptIn(ExperimentalSharedTransitionApi::class) - fun Modifier.navigationSharedElement( - sharedContentState: SharedTransitionScope.SharedContentState, - ) = sharedElementWithCallerManagedVisibility( - sharedContentState = sharedContentState, - visible = canShow && delegate.isActive, - zIndexInOverlay = NavigationSharedElementZIndex, - ) + } } -private fun Modifier.fillMaxConstraints() = - layout { measurable, constraints -> - val placeable = measurable.measure( - constraints.copy( - minWidth = constraints.maxWidth, - maxHeight = constraints.maxHeight +@Composable +internal fun AppState.PaneNavigationRail( + modifier: Modifier = Modifier +) { + NavigationRail( + modifier = modifier + ) { + SampleDestination.NavTabs.entries.forEach { item -> + NavigationRailItem( + selected = item == currentNavigation.current, + icon = { + Icon( + imageVector = item.icon, + contentDescription = item.title, + ) + }, + onClick = { setTab(item) } ) - ) - layout( - width = placeable.width, - height = placeable.height - ) { - placeable.place(0, 0) } } +} -private data object BottomNavSharedElementKey -private data object NavRailSharedElementKey +private data object NavigationBarSharedElementKey +private data object NavigationRailSharedElementKey private const val NavigationSharedElementZIndex = 2f diff --git a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PaneScaffold.kt b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PaneScaffold.kt index 6f7d66b..373904f 100644 --- a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PaneScaffold.kt +++ b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PaneScaffold.kt @@ -64,12 +64,22 @@ class PaneScaffoldState internal constructor( threePaneMovableElementSharedTransitionScope: ThreePaneMovableElementSharedTransitionScope, ) : ThreePaneMovableElementSharedTransitionScope by threePaneMovableElementSharedTransitionScope { - internal val canShowBottomNavigation get() = !appState.isMediumScreenWidthOrWider + internal val canShowNavigationBar get() = !appState.isMediumScreenWidthOrWider - internal val canShowNavRail + internal val canShowNavigationRail get() = appState.filteredPaneOrder.firstOrNull() == paneState.pane && appState.isMediumScreenWidthOrWider + val canUseMovableNavigationBar + get() = canShowNavigationBar && when { + isActive && isPreviewingBack && paneState.pane == ThreePane.TransientPrimary -> true + isActive && !isPreviewingBack && paneState.pane == ThreePane.Primary -> true + else -> false + } + + val canUseMovableNavigationRail + get() = canShowNavigationRail && isActive + internal val canShowFab get() = when (paneState.pane) { ThreePane.Primary -> true @@ -86,6 +96,9 @@ class PaneScaffoldState internal constructor( internal fun hasMatchedSize(): Boolean = abs(scaffoldCurrentSize.width - scaffoldTargetSize.width) <= 2 && abs(scaffoldCurrentSize.height - scaffoldTargetSize.height) <= 2 + + private val isPreviewingBack: Boolean + get() = paneState.adaptations.contains(ThreePane.PrimaryToTransient) } @Composable From 7d4be28efce6149b508e1b3722b48fe994126abc Mon Sep 17 00:00:00 2001 From: Adetunji Dahunsi Date: Sun, 18 May 2025 09:13:50 -0400 Subject: [PATCH 4/6] Change shared element modifiers used --- .../kotlin/com/tunjid/demo/common/ui/PaneNavigation.kt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PaneNavigation.kt b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PaneNavigation.kt index 95a0672..f37d836 100644 --- a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PaneNavigation.kt +++ b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PaneNavigation.kt @@ -22,6 +22,7 @@ import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.EnterTransition import androidx.compose.animation.ExitTransition import androidx.compose.animation.ExperimentalSharedTransitionApi +import androidx.compose.animation.core.snap import androidx.compose.animation.slideInHorizontally import androidx.compose.animation.slideInVertically import androidx.compose.animation.slideOutHorizontally @@ -44,9 +45,9 @@ fun PaneScaffoldState.PaneNavigationBar( ) { AnimatedVisibility( modifier = modifier - .sharedElementWithCallerManagedVisibility( + .sharedElement( sharedContentState = rememberSharedContentState(NavigationBarSharedElementKey), - visible = isActive && canUseMovableNavigationBar, + animatedVisibilityScope = this, zIndexInOverlay = NavigationSharedElementZIndex, ), visible = canShowNavigationBar, @@ -68,10 +69,11 @@ fun PaneScaffoldState.PaneNavigationRail( ) { AnimatedVisibility( modifier = modifier - .sharedElementWithCallerManagedVisibility( + .sharedElement( sharedContentState = rememberSharedContentState(NavigationRailSharedElementKey), - visible = isActive && canUseMovableNavigationRail, + animatedVisibilityScope = this, zIndexInOverlay = NavigationSharedElementZIndex, + boundsTransform = { _, _ -> snap() }, ), visible = canShowNavigationRail, enter = if (canShowNavigationRail) enterTransition else EnterTransition.None, From fc2f744b8d2229aac4aeebb0a5eb0bd1946a58f3 Mon Sep 17 00:00:00 2001 From: Adetunji Dahunsi Date: Sun, 18 May 2025 09:20:18 -0400 Subject: [PATCH 5/6] Touch ups --- .../kotlin/com/tunjid/demo/common/ui/PaneNavigation.kt | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PaneNavigation.kt b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PaneNavigation.kt index f37d836..99042dd 100644 --- a/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PaneNavigation.kt +++ b/sample/common/src/commonMain/kotlin/com/tunjid/demo/common/ui/PaneNavigation.kt @@ -19,6 +19,7 @@ package com.tunjid.demo.common.ui import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.BoundsTransform import androidx.compose.animation.EnterTransition import androidx.compose.animation.ExitTransition import androidx.compose.animation.ExperimentalSharedTransitionApi @@ -69,11 +70,11 @@ fun PaneScaffoldState.PaneNavigationRail( ) { AnimatedVisibility( modifier = modifier - .sharedElement( + .sharedElementWithCallerManagedVisibility( sharedContentState = rememberSharedContentState(NavigationRailSharedElementKey), - animatedVisibilityScope = this, + visible = canShowNavigationRail, zIndexInOverlay = NavigationSharedElementZIndex, - boundsTransform = { _, _ -> snap() }, + boundsTransform = NavigationRailBoundsTransform, ), visible = canShowNavigationRail, enter = if (canShowNavigationRail) enterTransition else EnterTransition.None, @@ -133,3 +134,5 @@ private data object NavigationBarSharedElementKey private data object NavigationRailSharedElementKey private const val NavigationSharedElementZIndex = 2f + +private val NavigationRailBoundsTransform = BoundsTransform { _, _ -> snap() } From a71114f75fb669f9196e98904f9e239849a35289 Mon Sep 17 00:00:00 2001 From: Adetunji Dahunsi Date: Mon, 19 May 2025 10:25:28 -0400 Subject: [PATCH 6/6] Bump library version --- libraryVersion.properties | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraryVersion.properties b/libraryVersion.properties index e854783..e89f8ed 100644 --- a/libraryVersion.properties +++ b/libraryVersion.properties @@ -14,7 +14,7 @@ # limitations under the License. # groupId=com.tunjid.treenav -treenav_version=0.0.25 -strings_version=0.0.25 -compose_version=0.0.25 -compose-threepane_version=0.0.25 \ No newline at end of file +treenav_version=0.0.26 +strings_version=0.0.26 +compose_version=0.0.26 +compose-threepane_version=0.0.26 \ No newline at end of file