Use buttons for actions that submit, confirm, cancel, create, delete, or move a user through a workflow.
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.composables.icons.lucide.Lucide
import com.composables.icons.lucide.Plus
import com.composables.ui.components.Button
import com.composables.ui.components.Icon
import com.composables.ui.components.IconButton
import com.composables.ui.components.Text
@Composable
fun ButtonExample() {
Row(
horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Button(onClick = { /* TODO */ }) {
Text("Button")
}
IconButton(onClick = { /* TODO */ }) {
Icon(
imageVector = Lucide.Plus,
contentDescription = "Add",
modifier = Modifier.size(18.dp),
)
}
}
}Installation
implementation("com.composables:ui:0.1.0")Add the required dependencies
implementation("com.composables:composeunstyled:2.7.0")
Copy and paste the following sources into your project
components/Button.kt
package com.composables.ui.components
import androidx.compose.foundation.Indication
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.collectIsHoveredAsState
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.graphics.isSpecified
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.composables.ui.theme.InteractionMode
import com.composables.ui.theme.LocalInteractionMode
import com.composables.ui.theme.alphas
import com.composables.ui.theme.borderColor
import com.composables.ui.theme.buttonShape
import com.composables.ui.theme.colors
import com.composables.ui.theme.defaultIndication
import com.composables.ui.theme.destructiveColor
import com.composables.ui.theme.disabledAlpha
import com.composables.ui.theme.indications
import com.composables.ui.theme.inverseIndication
import com.composables.ui.theme.onDestructiveColor
import com.composables.ui.theme.onPanelColor
import com.composables.ui.theme.onPrimaryColor
import com.composables.ui.theme.onSecondaryColor
import com.composables.ui.theme.panelColor
import com.composables.ui.theme.primaryColor
import com.composables.ui.theme.ringColor
import com.composables.ui.theme.secondaryColor
import com.composables.ui.theme.shapes
import com.composables.ui.theme.smallShape
import com.composeunstyled.LocalContentColor
import com.composeunstyled.LocalTextStyle
import com.composeunstyled.ProvideContentColor
import com.composeunstyled.ProvideTextStyle
import com.composeunstyled.UnstyledButton
import com.composeunstyled.buildModifier
import com.composeunstyled.theme.Theme
import kotlin.jvm.JvmInline
/**
* Visual style variants for Button and IconButton.
*/
@JvmInline
value class ButtonStyle internal constructor(@Suppress("unused") private val value: Int) {
companion object {
/**
* Use for the primary action on a screen.
*/
val Primary = ButtonStyle(0)
/**
* Use for secondary actions.
*/
val Secondary = ButtonStyle(1)
/**
* Use for lower-emphasis actions with an outline.
*/
val Outlined = ButtonStyle(2)
/**
* Use for destructive actions.
*/
val Destructive = ButtonStyle(3)
/**
* Use for low-emphasis actions without a container.
*/
val Ghost = ButtonStyle(4)
/**
* Style for clickable text links.
*/
val Link = ButtonStyle(5)
/**
* The default button style.
*/
val Default = Secondary
}
}
/**
* Size variants for Button and IconButton.
*/
@JvmInline
value class ButtonSize internal constructor(@Suppress("unused") private val value: Int) {
companion object {
/**
* Small button size.
*/
val Small = ButtonSize(0)
/**
* Regular button size.
*/
val Regular = ButtonSize(1)
/**
* Large button size.
*/
val Large = ButtonSize(2)
/**
* The default button size.
*/
val Default = Regular
}
}
/**
* A component that can be clicked.
* @param onClick Called when the button is activated.
* @param modifier Modifier applied to the button.
* @param enabled Whether the button can be interacted with.
* @param style Visual style used by the button.
* @param shape Shape used for the button container, border, and focus ring.
* @param buttonSize Size used for button height, padding, and icon-only button dimensions.
* @param contentPadding Padding applied inside the button bounds, around the button content.
* @param borderWidth Width of the button border when the selected style draws one.
* @param interactionSource Interaction source used for focus, press, hover, and indication state.
* @param content The content to display within the button.
*/
@Composable
fun Button(
onClick: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
style: ButtonStyle = ButtonStyle.Default,
shape: Shape = buttonShapeFor(style),
buttonSize: ButtonSize = ButtonSize.Default,
contentPadding: PaddingValues = buttonPaddingFor(buttonSize, style),
borderWidth: Dp = 1.dp,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
indication: Indication? = buttonIndicationFor(style),
contentColor: Color = buttonContentColorFor(style),
content: @Composable RowScope.() -> Unit,
) {
val hovered by interactionSource.collectIsHoveredAsState()
val backgroundColor = buttonBackgroundColorFor(style)
BaseButton(
onClick = onClick,
modifier = modifier.size(buttonSize, style),
enabled = enabled,
style = style,
backgroundColor = backgroundColor,
contentColor = contentColor,
shape = shape,
contentPadding = contentPadding,
borderColor = buttonBorderColorFor(style),
borderWidth = borderWidth,
interactionSource = interactionSource,
indication = indication,
content = {
Row(
horizontalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterHorizontally),
verticalAlignment = Alignment.CenterVertically,
) {
ProvideTextStyle(LocalTextStyle.current.merge(buttonLabelTextStyleFor(style, hovered))) {
content()
}
}
},
)
}
/**
* Variant of [Button] meant for square targets, such as icons.
*
* @param onClick Called when the button is activated.
* @param modifier Modifier applied to the button.
* @param enabled Whether the button can be interacted with.
* @param style Visual style used by the button.
* @param shape Shape used for the button container, border, and focus ring.
* @param buttonSize Size used for button height, padding, and icon-only button dimensions.
* @param borderWidth Width of the button border when the selected style draws one.
* @param interactionSource Interaction source used for focus, press, hover, and indication state.
* @param content Composable content displayed inside the button.
*/
@Composable
fun IconButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
style: ButtonStyle = ButtonStyle.Default,
shape: Shape = Theme[shapes][buttonShape],
buttonSize: ButtonSize = ButtonSize.Default,
borderWidth: Dp = 1.dp,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
indication: Indication? = buttonIndicationFor(style),
contentColor: Color = buttonContentColorFor(style),
content: @Composable () -> Unit,
) {
val backgroundColor = buttonBackgroundColorFor(style)
BaseButton(
onClick = onClick,
modifier = modifier.size(buttonHeightFor(buttonSize)),
enabled = enabled,
style = style,
backgroundColor = backgroundColor,
contentColor = contentColor,
shape = shape,
borderColor = buttonBorderColorFor(style),
borderWidth = borderWidth,
interactionSource = interactionSource,
indication = indication,
content = content,
)
}
@Composable
private fun buttonPaddingFor(buttonSize: ButtonSize, style: ButtonStyle): PaddingValues {
if (style == ButtonStyle.Link) {
return NoPadding
}
return PaddingValues(horizontal = buttonHorizontalPaddingFor(buttonSize))
}
@Composable
private fun buttonShapeFor(style: ButtonStyle): Shape {
return if (style == ButtonStyle.Link) Theme[shapes][smallShape] else Theme[shapes][buttonShape]
}
@Composable
private fun Modifier.size(buttonSize: ButtonSize, style: ButtonStyle): Modifier {
return if (style == ButtonStyle.Link) this else heightIn(min = buttonHeightFor(buttonSize))
}
@Composable
private fun buttonHeightFor(buttonSize: ButtonSize): Dp {
val baseHeight = if (LocalInteractionMode.current == InteractionMode.Touch) 48.dp else 36.dp
return when (buttonSize) {
ButtonSize.Small -> baseHeight - 4.dp
ButtonSize.Large -> baseHeight + 4.dp
else -> baseHeight
}
}
@Composable
private fun buttonHorizontalPaddingFor(buttonSize: ButtonSize): Dp {
val basePadding = if (LocalInteractionMode.current == InteractionMode.Touch) 20.dp else 16.dp
return when (buttonSize) {
ButtonSize.Small -> basePadding - 4.dp
ButtonSize.Large -> basePadding + 4.dp
else -> basePadding
}
}
private val NoPadding = PaddingValues(0.dp)
private val ButtonLabelTextStyle = TextStyle(
fontWeight = FontWeight.Medium,
)
private fun buttonLabelTextStyleFor(style: ButtonStyle, hovered: Boolean): TextStyle {
return if (style == ButtonStyle.Link && hovered) {
ButtonLabelTextStyle.copy(textDecoration = TextDecoration.Underline)
} else {
ButtonLabelTextStyle
}
}
@Composable
private fun buttonBackgroundColorFor(style: ButtonStyle): Color {
return when (style) {
ButtonStyle.Primary -> Theme[colors][primaryColor]
ButtonStyle.Secondary -> Theme[colors][secondaryColor]
ButtonStyle.Outlined -> Theme[colors][panelColor]
ButtonStyle.Destructive -> Theme[colors][destructiveColor]
else -> Color.Transparent
}
}
@Composable
private fun buttonContentColorFor(style: ButtonStyle): Color {
return when (style) {
ButtonStyle.Primary -> Theme[colors][onPrimaryColor]
ButtonStyle.Secondary -> Theme[colors][onSecondaryColor]
ButtonStyle.Destructive -> Theme[colors][onDestructiveColor]
ButtonStyle.Outlined -> Theme[colors][onPanelColor]
else -> LocalContentColor.current
}
}
@Composable
private fun buttonBorderColorFor(style: ButtonStyle): Color {
return when (style) {
ButtonStyle.Outlined -> Theme[colors][borderColor]
else -> Color.Unspecified
}
}
@Composable
private fun BaseButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
style: ButtonStyle,
backgroundColor: Color,
contentColor: Color,
shape: Shape,
contentPadding: PaddingValues = NoPadding,
borderColor: Color,
borderWidth: Dp,
interactionSource: MutableInteractionSource,
indication: Indication?,
content: @Composable () -> Unit,
) {
val alpha = if (enabled) 1f else Theme[alphas][disabledAlpha]
UnstyledButton(
onClick = onClick,
enabled = enabled,
contentPadding = contentPadding,
modifier = modifier
.focusRing(
interactionSource = interactionSource,
color = Theme[colors][ringColor],
shape = shape,
)
.bouncyPress(
interactionSource = interactionSource,
enabled = enabled && style != ButtonStyle.Link,
)
.graphicsLayer { this.alpha = alpha }
.then(buildModifier {
if (style != ButtonStyle.Link) {
add(Modifier.clip(shape))
add(Modifier.background(backgroundColor, shape))
if (borderColor.isSpecified && borderColor != Color.Transparent && borderWidth > 0.dp) {
add(Modifier.border(borderWidth, borderColor, shape))
}
}
}),
interactionSource = interactionSource,
indication = indication,
) {
ProvideContentColor(contentColor) {
content()
}
}
}
@Composable
private fun buttonIndicationFor(style: ButtonStyle) = when (style) {
ButtonStyle.Primary, ButtonStyle.Destructive -> Theme[indications][inverseIndication]
ButtonStyle.Link -> null
else -> Theme[indications][defaultIndication]
}components/Utils.kt
package com.composables.ui.components
import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.spring
import androidx.compose.animation.core.tween
import androidx.compose.foundation.interaction.InteractionSource
import androidx.compose.foundation.interaction.collectIsFocusedAsState
import androidx.compose.foundation.interaction.collectIsPressedAsState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.composables.ui.theme.colors
import com.composables.ui.theme.ringColor
import com.composeunstyled.FocusRingVisibility
import com.composeunstyled.collectIsFocusVisibleAsState
import com.composeunstyled.outline
import com.composeunstyled.theme.Theme
@Composable
fun Modifier.focusRing(
interactionSource: InteractionSource,
width: Dp = 2.dp,
color: Color = Theme[colors][ringColor],
shape: Shape = RectangleShape,
offset: Dp = 0.dp,
visibility: FocusRingVisibility = FocusRingVisibility.FocusVisible,
): Modifier {
val showFocusRing by if (visibility == FocusRingVisibility.FocusVisible) {
interactionSource.collectIsFocusVisibleAsState()
} else {
interactionSource.collectIsFocusedAsState()
}
val animatedWidth by animateDpAsState(
targetValue = if (showFocusRing) width else 0.dp,
animationSpec = tween(durationMillis = 120),
label = "FocusRingWidth",
)
return this then Modifier.outline(
width = animatedWidth,
color = color,
shape = shape,
offset = offset,
)
}
@Composable
fun Modifier.bouncyPress(
interactionSource: InteractionSource,
enabled: Boolean = true,
pressedScale: Float = 0.98f,
): Modifier {
val pressed by interactionSource.collectIsPressedAsState()
val scale by animateFloatAsState(
targetValue = if (enabled && pressed) pressedScale else 1f,
animationSpec = spring(
dampingRatio = Spring.DampingRatioMediumBouncy,
stiffness = Spring.StiffnessMediumLow,
),
label = "BouncyPressScale",
)
return this then Modifier.graphicsLayer {
scaleX = scale
scaleY = scale
}
}Examples
Size
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.composables.icons.lucide.Lucide
import com.composables.icons.lucide.Plus
import com.composables.ui.components.Button
import com.composables.ui.components.ButtonSize
import com.composables.ui.components.ButtonStyle
import com.composables.ui.components.Icon
import com.composables.ui.components.IconButton
import com.composables.ui.components.Text
@Composable
fun ButtonSizesExample() {
Column(
verticalArrangement = Arrangement.spacedBy(12.dp),
horizontalAlignment = Alignment.Start,
) {
Row(
horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Button(
onClick = { /* TODO */ },
style = ButtonStyle.Secondary,
buttonSize = ButtonSize.Small,
) {
Text("Button")
}
IconButton(
onClick = { /* TODO */ },
style = ButtonStyle.Secondary,
buttonSize = ButtonSize.Small,
) {
Icon(
imageVector = Lucide.Plus,
contentDescription = "Add",
modifier = Modifier.size(18.dp),
)
}
}
Row(
horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Button(
onClick = { /* TODO */ },
style = ButtonStyle.Secondary,
buttonSize = ButtonSize.Regular,
) {
Text("Button")
}
IconButton(
onClick = { /* TODO */ },
style = ButtonStyle.Secondary,
buttonSize = ButtonSize.Regular,
) {
Icon(
imageVector = Lucide.Plus,
contentDescription = "Add",
modifier = Modifier.size(18.dp),
)
}
}
Row(
horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Button(
onClick = { /* TODO */ },
style = ButtonStyle.Secondary,
buttonSize = ButtonSize.Large,
) {
Text("Button")
}
IconButton(
onClick = { /* TODO */ },
style = ButtonStyle.Secondary,
buttonSize = ButtonSize.Large,
) {
Icon(
imageVector = Lucide.Plus,
contentDescription = "Add",
modifier = Modifier.size(18.dp),
)
}
}
}
}Primary
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.composables.icons.lucide.Lucide
import com.composables.icons.lucide.Plus
import com.composables.ui.components.Button
import com.composables.ui.components.ButtonStyle
import com.composables.ui.components.Icon
import com.composables.ui.components.IconButton
import com.composables.ui.components.Text
@Composable
fun PrimaryButtonExample() {
Row(
horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Button(
onClick = { /* TODO */ },
style = ButtonStyle.Primary,
) {
Text("Button")
}
IconButton(
onClick = { /* TODO */ },
style = ButtonStyle.Primary,
) {
Icon(
imageVector = Lucide.Plus,
contentDescription = "Add",
modifier = Modifier.size(18.dp),
)
}
}
}Secondary
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.composables.icons.lucide.Lucide
import com.composables.icons.lucide.Plus
import com.composables.ui.components.Button
import com.composables.ui.components.ButtonStyle
import com.composables.ui.components.Icon
import com.composables.ui.components.IconButton
import com.composables.ui.components.Text
@Composable
fun SecondaryButtonExample() {
Row(
horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Button(
onClick = { /* TODO */ },
style = ButtonStyle.Secondary,
) {
Text("Button")
}
IconButton(
onClick = { /* TODO */ },
style = ButtonStyle.Secondary,
) {
Icon(
imageVector = Lucide.Plus,
contentDescription = "Add",
modifier = Modifier.size(18.dp),
)
}
}
}Outlined
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.composables.icons.lucide.Lucide
import com.composables.icons.lucide.Plus
import com.composables.ui.components.Button
import com.composables.ui.components.ButtonStyle
import com.composables.ui.components.Icon
import com.composables.ui.components.IconButton
import com.composables.ui.components.Text
@Composable
fun OutlinedButtonExample() {
Row(
horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Button(
onClick = { /* TODO */ },
style = ButtonStyle.Outlined,
) {
Text("Button")
}
IconButton(
onClick = { /* TODO */ },
style = ButtonStyle.Outlined,
) {
Icon(
imageVector = Lucide.Plus,
contentDescription = "Add",
modifier = Modifier.size(18.dp),
)
}
}
}Ghost
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.composables.icons.lucide.Lucide
import com.composables.icons.lucide.Plus
import com.composables.ui.components.Button
import com.composables.ui.components.ButtonStyle
import com.composables.ui.components.Icon
import com.composables.ui.components.IconButton
import com.composables.ui.components.Text
@Composable
fun GhostButtonExample() {
Row(
horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Button(
onClick = { /* TODO */ },
style = ButtonStyle.Ghost,
) {
Text("Button")
}
IconButton(
onClick = { /* TODO */ },
style = ButtonStyle.Ghost,
) {
Icon(
imageVector = Lucide.Plus,
contentDescription = "Add",
modifier = Modifier.size(18.dp),
)
}
}
}Destructive
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.composables.icons.lucide.Lucide
import com.composables.icons.lucide.Plus
import com.composables.ui.components.Button
import com.composables.ui.components.ButtonStyle
import com.composables.ui.components.Icon
import com.composables.ui.components.IconButton
import com.composables.ui.components.Text
@Composable
fun DestructiveButtonExample() {
Row(
horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Button(
onClick = { /* TODO */ },
style = ButtonStyle.Destructive,
) {
Text("Button")
}
IconButton(
onClick = { /* TODO */ },
style = ButtonStyle.Destructive,
) {
Icon(
imageVector = Lucide.Plus,
contentDescription = "Add",
modifier = Modifier.size(18.dp),
)
}
}
}Disabled
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.composables.icons.lucide.Lucide
import com.composables.icons.lucide.Plus
import com.composables.ui.components.Button
import com.composables.ui.components.Icon
import com.composables.ui.components.IconButton
import com.composables.ui.components.Text
@Composable
fun DisabledButtonExample() {
Row(
horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Button(onClick = { /* TODO */ }, enabled = false) {
Text("Button")
}
IconButton(onClick = { /* TODO */ }, enabled = false) {
Icon(
imageVector = Lucide.Plus,
contentDescription = "Add",
modifier = Modifier.size(18.dp),
)
}
}
}API Reference
Button
A component that can be clicked.
@Composable
fun Button(
onClick: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
style: ButtonStyle = ButtonStyle.Default,
shape: Shape = buttonShapeFor(style),
buttonSize: ButtonSize = ButtonSize.Default,
contentPadding: PaddingValues = buttonPaddingFor(buttonSize, style),
borderWidth: Dp = 1.dp,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
indication: Indication? = buttonIndicationFor(style),
contentColor: Color = buttonContentColorFor(style),
content: @Composable RowScope.() -> Unit,
)
| Parameter | Type | Description |
|---|---|---|
onClick |
() -> Unit |
Called when the button is activated. |
modifier |
Modifier |
Modifier applied to the button. |
enabled |
Boolean |
Whether the button can be interacted with. |
style |
ButtonStyle |
Visual style used by the button. |
shape |
Shape |
Shape used for the button container, border, and focus ring. |
buttonSize |
ButtonSize |
Size used for button height, padding, and icon-only button dimensions. |
contentPadding |
PaddingValues |
Padding applied inside the button bounds, around the button content. |
borderWidth |
Dp |
Width of the button border when the selected style draws one. |
interactionSource |
MutableInteractionSource |
Interaction source used for focus, press, hover, and indication state. |
indication |
Indication? |
|
contentColor |
Color |
|
content |
@Composable RowScope.() -> Unit |
The content to display within the button. |
IconButton
Variant of Button meant for square targets, such as icons.
@Composable
fun IconButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
style: ButtonStyle = ButtonStyle.Default,
shape: Shape = Theme[shapes][buttonShape],
buttonSize: ButtonSize = ButtonSize.Default,
borderWidth: Dp = 1.dp,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
indication: Indication? = buttonIndicationFor(style),
contentColor: Color = buttonContentColorFor(style),
content: @Composable () -> Unit,
)
| Parameter | Type | Description |
|---|---|---|
onClick |
() -> Unit |
Called when the button is activated. |
modifier |
Modifier |
Modifier applied to the button. |
enabled |
Boolean |
Whether the button can be interacted with. |
style |
ButtonStyle |
Visual style used by the button. |
shape |
Shape |
Shape used for the button container, border, and focus ring. |
buttonSize |
ButtonSize |
Size used for button height, padding, and icon-only button dimensions. |
borderWidth |
Dp |
Width of the button border when the selected style draws one. |
interactionSource |
MutableInteractionSource |
Interaction source used for focus, press, hover, and indication state. |
indication |
Indication? |
|
contentColor |
Color |
|
content |
@Composable () -> Unit |
Composable content displayed inside the button. |
ButtonStyle
Visual style variants for Button and IconButton.
@JvmInline
value class ButtonStyle internal constructor(@Suppress("unused") private val value: Int)
| Value | Description |
|---|---|
Default |
The default button style. |
Primary |
Use for the primary action on a screen. |
Secondary |
Use for secondary actions. |
Outlined |
Use for lower-emphasis actions with an outline. |
Destructive |
Use for destructive actions. |
Ghost |
Use for low-emphasis actions without a container. |
ButtonSize
Size variants for Button and IconButton.
@JvmInline
value class ButtonSize internal constructor(@Suppress("unused") private val value: Int)
| Value | Description |
|---|---|
Small |
Small button size. |
Regular |
Regular button size. |
Large |
Large button size. |
Default |
The default button size. |