DismissibleModalWideNavigationRail
Component in Material 3 Compose
A dismissible modal wide navigation rail.
Wide navigation rails provide access to primary destinations in apps when using tablet and desktop screens.
The dismissible modal wide navigation rail blocks interaction with the rest of an app’s content with a scrim when expanded. It is elevated above most of the app’s UI and doesn't affect the screen’s layout grid. When collapsed, the rail is hidden.
The dismissible modal wide navigation rai should be used to display at least three [WideNavigationRailItem]s with their icon position set to [NavigationItemIconPosition.Start], each representing a singular app destination, and, optionally, a header containing a menu button, a [FloatingActionButton], and/or a logo. Each destination is typically represented by an icon and a text label. A simple example looks like:
@sample androidx.compose.material3.samples.DismissibleModalWideNavigationRailSample
For a modal rail that expands from a collapsed rail, instead of entering from offscreen, see [ModalWideNavigationRail].
See [WideNavigationRailItem] for configuration specific to each item, and not the overall [DismissibleModalWideNavigationRail] component.
Last updated:
Installation
dependencies {
implementation("androidx.compose.material3:material3:1.4.0-alpha02")
}
Overloads
@ExperimentalMaterial3ExpressiveApi
@Composable
fun DismissibleModalWideNavigationRail(
onDismissRequest: () -> Unit,
modifier: Modifier = Modifier,
railState: DismissibleModalWideNavigationRailState =
rememberDismissibleModalWideNavigationRailState(),
shape: Shape = WideNavigationRailDefaults.modalContainerShape,
colors: WideNavigationRailColors = WideNavigationRailDefaults.colors(),
header: @Composable (() -> Unit)? = null,
windowInsets: WindowInsets = WideNavigationRailDefaults.windowInsets,
arrangement: WideNavigationRailArrangement = WideNavigationRailDefaults.Arrangement,
gesturesEnabled: Boolean = true,
properties: ModalWideNavigationRailProperties =
DismissibleModalWideNavigationRailDefaults.Properties,
content: @Composable () -> Unit
)
Parameters
name | description |
---|---|
onDismissRequest | executes when the user closes the rail, after it animates to [DismissibleModalWideNavigationRailValue.Closed] |
modifier | the [Modifier] to be applied to this dismissible modal wide navigation rail |
railState | state of the dismissible modal wide navigation rail |
shape | defines the shape of this dismissible modal wide navigation rail's container |
colors | [WideNavigationRailColors] that will be used to resolve the colors used for this dismissible modal wide navigation rail. See [WideNavigationRailDefaults.colors] |
header | optional header that may hold a [FloatingActionButton] or a logo |
windowInsets | a window insets of this dismissible modal wide navigation rail |
arrangement | the [WideNavigationRailArrangement] of this dismissible modal wide navigation rail |
gesturesEnabled | whether the dismissible modal wide navigation rail can be interacted by gestures |
properties | [ModalWideNavigationRailProperties] for further customization of this modal expanded navigation rail's window behavior |
content | the content of this dismissible modal wide navigation rail, typically [WideNavigationRailItem]s with [NavigationItemIconPosition.Start] icon position |
Code Example
DismissibleModalWideNavigationRailSample
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Preview
@Composable
fun DismissibleModalWideNavigationRailSample() {
var selectedItem by remember { mutableIntStateOf(0) }
val items = listOf("Home", "Search", "Settings")
val selectedIcons = listOf(Icons.Filled.Home, Icons.Filled.Favorite, Icons.Filled.Star)
val unselectedIcons =
listOf(Icons.Outlined.Home, Icons.Outlined.FavoriteBorder, Icons.Outlined.StarBorder)
var openModalRail by rememberSaveable { mutableStateOf(false) }
var dismissRailOnItemSelection by rememberSaveable { mutableStateOf(true) }
val modalRailState = rememberDismissibleModalWideNavigationRailState()
val scope = rememberCoroutineScope()
Row(Modifier.fillMaxSize()) {
if (openModalRail) {
DismissibleModalWideNavigationRail(
onDismissRequest = { openModalRail = false },
railState = modalRailState
) {
items.forEachIndexed { index, item ->
WideNavigationRailItem(
railExpanded = true,
icon = {
Icon(
if (selectedItem == index) selectedIcons[index]
else unselectedIcons[index],
contentDescription = null
)
},
label = { Text(item) },
selected = selectedItem == index,
onClick = {
selectedItem = index
if (dismissRailOnItemSelection) {
// Note: If you provide logic outside of onDismissRequest to close
// the rail, you must additionally handle intended state cleanup, if
// any.
scope
.launch {
// Add a minimum delay so that the selected state of the
// item is properly announced to screen readers before the
// rail closes.
delay(250)
modalRailState.close()
}
.invokeOnCompletion { openModalRail = false }
}
}
)
}
}
}
Column(Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) {
Button(onClick = { openModalRail = !openModalRail }, Modifier.padding(32.dp)) {
Text(text = "Open modal rail")
}
Row(
Modifier.toggleable(
value = dismissRailOnItemSelection,
role = Role.Checkbox,
onValueChange = { checked -> dismissRailOnItemSelection = checked }
)
) {
Checkbox(checked = dismissRailOnItemSelection, onCheckedChange = null)
Spacer(Modifier.width(16.dp))
Text("Dismiss rail on item selection.")
}
}
}
}