A state object that can be used to control the resizing behavior of a pane.

This class provides a way to track the current size of a resizable pane and to handle drag interactions that modify the size. It supports both horizontal and vertical resizing.

This state object is primarily designed for internal use within pane scaffolds.

import androidx.compose.material3.Scaffold
import androidx.compose.material3.adaptive.layout.AdaptStrategy
import androidx.compose.material3.adaptive.layout.AnimatedPane
import androidx.compose.material3.adaptive.layout.DockedEdge
import androidx.compose.material3.adaptive.layout.PaneExpansionAnchor
import androidx.compose.material3.adaptive.layout.PaneExpansionState
import androidx.compose.material3.adaptive.layout.SupportingPaneScaffold
import androidx.compose.material3.adaptive.layout.SupportingPaneScaffoldDefaults
import androidx.compose.material3.adaptive.layout.rememberDragToResizeState
import androidx.compose.material3.adaptive.layout.rememberPaneExpansionState
import androidx.compose.material3.adaptive.navigation.rememberSupportingPaneScaffoldNavigator
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 coroutineScope = rememberCoroutineScope()
val scaffoldNavigator =
    rememberSupportingPaneScaffoldNavigator<NavItemData>(
        adaptStrategies =
            SupportingPaneScaffoldDefaults.adaptStrategies(
                extraPaneAdaptStrategy =
                    AdaptStrategy.Levitate(
                        strategy = AdaptStrategy.Levitate.Strategy.SinglePaneOnly,
                        alignment = Alignment.BottomCenter,
                    )
            )
    )
val extraItems = listOf("Extra content")
val selectedItem = NavItemData(index = 0, showExtra = true)

SupportingPaneScaffold(
    directive = scaffoldNavigator.scaffoldDirective,
    scaffoldState = scaffoldNavigator.scaffoldState,
    mainPane = {
        AnimatedPane {
            MainPaneContent(
                scaffoldNavigator = scaffoldNavigator,
                hasExtraPane = true,
                coroutineScope = coroutineScope
            )
        }
    },
    supportingPane = {
        AnimatedPane(modifier = Modifier.preferredWidth(200.dp)) { SupportingPaneContent() }
    },
    extraPane = {
        AnimatedPane(
            modifier =
                Modifier.preferredWidth(480.dp)
                    .preferredHeight(412.dp)
                    .dragToResize(rememberDragToResizeState(dockedEdge = DockedEdge.Bottom))
        ) {
            ExtraPaneContent(
                extraItems = extraItems,
                selectedItem = selectedItem,
                scaffoldNavigator = scaffoldNavigator,
                coroutineScope = coroutineScope
            )
        }
    },
    paneExpansionState =
        rememberPaneExpansionState(
            keyProvider = scaffoldNavigator.scaffoldValue,
            anchors = PaneExpansionAnchors
        ),
    paneExpansionDragHandle = { state -> PaneExpansionDragHandleSample(state) }
)
See also
dragToResize

Summary

Public functions

open Unit

Dispatch drag delta in pixels avoiding all drag related priority mechanisms.

Cmn
open suspend Unit
drag(dragPriority: MutatePriority, block: suspend DragScope.() -> Unit)

Call this function to take control of drag logic.

Cmn

Public functions

dispatchRawDelta

open fun dispatchRawDelta(delta: Float): Unit

Dispatch drag delta in pixels avoiding all drag related priority mechanisms.

NOTE: unlike drag, dispatching any delta with this method will bypass scrolling of any priority. This method will also ignore reverseDirection and other parameters set in draggable.

This method is used internally for low level operations, allowing implementers of DraggableState influence the consumption as suits them, e.g. introduce nested scrolling. Manually dispatching delta via this method will likely result in a bad user experience, you must prefer drag method over this one.

Parameters
delta: Float

amount of scroll dispatched in the nested drag process

drag

open suspend fun drag(dragPriority: MutatePriority, block: suspend DragScope.() -> Unit): Unit

Call this function to take control of drag logic.

All actions that change the logical drag position must be performed within a drag block (even if they don't call any other methods on this object) in order to guarantee that mutual exclusion is enforced.

If drag is called from elsewhere with the dragPriority higher or equal to ongoing drag, ongoing drag will be canceled.

Parameters
dragPriority: MutatePriority

of the drag operation

block: suspend DragScope.() -> Unit

to perform drag in