fix(sidebar): let the org/project picker scroll on touch - #7013
Closed
tlgimenes wants to merge 1 commit into
Closed
Conversation
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
force-pushed
the
claude/compressed-painting-koala
branch
from
September 4, 2026 19:36
8ada66b to
d726fb6
Compare
Contributor
Author
|
Superseded by #7019, which now targets |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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) callspreventDefault()on every wheel and touchmove landing outside the dialog's own DOM subtree. The picker's popover is portalled todocument.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 inpage-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.
Commanddeclaredmax-h-[min(560px,70dvh)], butCommandList's sharedmax-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-heightso a picker opened low on a short screen ends where the screen does.Testing
Built a throwaway page against the real
Sheet+PopoverContent+Commandcomponents, drove it in Chrome, and dispatched a real touch sequence over the list:touchmoveprevented?modal)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.tsxonly. Desktop is unaffected by the lock (the sidebar is not a dialog there);modalon 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 ish-dvh overflow-hiddenand the body never scrolls.Follow-ups (not in this PR)
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.dvhtracks 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 separatevisualViewportjob.🤖 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;modalthere only closes the popover on outside click without activating the element behind it.Written for commit d726fb6. Summary will update on new commits.