ExtendedPaneScaffoldPaneScope

Known direct subclasses

Extended scope for the panes of pane scaffolds. All pane scaffolds will implement this interface to provide necessary info for panes to correctly render their content, motion, etc.

Parameters
<Role : Any?>

The type of roles that denotes panes in the associated pane scaffold.

<ScaffoldValue : PaneScaffoldValue<Role>>

The type of scaffold values that denotes the PaneAdaptedValues in the associated pane scaffold.

Summary

Extension functions

Unit
@ExperimentalMaterial3AdaptiveApi
@Composable
<S : Any?, T : PaneScaffoldValue<S>> ExtendedPaneScaffoldPaneScope<S, T>.AnimatedPane(
    modifier: Modifier,
    enterTransition: EnterTransition,
    exitTransition: ExitTransition,
    boundsAnimationSpec: FiniteAnimationSpec<IntRect>,
    content: @Composable AnimatedPaneScope.() -> Unit
)

The root composable of pane contents in a ThreePaneScaffold that supports default motions during pane switching.

Cmn

Inherited functions

From androidx.compose.ui.layout.LookaheadScope
open Offset
LayoutCoordinates.localLookaheadPositionOf(
    sourceCoordinates: LayoutCoordinates,
    relativeToSource: Offset,
    includeMotionFrameOfReference: Boolean
)

Converts relativeToSource in sourceCoordinates's lookahead coordinate space into local lookahead coordinates.

Cmn
LayoutCoordinates

Converts a LayoutCoordinates into a LayoutCoordinates in the Lookahead coordinate space.

Cmn
From androidx.compose.material3.adaptive.layout.PaneScaffoldScope
Modifier
@ExperimentalMaterial3AdaptiveApi
Modifier.paneExpansionDraggable(
    state: PaneExpansionState,
    minTouchTargetSize: Dp,
    interactionSource: MutableInteractionSource
)

The modifier that should be applied on a drag handle composable so the drag handle can be dragged and operate on the provided PaneExpansionState properly.

Cmn
Modifier

This modifier specifies the preferred width for a pane, and the pane scaffold implementation will try its best to respect this width when the associated pane is rendered as a fixed pane, i.e., a pane that are not stretching to fill the remaining spaces.

Cmn

Inherited properties

From androidx.compose.ui.layout.LookaheadScope
From androidx.compose.material3.adaptive.layout.PaneScaffoldPaneScope
PaneMotion

The specified pane motion of the current pane in the scope.

Cmn
Role

The role of the current pane in the scope.

Cmn
From androidx.compose.material3.adaptive.layout.PaneScaffoldTransitionScope
open EnterTransition

A convenient function to get the given PaneMotion's EnterTransition under the context of the current PaneScaffoldTransitionScope.

Cmn
open ExitTransition

A convenient function to get the given PaneMotion's EnterTransition under the context of the current PaneScaffoldTransitionScope.

Cmn
PaneScaffoldMotionDataProvider<Role>

Provides measurement and other data required in motion calculation like the size and offset of each pane before and after the motion.

Cmn
Float

The current motion progress.

Cmn
Transition<ScaffoldValue>

The current scaffold state transition between PaneScaffoldValues.

Cmn

Extension functions

@ExperimentalMaterial3AdaptiveApi
@Composable
fun <S : Any?, T : PaneScaffoldValue<S>> ExtendedPaneScaffoldPaneScope<S, T>.AnimatedPane(
    modifier: Modifier = Modifier,
    enterTransition: EnterTransition = paneMotion.enterTransition,
    exitTransition: ExitTransition = paneMotion.exitTransition,
    boundsAnimationSpec: FiniteAnimationSpec<IntRect> = PaneMotionDefaults.AnimationSpec,
    content: @Composable AnimatedPaneScope.() -> Unit
): Unit

The root composable of pane contents in a ThreePaneScaffold that supports default motions during pane switching. It's recommended to use this composable to wrap your own contents when passing them into pane parameters of the scaffold functions, therefore your panes can have a nice default animation for free.

import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.adaptive.layout.AnimatedPane
import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffold
import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffoldRole
import androidx.compose.material3.adaptive.navigation.rememberListDetailPaneScaffoldNavigator
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp

val scaffoldNavigator = rememberListDetailPaneScaffoldNavigator()
val coroutineScope = rememberCoroutineScope()
ListDetailPaneScaffold(
    directive = scaffoldNavigator.scaffoldDirective,
    value = scaffoldNavigator.scaffoldValue,
    listPane = {
        AnimatedPane(
            modifier = Modifier.preferredWidth(200.dp),
        ) {
            Surface(
                color = MaterialTheme.colorScheme.secondary,
                onClick = {
                    coroutineScope.launch {
                        scaffoldNavigator.navigateTo(ListDetailPaneScaffoldRole.Detail)
                    }
                }
            ) {
                Text("List")
            }
        }
    },
    detailPane = {
        AnimatedPane(modifier = Modifier) {
            Surface(
                color = MaterialTheme.colorScheme.primary,
                onClick = { coroutineScope.launch { scaffoldNavigator.navigateBack() } }
            ) {
                Text("Details")
            }
        }
    }
)
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.LocalMinimumInteractiveComponentSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.VerticalDivider
import androidx.compose.material3.VerticalDragHandle
import androidx.compose.material3.adaptive.layout.AnimatedPane
import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffold
import androidx.compose.material3.adaptive.layout.ListDetailPaneScaffoldRole
import androidx.compose.material3.adaptive.layout.PaneExpansionAnchor
import androidx.compose.material3.adaptive.layout.PaneExpansionState
import androidx.compose.material3.adaptive.layout.rememberPaneExpansionState
import androidx.compose.material3.adaptive.navigation.rememberListDetailPaneScaffoldNavigator
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp

val scaffoldNavigator = rememberListDetailPaneScaffoldNavigator()
val coroutineScope = rememberCoroutineScope()
ListDetailPaneScaffold(
    directive = scaffoldNavigator.scaffoldDirective,
    value = scaffoldNavigator.scaffoldValue,
    listPane = {
        AnimatedPane(
            modifier = Modifier.preferredWidth(200.dp),
        ) {
            Surface(
                color = MaterialTheme.colorScheme.secondary,
                onClick = {
                    coroutineScope.launch {
                        scaffoldNavigator.navigateTo(ListDetailPaneScaffoldRole.Detail)
                    }
                }
            ) {
                Text("List")
            }
        }
    },
    detailPane = {
        AnimatedPane(modifier = Modifier) {
            Surface(
                color = MaterialTheme.colorScheme.primary,
            ) {
                Column(verticalArrangement = Arrangement.spacedBy(16.dp)) {
                    Text("Detail")
                    Row(
                        modifier = Modifier.fillMaxWidth().padding(horizontal = 4.dp),
                        horizontalArrangement = Arrangement.spacedBy(8.dp)
                    ) {
                        Surface(
                            onClick = {
                                coroutineScope.launch { scaffoldNavigator.navigateBack() }
                            },
                            modifier = Modifier.weight(0.5f).fillMaxHeight(),
                            color = MaterialTheme.colorScheme.primary.copy(alpha = 0.8f)
                        ) {
                            Box(
                                modifier = Modifier.fillMaxSize(),
                                contentAlignment = Alignment.Center
                            ) {
                                Text("Previous")
                            }
                        }
                        VerticalDivider()
                        Surface(
                            onClick = {
                                coroutineScope.launch {
                                    scaffoldNavigator.navigateTo(
                                        ListDetailPaneScaffoldRole.Extra
                                    )
                                }
                            },
                            modifier = Modifier.weight(0.5f).fillMaxHeight(),
                            color = MaterialTheme.colorScheme.primary.copy(alpha = 0.6f)
                        ) {
                            Box(
                                modifier = Modifier.fillMaxSize(),
                                contentAlignment = Alignment.Center
                            ) {
                                Text("Next")
                            }
                        }
                    }
                }
            }
        }
    },
    extraPane = {
        AnimatedPane(modifier = Modifier.fillMaxSize()) {
            Surface(
                modifier = Modifier.fillMaxSize(),
                color = MaterialTheme.colorScheme.tertiary,
                onClick = { coroutineScope.launch { scaffoldNavigator.navigateBack() } }
            ) {
                Text("Extra")
            }
        }
    },
    paneExpansionState =
        rememberPaneExpansionState(
            keyProvider = scaffoldNavigator.scaffoldValue,
            anchors = PaneExpansionAnchors
        ),
    paneExpansionDragHandle = { state ->
        val interactionSource = remember { MutableInteractionSource() }
        VerticalDragHandle(
            modifier =
                Modifier.paneExpansionDraggable(
                    state,
                    LocalMinimumInteractiveComponentSize.current,
                    interactionSource
                ),
            interactionSource = interactionSource
        )
    }
)
Parameters
modifier: Modifier = Modifier

The modifier applied to the AnimatedPane.

enterTransition: EnterTransition = paneMotion.enterTransition

The EnterTransition used to animate the pane in.

exitTransition: ExitTransition = paneMotion.exitTransition

The ExitTransition used to animate the pane out.

boundsAnimationSpec: FiniteAnimationSpec<IntRect> = PaneMotionDefaults.AnimationSpec

The FiniteAnimationSpec used to animate the bounds of the pane when the pane is keeping showing but changing its size and/or position.

content: @Composable AnimatedPaneScope.() -> Unit

The content of the AnimatedPane. Also see AnimatedPaneScope.

See usage samples at: