Skip to content

Commit

Permalink
Make shared element APIs a no-op when the locals are not set
Browse files Browse the repository at this point in the history
This makes previews easier to work with as they don't need to know about
those locals nor set them up in any way.
  • Loading branch information
StylianosGakis committed Jan 21, 2025
1 parent 97959b6 commit 5279da0
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import androidx.compose.animation.fadeOut
import androidx.compose.runtime.Composable
import androidx.compose.runtime.ProvidableCompositionLocal
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.staticCompositionLocalOf
import androidx.compose.ui.Alignment.Companion.Center
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Rect
Expand All @@ -32,33 +33,40 @@ import androidx.compose.ui.unit.LayoutDirection
* A local which contains the SharedTransitionScope wrapping the entire app. This is always taking up the entire
* screen's size and must be provided by the app's main activity
*/
val LocalSharedTransitionScope: ProvidableCompositionLocal<SharedTransitionScope> = compositionLocalOf {
error("The app must provide a SharedTransitionScope to the entire compose hierarchy")
val LocalSharedTransitionScope: ProvidableCompositionLocal<SharedTransitionScope?> = staticCompositionLocalOf {
null
}

@Composable
fun rememberGlobalSharedContentState(key: Any): SharedContentState =
LocalSharedTransitionScope.current.rememberSharedContentState(key)
fun rememberGlobalSharedContentState(key: Any): SharedContentState? =
LocalSharedTransitionScope.current?.rememberSharedContentState(key)

/**
* Is a no-op if [SharedTransitionScope], [AnimatedVisibilityScope] or [SharedContentState] are null
*/
fun Modifier.globalSharedElement(
sharedTransitionScope: SharedTransitionScope,
animatedVisibilityScope: AnimatedVisibilityScope,
state: SharedContentState,
sharedTransitionScope: SharedTransitionScope?,
animatedVisibilityScope: AnimatedVisibilityScope?,
state: SharedContentState?,
boundsTransform: BoundsTransform = DefaultBoundsTransform,
placeHolderSize: PlaceHolderSize = contentSize,
renderInOverlayDuringTransition: Boolean = true,
zIndexInOverlay: Float = 0f,
clipInOverlayDuringTransition: OverlayClip = ParentClip,
): Modifier = with(sharedTransitionScope) {
this@globalSharedElement.sharedElement(
state = state,
animatedVisibilityScope = animatedVisibilityScope,
boundsTransform = boundsTransform,
placeHolderSize = placeHolderSize,
renderInOverlayDuringTransition = renderInOverlayDuringTransition,
zIndexInOverlay = zIndexInOverlay,
clipInOverlayDuringTransition = clipInOverlayDuringTransition,
)
): Modifier = if (sharedTransitionScope == null || animatedVisibilityScope == null || state == null) {
this
} else {
with(sharedTransitionScope) {
this@globalSharedElement.sharedElement(
state = state,
animatedVisibilityScope = animatedVisibilityScope,
boundsTransform = boundsTransform,
placeHolderSize = placeHolderSize,
renderInOverlayDuringTransition = renderInOverlayDuringTransition,
zIndexInOverlay = zIndexInOverlay,
clipInOverlayDuringTransition = clipInOverlayDuringTransition,
)
}
}

fun Modifier.globalSharedBounds(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ import androidx.navigation.NavGraphBuilder
* A local which contains the AnimatedVisibilityScope tied to the current navigation's destination.
* See [NavGraphBuilder.navdestination] for how it's provided.
*/
val LocalNavAnimatedVisibilityScope: ProvidableCompositionLocal<AnimatedVisibilityScope> = compositionLocalOf {
error("Must be under a compose `navdestination`")
val LocalNavAnimatedVisibilityScope: ProvidableCompositionLocal<AnimatedVisibilityScope?> = compositionLocalOf {
null
}

0 comments on commit 5279da0

Please sign in to comment.