Skip to content

fix(ui): stop the session player shaking at the scrollbar threshold - #7125

Open
geovannewashington wants to merge 1 commit into
masterfrom
fix/ui/session-player-shaking
Open

geovannewashington wants to merge 1 commit into
masterfrom
fix/ui/session-player-shaking

Conversation

@geovannewashington

@geovannewashington geovannewashington commented Sep 16, 2026

Copy link
Copy Markdown
Member

What

Reserve the scrollbar gutter on the session player's scroll container so replays stop shaking.

Why

The player is created with fit: "width", so asciinema derives the font size from the container width and the rendered height falls out of that, never checked against the container. When a recording's height lands on the container's, width and height feed each other: the content overflows, the scrollbar takes its width, the narrower container shrinks the font, the shorter content fits, the scrollbar goes away, and it starts over.

A 160x35 recording hits this at common window heights, which is why it showed up on sessions recorded inside tmux: the status bar takes a row, so a 160x36 terminal records 160x35.

Changes

SessionPlayer.tsx: scrollbar-gutter: stable on the scroll container, so its width is identical whether or not a scrollbar is showing.

No test accompanies it. The first draft asserted the class string on the container reached through the asciinema mock, which pinned the spelling rather than the behaviour: it failed on a rename that preserved the fix and passed if overflow-y-auto were dropped while the gutter class stayed, which is the regression it appeared to guard. jsdom computes no layout, so no seam in this suite can observe the shaking. The reason the gutter is there is in the commit message.

Testing

Unit: the existing 17 cases pass unchanged. eslint and tsc -b clean.

Manual, dev stack: a 160x35 tmux recording at the window height where it shook plays steadily. Deleting the class from the element in devtools brings the shaking back, typing it in stops it again, same window and same recording. That A/B is the only check that can see the behaviour, and it is what this change rests on.

Closes #7121

@geovannewashington
geovannewashington requested a review from a team as a code owner September 16, 2026 19:17
@geovannewashington geovannewashington added kind/bug Something isn't working area/ui javascript Pull requests that update Javascript code labels Sep 16, 2026
@github-actions

github-actions Bot commented Sep 16, 2026

Copy link
Copy Markdown

Claude finished @geovannewashington's task in 6m 35s —— View job


Code Review Complete

Reviewed 2 files. 1 inline issue posted. Standards: 1 violation, 0 judgement calls. Spec: 0. Correctness: 0.

Standards

The new test at SessionPlayer.test.tsx:72-78 asserts the literal [scrollbar-gutter:stable] class string, reached through mockedCreate.mock.calls[0] and a parentElement walk, which react-conventions forbids ("Never query by CSS class, tag name, or DOM structure"). It breaks on refactors that preserve the fix and passes on one that destroys it.

Spec

Every requirement in #7121 is met. The gutter is reserved on the same element that carries overflow-y-auto, which is the scroll container the issue names, so the width the loop fed on is now constant; fit: "width" and the cast handling are untouched, matching "The same cast plays smoothly under asciinema play. The file is fine." No scope creep.

Additional notes

The production change itself is sound and minimal. Two things the author may want to weigh, neither posted inline because they did not clear the review's confidence bar:

  • scrollbar-gutter ships in Safari 18.2 and later. On older WebKit with classic scrollbars the declaration is ignored, so the fix no-ops and the shaking remains there. Not a regression, and there is no browserslist target in ui/ that pins the floor either way. The issue's other option, overflow-y: scroll, would cover those browsers but shows a permanent track on classic-scrollbar platforms, so it is a trade rather than a strict improvement.
  • The issue closes with "Constraining the player's height instead is a different tradeoff. Worth deciding rather than defaulting." The commit message explains at length why the gutter works, but does not name the height option or say why it lost. Worth a line there, since code-style.md puts that reasoning in the commit message and nowhere else.

If you've addressed the feedback and want a new review, tag @shellhub-io/admin and a team member can trigger it.
fix/ui/session-player-shaking

@geovannewashington geovannewashington self-assigned this Sep 16, 2026
Comment thread ui/apps/console/src/components/sessions/__tests__/SessionPlayer.test.tsx Outdated
The player is created with fit: "width", so asciinema derives the font size from the
container width and the rendered height falls out of that. Nothing checks the height
against the container, so a recording whose height lands near the container's creates a
loop: the content overflows, the scrollbar takes its width, the narrower container
shrinks the font, the shorter content no longer overflows, the scrollbar goes away, and
it starts over. Reserving the gutter keeps the container width constant whether the
scrollbar is showing or not, so the loop has nothing to oscillate on.

A 160x35 recording hits this at common window heights, which is why it showed up on
sessions recorded inside tmux: the status bar takes a row, so a 160x36 terminal records
160x35.

No test comes with it. jsdom computes no layout, so nothing in the console suite can
observe the shaking, and an assertion on the class string would fail on a rename that
preserved the fix while passing if overflow-y-auto were dropped.

Fixes: #7121
@geovannewashington
geovannewashington force-pushed the fix/ui/session-player-shaking branch from 78e4cae to 5a9af34 Compare September 16, 2026 20:22
@otavio

otavio commented Sep 16, 2026

Copy link
Copy Markdown
Member

/review

@github-actions

Copy link
Copy Markdown

Claude Code is working…

I'll analyze this and get back to you.

View job run

@github-actions

github-actions Bot commented Sep 16, 2026

Copy link
Copy Markdown

Claude finished @otavio's task in 2m 46s —— View job


Code Review Complete

Reviewed 1 file on all three axes: Standards (repo rules, language conventions, tests, code smells), Spec (does it implement the issue?) and Correctness (security and runtime defects). No new issues found. The code looks good as-is.

The previous round's inline finding — the test asserting the [scrollbar-gutter:stable] class string — is resolved; the test is gone from the diff. Two observations this round matched notes already made in that round (older WebKit ignoring scrollbar-gutter, and the commit message not naming the height-constraining option the issue asked to weigh), so they are not repeated here.

If you push additional changes and want a new review, tag @shellhub-io/admin and a team member can trigger it.
fix/ui/session-player-shaking

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

Labels

area/ui javascript Pull requests that update Javascript code kind/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(ui): session replay shakes when the player's height lands on the scrollbar threshold

2 participants