fix(ui): keep phone status-bar safe-area when header collapses#1234
Conversation
Hide-on-scroll was reclaiming the entire header including the OS top inset, so scrolled service-detail text painted under the system status bar. Keep an always-on chrome-safe-area-top spacer outside the 0fr / translate hide path, and guard it with contract + phone Playwright proof. Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
|
This pull request has been ignored for the connected project Preview Branches by Supabase. |
📝 WalkthroughWalkthroughThe search chrome contract now preserves the top OS safe-area band during header collapse, releases composer focus in submitted result views, uses shared bottom safe-area calculations for dock hiding, and adds contract and mobile UI coverage. ChangesSearch chrome behavior
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
CI triageCI failed on this PR. Automated classification of the 3 failed job(s):
Compared with main CI run #5694 (success). Classification is evidence routing, not permission to ignore a failure. Exact quarantined Playwright identities remain governed by the flake ledger. |
Keep the status-bar band above the 0fr header's upward layout box and assert geometry (main/content top >= safe-area) instead of hit-testing through the spacer. Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Submitted shell searches kept focus=1 on the dock input, which pins both chrome edges and leaves the header plus bottom white safe-area rail stuck visible. Stop carrying focus into run=1 views, blur on result scroll, and clear the hidden dock with var(--safe-area-bottom). Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/components/clinical-dashboard/global-search-shell.tsx (1)
548-594: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDuplicated blur-on-scroll threshold logic.
The same condition (
target.scrollTop > 8 && inputRef.current && document.activeElement === inputRef.current→ blur) appears in bothhandleMainScroll(Lines 553-555) and the nested-scrolleronScrollCapture(Lines 579-581). Consider extracting a small helper (e.g.blurComposerIfPastThreshold(target)) so the two sites can't drift if the threshold or condition changes later.♻️ Proposed refactor
+ function blurComposerIfPastThreshold(target: HTMLElement) { + if (target.scrollTop > 8 && inputRef.current && document.activeElement === inputRef.current) { + inputRef.current.blur(); + } + } + function handleMainScroll(event: UIEvent<HTMLDivElement>) { const target = event.currentTarget; - if (target.scrollTop > 8 && inputRef.current && document.activeElement === inputRef.current) { - inputRef.current.blur(); - } + blurComposerIfPastThreshold(target); chromeScrollHide.reportScroll({...}); }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/clinical-dashboard/global-search-shell.tsx` around lines 548 - 594, Extract the shared focus-release condition from handleMainScroll and the nested-scroller onScrollCapture callback into a small helper such as blurComposerIfPastThreshold, accepting the scroll target and performing the existing blur behavior. Replace both duplicated conditionals with calls to this helper while preserving the current threshold and focus checks.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@src/components/clinical-dashboard/global-search-shell.tsx`:
- Around line 548-594: Extract the shared focus-release condition from
handleMainScroll and the nested-scroller onScrollCapture callback into a small
helper such as blurComposerIfPastThreshold, accepting the scroll target and
performing the existing blur behavior. Replace both duplicated conditionals with
calls to this helper while preserving the current threshold and focus checks.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 9e6664ad-426e-4cae-8d18-0da451f5ce59
📒 Files selected for processing (6)
docs/search-chrome-behaviour.mdsrc/app/globals.csssrc/components/clinical-dashboard/global-search-shell.tsxsrc/components/clinical-dashboard/master-search-header.tsxtests/header-scroll-hide-contract.test.tstests/ui-phone-scroll.spec.ts
Summary
Two phone chrome bugs from the user’s Forms / service screenshots:
focus=1on the dock. Composer focus pins both chrome edges, so hide-on-scroll never fired and the bottom white safe-area rail stayed on screen.env(safe-area-inset-bottom)while the visible pad usedvar(--safe-area-bottom), so a white rail could peep; also covered by the same focus/scroll release path when the detail footer search is shown.Also keeps the earlier top status-bar safe-area spacer so collapsed headers never release the OS inset.
Fixes
GlobalSearchShell: do not passfocus: truewithrun: true; gate autofocus on!hasSubmittedModeSearch; blur on submitted views and when the result canvas scrollsvar(--safe-area-bottom)chrome-safe-area-topoutside the collapse/translate hide pathForms results after scroll — header and footer dock hidden
Test plan
npx vitest run tests/header-scroll-hide-contract.test.ts(12/12)npm run test:e2e -- tests/ui-phone-scroll.spec.ts -g "forms search hides|status-bar inset" --project=chromium(2/2)verify:uibefore merge if desiredRAG impact: no retrieval behaviour change — UI chrome focus/safe-area only.
To show artifacts inline, enable in settings.
Summary by CodeRabbit
Bug Fixes
Documentation