Fix search scrolling (#1982)
This commit is contained in:
@@ -102,26 +102,39 @@ export const SearchView: React.FC<PropsWithChildren<SearchViewProps>> = ({
|
|||||||
|
|
||||||
const marks = containerRef.current.querySelectorAll('mark');
|
const marks = containerRef.current.querySelectorAll('mark');
|
||||||
const mark = marks[index] as HTMLElement;
|
const mark = marks[index] as HTMLElement;
|
||||||
|
if (!mark) return;
|
||||||
|
|
||||||
if (mark) {
|
// Update highlight
|
||||||
// Update highlight
|
marks.forEach((m) => m.classList.remove('current'));
|
||||||
marks.forEach((m) => m.classList.remove('current'));
|
mark.classList.add('current');
|
||||||
mark.classList.add('current');
|
|
||||||
|
|
||||||
// Calculate position to center the mark in the viewport
|
// Find the viewport element
|
||||||
const markRect = mark.getBoundingClientRect();
|
const viewport = mark.closest('[data-radix-scroll-area-viewport]') as HTMLElement;
|
||||||
const viewportRect = mark
|
if (!viewport) return;
|
||||||
.closest('[data-radix-scroll-area-viewport]')
|
|
||||||
?.getBoundingClientRect();
|
|
||||||
|
|
||||||
if (viewportRect) {
|
// Get measurements
|
||||||
const targetPosition = mark.offsetTop - viewportRect.height / 2 + markRect.height / 2;
|
const viewportRect = viewport.getBoundingClientRect();
|
||||||
scrollAreaRef.current.scrollToPosition({
|
const markRect = mark.getBoundingClientRect();
|
||||||
top: targetPosition,
|
const currentScrollTop = viewport.scrollTop;
|
||||||
behavior: 'smooth',
|
|
||||||
});
|
// Calculate how far the element is from the top of the viewport
|
||||||
}
|
const elementRelativeToViewport = markRect.top - viewportRect.top;
|
||||||
}
|
|
||||||
|
// Calculate the new scroll position that would center the element
|
||||||
|
const targetPosition =
|
||||||
|
currentScrollTop + elementRelativeToViewport - (viewportRect.height - markRect.height) / 2;
|
||||||
|
|
||||||
|
// Ensure we don't scroll past the bottom
|
||||||
|
const maxScroll = viewport.scrollHeight - viewport.clientHeight;
|
||||||
|
const finalPosition = Math.max(0, Math.min(targetPosition, maxScroll));
|
||||||
|
|
||||||
|
// Use requestAnimationFrame to ensure DOM measurements are accurate
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
scrollAreaRef.current?.scrollToPosition({
|
||||||
|
top: finalPosition,
|
||||||
|
behavior: 'smooth',
|
||||||
|
});
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const clearHighlights = () => {
|
const clearHighlights = () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user