Skip to content

Commit

Permalink
Improve pane transitions in bank auth flow
Browse files Browse the repository at this point in the history
  • Loading branch information
tillh-stripe committed Jun 25, 2024
1 parent 12f37a0 commit ae684c9
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
@@ -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<NavBackStackEntry>.() -> EnterTransition {
return {
if (initialState.skipTransition) {
FADE_IN_TRANSITION
} else {
FADE_IN_TRANSITION + slideInHorizontally(
animationSpec = tween(TransitionDurationMillis),
initialOffsetX = { fullWidth ->
fullWidth / 2
},
)
}
}
}

internal fun resumeTransition(): AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition {
return {
if (initialState.skipTransition) {
FADE_IN_TRANSITION
} else {
FADE_IN_TRANSITION + slideInHorizontally(
animationSpec = tween(TransitionDurationMillis),
initialOffsetX = { fullWidth ->
-fullWidth / 2
},
)
}
}
}

internal fun pauseTransition(): AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition {
return {
if (initialState.skipTransition) {
FADE_OUT_TRANSITION
} else {
FADE_OUT_TRANSITION + slideOutHorizontally(
animationSpec = tween(TransitionDurationMillis),
targetOffsetX = { fullWidth ->
-fullWidth / 2
},
)
}
}
}

internal fun exitTransition(): AnimatedContentTransitionScope<NavBackStackEntry>.() -> 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
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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(
Expand Down

0 comments on commit ae684c9

Please sign in to comment.