androidandroid-jetpack-composematerial3

How to define shape for Button in Jetpack compose when using Material design 3


I am using Material design 3 with Jetpack compose.

By default the Shape for Button has a corner radius of type full which is 20dp. As per the documentation. https://m3.material.io/components/buttons/overview

If I look at the shape documentation, I can see following shapes in token section enter image description here

However when I provide the Shapes object to the Theme for the app. I don't have an option to customise Full Shape.

Here is my code

Shapes(
    extraSmall = RoundedCornerShape(4.dp),
    small = RoundedCornerShape(8.dp),
    medium = RoundedCornerShape(12.dp),
    large = RoundedCornerShape(16.dp),
    extraLarge = RoundedCornerShape(8.dp)
)

What I am trying to achieve:

  1. I don't want to specify shape explicitly to the each button or create a composable for button and then reuse it everywhere.

I want to apply it once and not need to specify it explicitly as other components


Solution

  • As you mentioned, M3 FilledButton's container shape is by default ShapeKeyTokens.CornerFull, as you can see in FilledButtonTokens. This token is then converted to Shape in Shapes.fromToken function:

    internal fun Shapes.fromToken(value: ShapeKeyTokens): Shape {
        return when (value) {
            ShapeKeyTokens.CornerExtraLarge -> extraLarge
            ShapeKeyTokens.CornerExtraLargeTop -> extraLarge.top()
            ShapeKeyTokens.CornerExtraSmall -> extraSmall
            ShapeKeyTokens.CornerExtraSmallTop -> extraSmall.top()
            ShapeKeyTokens.CornerFull -> CircleShape
            ShapeKeyTokens.CornerLarge -> large
            ShapeKeyTokens.CornerLargeEnd -> large.end()
            ShapeKeyTokens.CornerLargeTop -> large.top()
            ShapeKeyTokens.CornerMedium -> medium
            ShapeKeyTokens.CornerNone -> RectangleShape
            ShapeKeyTokens.CornerSmall -> small
        }
    }
    

    As you can see, ShapeKeyTokens.CornerFull, unlike most others, isn't converted to some Shape from the theme, but simply to CircleShape. This means that it's not possible to do what you want. You will either have to pass your shape to each button or create custom button composable.