Custom color elevation effect in Compose
At Medium Engineering we’re in the process of moving to Compose. Today I found some funny stuff I wanted to share quickly.
I was having an elevated surface where there was no illumination effect on it so I had to look at why and how I could customize it.
no illumination in the 6 dp elevated surface
I was wondering why our colors weren’t illuminated in dark theme with Compose like described in material documentation with the following code:
Surface(
Modifier.height(40.dp), color = MediumTheme.colors.backgroundNeutralPrimary,
shape = CircleShape,
elevation = 6._dp
_) { _// content
_}
Like every time a Compose behavior surprised me, I jumped into the composable code so here I follow my color into the Surface code with some cmd + click to see what I missed.
I ended up to:
@Composableprivate fun Surface( modifier: Modifier, shape: Shape, color: Color, contentColor: Color, border: BorderStroke?, elevation: Dp, clickAndSemanticsModifier: Modifier, content: @Composable () -> Unit) {
val elevationOverlay = LocalElevationOverlay.current
val absoluteElevation = LocalAbsoluteElevation.current + elevation val backgroundColor = if (color == MaterialTheme.colors.surface && elevationOverlay != null) { elevationOverlay.apply(color, absoluteElevation) } else { color } CompositionLocalProvider(
LocalContentColor provides contentColor,
LocalAbsoluteElevation provides absoluteElevation
) { Box( modifier
.shadow(elevation, shape, clip = false)
.then(if (border != null) Modifier.border(border, shape) else Modifier)
.background( color = backgroundColor, shape = shape )
.clip(shape)
.then(clickAndSemanticsModifier), propagateMinConstraints = true
) { content()
} }}
In this code we can find:
val backgroundColor = if (color == MaterialTheme.colors.surface && elevationOverlay != null) { elevationOverlay.apply(color, absoluteElevation)} else { color
}
This basically means that if the provided color to the surface is not the same as the default surface color you defined in the Material theme the elevation overlay color won’t be applied. I found this is lacking flexibility regarding how colors are applied but I do understand the goal is to enforce a strong link to the material theme (so it won’t apply well to a custom theme).