fix(client): inset the native sidebar below the status bar #296

Merged
james merged 1 commit from 295-sidebar-safe-area into main 2026-06-26 22:29:00 +00:00
Owner

The native navigation sidebar slid out over the system status bar — the Carol brand row overlapped the clock/battery/signal area.

Cause

The drawer surface paints from y=0 (under Android's translucent status bar / behind the iOS notch), but the Sidebar root container (apps/client/lib/nav/Sidebar.tsx) used only paddingVertical: 16 and never consumed useSafeAreaInsets(). The in-scene MobileHeader in app/(app)/_layout.tsx already insets correctly; the drawer didn't.

Fix

Add useSafeAreaInsets() and set the sidebar container paddingTop = 16 + insets.top, mirroring the header's pattern. react-native-safe-area-context is already a dep and SafeAreaProvider is already mounted at the root.

Correct on all targets

  • Android / iOS: insets.top (status-bar height / notch) pushes content clear; the inset strip still fills with the themed surface, so no content sits under the clock.
  • Web: insets.top is 0 → paddingTop collapses to the existing 16; the permanent (≥720px) and narrow-web slide-in sidebars are unchanged.

Top-only, matching the reported bug and the MobileHeader precedent (bottom inset out of scope).

Verification

  • pnpm -F @carol/client typecheck — passes.
  • Manual: open the drawer on Android — brand row now sits below the status bar.

Closes #295

🤖 Generated with Claude Code

The native navigation sidebar slid out **over the system status bar** — the Carol brand row overlapped the clock/battery/signal area. ## Cause The drawer surface paints from `y=0` (under Android's translucent status bar / behind the iOS notch), but the `Sidebar` root container (`apps/client/lib/nav/Sidebar.tsx`) used only `paddingVertical: 16` and never consumed `useSafeAreaInsets()`. The in-scene `MobileHeader` in `app/(app)/_layout.tsx` already insets correctly; the drawer didn't. ## Fix Add `useSafeAreaInsets()` and set the sidebar container `paddingTop = 16 + insets.top`, mirroring the header's pattern. `react-native-safe-area-context` is already a dep and `SafeAreaProvider` is already mounted at the root. ## Correct on all targets - **Android / iOS:** `insets.top` (status-bar height / notch) pushes content clear; the inset strip still fills with the themed surface, so no content sits under the clock. - **Web:** `insets.top` is 0 → `paddingTop` collapses to the existing 16; the permanent (≥720px) and narrow-web slide-in sidebars are unchanged. Top-only, matching the reported bug and the `MobileHeader` precedent (bottom inset out of scope). ## Verification - `pnpm -F @carol/client typecheck` — passes. - Manual: open the drawer on Android — brand row now sits below the status bar. Closes #295 🤖 Generated with [Claude Code](https://claude.com/claude-code)
fix(client): inset the native sidebar below the status bar
Some checks failed
Commits / Conventional Commits (pull_request) Successful in 7s
PR / OSV-Scanner (pull_request) Successful in 1m15s
PR / Static analysis (pull_request) Successful in 2m14s
PR / pnpm audit (pull_request) Successful in 2m31s
PR / Typecheck (pull_request) Successful in 2m31s
PR / Client (web export smoke) (pull_request) Successful in 2m41s
PR / Lint (pull_request) Successful in 2m51s
PR / Build (pull_request) Successful in 3m0s
PR / Test (sqlite) (pull_request) Successful in 3m0s
PR / OpenAPI (pull_request) Successful in 3m8s
PR / Test (postgres) (pull_request) Failing after 3m44s
PR / Package age policy (soft) (pull_request) Successful in 1m10s
Secrets / gitleaks (pull_request) Successful in 1m11s
PR / Trivy (image) (pull_request) Successful in 2m31s
PR / Coverage (soft) (pull_request) Successful in 2m9s
dfa3748b1c
The drawer surface paints from y=0 (under Android's translucent status
bar / behind the iOS notch), but the Sidebar root only used
paddingVertical: 16 and never consumed the safe-area inset, so the brand
row slid out over the system clock/battery area. Add useSafeAreaInsets()
and set the container paddingTop to 16 + insets.top, mirroring the
MobileHeader inset handling in app/(app)/_layout.tsx. On web insets.top
is 0, so the permanent and narrow-web sidebars are unchanged.

Closes #295

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
james merged commit f12fffaf85 into main 2026-06-26 22:29:00 +00:00
james deleted branch 295-sidebar-safe-area 2026-06-26 22:29:01 +00:00

📊 Test coverage

Patch coverage: no testable lines changed.

Overall (app/, lib/, db/, excluding UI per ADR-0019):

Metric Value Soft target
Lines 81.6% ≥ 50%
Branches 72.8% ⚠️ ≥ 75%
Functions 91.1% informational

Soft thresholds per ADR-0019. Coverage is informational and does not block merge.

<!-- coverage-comment --> ## 📊 Test coverage **Patch coverage:** no testable lines changed. **Overall** (`app/`, `lib/`, `db/`, excluding UI per ADR-0019): | Metric | Value | Soft target | |---|---|---| | Lines | 81.6% ✅ | ≥ 50% | | Branches | 72.8% ⚠️ | ≥ 75% | | Functions | 91.1% | informational | Soft thresholds per [ADR-0019](docs/adr/0019-coverage-soft-targets.md). Coverage is informational and does not block merge.
Sign in to join this conversation.
No description provided.