Kotlin Mutliplatform responsive menu

You may have noticed that it’s hard to limit the size of the menu (ModelDrawer) in Kotlin Multiplatform, since there is just no such parameter.

In this article we will find answers to these questions:

  • ModelDrawer limit size
  • ModelDrawer limit width
  • ModelDrawer set max size
  • ModelDrawer set max width
  • Kotlin Multiplatform set menu width
  • Jetpack Compose set menu width
  • Responsive menu Kotlin Multiplatform
  • Responsive menu Jetpack Compose

The workaround here is to set the transparent color for the background, add new box with our own size limitations and get close gestures back. Moreover, we’ll make the menu responsive, meaning it will change it’s size depending on the screen orientation.

@Composable
fun YourScreen(navController: NavController) {
    val drawerState = rememberDrawerState(DrawerValue.Closed)
    val scope = rememberCoroutineScope()

    // Workaround to get screen size
    BoxWithConstraints(Modifier.fillMaxSize(), propagateMinConstraints = true) {
        val screenWidth = this.maxWidth
        val screenHeight = this.maxHeight

        ModalDrawer(
            drawerState = drawerState,
            drawerContent = {
                Row(modifier = Modifier.fillMaxWidth()) {
                    Column(
                        modifier = Modifier
                            .width(if (screenWidth < screenHeight) screenWidth * 2 / 3 else screenWidth / 3)
                            .fillMaxHeight()
                            // Workaround to limit max menu width
                            .background(
                                Color.GRAY,
                                RoundedCornerShape(topEnd = 16.dp, bottomEnd = 16.dp)
                            )
                    ) {
                        // < DrawerContent >
                    }
                    // Workaround to bring close gesture back
                    Spacer(
                        modifier = Modifier
                            .fillMaxSize()
                            .clickable(
                                interactionSource = MutableInteractionSource(),
                                indication = null
                            ) {
                                scope.launch {
                                    if (drawerState.isOpen) {
                                        drawerState.close()
                                    }
                                }
                            },
                    )
                }
            },
            gesturesEnabled = drawerState.isOpen,
            drawerShape = RoundedCornerShape(0.dp),
            drawerBackgroundColor = Color.Transparent,
            drawerContentColor = Color.Transparent,
            drawerElevation = 0.dp
        ) {
            // < Main page content >
        }
    }
}

We use BoxWithConstraints to obtain screen dimensions and Column with .fillMaxHeight() and .width() inside drawerContent to have block with desired size.

Note, that you need to place your content here < DrawerContent > and here < Main page content > in the code from above.

Many thanks to:

That’s all!


Telegram channel

If you still have any questions, feel free to ask me in the comments under this article or write me at promark33@gmail.com.

If I saved your day, you can support me 🤝