For My use case I created a Icon button which has pop up menu and that can be used where pop menu is needed.
@Composable fun PopUpMenuButton( options: List<PopUpMenuItem>, action: (String) -> Unit, iconTint: Color = Color.Black, modifier: Modifier ) { var expanded by remember { mutableStateOf(false) } Column { Box(modifier = Modifier.size(24.dp)) { IconButton(onClick = { expanded = !expanded }) { Icon( painter = painterResource(id = R.drawable.ic_dots), contentDescription = null, modifier = Modifier.wrapContentSize(), tint = iconTint ) } } Box(modifier = modifier) { DropdownMenu( expanded = expanded, onDismissRequest = { expanded = false }, modifier = Modifier .widthIn(min = 120.dp, max = 240.dp) .background(MaterialTheme.colors.background) ) { options.forEachIndexed { _, item -> DropdownMenuItem(onClick = { expanded = false action(item.id) }) { Row( horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically, ) { Icon( painterResource(id = item.icon), contentDescription = null, tint = iconTint, ) Spacer(modifier = Modifier.width(8.dp)) Text( text = item.label, style = MaterialTheme.typography.body1, overflow = TextOverflow.Ellipsis ) } } if (item.hasBottomDivider) { Divider() } } } } } }
Then I created a simple data class for defining menu item
data class PopUpMenuItem( val id: String, val label: String, val icon: Int, val hasBottomDivider: Boolean = false, )
Then at the calling side I simply use this button like this
PopUpMenuButton( modifier = Modifier.wrapContentSize(), options = PopMenuOptionsProvider.sectionCardMenu, iconTint = MaterialTheme.extendedColor.regularGray, action = { menuId -> onSectionMenuAction(menuId) } )
It can be further refactored to make it more extensible, but this worked for me.