# Buttons

> Let people take an action. Five types, five sizes, and shapes that morph when pressed.

- Category: Actions
- API status: Expressive
- Compose APIs: `Button`, `FilledTonalButton`, `ElevatedButton`, `OutlinedButton`, `TextButton`, `ButtonDefaults`
- Interactive page: https://m3e.ljzapps.app/#components/button

## When to use

Use a filled button for the single most important action on a screen, a tonal button for secondary actions, an outlined button for medium emphasis and a text button for the lowest emphasis.

Expressive buttons come in five sizes. Pair the height with the matching content padding, text style and icon size from ButtonDefaults so the proportions stay correct.

Pass a ButtonShapes to animate the container between a round and a squared shape when the button is pressed.

## Playground

The interactive page has a playground with live property controls for this component and generated code.

## Examples

### Types

From highest to lowest emphasis.

```kotlin
Button(onClick = {}) { Text("Filled") }
FilledTonalButton(onClick = {}) { Text("Tonal") }
ElevatedButton(onClick = {}) { Text("Elevated") }
OutlinedButton(onClick = {}) { Text("Outlined") }
TextButton(onClick = {}) { Text("Text") }
```

### Sizes

Extra small to extra large.

```kotlin
val heights = listOf(
    "XS" to ButtonDefaults.ExtraSmallContainerHeight,
    "S" to ButtonDefaults.MinHeight,
    "M" to ButtonDefaults.MediumContainerHeight,
    "L" to ButtonDefaults.LargeContainerHeight,
    "XL" to ButtonDefaults.ExtraLargeContainerHeight,
)
heights.forEach { (label, height) ->
    Button(
        onClick = {},
        shapes = ButtonDefaults.shapesFor(height),
        modifier = Modifier.heightIn(min = height),
        contentPadding = ButtonDefaults.contentPaddingFor(height),
    ) {
        Text(label, style = ButtonDefaults.textStyleFor(height))
    }
}
```

### With icon

Use the icon helpers so size and spacing follow the button size.

```kotlin
val height = ButtonDefaults.MediumContainerHeight
Button(
    onClick = {},
    shapes = ButtonDefaults.shapesFor(height),
    modifier = Modifier.heightIn(min = height),
    contentPadding = ButtonDefaults.contentPaddingFor(height, hasStartIcon = true),
) {
    Icon(
        imageVector = Icons.Rounded.Favorite,
        contentDescription = null,
        modifier = Modifier.size(ButtonDefaults.iconSizeFor(height)),
    )
    Spacer(Modifier.width(ButtonDefaults.iconSpacingFor(height)))
    Text("Like", style = ButtonDefaults.textStyleFor(height))
}
```

### Shape morphing

The shapes parameter animates the corners on press.

```kotlin
Button(
    onClick = {},
    shapes = ButtonDefaults.shapes(),
) { Text("Round, squares on press") }

Button(
    onClick = {},
    shapes = ButtonDefaults.shapes(
        shape = ButtonDefaults.squareShape,
        pressedShape = ButtonDefaults.pressedShape,
    ),
) { Text("Square, rounds on press") }
```

## Parameters

| Name | Type | Default | Description |
|---|---|---|---|
| `onClick` | `() -> Unit` |  | Called when the button is clicked. |
| `shapes` | `ButtonShapes` | `ButtonDefaults.shapes()` | Resting and pressed shape. Use shapesFor(height) to match a size. |
| `modifier` | `Modifier` | `Modifier` | Apply a minimum height with heightIn to select a size. |
| `enabled` | `Boolean` | `true` | When false the button ignores input and uses disabled colors. |
| `colors` | `ButtonColors` | `ButtonDefaults.buttonColors()` | Container and content colors for enabled and disabled states. |
| `contentPadding` | `PaddingValues` | `contentPaddingFor(MinHeight)` | Use contentPaddingFor(height, hasStartIcon) for the matching padding. |
| `interactionSource` | `MutableInteractionSource?` | `null` | Observe or emit interactions such as press and hover. |

## Guidelines

Do:
- Use one filled button per screen section.
- Use verbs in the label, such as Save or Send.
- Keep related buttons in a button group.

Don't:
- Do not place several filled buttons next to each other.
- Do not mix sizes within one row of actions.
- Do not use a button to navigate between destinations. Use navigation components.

## Accessibility

- Buttons expose the Button role and their label to screen readers. Keep labels short and action oriented.
- Extra small buttons are visually 32 dp tall but still get a 48 dp touch target through the minimum interactive size.
- Disabled buttons are skipped by keyboard focus. Do not rely on color alone to explain why a button is disabled.

## Related components

- [Connected button group](https://m3e.ljzapps.app/docs/components/connected-button-group.md)
- [Icon button](https://m3e.ljzapps.app/docs/components/icon-button.md)
- [Split button](https://m3e.ljzapps.app/docs/components/split-button.md)
- [Floating action button](https://m3e.ljzapps.app/docs/components/fab.md)
