diff --git a/src/devtools/views/Components/Element.css b/src/devtools/views/Components/Element.css index 2a923c15d9..425b901bd8 100644 --- a/src/devtools/views/Components/Element.css +++ b/src/devtools/views/Components/Element.css @@ -17,6 +17,11 @@ background-color: var(--color-inactive-background); } +.ScrollAnchor { + height: 100%; + width: 0; +} + .SelectedElement { background-color: var(--color-selected-background); color: var(--color-selected-foreground); diff --git a/src/devtools/views/Components/Element.js b/src/devtools/views/Components/Element.js index 6bc9bfeb7e..5e5b52fe08 100644 --- a/src/devtools/views/Components/Element.js +++ b/src/devtools/views/Components/Element.js @@ -56,7 +56,8 @@ export default function ElementView({ data, index, style }: Props) { } }, [id, selectOwner]); - const ref = useRef(null); + const scrollAnchorStartRef = useRef(null); + const scrollAnchorEndRef = useRef(null); // The tree above has its own autoscrolling, but it only works for rows. // However, even when the row gets into the viewport, the component name @@ -74,8 +75,22 @@ export default function ElementView({ data, index, style }: Props) { } lastScrolledIDRef.current = id; - if (ref.current !== null) { - ref.current.scrollIntoView({ + // We want to bring the whole name into view, + // including the expansion toggle and the "=== $r" hint. + // However, even calling scrollIntoView() on a wrapper parent node (e.g. ) + // wouldn't guarantee that it will be *fully* brought into view. + // As a workaround, we'll have two anchor spans, and scroll each into view. + if (scrollAnchorEndRef.current !== null) { + scrollAnchorEndRef.current.scrollIntoView({ + behavior: 'auto', + block: 'nearest', + inline: 'nearest', + }); + } + if (scrollAnchorStartRef.current !== null) { + // We scroll the start anchor last because it's + // more important for it to be in the view. + scrollAnchorStartRef.current.scrollIntoView({ behavior: 'auto', block: 'nearest', inline: 'nearest', @@ -149,10 +164,11 @@ export default function ElementView({ data, index, style }: Props) { marginBottom: `-${style.height}px`, }} > + {ownerStack.length === 0 ? ( ) : null} - + {key && ( @@ -162,6 +178,7 @@ export default function ElementView({ data, index, style }: Props) { )} {showDollarR &&  == $r} + ); }