Bottom sheet

Bottom sheets are views rendered on top of screen content, containing supplementary content that are anchored to the bottom of the screen.

Bottom Sheet

Maven Central Class reference Source code

Default

Day Night
BottomSheet component BottomSheet component - dark mode

BottomSheet with Light Drag Handle over Image content

Day Night
BottomSheet component BottomSheet component - dark mode
Day Night
Modal BottomSheet component Modal BottomSheet component - dark mode
Day Night
Modal With TopBar BottomSheet component Modal With TopBar BottomSheet component - dark mode
Day Night
BottomSheet component BottomSheet component - dark mode
Day Night
Modal with TopBar BottomSheet over image component Modal with TopBar BottomSheet over image component - dark mode

Installation

Backpack Compose is available through Maven Central. Check the main Readme for a complete installation guide.

Usage

Example of a Bottom Sheet:


                                                
                                                import net.skyscanner.backpack.compose.bottomsheet.BpkBottomSheet
                                                import net.skyscanner.backpack.compose.bottomsheet.BpkBottomSheetState
                                                import net.skyscanner.backpack.compose.bottomsheet.rememberBpkBottomSheetState
                                                
                                                val state = rememberBpkBottomSheetState()
                                                
                                                BpkBottomSheet(
                                                  state = state,
                                                  peekHeight = HeightOfCollapsedBottomSheet,
                                                  sheetContent = { /* content of the bottom sheet */ },
                                                  dragHandleStyle = BpkDragHandleStyle.Default,
                                                  content = { contentPadding ->
                                                    // content displayed behind bottom sheet
                                                    // you should apply content padding to avoid displaying content behind collapsed bottom sheet
                                                    // here's an example:
                                                    Box(modifier = Modifier
                                                      .fillMaxSize()
                                                      .background(myBackground)
                                                      .padding(contentPadding)
                                                    ) {
                                                        // this content will respect the paddings
                                                    }
                                                  }
                                                )

Example of a Modal Bottom Sheet:


                                                
                                                import net.skyscanner.backpack.compose.bottomsheet.BpkModalBottomSheet
                                                import net.skyscanner.backpack.compose.bottomsheet.BpkModalBottomSheetState
                                                import net.skyscanner.backpack.compose.bottomsheet.rememberBpkModalBottomSheetState
                                                
                                                var openBottomSheet by rememberSaveable { mutableStateOf(true) }
                                                val state = rememberBpkModalBottomSheetState()
                                                
                                                if (openBottomSheet) {
                                                    BpkModalBottomSheet(
                                                        state = state,
                                                        content = { /* content of the bottom sheet */ },
                                                        dragHandleStyle = BpkDragHandleStyle.Default,
                                                        onDismissRequest = { openBottomSheet = false },
                                                    )
                                                }

Example of a Modal Bottom Sheet With Title and Close NavAction:


                                                
                                                import net.skyscanner.backpack.compose.bottomsheet.BpkModalBottomSheet
                                                import net.skyscanner.backpack.compose.bottomsheet.BpkModalBottomSheetState
                                                import net.skyscanner.backpack.compose.bottomsheet.rememberBpkModalBottomSheetState
                                                
                                                var openBottomSheet by rememberSaveable { mutableStateOf(true) }
                                                val state = rememberBpkModalBottomSheetState()
                                                
                                                if (openBottomSheet) {
                                                    BpkModalBottomSheet(
                                                        state = state,
                                                        title = stringResource(id = R.string.generic_title),
                                                        closeButton = BpkModalBottomSheetCloseAction.Default(stringResource(id = R.string.navigation_close)),
                                                        action = TextAction(text = stringResource(id = R.string.section_header_button_text), {}),
                                                        content = { /* content of the bottom sheet */ },
                                                        dragHandleStyle = BpkDragHandleStyle.Default,
                                                        onDismissRequest = { openBottomSheet = false },
                                                    )
                                                }

By default the Bottom sheet content starts below the drag handle. In cases where you need to show an image at the top you can set the dragHandleStyle property to OnImage to remove the safe area, like this:


                                                
                                                import net.skyscanner.backpack.compose.bottomsheet.BpkModalBottomSheet
                                                import net.skyscanner.backpack.compose.bottomsheet.BpkModalBottomSheetState
                                                import net.skyscanner.backpack.compose.bottomsheet.rememberBpkModalBottomSheetState
                                                
                                                var openBottomSheet by rememberSaveable { mutableStateOf(true) }
                                                val state = rememberBpkModalBottomSheetState()
                                                
                                                if (openBottomSheet) {
                                                    BpkModalBottomSheet(
                                                        state = state,
                                                        content = { /* image content of the bottom sheet */ },
                                                        dragHandleStyle = BpkDragHandleStyle.OnImage(Type.Light), // use Type.Dark for Dark dragHandle on Image
                                                        onDismissRequest = { openBottomSheet = false },
                                                    )
                                                }