ToolbarCoordinator

class ToolbarCoordinator(scope: CoroutineScope, initialFrame: ToolbarFrame = ToolbarFrame.Default, initialItems: ToolbarItems = ToolbarItems.Empty, restoreSnapshot: Map<String, Any>? = null)

Host-agnostic toolbar state container.

No Android imports allowed in this file or in any file under compose/toolbar/state/ and compose/toolbar/adapter/. The ToolbarSharedPackageLeak lint rule (MOD-4) enforces this at build time. Keeping this surface pure Kotlin is what gives us:

  1. Three lifecycle bindings (Activity, Fragment, Composable) on top of one coordinator (ADR-Toolbar-3).

  2. KMP-readiness at near-zero cost.

  3. Unit-testability without Robolectric — just inject a TestScope.

Owners:

  • ComponentActivity.nutrientToolbarCoordinator() (fragment flavor)

  • Fragment.nutrientToolbarCoordinator() (fragment flavor)

  • rememberNutrientToolbarCoordinator() (compose, shared)

Pre-Phase 0 scaffolding (ADR-Toolbar-3, loophole P0-3).

Constructors

Link copied to clipboard
constructor(scope: CoroutineScope, initialFrame: ToolbarFrame = ToolbarFrame.Default, initialItems: ToolbarItems = ToolbarItems.Empty, restoreSnapshot: Map<String, Any>? = null)

Properties

Link copied to clipboard

Identity of the binder currently authorized to write through this coordinator. null means no binder is bound — actions registered in that state are unbound and survive writer swaps (used for test setup and pipeline-stage registrations).

Link copied to clipboard
val frame: StateFlow<ToolbarFrame>

Observable frame-level toolbar state (visibility, height, position, title).

Link copied to clipboard
val items: StateFlow<ToolbarItems>

Observable, pre-grouped collection of visible and overflow toolbar items.

Functions

Link copied to clipboard
fun acquireWriter(writerId: Any)

Claim the active-writer slot for writerId. Last-acquirer wins: any actions registered by the previous writer are evicted from the registry. Unbound registrations survive.

Link copied to clipboard

Register a listener for ToolbarActions emitted by composables.

Link copied to clipboard
fun close()

Tear down the coordinator. After close the scope is no longer used, all listeners are cleared, and any further dispatch call is a no-op.

Link copied to clipboard
fun dispatch(action: ToolbarAction)

Composable-facing: emit a user-initiated action.

Link copied to clipboard
fun dispatchAction(actionId: String)

Invoke the lambda registered for actionId, if any. Silent no-op when no registration exists — pipeline stages can fire actions during initial render before binders have registered, and that must not crash.

Link copied to clipboard
fun registerAction(actionId: String, action: () -> Unit): ToolbarSubscription

Register a click handler for the action identified by actionId.

Link copied to clipboard
fun releaseWriter(writerId: Any)

Release the active-writer slot iff writerId is currently the active writer. Calls from non-active writers (a stale PdfFragment binder that already lost its slot to a swap) are silent no-ops.

Link copied to clipboard
fun restoreState(state: Map<String, Any>)

Counterpart to saveState.

Link copied to clipboard

Snapshot for process-death restoration.

Link copied to clipboard

Producer-facing: replace the current frame.

Link copied to clipboard

Producer-facing: replace the current items.