Skip to content

Instantly share code, notes, and snippets.

@rock3r
Created December 7, 2024 15:25
Show Gist options
  • Save rock3r/49c34588760e05495741c0786a2382b2 to your computer and use it in GitHub Desktop.
Save rock3r/49c34588760e05495741c0786a2382b2 to your computer and use it in GitHub Desktop.
Boxy button: a custom "raised" Compose button
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* Sebastiano Poggi wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return.
* ----------------------------------------------------------------------------
*/
package dev.sebastiano.boxybutton
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.PressInteraction
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.BasicText
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.singleWindowApplication
fun main() = singleWindowApplication {
Box(
Modifier.fillMaxSize().background(Color.White).padding(16.dp),
contentAlignment = Alignment.Center,
) {
BoxyButton() {
BasicText(
"Click meeeeee",
style =
TextStyle(
color = Color(0xFF4E0D72),
fontWeight = FontWeight.Medium,
fontSize = 16.sp,
),
)
}
}
}
@Composable
fun BoxyButton(modifier: Modifier = Modifier, content: @Composable () -> Unit) {
val interactionSource = remember { MutableInteractionSource() }
var isPressed by remember { mutableStateOf(false) }
LaunchedEffect(interactionSource) {
interactionSource.interactions.collect { interaction ->
isPressed =
when (interaction) {
is PressInteraction.Press -> true
else -> false
}
}
}
val topPadding = if (isPressed) 8.dp else 4.dp
val bottomPadding = if (isPressed) 4.dp else 8.dp
Box(
modifier
.background(Color(0xFF4E0D72), RoundedCornerShape(16.dp))
.padding(start = 4.dp, top = topPadding, end = 4.dp, bottom = bottomPadding)
.clickable(
onClick = { println("clicked") },
indication = null,
interactionSource = interactionSource,
role = Role.Button,
)
) {
Box(
Modifier.background(Color(0xFFF7FEEC), RoundedCornerShape(12.dp))
.defaultMinSize(minWidth = 72.dp, minHeight = 48.dp)
.padding(horizontal = 32.dp, vertical = 12.dp),
contentAlignment = Alignment.Center,
) {
content()
}
}
}
@rock3r
Copy link
Author

rock3r commented Dec 7, 2024

This looks like this:

Screen.Recording.2024-12-07.at.16.16.35.mov

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment