# Button group

> Arranges related buttons and moves the ones that do not fit into an overflow menu.

- Category: Actions
- API status: Expressive
- Compose APIs: `ButtonGroup`, `ButtonGroupDefaults.OverflowIndicator`, `clickableItem`, `toggleableItem`, `customItem`
- Interactive page: https://m3e.ljzapps.app/#components/button-group

## When to use

ButtonGroup lays out clickable and toggleable items in a row. Items grow slightly when pressed and push their neighbors aside. When the available width is too small, the remaining items move into an overflow menu.

Use items through the group scope instead of placing buttons directly. That lets the group measure every item, decide what fits and build the overflow menu from the same data.

## Playground

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

## Examples

### Overflow

Narrow the window or use the playground to see items move into the menu.

```kotlin
var starred by rememberSaveable { mutableStateOf(false) }

ButtonGroup(
    modifier = Modifier.width(360.dp),
    overflowIndicator = { menuState -> ButtonGroupDefaults.OverflowIndicator(menuState) },
) {
    clickableItem(
        onClick = {},
        label = "Edit",
        icon = { Icon(Icons.Rounded.Edit, contentDescription = null) },
    )
    toggleableItem(
        checked = starred,
        label = "Star",
        onCheckedChange = { starred = it },
        icon = { Icon(Icons.Rounded.Star, contentDescription = null) },
    )
    clickableItem(
        onClick = {},
        label = "Share",
        icon = { Icon(Icons.Rounded.Share, contentDescription = null) },
    )
    clickableItem(
        onClick = {},
        label = "Delete",
        icon = { Icon(Icons.Rounded.Delete, contentDescription = null) },
    )
}
```

## Parameters

| Name | Type | Default | Description |
|---|---|---|---|
| `overflowIndicator` | `@Composable (ButtonGroupMenuState) -> Unit` |  | Shown when items do not fit. Use ButtonGroupDefaults.OverflowIndicator. |
| `modifier` | `Modifier` | `Modifier` | Constrain the width to control when overflow happens. |
| `expandedRatio` | `Float` | `0.15f` | How much a pressed item grows. |
| `horizontalArrangement` | `Arrangement.Horizontal` | `ButtonGroupDefaults.HorizontalArrangement` | Spacing between items. |
| `verticalAlignment` | `Alignment.Vertical` | `Alignment.Top` | Cross axis alignment of items. |
| `content` | `ButtonGroupScope.() -> Unit` |  | Declare items with clickableItem, toggleableItem and customItem. |

## Guidelines

Do:
- Group actions that are closely related.
- Put the most important actions first, they overflow last.

Don't:
- Do not mix unrelated actions in one group.
- Do not rely on overflow for primary actions on small screens.

## Accessibility

- Every item needs a label. The label doubles as the menu text when the item overflows.
- Icon-only items still need a label string, which is announced by screen readers.
- The overflow indicator is an icon button with a built-in content description.

## Related components

- [Connected button group](https://m3e.ljzapps.app/docs/components/connected-button-group.md)
- [Buttons](https://m3e.ljzapps.app/docs/components/button.md)
- [Split button](https://m3e.ljzapps.app/docs/components/split-button.md)
- [Segmented button](https://m3e.ljzapps.app/docs/components/segmented-button.md)
