Skip to content

Commit 97f089b

Browse files
authored
Merge pull request facebook#148 from gaearon/scroll-consistent
Consistently scroll component name into view
2 parents b2cf896 + 518f3d7 commit 97f089b

File tree

2 files changed

+26
-4
lines changed

2 files changed

+26
-4
lines changed

src/devtools/views/Components/Element.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@
1717
background-color: var(--color-inactive-background);
1818
}
1919

20+
.ScrollAnchor {
21+
height: 100%;
22+
width: 0;
23+
}
24+
2025
.SelectedElement {
2126
background-color: var(--color-selected-background);
2227
color: var(--color-selected-foreground);

src/devtools/views/Components/Element.js

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ export default function ElementView({ data, index, style }: Props) {
5656
}
5757
}, [id, selectOwner]);
5858

59-
const ref = useRef<HTMLSpanElement | null>(null);
59+
const scrollAnchorStartRef = useRef<HTMLSpanElement | null>(null);
60+
const scrollAnchorEndRef = useRef<HTMLSpanElement | null>(null);
6061

6162
// The tree above has its own autoscrolling, but it only works for rows.
6263
// However, even when the row gets into the viewport, the component name
@@ -74,8 +75,22 @@ export default function ElementView({ data, index, style }: Props) {
7475
}
7576
lastScrolledIDRef.current = id;
7677

77-
if (ref.current !== null) {
78-
ref.current.scrollIntoView({
78+
// We want to bring the whole <Component> name into view,
79+
// including the expansion toggle and the "=== $r" hint.
80+
// However, even calling scrollIntoView() on a wrapper parent node (e.g. <span>)
81+
// wouldn't guarantee that it will be *fully* brought into view.
82+
// As a workaround, we'll have two anchor spans, and scroll each into view.
83+
if (scrollAnchorEndRef.current !== null) {
84+
scrollAnchorEndRef.current.scrollIntoView({
85+
behavior: 'auto',
86+
block: 'nearest',
87+
inline: 'nearest',
88+
});
89+
}
90+
if (scrollAnchorStartRef.current !== null) {
91+
// We scroll the start anchor last because it's
92+
// more important for it to be in the view.
93+
scrollAnchorStartRef.current.scrollIntoView({
7994
behavior: 'auto',
8095
block: 'nearest',
8196
inline: 'nearest',
@@ -149,10 +164,11 @@ export default function ElementView({ data, index, style }: Props) {
149164
marginBottom: `-${style.height}px`,
150165
}}
151166
>
167+
<span className={styles.ScrollAnchor} ref={scrollAnchorStartRef} />
152168
{ownerStack.length === 0 ? (
153169
<ExpandCollapseToggle element={element} store={store} />
154170
) : null}
155-
<span className={styles.Component} ref={ref}>
171+
<span className={styles.Component}>
156172
<DisplayName displayName={displayName} id={((id: any): number)} />
157173
{key && (
158174
<Fragment>
@@ -162,6 +178,7 @@ export default function ElementView({ data, index, style }: Props) {
162178
)}
163179
</span>
164180
{showDollarR && <span className={styles.DollarR}>&nbsp;== $r</span>}
181+
<span className={styles.ScrollAnchor} ref={scrollAnchorEndRef} />
165182
</div>
166183
);
167184
}

0 commit comments

Comments
 (0)