minimumInteractiveComponentSize
Modifier in Material 3 Compose
Reserves at least 48.dp in size to disambiguate touch interactions if the element would measure smaller.
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.
@sample androidx.compose.material3.samples.MinimumInteractiveComponentSizeSample @sample androidx.compose.material3.samples.MinimumInteractiveComponentSizeCheckboxRowSample @see LocalMinimumInteractiveComponentSize
Last updated:
Installation
dependencies {
implementation("androidx.compose.material3:material3:1.4.0-alpha02")
}
Overloads
@Stable
fun Modifier.minimumInteractiveComponentSize(): Modifier
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")
}
}