minimumInteractiveComponentSize
fun Modifier.minimumInteractiveComponentSize(): Modifier
Reserves at least 48.dp in size to disambiguate touch interactions if the element would measure smaller.
Target sizes
(https://m3.material.io/foundations/designing/structure#dab862b1-e042-4c40-b680-b484b9f077f6)
This uses the Material recommended minimum size of 48.dp x 48.dp, which may not the same as the
system enforced minimum size. The minimum clickable / touch target size (48.dp by default) is
controlled by the system via ViewConfiguration
and automatically expanded at the touch input
layer.
This modifier is not needed for touch target expansion to happen. It only affects layout, to make sure there is adequate space for touch target expansion.
Because layout constraints are affected by modifier order, for this modifier to take effect, it must come before any size modifiers on the element that might limit its constraints.
Code Examples
MinimumInteractiveComponentSizeSample
@Preview
@Composable
fun MinimumInteractiveComponentSizeSample() {
@Composable
fun Widget(color: Color, modifier: Modifier = Modifier) {
// Default size is 24.dp, which is smaller than the recommended touch target
Box(modifier.size(24.dp).background(color))
}
Column(Modifier.border(1.dp, Color.Black)) {
// Not interactable, no need for touch target enforcement
Widget(Color.Red)
Widget(
color = Color.Green,
modifier =
Modifier.clickable { /* do something */ }
// Component is now interactable, so it should enforce a sufficient touch target
.minimumInteractiveComponentSize(),
)
Widget(
color = Color.Blue,
modifier =
Modifier.clickable { /* do something */ }
// Component is now interactable, so it should enforce a sufficient touch target
.minimumInteractiveComponentSize()
// Any size modifiers should come after `minimumInteractiveComponentSize`
// so as not to interfere with layout expansion
.size(36.dp),
)
}
}
MinimumInteractiveComponentSizeCheckboxRowSample
@Preview
@Composable
fun MinimumInteractiveComponentSizeCheckboxRowSample() {
var checked by remember { mutableStateOf(false) }
// The entire row accepts interactions to toggle the checkbox,
// so we apply `minimumInteractiveComponentSize`
Row(
verticalAlignment = Alignment.CenterVertically,
modifier =
Modifier.toggleable(
value = checked,
onValueChange = { checked = it },
role = Role.Checkbox,
)
.minimumInteractiveComponentSize(),
) {
// Cannot rely on Checkbox for touch target expansion because it only enforces
// `minimumInteractiveComponentSize` if onCheckedChange is non-null
Checkbox(checked = checked, onCheckedChange = null)
Spacer(Modifier.width(8.dp))
Text("Label for checkbox")
}
}