Toolbar Coordinator
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:
Three lifecycle bindings (Activity, Fragment, Composable) on top of one coordinator (ADR-Toolbar-3).
KMP-readiness at near-zero cost.
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
Properties
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).
Observable frame-level toolbar state (visibility, height, position, title).
Observable, pre-grouped collection of visible and overflow toolbar items.
Functions
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.
Register a listener for ToolbarActions emitted by composables.
Composable-facing: emit a user-initiated action.
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.
Register a click handler for the action identified by actionId.
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.
Counterpart to saveState.
Producer-facing: replace the current frame.
Producer-facing: replace the current items.