android: the editor toolbar was black icons on a near-black bar
Desktop (Tauri) / Windows installer (cross-compiled) (push) Successful in 3m11s
Desktop (Tauri) / Tauri desktop (Linux) (push) Successful in 5m38s
Desktop (Tauri) / Update manifest (push) Successful in 3s
Android / Kotlin + Rust (APK) (push) Successful in 7m54s

Reported as "I'm unable to see a toolbar in the editor on android, is
there one?" — and it was rendering the whole time.

EditorBottomBar passed containerColor but no contentColor, so Material3
defaulted it to contentColorFor(containerColor). That maps a colour-SCHEME
ROLE to its `on-` pair and returns Color.Unspecified for anything else. A
note tint is never a role: the default note is 0xFF171717 while the dark
scheme's surface is 0xFF0A0A0A. So contentColor resolved to Unspecified,
Surface published it as LocalContentColor, Icon took it as its tint, and an
unspecified tint applies no colour filter — leaving the icons-core vectors
their intrinsic black, on a near-black bar.

Every note colour, both themes, only visible in dark. The top bar escaped
it because topAppBarColors(containerColor = …) overrides the container and
leaves the icon colours at their scheme defaults.

Also inset the bar for the keyboard. enableEdgeToEdge makes the manifest's
adjustResize a no-op and Scaffold does not inset its bottomBar slot, so the
bar would sit under the IME the moment anyone typed — a second way to not
see it. imePadding moves to the bar; the content Column drops its own, since
Scaffold now measures the bar at its lifted height and the inset reaches the
content through innerPadding.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-23 17:40:28 -04:00
co-authored by Claude Opus 5
parent 77c5422951
commit 50e2d308ea
2 changed files with 23 additions and 3 deletions
@@ -8,6 +8,7 @@ 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.imePadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
@@ -63,7 +64,24 @@ fun EditorBottomBar(
onAction: (EditorAction) -> Unit,
) {
val dark = isSystemInDarkTheme()
BottomAppBar(containerColor = tint.background(dark)) {
BottomAppBar(
// imePadding so the bar rides above the keyboard. `enableEdgeToEdge` makes
// the manifest's adjustResize a no-op, and Scaffold does not inset its
// bottomBar slot for the IME — without this the bar sits under the keyboard
// the moment anyone types. The content Column deliberately does NOT also
// add imePadding: Scaffold measures this bar at its padded height, so the
// inset already reaches the content through innerPadding.
modifier = Modifier.imePadding(),
containerColor = tint.background(dark),
// EXPLICIT, and not optional. The default is contentColorFor(containerColor),
// which maps a colour-SCHEME ROLE to its `on-` pair and returns Unspecified
// for anything else. A note tint is never a role — the default note is
// 0xFF171717 while the dark scheme's surface is 0xFF0A0A0A — so the default
// resolved to Unspecified, Surface published that as LocalContentColor, and
// Icon drew with no colour filter: black vectors on a near-black bar. The
// toolbar was rendering the whole time and was invisible in dark mode.
contentColor = MaterialTheme.colorScheme.onSurface,
) {
if (!readOnly) {
// A dot in the note's CURRENT colour rather than a palette icon: it
// shows what the colour is as well as what the button does.
@@ -6,7 +6,6 @@ import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
@@ -122,8 +121,11 @@ fun NoteEditorScreen(
modifier =
Modifier
.fillMaxSize()
// No imePadding here: EditorBottomBar carries it, so Scaffold
// measures that bar at its keyboard-lifted height and the inset
// already reaches this Column through `padding`. Adding it again
// would inset for the keyboard twice.
.padding(padding)
.imePadding()
.verticalScroll(rememberScrollState())
.padding(horizontal = 16.dp),
) {