Skip to content

Commit 273ac57

Browse files
committed
fix(ui): match the native page step for routed PageDown/Space (#1647)
Chromium, WebKit and Firefox all page by max(87.5% of the viewport, viewport - 40px). Using the fraction alone made the first routed PageDown on load shorter than every native one after a click (746px vs 812px at 900px tall).
1 parent 718d126 commit 273ac57

1 file changed

Lines changed: 9 additions & 2 deletions

File tree

‎packages/ui/hooks/useScrollKeyRouting.ts‎

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,14 @@ import { isDocumentScrollViewport } from './useScrollViewport';
2828
*/
2929

3030
const LINE_STEP_PX = 40;
31-
/** Chrome's paging fraction (kMinFractionToStepWhenPaging). */
31+
/**
32+
* Page step as Chromium and WebKit compute it: the larger of 87.5% of the
33+
* viewport (kMinFractionToStepWhenPaging) and the viewport minus a 40px
34+
* overlap (kMaxOverlapBetweenPages). On a normal window the overlap rule wins,
35+
* so a routed PageDown matches the native one taken after a click.
36+
*/
3237
const PAGE_FRACTION = 0.875;
38+
const PAGE_OVERLAP_PX = 40;
3339

3440
const OPEN_POPUP_SELECTOR = '[role="menu"], [role="listbox"]';
3541

@@ -101,7 +107,8 @@ function applyScroll(viewport: HTMLElement, action: ScrollKeyAction): void {
101107
viewport.scrollTo({ top: action.edge === 'start' ? 0 : viewport.scrollHeight, behavior });
102108
return;
103109
}
104-
const page = Math.max(1, Math.round(viewport.clientHeight * PAGE_FRACTION));
110+
const height = viewport.clientHeight;
111+
const page = Math.max(1, Math.round(Math.max(height * PAGE_FRACTION, height - PAGE_OVERLAP_PX)));
105112
viewport.scrollBy({ top: action.direction * page, behavior });
106113
}
107114

0 commit comments

Comments
 (0)