diff --git a/financial-connections/src/main/java/com/stripe/android/financialconnections/ui/FinancialConnectionsSheetNativeActivity.kt b/financial-connections/src/main/java/com/stripe/android/financialconnections/ui/FinancialConnectionsSheetNativeActivity.kt index 8fd89f76f93..6c2284884e2 100644 --- a/financial-connections/src/main/java/com/stripe/android/financialconnections/ui/FinancialConnectionsSheetNativeActivity.kt +++ b/financial-connections/src/main/java/com/stripe/android/financialconnections/ui/FinancialConnectionsSheetNativeActivity.kt @@ -201,6 +201,10 @@ internal class FinancialConnectionsSheetNativeActivity : AppCompatActivity() { NavHost( navController = navController, startDestination = initialDestination.fullRoute, + enterTransition = enterTransition(), + exitTransition = pauseTransition(), + popEnterTransition = resumeTransition(), + popExitTransition = exitTransition(), ) { composable(Destination.Consent) composable(Destination.ManualEntry) diff --git a/financial-connections/src/main/java/com/stripe/android/financialconnections/ui/Transitions.kt b/financial-connections/src/main/java/com/stripe/android/financialconnections/ui/Transitions.kt new file mode 100644 index 00000000000..30ad147a30d --- /dev/null +++ b/financial-connections/src/main/java/com/stripe/android/financialconnections/ui/Transitions.kt @@ -0,0 +1,89 @@ +package com.stripe.android.financialconnections.ui + +import androidx.compose.animation.AnimatedContentTransitionScope +import androidx.compose.animation.EnterTransition +import androidx.compose.animation.ExitTransition +import androidx.compose.animation.core.tween +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut +import androidx.compose.animation.slideInHorizontally +import androidx.compose.animation.slideOutHorizontally +import androidx.navigation.NavBackStackEntry +import com.stripe.android.financialconnections.model.FinancialConnectionsSessionManifest.Pane.ATTACH_LINKED_PAYMENT_ACCOUNT +import com.stripe.android.financialconnections.navigation.pane + +private const val TransitionDurationMillis = 300 + +private val FADE_IN_TRANSITION = fadeIn( + animationSpec = tween(TransitionDurationMillis) +) + +private val FADE_OUT_TRANSITION = fadeOut( + animationSpec = tween(TransitionDurationMillis) +) + +internal fun enterTransition(): AnimatedContentTransitionScope.() -> EnterTransition { + return { + if (initialState.skipTransition) { + FADE_IN_TRANSITION + } else { + FADE_IN_TRANSITION + slideInHorizontally( + animationSpec = tween(TransitionDurationMillis), + initialOffsetX = { fullWidth -> + fullWidth / 2 + }, + ) + } + } +} + +internal fun resumeTransition(): AnimatedContentTransitionScope.() -> EnterTransition { + return { + if (initialState.skipTransition) { + FADE_IN_TRANSITION + } else { + FADE_IN_TRANSITION + slideInHorizontally( + animationSpec = tween(TransitionDurationMillis), + initialOffsetX = { fullWidth -> + -fullWidth / 2 + }, + ) + } + } +} + +internal fun pauseTransition(): AnimatedContentTransitionScope.() -> ExitTransition { + return { + if (initialState.skipTransition) { + FADE_OUT_TRANSITION + } else { + FADE_OUT_TRANSITION + slideOutHorizontally( + animationSpec = tween(TransitionDurationMillis), + targetOffsetX = { fullWidth -> + -fullWidth / 2 + }, + ) + } + } +} + +internal fun exitTransition(): AnimatedContentTransitionScope.() -> ExitTransition { + return { + if (initialState.skipTransition) { + FADE_OUT_TRANSITION + } else { + FADE_OUT_TRANSITION + slideOutHorizontally( + animationSpec = tween(TransitionDurationMillis), + targetOffsetX = { fullWidth -> + fullWidth / 2 + }, + ) + } + } +} + +/** + * We want to skip the transition for some screens and use a simple fade instead. This + */ +private val NavBackStackEntry.skipTransition: Boolean + get() = destination.pane == ATTACH_LINKED_PAYMENT_ACCOUNT diff --git a/financial-connections/src/main/java/com/stripe/android/financialconnections/ui/components/TopAppBar.kt b/financial-connections/src/main/java/com/stripe/android/financialconnections/ui/components/TopAppBar.kt index f27373839a4..88a6be1a38d 100644 --- a/financial-connections/src/main/java/com/stripe/android/financialconnections/ui/components/TopAppBar.kt +++ b/financial-connections/src/main/java/com/stripe/android/financialconnections/ui/components/TopAppBar.kt @@ -2,7 +2,11 @@ package com.stripe.android.financialconnections.ui.components import androidx.activity.OnBackPressedDispatcher import androidx.activity.compose.LocalOnBackPressedDispatcherOwner +import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.core.animateDpAsState +import androidx.compose.animation.core.tween +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.padding @@ -179,13 +183,18 @@ private fun Title(hideStripeLogo: Boolean, testmode: Boolean) = Row( verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(8.dp) ) { - if (hideStripeLogo.not()) { + AnimatedVisibility( + visible = !hideStripeLogo, + enter = fadeIn(animationSpec = tween()), + exit = fadeOut(animationSpec = tween()), + ) { Icon( modifier = Modifier.size(width = LOGO_WIDTH, height = LOGO_HEIGHT), painter = painterResource(id = R.drawable.stripe_logo), contentDescription = null // decorative element ) } + // show a test mode pill if in test mode if (testmode) { Text(