Skip to content

Commit ff33b9a

Browse files
VTT-AI-Agentclaude
andcommitted
Keep the overflowing toolbar from scrolling itself while the window is resized
Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 48493c4 commit ff33b9a

3 files changed

Lines changed: 25 additions & 5 deletions

File tree

client/css/layout.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,9 @@ body.aspectTooGood.hiddenToolbar {
490490
scrollbar-width: none;
491491
padding-top: 0;
492492
padding-bottom: 0;
493+
/* every compaction level changes the size of the contents, so scroll anchoring would keep
494+
adjusting scrollTop while the window is resized until the toolbar sits at its end */
495+
overflow-anchor: none;
493496
/* scrolling comes to rest on a button instead of cutting one in half behind an arrow */
494497
scroll-snap-type: y proximity;
495498
scroll-padding: var(--toolbarArrowSize) 0;

client/js/main.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -313,8 +313,6 @@ function updateToolbarScrolling() {
313313
positionToolbarTooltip();
314314
}
315315

316-
const toolbarArrowSize = 24; // --toolbarArrowSize in layout.css
317-
318316
// clicking one of the arrows scrolls by roughly one screen and returns true - the arrows are
319317
// pseudo elements, so whether a click on one is reported on the toolbar or on a button that
320318
// scrolled underneath it depends on the scroll position, which is why the caller catches the
@@ -328,8 +326,9 @@ function scrollToolbarByArrow(e) {
328326
const toolbar = $('#toolbar');
329327
const rect = toolbar.getBoundingClientRect();
330328
const horizontal = body.contains('horizontalToolbar');
331-
const back = body.contains('toolbarScrollBack') && (horizontal ? e.clientX < rect.left + toolbarArrowSize : e.clientY < rect.top + toolbarArrowSize);
332-
const forward = body.contains('toolbarScrollForward') && (horizontal ? e.clientX > rect.right - toolbarArrowSize : e.clientY > rect.bottom - toolbarArrowSize);
329+
const arrow = parseFloat(getComputedStyle(toolbar).getPropertyValue('--toolbarArrowSize')) || 0;
330+
const back = body.contains('toolbarScrollBack') && (horizontal ? e.clientX < rect.left + arrow : e.clientY < rect.top + arrow);
331+
const forward = body.contains('toolbarScrollForward') && (horizontal ? e.clientX > rect.right - arrow : e.clientY > rect.bottom - arrow);
333332
if(back || forward)
334333
scrollToolbarBy((horizontal ? toolbar.clientWidth : toolbar.clientHeight) * (back ? -0.8 : 0.8), 'smooth');
335334
return back || forward;
@@ -338,7 +337,8 @@ function scrollToolbarByArrow(e) {
338337
function scrollToolbarByWheel(e) {
339338
if(!$('body').classList.contains('horizontalToolbar') || !$('body').classList.contains('toolbarOverflow') || e.deltaX)
340339
return;
341-
scrollToolbarBy(e.deltaY * (e.deltaMode ? 16 : 1)); // some mice report lines instead of pixels
340+
// deltaMode says whether the wheel reports pixels, lines or pages
341+
scrollToolbarBy(e.deltaY * ([ 1, 16, $('#toolbar').clientWidth ][e.deltaMode] || 1));
342342
e.preventDefault();
343343
}
344344

tests/testcafe/toolbar.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,23 @@ test('The toolbar layout does not depend on the direction the window was resized
9595
await t.resizeWindow(1280, 800);
9696
});
9797

98+
// the compaction levels change the size of the toolbar contents, which makes the browser's scroll
99+
// anchoring adjust the scroll position on every resize step - without turning that off, shrinking
100+
// the window walks the overflowing toolbar to its end and pushes the first buttons out of sight
101+
test('Resizing the window does not scroll the overflowing toolbar by itself', async t => {
102+
await setRoomState();
103+
await ClientFunction(prepareClient)();
104+
105+
for(const [ width, height ] of [ [ 420, 260 ], [ 420, 250 ], [ 420, 240 ], [ 420, 230 ], [ 420, 220 ] ]) {
106+
const size = `${width}x${height}`;
107+
await t.resizeWindow(width, height).wait(300);
108+
await t.expect((await toolbarLayout()).overflow).ok(`${size}: the toolbar is expected to overflow`);
109+
await t.expect((await toolbarState()).position).lte(2, `${size}: resizing the window scrolled the toolbar`);
110+
}
111+
112+
await t.resizeWindow(1280, 800);
113+
});
114+
98115
test('Clicking a toolbar scroll arrow scrolls instead of pressing the button underneath it', async t => {
99116
await setRoomState();
100117
await ClientFunction(prepareClient)();

0 commit comments

Comments
 (0)