Cap indentation increase at a max
Brian Vaughn committed
Jun 2, 2019 at 21:01 UTC
f713265a00ac3ad30dc578dde185ec3fcddc995b
1 file changed
+31
-4
src/devtools/views/Components/Tree.js
+31
-4
@@ -35,6 +35,13 @@ export type ItemData = {|
35
treeFocused: boolean,
36
|};
37
38
+// Never indent more than this number of pixels (even if we have the room).
39
+const DEFAULT_INDENTATION_SIZE = 12;
40
+
41
+// Never increase indentation by more than this number of pixels in a single adjustment.
42
+// This is to prevent things from "jumping" when a wide item is scrolled out of view.
43
+const MAX_INDENTATION_SIZE_INCREASE = 0.25;
44
+
45
type Props = {||};
46
47
export default function Tree(props: Props) {
@@ -370,12 +377,13 @@ export default function Tree(props: Props) {
377
// Then we take the smallest of these indentation sizes...
378
function updateIndentationSizeVar(
379
innerDiv: HTMLDivElement,
373
- cachedChildWidths: WeakMap<HTMLElement, number>
380
+ cachedChildWidths: WeakMap<HTMLElement, number>,
381
+ indentationSizeRef: {| current: number |}
382
): void {
383
const list = ((innerDiv.parentElement: any): HTMLDivElement);
384
const listWidth = list.clientWidth;
385
378
- let maxIndentationSize: number = 12;
386
+ let maxIndentationSize: number = DEFAULT_INDENTATION_SIZE;
387
388
for (let child of innerDiv.children) {
389
const depth = parseInt(child.getAttribute('data-depth'), 10) || 0;
@@ -400,7 +408,21 @@ function updateIndentationSizeVar(
408
maxIndentationSize = Math.min(maxIndentationSize, remainingWidth / depth);
409
}
410
403
- list.style.setProperty('--indentation-size', `${maxIndentationSize}px`);
411
+ // It's very important to shrink indentation so that nothing gets clipped.
412
+ // But it is less important to increase indentation when something wide is scrolled out of view.
413
+ // In fact, increasing too much leads to visual "jumping" which can be unpleasant.
414
+ // To avoid this, we only increase by a maximum of some threshold (MAX_INDENTATION_SIZE_INCREASE).
415
+ const newIndentationSize =
416
+ indentationSizeRef.current > maxIndentationSize
417
+ ? maxIndentationSize
418
+ : Math.min(
419
+ maxIndentationSize,
420
+ indentationSizeRef.current + MAX_INDENTATION_SIZE_INCREASE
421
+ );
422
+
423
+ list.style.setProperty('--indentation-size', `${newIndentationSize}px`);
424
+
425
+ indentationSizeRef.current = newIndentationSize;
426
}
427
428
function InnerElementType({ children, style, ...rest }) {
@@ -410,6 +432,7 @@ function InnerElementType({ children, style, ...rest }) {
432
() => new WeakMap(),
433
[]
434
);
435
+ const indentationSizeRef = useRef<number>(DEFAULT_INDENTATION_SIZE);
436
437
// The list may need to scroll horizontally due to deeply nested elements.
438
// We don't know the maximum scroll width up front, because we're windowing.
@@ -422,7 +445,11 @@ function InnerElementType({ children, style, ...rest }) {
445
// eslint-disable-next-line react-hooks/exhaustive-deps
446
useEffect(() => {
447
if (divRef.current !== null) {
425
- updateIndentationSizeVar(divRef.current, cachedChildWidths);
448
+ updateIndentationSizeVar(
449
+ divRef.current,
450
+ cachedChildWidths,
451
+ indentationSizeRef
452
+ );
453
}
454
});
455