@samitouri / QOS-React / commits / ba9c763954

Consistently scroll component name into view

Dan committed Apr 13, 2019 at 01:58 UTC ba9c763954276e18b6f577f721d0330d2eeb494b
2 files changed +24 -4
src/devtools/views/Components/Element.css
+5
@@ -17,6 +17,11 @@
17 background-color: var(--color-inactive-background);
18 }
19
20 +.ScrollAnchor {
21 + height: 100%;
22 + width: 0;
23 +}
24 +
25 .SelectedElement {
26 background-color: var(--color-selected-background);
27 color: var(--color-selected-foreground);
src/devtools/views/Components/Element.js
+19 -4
@@ -56,7 +56,8 @@ export default function ElementView({ data, index, style }: Props) {
56 }
57 }, [id, selectOwner]);
58
59 - const ref = useRef<HTMLSpanElement | null>(null);
59 + const scrollAnchorStartRef = useRef<HTMLSpanElement | null>(null);
60 + const scrollAnchorEndRef = useRef<HTMLSpanElement | null>(null);
61
62 // The tree above has its own autoscrolling, but it only works for rows.
63 // However, even when the row gets into the viewport, the component name
@@ -74,8 +75,20 @@ export default function ElementView({ data, index, style }: Props) {
75 }
76 lastScrolledIDRef.current = id;
77
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 their parent node
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 (scrollAnchorStartRef.current !== null) {
84 + scrollAnchorStartRef.current.scrollIntoView({
85 + behavior: 'auto',
86 + block: 'nearest',
87 + inline: 'nearest',
88 + });
89 + }
90 + if (scrollAnchorEndRef.current !== null) {
91 + scrollAnchorEndRef.current.scrollIntoView({
92 behavior: 'auto',
93 block: 'nearest',
94 inline: 'nearest',
@@ -149,10 +162,11 @@ export default function ElementView({ data, index, style }: Props) {
162 marginBottom: `-${style.height}px`,
163 }}
164 >
165 + <span className={styles.ScrollAnchor} ref={scrollAnchorStartRef} />
166 {ownerStack.length === 0 ? (
167 <ExpandCollapseToggle element={element} store={store} />
168 ) : null}
155 - <span className={styles.Component} ref={ref}>
169 + <span className={styles.Component}>
170 <DisplayName displayName={displayName} id={((id: any): number)} />
171 {key && (
172 <Fragment>
@@ -162,6 +176,7 @@ export default function ElementView({ data, index, style }: Props) {
176 )}
177 </span>
178 {showDollarR && <span className={styles.DollarR}>&nbsp;== $r</span>}
179 + <span className={styles.ScrollAnchor} ref={scrollAnchorEndRef} />
180 </div>
181 );
182 }