diff --git a/frontend/app/view/preview/directorypreview.tsx b/frontend/app/view/preview/directorypreview.tsx index 7bdc275dd5..5bb5aab4bc 100644 --- a/frontend/app/view/preview/directorypreview.tsx +++ b/frontend/app/view/preview/directorypreview.tsx @@ -31,6 +31,8 @@ import { quote as shellQuote } from "shell-quote"; import { debounce } from "throttle-debounce"; import "./directorypreview.scss"; +const PageJumpSize = 20; + declare module "@tanstack/react-table" { interface TableMeta { updateName: (path: string) => void; @@ -493,18 +495,21 @@ function TableBody({ const viewportHeight = viewport.offsetHeight; const rowElement = rowRefs.current[focusIndex]; const rowRect = rowElement.getBoundingClientRect(); - const parentRect = bodyRef.current.getBoundingClientRect(); + const parentRect = viewport.getBoundingClientRect(); const viewportScrollTop = viewport.scrollTop; - - const rowTopRelativeToViewport = rowRect.top - parentRect.top; - const rowBottomRelativeToViewport = rowRect.bottom - parentRect.top; - - if (rowTopRelativeToViewport < viewportScrollTop) { + const rowTopRelativeToViewport = rowRect.top - parentRect.top + viewport.scrollTop; + const rowBottomRelativeToViewport = rowRect.bottom - parentRect.top + viewport.scrollTop; + if (rowTopRelativeToViewport - 30 < viewportScrollTop) { // Row is above the visible area - viewport.scrollTo({ top: rowTopRelativeToViewport }); - } else if (rowBottomRelativeToViewport > viewportScrollTop + viewportHeight) { + let topVal = rowTopRelativeToViewport - 30; + if (topVal < 0) { + topVal = 0; + } + viewport.scrollTo({ top: topVal }); + } else if (rowBottomRelativeToViewport + 5 > viewportScrollTop + viewportHeight) { // Row is below the visible area - viewport.scrollTo({ top: rowBottomRelativeToViewport - viewportHeight }); + const topVal = rowBottomRelativeToViewport - viewportHeight + 5; + viewport.scrollTo({ top: topVal }); } } // setIndexChangedFromClick(false); @@ -772,6 +777,14 @@ function DirectoryPreview({ model }: DirectoryPreviewProps) { setFocusIndex((idx) => Math.min(idx + 1, filteredData.length - 1)); return true; } + if (checkKeyPressed(waveEvent, "PageUp")) { + setFocusIndex((idx) => Math.max(idx - PageJumpSize, 0)); + return true; + } + if (checkKeyPressed(waveEvent, "PageDown")) { + setFocusIndex((idx) => Math.min(idx + PageJumpSize, filteredData.length - 1)); + return true; + } if (checkKeyPressed(waveEvent, "Enter")) { if (filteredData.length == 0) { return;