This problem is solved by taking the code from the docs
val options = listOf("Option 1", "Option 2", "Option 3", "Option 4", "Option 5")
var expanded by remember { mutableStateOf(false) }
var selectedOptionText by remember { mutableStateOf("") }
ExposedDropdownMenuBox(
expanded = expanded,
onExpandedChange = { expanded = !expanded },
) {
TextField(
// The `menuAnchor` modifier must be passed to the text field for correctness.
modifier = Modifier.menuAnchor(),
value = selectedOptionText,
onValueChange = { selectedOptionText = it },
label = { Text("Label") },
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) },
colors = ExposedDropdownMenuDefaults.textFieldColors(),
)
// filter options based on text field value
val filteringOptions = options.filter { it.contains(selectedOptionText, ignoreCase = true) }
if (filteringOptions.isNotEmpty()) {
ExposedDropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false },
) {
filteringOptions.forEach { selectionOption ->
DropdownMenuItem(
text = { Text(selectionOption) },
onClick = {
selectedOptionText = selectionOption
expanded = false
},
contentPadding = ExposedDropdownMenuDefaults.ItemContentPadding,
)
}
}
}
}
And we replace the nested ExposedDropdownMenu with
DropdownMenu(
modifier = Modifier
.background(Color.White)
.exposedDropdownSize(true),
properties = PopupProperties(focusable = false),
expanded = expanded,
onDismissRequest = { expanded = false },
)
the final code will look and behave as expected. When you type, the suggestions will follow dynamically and user input will not be blocked
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun docs() {
val options = listOf("Option 1", "comment", "Afghanistan", "Albania", "Algeria", "Andorra", "Egypt")
var expanded by remember { mutableStateOf(false) }
var selectedOptionText by remember { mutableStateOf("") }
ExposedDropdownMenuBox(
expanded = expanded,
onExpandedChange = { expanded = !expanded },
) {
TextField(
// The `menuAnchor` modifier must be passed to the text field for correctness.
modifier = Modifier.menuAnchor(),
value = selectedOptionText,
onValueChange = { selectedOptionText = it },
label = { Text("Label") },
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) },
colors = ExposedDropdownMenuDefaults.textFieldColors(
focusedContainerColor = Color.White,
unfocusedContainerColor = Color.White
),
)
// filter options based on text field value
val filteringOptions = options.filter { it.contains(selectedOptionText, ignoreCase = true) }
if (filteringOptions.isNotEmpty()) {
DropdownMenu(
modifier = Modifier
.background(Color.White)
.exposedDropdownSize(true)
,
properties = PopupProperties(focusable = false),
expanded = expanded,
onDismissRequest = { expanded = false },
) {
filteringOptions.forEach { selectionOption ->
DropdownMenuItem(
text = { Text(selectionOption) },
onClick = {
selectedOptionText = selectionOption
expanded = false
},
contentPadding = ExposedDropdownMenuDefaults.ItemContentPadding,
)
}
}
}
}
}