I'm trying to recreate this button style, but runn...
# compose
m
I'm trying to recreate this button style, but running into a few issues, code in thread.
Copy code
@Composable
fun MewsicButton(
    onClick: () -> Unit,
    color: Color = ButtonDefaults.buttonColors().containerColor,
    contentColor: Color = contentColorFor(color),
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    content: @Composable (RowScope.() -> Unit)
) {
    // Behavior:
    // - 3d-style button
    // - slightly presses and darkens on hover
    // - fully presses and lightens on click
    val source = remember { MutableInteractionSource() }
    val isPressed by source.collectIsPressedAsState()
    val isHover by source.collectIsHoveredAsState()


    val isFull = !enabled || (!isHover && !isPressed)

    // How far up the button moves
    val heightOffset by animateDpAsState(
        if (isFull) 10.dp else if (isPressed) 2.dp else 8.dp,
        animationSpec = spring(stiffness = Spring.StiffnessHigh, visibilityThreshold = Dp.VisibilityThreshold)
    )
    // TODO: Animate color in a similar way

    val shape = RoundedCornerShape(16.dp)
    Button(
        onClick = onClick,
        modifier = modifier
            // FIXME: Downward fill for simulating button height; currently just fills the rect instead
            .drawBehind {
                drawRoundRect(shadowColorFor(color))
            }
            .offset(y = -heightOffset)  // Button content height
            .border(4.dp, borderColorFor(color), shape) // Border



            // FIXME: Non-functional attempt to disable default hover/click events
            .clickable(
                interactionSource = source,
                indication = null
            ) {
                onClick()
            }
        ,
        enabled = enabled,
        interactionSource = source,
        shape = shape,
        colors = ButtonDefaults.buttonColors(containerColor = color, contentColor = contentColor),
        content = content
    )
}
The problems: • The fill method I tried to use (drawBehind) fills the entire original rect rather than following the same shape • The fill at the bottom or the offset upward don't contribute to the element height, making it overflow into other content • The default button hover/click events are still handled (i.e. color change and the ripple on click)
l
It would be easier to handle / fix these issues if you just build your own button instead of trying to coerce the very different Material button to match this - there probably isn’t much from the Material button you need to reuse here
3