I have a question about buttons. I have this code:...
# compose
k
I have a question about buttons. I have this code:
Copy code
import androidx.compose.material3.Button

@Composable
@Preview
private fun Test() {
    Box(Modifier.background(Color.Yellow)) {
        Button(
            onClick = { },
            enabled = true,
            modifier = Modifier.background(Color.Red),
        ) {
            Text("Hello")
        }
    }
}
If you look at the image, there's a large amount of red vertically around the button. Why is this? Is there a way to have it actually wrap the button? If I update the height it goes away, but id rather shrink the padding instead.
m
Is it the
LocalMinimumInteractiveComponentSize
? If so, then you can override that.
l
Looks like it, yes. This extra space is reserved to ensure a minimum touch target for accessibility reasons
k
Ah ok, yea that's likely it. Do you know if it's possible to get the height of the background? Like the height of the rounded rectangle, rather than the total height including the interactive size
l
What's your use case for this?
k
I am trying to create a shadow, like this. However when I get the height it's the height of the entire button rather than the box
l
To build something like that it’s probably going to be easier to build your own button, anyway
1
s
Can you achieve this with a
graphicsLayer
modifier on your box layout? https://developer.android.com/develop/ui/compose/graphics/draw/modifiers#graphicsLayer
l
This would still include the outer 'padding' reserved for touch target
s
Even if the bounds of the graphicslayer are too large, couldn't you just create the shadow from the visible layer of the component?
k
Got it working
Copy code
private fun Modifier.addButtonShadow(
    cornerRadiusDp: Dp,
    shadowColor: Color,
    shadowHeight: Dp,
) =
    this.drawWithContent {
        val cornerRadius = CornerRadius(cornerRadiusDp.toPx(), cornerRadiusDp.toPx())
        val roundedRectanglePath = Path().apply {
            addRoundRect(
                RoundRect(
                    left = -1f,
                    top = -shadowHeight.toPx(),
                    right = size.width + 1,
                    bottom = size.height - shadowHeight.toPx(),
                    topLeftCornerRadius = cornerRadius,
                    topRightCornerRadius = cornerRadius,
                    bottomLeftCornerRadius = cornerRadius,
                    bottomRightCornerRadius = cornerRadius
                )
            )
        }

        drawContent()
        clipPath(roundedRectanglePath, clipOp = ClipOp.Difference) {
            drawRoundRect(
                shadowColor,
                topLeft = Offset(0f, 0f),
                size = size,
                cornerRadius = cornerRadius
            )
        }
    }
This is without the extra padding
c
i second what Louis said. likely a ton easier doing it yourself. not sure if you get any benefit from a material 3 button here that you smush into your design.