Compose Unstyled 2.0 is out! Check the official announcement blog ->

Button components for primary actions, secondary actions, outlines, destructive actions, and icon-only controls.

Use buttons for actions that submit, confirm, cancel, create, delete, or move a user through a workflow.

View on GitHub
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")

Examples

Size

View on GitHub
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

View on GitHub
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

View on GitHub
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

View on GitHub
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

View on GitHub
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

View on GitHub
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

View on GitHub
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.