Skip to content

fix: resolve header scroll hide behavior - #1354

Closed
BigSimmo wants to merge 35 commits into
mainfrom
codex/wt-header-scroll-resume
Closed

fix: resolve header scroll hide behavior#1354
BigSimmo wants to merge 35 commits into
mainfrom
codex/wt-header-scroll-resume

Conversation

@BigSimmo

@BigSimmo BigSimmo commented Jul 28, 2026

Copy link
Copy Markdown
Owner

Summary

  • Fix header and search-shell hide/reveal behavior on scroll for mobile/desktop composer interactions.

RAG impact

  • RAG impact: no retrieval behaviour change

Summary by CodeRabbit

  • Bug Fixes

    • Improved mobile answer navigation and composer focus behavior.
    • Prevented headers and composers from flickering or revealing unexpectedly when scrolling or when layout geometry changes.
    • Kept related header and composer controls visible while interacting with either surface.
    • Improved hide-on-scroll behavior across phone and wider layouts.
  • Enhancements

    • Added flexible wide-screen header behavior, allowing it to collapse or remain sticky above phone-sized breakpoints.
    • Refined mobile composer spacing and scroll transitions for smoother interactions.

cursoragent and others added 30 commits July 25, 2026 04:00
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
…scroll-5b1d' into cursor/fix-mobile-composer-edge-scroll-5b1d

Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
@supabase

supabase Bot commented Jul 28, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project sjrfecxgysukkwxsowpy because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds geometry-aware scroll-hide metrics and clamp handling, supports wide header collapse modes, coordinates header/composer pinning, improves composer autofocus retention, updates scroll-reporting wiring, and adds unit, UI, documentation, and verification coverage.

Changes

Mobile chrome scroll and focus behavior

Layer / File(s) Summary
Geometry-aware scroll metrics and state
src/components/clinical-dashboard/use-hide-on-scroll.ts, tests/use-hide-on-scroll.test.ts, docs/search-chrome-behaviour.md, src/components/clinical-dashboard/mobile-composer-reserve.ts, tests/mobile-composer-reserve.test.ts
Collapse metrics now include collapse kind, scroll-range changes prevent false reveals, reporter baselines reset on context changes, and reserve-only behavior is covered by tests and invariants.
Header collapse and shared pinning
src/components/clinical-dashboard/master-search-header.tsx
hideOnScroll.wide supports collapse or sticky behavior, while shared header/composer pinning controls both chrome edges.
Composer focus and scroll reporting integration
src/components/ClinicalDashboard.tsx, src/components/clinical-dashboard/global-search-shell.tsx
Composer autofocus is derived centrally, URL bootstrapping can retain its requested target, and scroll handlers pass complete collapse metrics.
End-to-end mobile behavior validation
tests/ui-smoke.spec.ts, docs/branch-review-ledger.md
A phone answer-flow test validates dock geometry, hide/reveal transitions, reserve spacing, and focus restoration; verification records are appended to the ledger.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

Suggested labels: codex

Suggested reviewers: cursoragent, claude

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description is missing the required Verification section and template checkboxes, so it is largely incomplete. Add the template sections, especially Verification, and include the relevant verify:pr-local and verify:ui checkboxes with any notes.
Docstring Coverage ⚠️ Warning Docstring coverage is 71.43% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title matches the main change by describing scroll hide behavior fixes, though it omits the search-shell detail.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ac14e66e56

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

* cannot scroll (the phone shell is `fixed inset-0`) no scroll event arrives,
* so the internal scroller stays the single source at that width.
*/
export function useDocumentScrollHideReporter(reportScroll: (metrics: ScrollMetrics) => void) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Wire the desktop shell into the new scroll reporter

At viewport widths of 640px or greater, GlobalSearchShell hands scrolling to the document, but it still creates useScrollHideReporter() with the default phone-only gate and never invokes this newly added useDocumentScrollHideReporter; it also passes no wide: "sticky" option to MasterSearchHeader. Consequently, document scrolling can never update the hidden state and the new desktop sticky/transform branch is unreachable. A Playwright check that scrolls window on a desktop standalone-shell route and expects the header's data-scroll-hidden attribute would catch this.

Useful? React with 👍 / 👎.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/components/clinical-dashboard/use-hide-on-scroll.ts (1)

199-217: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

collapseKind ignores the grid-display test that gates headerRelease.

headerRelease is only counted when the collapse wrapper computes to display: grid, but collapseKind is "in-flow" whenever the element merely exists. For the wide: "sticky" host (GlobalSearchShell above the phone breakpoint) the wrapper is present but sticky/translating, so headerRelease is 0 and the only budget is bottom reserve — yet the stricter in-flow runway gate is applied instead of the reserve-only path. Deriving the kind from the same condition keeps the two halves consistent.

🔧 Proposed fix
-  const headerRelease =
-    collapse instanceof HTMLElement && window.getComputedStyle(collapse).display === "grid"
-      ? collapse.getBoundingClientRect().height
-      : 0;
+  const collapsesInFlow = collapse instanceof HTMLElement && window.getComputedStyle(collapse).display === "grid";
+  const headerRelease = collapsesInFlow ? collapse.getBoundingClientRect().height : 0;
@@
   return {
     collapseBudget: headerRelease + reserveRelease,
-    collapseKind: collapse instanceof HTMLElement ? "in-flow" : reserveRelease > 0 ? "reserve-only" : undefined,
+    collapseKind: collapsesInFlow ? "in-flow" : reserveRelease > 0 ? "reserve-only" : undefined,
   };
🤖 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/use-hide-on-scroll.ts` around lines 199 -
217, Update the collapseKind derivation in the surrounding scroll-budget logic
to use the same HTMLElement-and-computed-display-grid condition that enables
headerRelease, rather than element existence alone. Return "in-flow" only when
that condition is true; otherwise preserve "reserve-only" when reserveRelease is
positive and undefined when it is not.
src/components/clinical-dashboard/master-search-header.tsx (1)

367-392: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

composerChromeFocused never gets set in the wide hideOnScroll paths. composerFocusProps is only attached to the phone footer dock, so a focused sm+ composer won’t pin the header and can scroll under it. Attach the focus handlers to the sm+ composer placement too.

🤖 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/master-search-header.tsx` around lines 367
- 392, The wide-screen composer placement must participate in shared focus
pinning. Update the sm+ composer rendering path to attach the existing
composerFocusProps handlers, not only the phone footer dock, so
composerChromeFocused is set while the composer is focused and prevents header
hiding during hideOnScroll.
🧹 Nitpick comments (1)
tests/ui-smoke.spec.ts (1)

2139-2151: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider extracting the repeated geometry-probe evaluate() closures into shared helpers.

edgeGeometry, geometry, and settledHiddenGeometry each define an inline DOM-evaluation closure. This matches the pattern already established in tests/playwright-scroll.ts (readMobileComposerReservePx, scrollPrimarySurface), which this same test already imports. Extracting these three closures there would reduce duplication and the flagged complexity of this block, and make them reusable for future phone-chrome tests.

Based on the line-range change details noting [code_block_complexity_high] for this segment.

Also applies to: 2163-2170, 2190-2201

🤖 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 `@tests/ui-smoke.spec.ts` around lines 2139 - 2151, Extract the repeated DOM
geometry probes from the edgeGeometry, geometry, and settledHiddenGeometry
evaluate closures into shared helpers in the existing tests/playwright-scroll.ts
utility module. Reuse those helpers in tests/ui-smoke.spec.ts while preserving
each probe’s returned measurements and the current test behavior.
🤖 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.

Outside diff comments:
In `@src/components/clinical-dashboard/master-search-header.tsx`:
- Around line 367-392: The wide-screen composer placement must participate in
shared focus pinning. Update the sm+ composer rendering path to attach the
existing composerFocusProps handlers, not only the phone footer dock, so
composerChromeFocused is set while the composer is focused and prevents header
hiding during hideOnScroll.

In `@src/components/clinical-dashboard/use-hide-on-scroll.ts`:
- Around line 199-217: Update the collapseKind derivation in the surrounding
scroll-budget logic to use the same HTMLElement-and-computed-display-grid
condition that enables headerRelease, rather than element existence alone.
Return "in-flow" only when that condition is true; otherwise preserve
"reserve-only" when reserveRelease is positive and undefined when it is not.

---

Nitpick comments:
In `@tests/ui-smoke.spec.ts`:
- Around line 2139-2151: Extract the repeated DOM geometry probes from the
edgeGeometry, geometry, and settledHiddenGeometry evaluate closures into shared
helpers in the existing tests/playwright-scroll.ts utility module. Reuse those
helpers in tests/ui-smoke.spec.ts while preserving each probe’s returned
measurements and the current test behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 73de6cc7-bad8-4f15-a58f-89e24067c5db

📥 Commits

Reviewing files that changed from the base of the PR and between b92c272 and ac14e66.

📒 Files selected for processing (10)
  • docs/branch-review-ledger.md
  • docs/search-chrome-behaviour.md
  • src/components/ClinicalDashboard.tsx
  • src/components/clinical-dashboard/global-search-shell.tsx
  • src/components/clinical-dashboard/master-search-header.tsx
  • src/components/clinical-dashboard/mobile-composer-reserve.ts
  • src/components/clinical-dashboard/use-hide-on-scroll.ts
  • tests/mobile-composer-reserve.test.ts
  • tests/ui-smoke.spec.ts
  • tests/use-hide-on-scroll.test.ts

@BigSimmo

Copy link
Copy Markdown
Owner Author

Reviewed at exact head ac14e66. No replacement hunk. The near-bottom clamp was destructive and current main already has the safer scroll contract. Source branch and worktree are preserved; this PR is closed only to remove the superseded review queue entry.

@BigSimmo BigSimmo closed this Jul 28, 2026
@BigSimmo
BigSimmo deleted the codex/wt-header-scroll-resume branch July 30, 2026 09:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants