From 2efab6ab70efcde6e8d7e06b593d0605d35f1582 Mon Sep 17 00:00:00 2001 From: Damian Pieczynski Date: Tue, 4 Feb 2025 14:09:14 +0100 Subject: [PATCH 1/2] fix: offset calculation to handle transformed elements with translateY or translateX --- .../@react-aria/utils/src/scrollIntoView.ts | 29 ++++++++----------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/packages/@react-aria/utils/src/scrollIntoView.ts b/packages/@react-aria/utils/src/scrollIntoView.ts index bf4623b2ade..5f140037a1a 100644 --- a/packages/@react-aria/utils/src/scrollIntoView.ts +++ b/packages/@react-aria/utils/src/scrollIntoView.ts @@ -73,23 +73,18 @@ export function scrollIntoView(scrollView: HTMLElement, element: HTMLElement) { * offsetLeft or offsetTop through intervening offsetParents. */ function relativeOffset(ancestor: HTMLElement, child: HTMLElement, axis: 'left'|'top') { - const prop = axis === 'left' ? 'offsetLeft' : 'offsetTop'; - let sum = 0; - while (child.offsetParent) { - sum += child[prop]; - if (child.offsetParent === ancestor) { - // Stop once we have found the ancestor we are interested in. - break; - } else if (child.offsetParent.contains(ancestor)) { - // If the ancestor is not `position:relative`, then we stop at - // _its_ offset parent, and we subtract off _its_ offset, so that - // we end up with the proper offset from child to ancestor. - sum -= ancestor[prop]; - break; - } - child = child.offsetParent as HTMLElement; - } - return sum; + let childRect = child.getBoundingClientRect(); + let ancestorRect = ancestor.getBoundingClientRect(); + + let viewportOffset = axis === 'left' + ? childRect.left - ancestorRect.left + : childRect.top - ancestorRect.top; + + let scrollAdjustment = axis === 'left' + ? ancestor.scrollLeft + : ancestor.scrollTop; + + return viewportOffset + scrollAdjustment; } /** From f843f71ae08cac852480045bbb70df070df89ada Mon Sep 17 00:00:00 2001 From: Reid Barber Date: Fri, 7 Feb 2025 11:06:56 -0600 Subject: [PATCH 2/2] add story --- .../stories/GridList.stories.tsx | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/packages/react-aria-components/stories/GridList.stories.tsx b/packages/react-aria-components/stories/GridList.stories.tsx index d896c5d882b..bd38cfee3b5 100644 --- a/packages/react-aria-components/stories/GridList.stories.tsx +++ b/packages/react-aria-components/stories/GridList.stories.tsx @@ -199,3 +199,57 @@ export function TagGroupInsideGridList() { ); } + +export function GridListScrollIntoView() { + let items: {id: number, name: string}[] = []; + for (let i = 0; i < 100; i++) { + items.push({id: i, name: `Item ${i}`}); + } + + let list = useListData({ + initialItems: items + }); + + const getElement = (id: number) => document.querySelector(`[data-key="${id}"]`) as HTMLElement; + + const rowHeight = 25; + + return ( + <> +
+ + {item => ( + + {item.name} + )} + +
+ + + + ); +}