Search code examples
material-designandroid-jetpack-composematerial-components-androidandroid-jetpack-compose-material3

How to handle Shape when creating a theme for Material Design 3 for compose


I currently have an app written in jetpack compose which uses Material-Theming-Support from androidx.compose.material:material.

from / import androidx.compose.material.MaterialTheme

@Composable
fun MaterialTheme(
    colors: Colors = MaterialTheme.colors,
    typography: Typography = MaterialTheme.typography,
    shapes: Shapes = MaterialTheme.shapes,
    content: @Composable () -> Unit
)

I now plan to migrate to Material3: androidx.compose.material3:material3 (still in alpha, i know).

However, the theme-composable now doesn't allow any shapes anymore

from / import androidx.compose.material3.MaterialTheme

@Composable
fun MaterialTheme(
    colorScheme: ColorScheme = MaterialTheme.colorScheme,
    typography: Typography = MaterialTheme.typography,
    content: @Composable () -> Unit
)

What should i do now with my old shape definitions? The material-website only talks how to do that in xml & the old view-system.


Solution

  • Update: Now for shapes you can use inbuilt Material api just add latest compose-bom version and material3 library in toml or build.gradle.kts

    modifier = Modifier.clip(shape = MaterialTheme.shapes.medium),
    

    or let say for rounded shape you can use

    modifier = Modifier.clip(shape = CircleShape),
    

    or

    modifier = Modifier.clip(shape = RoundedCornerShape(percent = 50)),
    

    Old answer:

    Material Design 3 / Material You still don't have shapes. So to use shapes create composition local,

    In directory ui/theme create Shape.kt Kotlin file in that file paste following code

    Shape.kt

    data class Shape(
        val default: RoundedCornerShape = RoundedCornerShape(0.dp),
        val small: RoundedCornerShape = RoundedCornerShape(4.dp),
        val medium: RoundedCornerShape = RoundedCornerShape(8.dp),
        val large: RoundedCornerShape = RoundedCornerShape(16.dp)
    )
    
    val LocalShape = compositionLocalOf { Shape() }
    
    val MaterialTheme.shapeScheme: Shape
        @Composable
        @ReadOnlyComposable
        get() = LocalShape.current
    

    Now, to use shape in compose

    shape = MaterialTheme.shapeScheme.large
    

    eg. In card compose

    Card(
            modifier = Modifier
                .fillMaxWidth()
                .wrapContentHeight()
                .padding(all = 16.dp),
            shape = MaterialTheme.shapeScheme.large,
            backgroundColor = MaterialTheme.colorScheme.surface,
            border = BorderStroke(width = 1.dp, color = MaterialTheme.colorScheme.inverseOnSurface),
            elevation = 1.dp
        ) {
    ...
    }
    

    Edit : Check this