Skip to content

feat(mobile): scroll the page instead of main so mobile toolbars collapse - #535

Open
yhabib wants to merge 5 commits into
ux/glass-bottom-navfrom
ux/mobile-document-scroll
Open

yhabib wants to merge 5 commits into
ux/glass-bottom-navfrom
ux/mobile-document-scroll

Conversation

@yhabib

@yhabib yhabib commented Oct 20, 2026 •

Copy link
Copy Markdown
Collaborator

Motivation

On mobile, main was the scroller, so the browser toolbars never collapsed. In iPhone Safari a swipe scrolled main by 464 px while window.scrollY stayed 0, and the Safari toolbar stayed full size under the floating bottom nav.

With the document as the scroller, the visible height goes from 714 to 754 px in iOS 26 Safari and from 813 to 869 px in Chrome 155 on Android after one swipe.

Changes

  • Switched the scroller below lg from main to the document, and made the bottom nav fixed. Desktop keeps main as the scroller.
  • Moved the sticky offset of the vote bar above the bottom nav, and pointed its IntersectionObserver at the scroller in use.
  • Reset the window scroll too when the page changes.
  • Froze the scrolled document while a drawer is open, so a swipe down still closes it on a scrolled page.
  • Added tests for the drawer scroll lock and the observer root.

Screenshots

Before After
iOS Safari after one swipe before the change iOS Safari after one swipe after the change
Android Chrome after one swipe before the change Android Chrome after one swipe after the change
ios-proposal-prototype.mp4

Prev. #503

Mobile browsers collapse their toolbars only when the document scrolls.
Below lg, the document is now the scroller and the bottom nav is fixed.
The vote bar sticks above the bottom nav and observes the viewport.
Desktop keeps main as the scroller.
vaul does not start a drag when the document is scrolled. A drawer that
opened on a scrolled page did not close on a swipe down.
@yhabib
yhabib requested a review from a team as a code owner October 20, 2026 14:34
@zeropath-ai

zeropath-ai Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

✅ No security or compliance issues detected. Reviewed everything up to a9b9ca7.

Security Overview
Detected Code Changes
Change Type Relevant files
Enhancement ► src/governance-app-frontend/src/app/styles/main.css
    On desktop main is the scroller, so the document must not scroll.
Enhancement ► src/governance-app-frontend/src/common/components/Drawer.tsx
    Introduce DocumentScrollLock to freeze document scroll when drawer is open; render Drawer with noBodyStyles and include DocumentScrollLock.
Enhancement ► src/governance-app-frontend/src/common/components/MainLayout.tsx
    Update layout classes to support responsive scrolling behavior and new structure.
Enhancement ► src/governance-app-frontend/src/common/components/navigation/BottomNav.tsx
    Change bottom navigation positioning from absolute to fixed for certain viewports.
Enhancement ► src/governance-app-frontend/src/common/hooks/useScrollResetOnNavigation.ts
    Reset scroll on navigation for both main element and window.
Enhancement ► src/governance-app-frontend/src/features/proposals/components/ProposalDetailsVoting.tsx
    Modify docking footer logic to account for desktop vs mobile scrolling and follow main element changes.
Enhancement ► src/governance-app-frontend/src/features/proposals/components/ProposalDetailsVoting.test.tsx
    Adjust tests to reflect new scrolling behavior and container setup for main vs document scrolling.
Enhancement ► src/governance-app-frontend/src/routes/_auth/voting/proposals/$id/index.tsx
    Update sticky header container class to align with new safe-area and layout behavior

@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

📊 Build Bundle Stats

The latest build generated the following assets:

dist/index.html                                           5.86 kB │ gzip:   1.66 kB
dist/assets/index-lovToSUA.css                          158.89 kB │ gzip:  25.25 kB
dist/assets/icpLedger-2_GW0mmS.js                         0.23 kB │ gzip:   0.21 kB
dist/assets/Skeleton-CtBqCSR2.js                          0.44 kB │ gzip:   0.32 kB
dist/assets/webhid-D0yio6wG.js                            0.53 kB │ gzip:   0.32 kB
dist/assets/useTvlValue-DLJ6m2Eo.js                       0.60 kB │ gzip:   0.41 kB
dist/assets/nnsDapp-CGLmk-14.js                           0.68 kB │ gzip:   0.25 kB
dist/assets/SkeletonPageHeader-BfERjs16.js                0.76 kB │ gzip:   0.47 kB
dist/assets/PageHeader-jXzaR6sL.js                        0.77 kB │ gzip:   0.45 kB
dist/assets/CertifiedBadge-C-SJZ8Mj.js                    0.81 kB │ gzip:   0.48 kB
dist/assets/Separator-C-JM8RLT.js                         0.83 kB │ gzip:   0.50 kB
dist/assets/SkeletonStatCard-DkLSZf5-.js                  0.91 kB │ gzip:   0.56 kB
dist/assets/useForecastPeriod-txCEyjYg.js                 0.98 kB │ gzip:   0.60 kB
dist/assets/utils-1-JYkHZX.js                             1.02 kB │ gzip:   0.59 kB
dist/assets/useIcpIndex-By6eBKME.js                       1.09 kB │ gzip:   0.64 kB
dist/assets/numbers-CnzvcvZN.js                           1.15 kB │ gzip:   0.57 kB
dist/assets/routeLoaders-DvEt3Z2X.js                      1.19 kB │ gzip:   0.56 kB
dist/assets/rolldown-runtime-DAXXjFlN.js                  1.26 kB │ gzip:   0.70 kB
dist/assets/advancedFeatures-Cy6f4g3-.js                  1.50 kB │ gzip:   0.74 kB
dist/assets/events-ANLkBwUF.js                            1.66 kB │ gzip:   0.86 kB
dist/assets/useLedgerNeuronCall-CA4XZ1N5.js               1.89 kB │ gzip:   1.03 kB
dist/assets/errors-C_oENL0S.js                            1.95 kB │ gzip:   0.97 kB
dist/assets/AnimatedNumber-CF0IzNGF.js                    1.98 kB │ gzip:   1.13 kB
dist/assets/useCommandPaletteSettings-BISXzHAO.js         2.13 kB │ gzip:   1.06 kB
dist/assets/addressBook-D8NF1Zyn.js                       2.14 kB │ gzip:   1.20 kB
dist/assets/useIcpIndexTransactionsPolling-CsVz8KII.js    2.15 kB │ gzip:   1.15 kB
dist/assets/useGovernanceAppCanister-BtQ8HW9J.js          2.29 kB │ gzip:   1.04 kB
dist/assets/useShortcutSettings-BBzFimfu.js               2.41 kB │ gzip:   1.19 kB
dist/assets/useAddHotkey-Dxf5NiIT.js                      2.61 kB │ gzip:   1.34 kB
dist/assets/governance-QRVeTT8A.js                        2.99 kB │ gzip:   1.15 kB
dist/assets/useClaimPendingDeviceStakes-DZ1_hKQA.js       3.12 kB │ gzip:   1.42 kB
dist/assets/SkeletonText-BeO03Ex1.js                      3.71 kB │ gzip:   1.29 kB
dist/assets/ToggleGroup-B_Wt7F7C.js                       4.72 kB │ gzip:   1.76 kB
dist/assets/useAccounts-DH12uDth.js                       4.96 kB │ gzip:   2.21 kB
dist/assets/tickers-CS4YoidN.js                           6.04 kB │ gzip:   2.65 kB
dist/assets/useNowInSeconds-M67LrFfl.js                   7.13 kB │ gzip:   3.04 kB
dist/assets/DeviceActionDetail-B2pemSUM.js                7.95 kB │ gzip:   2.87 kB
dist/assets/TopicFollowingAccordion-xhHbXlc6.js           8.55 kB │ gzip:   3.41 kB
dist/assets/routes-3nNYZKXc.js                            8.96 kB │ gzip:   3.07 kB
dist/assets/AlertDialog-B0cQoXqF.js                       8.99 kB │ gzip:   3.16 kB
dist/assets/ledgerIdentity-CbGbEww2.js                   10.16 kB │ gzip:   3.70 kB
dist/assets/spamFilter-CCRb5WHo.js                       11.71 kB │ gzip:   5.00 kB
dist/assets/MutationDialog-D-8pLZ9g.js                   11.95 kB │ gzip:   4.08 kB
dist/assets/ResponsiveDialog-D4xG791T.js                 15.17 kB │ gzip:   4.34 kB
dist/assets/_id-CysQPDJo.js                              16.71 kB │ gzip:   5.38 kB
dist/assets/AmountInput-VsA55N4e.js                      16.85 kB │ gzip:   6.73 kB
dist/assets/_auth-CqTCLTdx.js                            22.52 kB │ gzip:   8.30 kB
dist/assets/HideBalancesToggle-D7ACrU6v.js               22.99 kB │ gzip:   8.58 kB
dist/assets/vendor-buffer-EX-AqChq.js                    26.95 kB │ gzip:   8.18 kB
dist/assets/accounts-DCezNGbn.js                         32.02 kB │ gzip:  10.88 kB
dist/assets/SendICPButton-C4mTrorf.js                    37.04 kB │ gzip:  13.51 kB
dist/assets/settings-CgveAFk2.js                         54.23 kB │ gzip:  15.50 kB
dist/assets/dashboard-CBUUew43.js                        55.80 kB │ gzip:  18.12 kB
dist/assets/index-C2CaEKkW.js                            65.16 kB │ gzip:  18.66 kB
dist/assets/voting-BuIZH0YJ.js                           69.24 kB │ gzip:  21.67 kB
dist/assets/vendor-md-BFlttn4C.js                        73.29 kB │ gzip:  19.98 kB
dist/assets/button-DB4ksHKA.js                           84.68 kB │ gzip:  28.30 kB
dist/assets/neurons-Cr1aB--e.js                          90.32 kB │ gzip:  27.06 kB
dist/assets/DisburseModal-C5ul34Zo.js                   101.46 kB │ gzip:  29.62 kB
dist/assets/vendor-tanstack-B8Ai_FW1.js                 120.02 kB │ gzip:  39.22 kB
dist/assets/vendor-jsqr-CjiBYtfG.js                     129.98 kB │ gzip:  47.50 kB
dist/assets/vendor-core-react-bRRjyX41.js               189.81 kB │ gzip:  59.76 kB
dist/assets/vendor-recharts-CWUgUTjK.js                 280.25 kB │ gzip:  76.83 kB
dist/assets/vendor-ledger-Bz6feAP8.js                   403.26 kB │ gzip:  98.84 kB
dist/assets/vendor-icp-e5O_ocwA.js                      468.31 kB │ gzip: 117.84 kB
dist/assets/vendor-libs-WVao-pYB.js                     581.20 kB │ gzip: 187.04 kB

Copilot AI 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.

🔵 Needs a closer look

Standalone navigation positioning needs correction, and global scroll locking warrants real-device validation.

1 open issue
What changed in this PR

Moves mobile scrolling to the document so browser toolbars can collapse, while preserving desktop scrolling inside main.

Changes:

  • Fixes the mobile navigation to the viewport and adjusts vote-bar docking.
  • Resets document scrolling on navigation and locks it while drawers are open.
  • Adds drawer-lock and observer-root tests.
File Description
src/​governance-app-frontend/​src/​features/​proposals/​components/​ProposalDetailsVoting.tsx Adapts docking offsets and observer roots.
src/​governance-app-frontend/​src/​features/​proposals/​components/​ProposalDetailsVoting.test.tsx Tests mobile and desktop observer behavior.
src/​governance-app-frontend/​src/​common/​hooks/​useScrollResetOnNavigation.ts Resets window scrolling on page changes.
src/​governance-app-frontend/​src/​common/​components/​navigation/​BottomNav.tsx Makes mobile navigation fixed.
src/​governance-app-frontend/​src/​common/​components/​MainLayout.tsx Enables document scrolling below desktop widths.
src/​governance-app-frontend/​src/​common/​components/​Drawer.tsx Freezes and restores document scrolling.
src/​governance-app-frontend/​src/​common/​components/​Drawer.test.tsx Covers scroll-lock lifecycle and overlapping drawers.
src/​governance-app-frontend/​src/​app/​styles/​main.css Restricts document overflow locking to desktop.

Review effort: Balanced

Copilot AI 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.

🔵 Needs a closer look

Browser-sensitive viewport and drawer scroll-lock interactions warrant final human validation beyond mocked DOM tests.

No open issues 🎉

1 resolved since last review

Review effort: Balanced

# Conflicts:
#	src/governance-app-frontend/src/app/styles/main.css
#	src/governance-app-frontend/src/common/components/Drawer.test.tsx
#	src/governance-app-frontend/src/common/components/Drawer.tsx
#	src/governance-app-frontend/src/common/components/MainLayout.tsx
#	src/governance-app-frontend/src/features/proposals/components/ProposalDetailsVoting.tsx
Copilot AI balanced review requested due to automatic review settings November 5, 2026 10:44
Copilot AI previously approved these changes Nov 5, 2026

Copilot AI 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.

🟢 Approved

No active review issues remain for the mobile document-scrolling and drawer scroll-lock changes.

No open issues 🎉

Review effort: Balanced

# Conflicts:
#	src/governance-app-frontend/src/features/proposals/components/ProposalDetailsVoting.test.tsx
#	src/governance-app-frontend/src/features/proposals/components/ProposalDetailsVoting.tsx
Copilot AI balanced review requested due to automatic review settings November 5, 2026 10:55
Copilot AI dismissed their stale review, a newer Copilot review was requested November 5, 2026 10:55

Copilot AI 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.

🔵 Needs a closer look

The fixed-body drawer lock requires on-device verification of keyboard focus, nested drawers, and close-time scroll restoration on iOS Safari and Android Chrome, which jsdom cannot validate.

No open issues 🎉

Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings November 5, 2026 11:17

Copilot AI 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.

🟢 Approved

No active review issues are recorded for the mobile document-scrolling changes.

No open issues 🎉

Review effort: Balanced

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