Skip to content

fix(sidebar): let the org/project picker scroll on touch - #7013

Closed
tlgimenes wants to merge 1 commit into
mainfrom
claude/compressed-painting-koala
Closed

fix(sidebar): let the org/project picker scroll on touch#7013
tlgimenes wants to merge 1 commit into
mainfrom
claude/compressed-painting-koala

Conversation

@tlgimenes

@tlgimenes tlgimenes commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Summary

Reported from a phone: the org/project picker menu would not scroll.

Two defects, one visible:

1. Touch scroll was being cancelled. On mobile the sidebar is a Radix Sheet — a modal dialog — whose scroll lock (react-remove-scroll) calls preventDefault() on every wheel and touchmove landing outside the dialog's own DOM subtree. The picker's popover is portalled to document.body, so it is outside: the list clipped at its max height and would not move under a finger. The repo already knew this failure mode for wheel and patched it by hand in page-template-select.tsx:87.

Fix: <Popover ... modal>. A modal popover installs its own lock, only the innermost lock acts, and that one counts the list as scrollable. It also restores the menu semantics this control inherited from the dropdown it replaced.

2. The height cap above it was dead code. Command declared max-h-[min(560px,70dvh)], but CommandList's shared max-h-[300px] default is smaller — so the picker was always ~373px tall whatever that number said. The list now takes the Command's budget (max-h-none min-h-0 flex-1), and the budget clamps to --radix-popover-content-available-height so a picker opened low on a short screen ends where the screen does.

Testing

Built a throwaway page against the real Sheet + PopoverContent + Command components, drove it in Chrome, and dispatched a real touch sequence over the list:

touchmove prevented?
before (non-modal) true → cannot scroll
after (modal) false → scrolls
after, list at its end true → no scroll chaining to the page behind

Layout after the change at an 806px viewport: Command 560px, input keeps its full 40px, verb strip 33px, list 487px and scrollable — nothing is squeezed. The repro page is not part of this diff.

bun run fmt, bun run lint (0 errors), tsc --noEmit, and the 89 sidebar unit tests pass.

Affected areas

apps/web/src/components/sidebar/org-project-picker.tsx only. Desktop is unaffected by the lock (the sidebar is not a dialog there); modal on desktop means the first outside click closes the popover without also activating what it hit, which is how the dropdown this replaced already behaved. No scrollbar-gap shift, because the org shell is h-dvh overflow-hidden and the body never scrolls.

Follow-ups (not in this PR)

  • The account popover (account-popover.tsx:601) and the inbox popover (sidebar/footer/inbox.tsx:134) sit in the same mobile sheet and carry the identical latent bug — the inbox one has a real scrolling list. One line each.
  • With the on-screen keyboard open no CSS unit shrinks (dvh tracks the layout viewport, not the visual one), so a tall popover can still extend under the keyboard. Typing filters the list, which makes it mostly moot; a real fix is a separate visualViewport job.

🤖 Generated with Claude Code

https://claude.ai/code/session_01AVd1o11cJLXR7HPSTyuyBC


Summary by cubic

Fixes the org/project picker so it scrolls on touch in the mobile sidebar. The picker's popover is now modal, so its own scroll lock handles the list instead of the sheet's lock canceling touch events on the portalled popover. The list also now respects the Command's height budget (max-h-none min-h-0 flex-1), removing a dead cap that pinned the picker to ~373px regardless of the set maximum. Desktop behavior is unchanged; modal there only closes the popover on outside click without activating the element behind it.

Written for commit d726fb6. Summary will update on new commits.

Review in cubic

On mobile the sidebar is a Radix Sheet — a modal dialog — and its scroll
lock (react-remove-scroll) calls preventDefault() on every wheel and
touchmove that lands outside the dialog's own subtree. The picker's
popover is portalled to the body, so it is outside: the list clipped at
its max height and would not move under a finger. The repo already knew
this failure mode for wheel (page-template-select.tsx patches it by
hand). Making the popover modal gives it its own lock — only the
innermost lock acts, and that one counts the list as scrollable — and it
restores the menu semantics this control inherited from the dropdown it
replaced.

While in there: the Command's max-h-[min(560px,70dvh)] was dead, because
CommandList's shared 300px default is smaller, so the picker was always
~373px tall whatever that number said. The list now takes the Command's
budget, and the budget clamps to --radix-popover-content-available-height
so a picker opened low on a short screen ends where the screen does.

Verified against the real Sheet + PopoverContent + Command components in
Chrome with a dispatched touch sequence over the list: touchmove is
prevented before the change, allowed after, and still prevented once the
list reaches its end, so nothing chains to the page behind. Layout at an
806px viewport: Command 560, input 40, strip 33, list 487 and scrollable.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AVd1o11cJLXR7HPSTyuyBC
@tlgimenes
tlgimenes force-pushed the claude/compressed-painting-koala branch from 8ada66b to d726fb6 Compare September 4, 2026 19:36
@tlgimenes

Copy link
Copy Markdown
Contributor Author

Superseded by #7019, which now targets main and carries this commit plus the rest of the mobile rework. Nothing is lost — the scroll fix is the first of the three commits there.

@tlgimenes tlgimenes closed this Sep 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

claude PR authored by a coding agent

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant