[devtools] Added minimum indent size to Component Tree (#33517)

## Summary

The devtools Components tab's component tree view currently has a
behavior where the indentation of each level of the tree scales based on
the available width of the view. If the view is narrow or component
names are long, all indentation showing the hierarchy of the tree scales
down with the view width until there is no indentation at all. This
makes it impossible to see the nesting of the tree, making the tree view
much less useful. With long component names and deep hierarchies this
issue is particularly egregious. For comparison, the Chrome Dev Tools
Elements panel uses a fixed indentation size, so it doesn't suffer from
this issue.

This PR adds a minimum pixel value for the indentation width, so that
even when the window is narrow some indentation will still be visible,
maintaining the visual representation of the component tree hierarchy.

Alternatively, we could match the behavior of the Chrome Dev Tools and
just use a constant indentation width.

## How did you test this change?

- tests (yarn test-build-devtools)
- tested in browser:
- added an alternate left/right split pane layout to
react-devtools-shell to test with
(https://github.com/facebook/react/pull/33516)
- tested resizing the tree view in different layout modes

### before this change:



https://github.com/user-attachments/assets/470991f1-dc05-473f-a2cb-4f7333f6bae4

with a long component name:



https://github.com/user-attachments/assets/1568fc64-c7d7-4659-bfb1-9bfc9592fb9d





### after this change:




https://github.com/user-attachments/assets/f60bd7fc-97f6-4680-9656-f0db3d155411

with a long component name:


https://github.com/user-attachments/assets/6ac3f58c-42ea-4c5a-9a52-c3b397f37b45
This commit is contained in:
James Friend
2025-06-13 10:28:31 -04:00
committed by GitHub
parent ed023cfc73
commit 12bc60f509

View File

@@ -41,7 +41,8 @@ import {useExtensionComponentsPanelVisibility} from 'react-devtools-shared/src/f
import {useChangeOwnerAction} from './OwnersListContext';
// Never indent more than this number of pixels (even if we have the room).
const DEFAULT_INDENTATION_SIZE = 12;
const MAX_INDENTATION_SIZE = 12;
const MIN_INDENTATION_SIZE = 4;
export type ItemData = {
isNavigatingWithKeyboard: boolean,
@@ -490,11 +491,11 @@ function updateIndentationSizeVar(
// Reset the max indentation size if the width of the tree has increased.
if (listWidth > prevListWidthRef.current) {
indentationSizeRef.current = DEFAULT_INDENTATION_SIZE;
indentationSizeRef.current = MAX_INDENTATION_SIZE;
}
prevListWidthRef.current = listWidth;
let maxIndentationSize: number = indentationSizeRef.current;
let indentationSize: number = indentationSizeRef.current;
// eslint-disable-next-line no-for-of-loops/no-for-of-loops
for (const child of innerDiv.children) {
@@ -517,12 +518,13 @@ function updateIndentationSizeVar(
const remainingWidth = Math.max(0, listWidth - childWidth);
maxIndentationSize = Math.min(maxIndentationSize, remainingWidth / depth);
indentationSize = Math.min(indentationSize, remainingWidth / depth);
}
indentationSizeRef.current = maxIndentationSize;
indentationSize = Math.max(indentationSize, MIN_INDENTATION_SIZE);
indentationSizeRef.current = indentationSize;
list.style.setProperty('--indentation-size', `${maxIndentationSize}px`);
list.style.setProperty('--indentation-size', `${indentationSize}px`);
}
// $FlowFixMe[missing-local-annot]
@@ -545,7 +547,7 @@ function InnerElementType({children, style}) {
// The user may have resized the window specifically to make more room for DevTools.
// In either case, this should reset our max indentation size logic.
// 2. The second is when the user enters or exits an owner tree.
const indentationSizeRef = useRef<number>(DEFAULT_INDENTATION_SIZE);
const indentationSizeRef = useRef<number>(MAX_INDENTATION_SIZE);
const prevListWidthRef = useRef<number>(0);
const prevOwnerIDRef = useRef<number | null>(ownerID);
const divRef = useRef<HTMLDivElement | null>(null);
@@ -554,7 +556,7 @@ function InnerElementType({children, style}) {
// so when the user opens the "owners tree" view, we should discard the previous width.
if (ownerID !== prevOwnerIDRef.current) {
prevOwnerIDRef.current = ownerID;
indentationSizeRef.current = DEFAULT_INDENTATION_SIZE;
indentationSizeRef.current = MAX_INDENTATION_SIZE;
}
// When we render new content, measure to see if we need to shrink indentation to fit it.