# Split button

> Pairs a primary action with a menu of related alternatives.

- Category: Actions
- API status: Expressive
- Compose APIs: `SplitButtonLayout`, `SplitButtonDefaults.LeadingButton`, `SplitButtonDefaults.TrailingButton`
- Interactive page: https://m3e.ljzapps.app/#components/split-button

## When to use

A split button has two touch targets: the leading button runs the main action and the trailing button opens a menu. The trailing button toggles, and its shape and arrow reflect whether the menu is open.

Compose the pieces with SplitButtonLayout and the buttons from SplitButtonDefaults. Pick the shapes, padding and icon sizes for the height with the ...For(height) helpers.

## Playground

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

## Examples

### Menu on the trailing button

The arrow rotates while the menu is open.

```kotlin
var expanded by remember { mutableStateOf(false) }

SplitButtonLayout(
    leadingButton = {
        SplitButtonDefaults.LeadingButton(onClick = {}) {
            Icon(
                Icons.Rounded.Edit,
                contentDescription = null,
                modifier = Modifier.size(SplitButtonDefaults.LeadingIconSize),
            )
            Spacer(Modifier.width(ButtonDefaults.IconSpacing))
            Text("Edit")
        }
    },
    trailingButton = {
        SplitButtonDefaults.TrailingButton(
            checked = expanded,
            onCheckedChange = { expanded = it },
            modifier = Modifier.semantics { contentDescription = "More options" },
        ) {
            val rotation by animateFloatAsState(if (expanded) 180f else 0f)
            Icon(
                Icons.Rounded.KeyboardArrowDown,
                contentDescription = null,
                modifier = Modifier.size(SplitButtonDefaults.TrailingIconSize).rotate(rotation),
            )
        }
        DropdownMenu(expanded = expanded, onDismissRequest = { expanded = false }) {
            DropdownMenuItem(text = { Text("Edit as copy") }, onClick = { expanded = false })
            DropdownMenuItem(text = { Text("Rename") }, onClick = { expanded = false })
        }
    },
)
```

## Parameters

| Name | Type | Default | Description |
|---|---|---|---|
| `leadingButton` | `@Composable () -> Unit` |  | The primary action. |
| `trailingButton` | `@Composable () -> Unit` |  | The toggle that opens the menu. |
| `spacing` | `Dp` | `SplitButtonDefaults.Spacing` | Gap between the two buttons. |

## Guidelines

Do:
- Make the leading action the most common one.
- Keep the menu short.

Don't:
- Do not hide the primary action in the menu.
- Do not use it when there is only one action.

## Accessibility

- Give the trailing button a content description such as More options, because it only shows an arrow.
- The trailing button exposes its expanded state. Return focus to it when the menu closes.

## Related components

- [Buttons](https://m3e.ljzapps.app/docs/components/button.md)
- [Button group](https://m3e.ljzapps.app/docs/components/button-group.md)
- [Menu](https://m3e.ljzapps.app/docs/components/menu.md)
