List-detail layout

Shows a list and the selected item side by side, or one after the other on small windows.

When to use

ListDetailPaneScaffold is the canonical layout for master and detail content such as mail or contacts. The window size decides how many panes are visible. On a compact window the detail pane replaces the list, on larger windows both are shown.

The navigator remembers the selected item and the back stack, so back navigation closes the detail pane first. Resize the browser window to watch the layout adapt.

Examples

Contacts

Resize the window to switch between one and two panes.

val navigator = rememberListDetailPaneScaffoldNavigator<String>()
val scope = rememberCoroutineScope()
val names = listOf("Maya Chen", "Jonas Weber", "Ana Silva", "Kenji Sato")

Box(Modifier.fillMaxWidth().height(340.dp)) {
    ListDetailPaneScaffold(
        directive = navigator.scaffoldDirective,
        scaffoldState = navigator.scaffoldState,
        listPane = {
            AnimatedPane {
                Box(Modifier.fillMaxSize()) {
                    LazyColumn {
                        items(names) { name ->
                            ListItem(
                                onClick = { scope.launch { navigator.navigateTo(ListDetailPaneScaffoldRole.Detail, name) } },
                                supportingContent = { Text("Tap to open") },
                            ) { Text(name) }
                        }
                    }
                }
            }
        },
        detailPane = {
            AnimatedPane {
                Box(Modifier.fillMaxSize().padding(24.dp), contentAlignment = Alignment.Center) {
                    val selected = navigator.currentDestination?.contentKey
                    if (selected == null) {
                        Text("Select a contact", style = MaterialTheme.typography.bodyLarge)
                    } else {
                        Text(selected, style = MaterialTheme.typography.headlineMedium)
                    }
                }
            }
        },
    )
}

Parameters

NameTypeDefaultDescription
directivePaneScaffoldDirectivenavigator.scaffoldDirectiveDerived from the window size class and posture.
scaffoldStateThreePaneScaffoldStatenavigator.scaffoldStateWhich panes are visible.
listPane / detailPane@Composable ThreePaneScaffoldPaneScope.() -> UnitWrap content in AnimatedPane.
extraPane@Composable (...)?nullOptional third pane for large windows.

Guidelines

Do:

Don't:

Accessibility

Related components