Skip to content

fix(web): programmatic scrolls jump instead of glide when Reduce Motion is on - #16014

Open
saphid wants to merge 1 commit into
pingdotgg:mainfrom
saphid:fix/web-reduced-motion-scrolling
Open

saphid wants to merge 1 commit into
pingdotgg:mainfrom
saphid:fix/web-reduced-motion-scrolling

Conversation

@saphid

@saphid saphid commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Problem

With Reduce Motion on (prefers-reduced-motion: reduce), the web and desktop client still animates four programmatic scrolls: the Scroll to end pill, PageUp/PageDown from the composer, timeline minimap jumps, and the theme editor's Inspect reveal. Part of #15953, which has repro steps and measurements on main a1d9d72aef.

Change

Each of those actions now reads the preference when it runs and moves instantly when motion is reduced:

  • ChatView scrollToEnd animates only when the caller asks and motion is not reduced.
  • pageScrollController gets a prefersReducedMotion environment hook. A discrete PageUp/PageDown press jumps the full page instead of the 150 ms ease. Holding the key still scrolls continuously, because that motion is driven by the user.
  • The minimap jump uses the prefersReducedMotion media query that MessagesTimeline already reads for streaming end-follow.
  • The theme editor reveal uses behavior: "auto" when motion is reduced.

Destinations, focus, and normal motion are unchanged. Paths that already honor the preference on main (right-panel tab scrolling, settings search reveal, citation reveal, streaming end-follow) are untouched.

Scope and approval

A small, focused fix for an accessibility bug reported in #15953. It replaces the web half of #12871, which was closed for missing live motion verification. The mobile half is a separate PR, #16015.

Verification

  • vp test run apps/web/src/components/chat/pageScrollController.test.ts: 11 passed. The two new tests (reduced-motion press jumps a full page with no frames; the preference is re-read on each press) fail without the fix.
  • vp run typecheck in apps/web, plus scoped vp lint and vp fmt --check on the changed files: all pass.
  • Live check against an isolated dev server on this branch. Headless Chrome for Testing with Playwright's real reducedMotion emulation sampled the timeline's scrollTop every animation frame after each action. Counts are frames strictly between the start and end positions:
Action main, reduce this PR, reduce this PR, no preference
Scroll to end (5479 px) 72 0 72
PageDown from composer (602 px) 9 0 4–9
Minimap jump (392 px) 18 0 18
Theme editor reveal (48 px) 4 positions 2 positions (jump) 7 positions
Scroll to end after flipping the preference live, without reload 72 0 —

Destinations are identical. After each action the composer keeps focus (Scroll to end, PageDown), and the minimap's Next button keeps focus.

Scroll to end, Reduce Motion on, frames 100 ms apart:

main this PR
before after

Recordings, captioned with the build and live preference value:

Not verified:

  • The macOS desktop app with the real system setting. Electron evaluates the same matchMedia query; it was tested here through Chrome's media emulation.
  • Safari and Firefox.
  • The send-message anchor scroll (onTimelineAnchorReady). It never produced intermediate frames in testing (a single 170 px jump from the live edge), so it is unchanged.

Reproduction, implementation and evidence: Claude Opus 5.5 in Claude Code, inside T3 Code. Independent review: GPT-6.1 Sol through Codex in T3 Code.

🤖 Generated with Claude Code

…on is on

Scroll to end, PageUp/PageDown from the composer, timeline minimap jumps and
the theme editor's color reveal now move instantly when the system asks for
reduced motion. The preference is read at the moment of each action, so
changing it applies without a reload. Normal motion is unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Oct 5, 2026
@macroscopeapp

macroscopeapp Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 4c417d0

Macroscope's review found this PR approvable — This is a narrowly scoped accessibility fix that makes four existing programmatic scroll actions honor the user's reduced-motion preference while preserving normal scrolling behavior. The added controller tests cover the new instant-scroll and live-preference paths, and no sensitive, schema, deployment, or static-analysis configuration is involved.

You can add or adjust custom eligibility rules. Learn more.

@coderabbitai

coderabbitai Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: pingdotgg/t3code/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 45829042-d03d-4005-8d3b-fc007c918f64
📥 Commits

Reviewing files that changed from the base of the PR and between 7812230 and 4c417d0.

📒 Files selected for processing (5)
  • apps/web/src/components/ChatView.tsx
  • apps/web/src/components/chat/MessagesTimeline.tsx
  • apps/web/src/components/chat/pageScrollController.test.ts
  • apps/web/src/components/chat/pageScrollController.ts
  • apps/web/src/components/settings/ThemeEditorPanel.tsx

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.


📝 Walkthrough

Walkthrough

Scrolling in chat navigation and theme editing now respects the browser’s reduced-motion preference. When reduced motion is enabled, these interactions use immediate scrolling; otherwise, they retain animated scrolling where applicable.

Changes

Reduced-motion scrolling

Layer / File(s) Summary
Preference-aware page scrolling
apps/web/src/components/chat/pageScrollController.ts, apps/web/src/components/chat/pageScrollController.test.ts
The page scroll environment exposes the reduced-motion preference. Page scrolling applies the delta immediately when reduced motion is enabled. Tests cover this behavior and preference changes between presses.
Other scrolling interactions
apps/web/src/components/ChatView.tsx, apps/web/src/components/chat/MessagesTimeline.tsx, apps/web/src/components/settings/ThemeEditorPanel.tsx
Chat scroll-to-end, minimap navigation, and theme color-role reveal disable smooth scrolling when reduced motion is preferred.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Possibly related PRs

  • pingdotgg/t3code#12871: It also disables animated scrolling when reduced motion is enabled and covers several of the same web behaviors.

Suggested reviewers: yash-singh1, maria-rcks

Merge Risk: ⚪ Minimal · up to 4c417

The changed scrolling interactions are ready to merge after normal checks; no actionable issue was established.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 5 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
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.
Title check ✅ Passed The title clearly summarizes the main change: programmatic scrolling moves instantly when Reduce Motion is enabled.
Description check ✅ Passed The description covers the problem, change, scope and approval rationale, and verification. It includes test results, live behavior checks, evidence, and unverified environments.
  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

@saphid

saphid commented Oct 6, 2026

Copy link
Copy Markdown
Contributor Author

Review requested

Date (UTC) Reviewer Where
2026-10-06 Maria Discord DM

Logged so this PR shows when a maintainer was asked to review it.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:S 10-29 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant