StylishSpeedDial

fun StylishSpeedDial(expanded: Boolean, onExpandedChange: (Boolean) -> Unit, modifier: Modifier = Modifier, fabIcon: @Composable () -> Unit = { Icon(Icons.Default.Add, contentDescription = null) }, direction: SpeedDialDirection = SpeedDialDirection.Up, actionCount: Int = 0, spacing: Dp = StylishTheme.dimensions.itemSpacing, fabSize: Dp = DefaultStylishDimensions.fabSize, fabContainerColor: Color? = null, fabContentColor: Color? = null, onActionClick: (Int) -> Unit = {}, actions: @Composable SpeedDialScope.(index: Int) -> Unit)

A floating action button that expands a fan of actions around itself when tapped, mirroring Material UI's SpeedDial.

The component is a compact stateful shell: expanded and onExpandedChange are hoisted, and the main button (the existing StylishFab atom) toggles the state. actionCount actions are composed via actions, each receiving its SpeedDialScope.index; render each action as its own small button (e.g. a circular androidx.compose.material3.Surface with an icon) and call onActionClick with the index from its click handler.

The actions fan out along direction (up/down/start/end) with a fade + expand/shrink animation driven by StylishTheme.animation.durationShort. When the platform requests reduced motion (see isStylishReducedMotionEnabled) the actions snap in and out without animation, and the container does not animate its size.

Usage pattern

Anchor the dial in the corner of a Box (typically bottom-end) and let it float above the content:

Box(Modifier.fillMaxSize()) {
var expanded by remember { mutableStateOf(false) }
StylishSpeedDial(
expanded = expanded,
onExpandedChange = { expanded = it },
actionCount = 2,
modifier = Modifier.align(Alignment.BottomEnd),
onActionClick = { index -> /* handle action */},
actions = { index ->
StylishFab(
imageVector = actionsIcons[index],
contentDescription = "アクション $index",
onClick = { onActionClick(index) },
size = 40.dp,
)
},
)
}

Testing

The root carries the default test tag stylish_speeddial for UI tests. Callers can override it by passing their own Modifier.testTag(...) in modifier.

Parameters

expanded

Whether the actions are currently visible.

onExpandedChange

Called with the new expanded state when the main button is tapped.

modifier

Modifier applied to the root container (Column for SpeedDialDirection.Up/SpeedDialDirection.Down, Row otherwise). Anchor this in a Box with align(Alignment.BottomEnd) for the standard floating pattern.

fabIcon

Content of the main button. Defaults to a plus Icon without label — provide labeled content (or an icon that rotates while expanded) as needed.

direction

The direction the actions fan out in (see SpeedDialDirection).

actionCount

The number of actions to compose. actions is invoked once per index 0 until actionCount.

spacing

The gap between the main button and the actions, and between adjacent actions. Defaults to StylishTheme.dimensions.itemSpacing.

fabSize

The diameter of the main button. Defaults to DefaultStylishDimensions.fabSize.

fabContainerColor

Background color override for the main button. When null, StylishFab's default applies.

fabContentColor

Content color override for the main button. When null, StylishFab's default applies.

onActionClick

Convenience callback for action taps; invoke it from within actions with the item's index.

actions

Slot composing one action per index. Render a small button here (see the usage pattern above).

See also