From 294e67064de08a00093f56bd133a6d9a93614853 Mon Sep 17 00:00:00 2001 From: Evan Simkowitz Date: Thu, 26 Feb 2026 15:01:37 -0800 Subject: [PATCH 1/3] fix(mobile): disable KeyboardProvider on Android to fix header inset KeyboardProvider's EdgeToEdgeReactViewGroup intercepts window insets at the root view level and zeros out the status bar top inset on Android. This prevents react-native-screens' CustomToolbar from receiving the correct system bar insets, causing headers to appear cramped against the status bar. Skip KeyboardProvider on Android entirely via a RootKeyboardProvider wrapper. Also remove unnecessary transparent headerStyle background on Android tab layouts. Refs: - https://github.com/kirillzyusko/react-native-keyboard-controller/issues/1013 - https://github.com/kirillzyusko/react-native-keyboard-controller/issues/1292 --- apps/mobile/app/_layout.tsx | 24 +++++++++++++++---- .../dashboard/(tabs)/(highlights)/_layout.tsx | 3 --- .../app/dashboard/(tabs)/(home)/_layout.tsx | 3 --- .../app/dashboard/(tabs)/(lists)/_layout.tsx | 3 --- .../dashboard/(tabs)/(settings)/_layout.tsx | 3 --- .../app/dashboard/(tabs)/(tags)/_layout.tsx | 3 --- apps/mobile/app/dashboard/_layout.tsx | 6 +---- 7 files changed, 20 insertions(+), 25 deletions(-) diff --git a/apps/mobile/app/_layout.tsx b/apps/mobile/app/_layout.tsx index a68fec53b..402d35b00 100644 --- a/apps/mobile/app/_layout.tsx +++ b/apps/mobile/app/_layout.tsx @@ -1,6 +1,7 @@ import "@/globals.css"; import "expo-dev-client"; +import type React from "react"; import { useEffect } from "react"; import { Platform } from "react-native"; import { GestureHandlerRootView } from "react-native-gesture-handler"; @@ -18,6 +19,22 @@ import { cn } from "@/lib/utils"; import { NAV_THEME } from "@/theme"; import { ThemeProvider as NavThemeProvider } from "@react-navigation/native"; +// On Android, KeyboardProvider's EdgeToEdgeReactViewGroup intercepts window insets at +// the root view level, zeroing out the status bar top inset. This prevents the native +// navigation toolbar (react-native-screens' CustomToolbar) from receiving the correct +// system bar insets, resulting in headers appearing cramped against the status bar. +// We skip KeyboardProvider on Android entirely to let the toolbar handle its own insets. +function RootKeyboardProvider({ children }: { children: React.ReactNode }) { + if (Platform.OS === "android") { + return children; + } + return ( + + {children} + + ); +} + export default function RootLayout() { useInitialAndroidBarSync(); const router = useRouter(); @@ -34,10 +51,7 @@ export default function RootLayout() { return ( - + - + Date: Fri, 27 Feb 2026 00:54:39 -0800 Subject: [PATCH 2/3] fix header color regression --- apps/mobile/theme/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/mobile/theme/index.ts b/apps/mobile/theme/index.ts index 05b42bf77..e6061bd60 100644 --- a/apps/mobile/theme/index.ts +++ b/apps/mobile/theme/index.ts @@ -19,7 +19,7 @@ const NAV_THEME = { colors: { background: COLORS.dark.background, border: COLORS.dark.grey5, - card: COLORS.dark.grey6, + card: COLORS.dark.card, notification: COLORS.dark.destructive, primary: COLORS.dark.primary, text: COLORS.white, From 75fb33c8017dfbeedc5bbb0ad34a2be3827562db Mon Sep 17 00:00:00 2001 From: Evan Simkowitz Date: Fri, 27 Feb 2026 08:30:05 -0800 Subject: [PATCH 3/3] revert all transparent header changes --- apps/mobile/app/dashboard/(tabs)/(highlights)/_layout.tsx | 3 +++ apps/mobile/app/dashboard/(tabs)/(home)/_layout.tsx | 3 +++ apps/mobile/app/dashboard/(tabs)/(lists)/_layout.tsx | 3 +++ apps/mobile/app/dashboard/(tabs)/(settings)/_layout.tsx | 3 +++ apps/mobile/app/dashboard/(tabs)/(tags)/_layout.tsx | 3 +++ apps/mobile/app/dashboard/_layout.tsx | 6 +++++- apps/mobile/theme/index.ts | 2 +- 7 files changed, 21 insertions(+), 2 deletions(-) diff --git a/apps/mobile/app/dashboard/(tabs)/(highlights)/_layout.tsx b/apps/mobile/app/dashboard/(tabs)/(highlights)/_layout.tsx index c4f525d22..d0dfafdce 100644 --- a/apps/mobile/app/dashboard/(tabs)/(highlights)/_layout.tsx +++ b/apps/mobile/app/dashboard/(tabs)/(highlights)/_layout.tsx @@ -14,6 +14,9 @@ export default function Layout() { headerLargeStyle: { backgroundColor: "transparent" }, }, android: { + headerStyle: { + backgroundColor: "transparent", + }, contentStyle: { // Manual padding to avoid the native tabbar until expo fixes this in sdk 55. paddingBottom: 100, diff --git a/apps/mobile/app/dashboard/(tabs)/(home)/_layout.tsx b/apps/mobile/app/dashboard/(tabs)/(home)/_layout.tsx index 62bc5c343..b4cb655f1 100644 --- a/apps/mobile/app/dashboard/(tabs)/(home)/_layout.tsx +++ b/apps/mobile/app/dashboard/(tabs)/(home)/_layout.tsx @@ -14,6 +14,9 @@ export default function Layout() { headerLargeStyle: { backgroundColor: "transparent" }, }, android: { + headerStyle: { + backgroundColor: "transparent", + }, contentStyle: { // Manual padding to avoid the native tabbar until expo fixes this in sdk 55. paddingBottom: 100, diff --git a/apps/mobile/app/dashboard/(tabs)/(lists)/_layout.tsx b/apps/mobile/app/dashboard/(tabs)/(lists)/_layout.tsx index 079f1d650..64deea59b 100644 --- a/apps/mobile/app/dashboard/(tabs)/(lists)/_layout.tsx +++ b/apps/mobile/app/dashboard/(tabs)/(lists)/_layout.tsx @@ -14,6 +14,9 @@ export default function Layout() { headerLargeStyle: { backgroundColor: "transparent" }, }, android: { + headerStyle: { + backgroundColor: "transparent", + }, contentStyle: { // Manual padding to avoid the native tabbar until expo fixes this in sdk 55. paddingBottom: 100, diff --git a/apps/mobile/app/dashboard/(tabs)/(settings)/_layout.tsx b/apps/mobile/app/dashboard/(tabs)/(settings)/_layout.tsx index af2dbf262..7bbb7774e 100644 --- a/apps/mobile/app/dashboard/(tabs)/(settings)/_layout.tsx +++ b/apps/mobile/app/dashboard/(tabs)/(settings)/_layout.tsx @@ -14,6 +14,9 @@ export default function Layout() { headerLargeStyle: { backgroundColor: "transparent" }, }, android: { + headerStyle: { + backgroundColor: "transparent", + }, contentStyle: { // Manual padding to avoid the native tabbar until expo fixes this in sdk 55. paddingBottom: 100, diff --git a/apps/mobile/app/dashboard/(tabs)/(tags)/_layout.tsx b/apps/mobile/app/dashboard/(tabs)/(tags)/_layout.tsx index d21c3e2f0..e97bcc4d4 100644 --- a/apps/mobile/app/dashboard/(tabs)/(tags)/_layout.tsx +++ b/apps/mobile/app/dashboard/(tabs)/(tags)/_layout.tsx @@ -14,6 +14,9 @@ export default function Layout() { headerLargeStyle: { backgroundColor: "transparent" }, }, android: { + headerStyle: { + backgroundColor: "transparent", + }, contentStyle: { // Manual padding to avoid the native tabbar until expo fixes this in sdk 55. paddingBottom: 100, diff --git a/apps/mobile/app/dashboard/_layout.tsx b/apps/mobile/app/dashboard/_layout.tsx index fbdbbcfb8..66d175143 100644 --- a/apps/mobile/app/dashboard/_layout.tsx +++ b/apps/mobile/app/dashboard/_layout.tsx @@ -39,7 +39,11 @@ export default function Dashboard() { headerLargeTitleShadowVisible: false, headerLargeStyle: { backgroundColor: "transparent" }, }, - android: {}, + android: { + headerStyle: { + backgroundColor: "transparent", + }, + }, }), headerShadowVisible: false, }} diff --git a/apps/mobile/theme/index.ts b/apps/mobile/theme/index.ts index e6061bd60..05b42bf77 100644 --- a/apps/mobile/theme/index.ts +++ b/apps/mobile/theme/index.ts @@ -19,7 +19,7 @@ const NAV_THEME = { colors: { background: COLORS.dark.background, border: COLORS.dark.grey5, - card: COLORS.dark.card, + card: COLORS.dark.grey6, notification: COLORS.dark.destructive, primary: COLORS.dark.primary, text: COLORS.white,