minimumInteractiveComponentSize
Functions summary
Modifier |
Reserves at least 48.dp in size to disambiguate touch interactions if the element would measure smaller. |
Cmn
|
Functions
Modifier.minimumInteractiveComponentSize
fun Modifier.minimumInteractiveComponentSize(): Modifier
Reserves at least 48.dp in size to disambiguate touch interactions if the element would measure smaller.
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.
import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.size import androidx.compose.material3.minimumInteractiveComponentSize import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp @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), ) }
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.width import androidx.compose.foundation.selection.toggleable import androidx.compose.material3.Checkbox import androidx.compose.material3.Text import androidx.compose.material3.minimumInteractiveComponentSize import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.semantics.Role import androidx.compose.ui.unit.dp 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") }