[DevTools] Separate breadcrumbs with »#473
Conversation
Greptile OverviewGreptile SummaryThis change updates the DevTools Owners Stack and Suspense breadcrumbs to visually indicate hierarchy by inserting a Main issue to address before merge: in Confidence Score: 3/5
Important Files Changed
|
| useLayoutEffect(() => { | ||
| const container = containerRef.current; | ||
| if (container === null) { | ||
| return; | ||
| } | ||
|
|
||
| const ResizeObserver = container.ownerDocument.defaultView.ResizeObserver; | ||
| const observer = new ResizeObserver(entries => { | ||
| const entry = entries[0]; |
There was a problem hiding this comment.
ResizeObserver missing guard
OwnerStackFlatList assumes container.ownerDocument.defaultView.ResizeObserver exists and is constructible. In environments without ResizeObserver (or where defaultView is null), this will throw during useLayoutEffect, breaking the Owners Stack UI. Add a null/feature check (and a safe fallback) before instantiating it.
Also affects packages/react-devtools-shared/src/devtools/views/SuspenseTab/SuspenseBreadcrumbs.js around useLayoutEffect in SuspenseBreadcrumbsFlatList.
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/react-devtools-shared/src/devtools/views/Components/OwnersStack.js
Line: 94:102
Comment:
**ResizeObserver missing guard**
`OwnerStackFlatList` assumes `container.ownerDocument.defaultView.ResizeObserver` exists and is constructible. In environments without `ResizeObserver` (or where `defaultView` is null), this will throw during `useLayoutEffect`, breaking the Owners Stack UI. Add a null/feature check (and a safe fallback) before instantiating it.
Also affects `packages/react-devtools-shared/src/devtools/views/SuspenseTab/SuspenseBreadcrumbs.js` around `useLayoutEffect` in `SuspenseBreadcrumbsFlatList`.
How can I resolve this? If you propose a fix, please make it concise.| type SuspenseBreadcrumbsDropdownProps = { | ||
| lineage: $ReadOnlyArray<SuspenseNode['id']>, | ||
| selectedIndex: number, | ||
| selectElement: (id: SuspenseNode['id']) => void, | ||
| }; |
There was a problem hiding this comment.
Unused/incorrect props type
SuspenseBreadcrumbsDropdownProps declares selectedIndex: number but the component neither accepts nor uses it, and callers don't pass it. This will fail Flow type-checking for missing props (and suggests the signature is stale).
| type SuspenseBreadcrumbsDropdownProps = { | |
| lineage: $ReadOnlyArray<SuspenseNode['id']>, | |
| selectedIndex: number, | |
| selectElement: (id: SuspenseNode['id']) => void, | |
| }; | |
| type SuspenseBreadcrumbsDropdownProps = { | |
| lineage: $ReadOnlyArray<SuspenseNode['id']>, | |
| selectElement: (id: SuspenseNode['id']) => void, | |
| }; |
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/react-devtools-shared/src/devtools/views/SuspenseTab/SuspenseBreadcrumbs.js
Line: 203:207
Comment:
**Unused/incorrect props type**
`SuspenseBreadcrumbsDropdownProps` declares `selectedIndex: number` but the component neither accepts nor uses it, and callers don't pass it. This will fail Flow type-checking for missing props (and suggests the signature is stale).
```suggestion
type SuspenseBreadcrumbsDropdownProps = {
lineage: $ReadOnlyArray<SuspenseNode['id']>,
selectElement: (id: SuspenseNode['id']) => void,
};
```
How can I resolve this? If you propose a fix, please make it concise.3b9fc4b to
dec687f
Compare
| @@ -180,16 +206,14 @@ export default function OwnerStack(): React.Node { | |||
| /> | |||
| )} | |||
| </Fragment> | |||
| ) : ( | |||
| <OwnerStackFlatList | |||
There was a problem hiding this comment.
Width measurement never updates
When isOverflowing becomes true, the flat list unmounts and OwnerStackFlatList stops calling setElementsTotalWidth, but elementsTotalWidth can still increase as the dropdown contents grow (drilling deeper). Since useIsOverflowing(elementsBarRef, elementsTotalWidth) depends on this value, the component can get stuck in the overflowing UI and never return to the flat list when there’s actually enough space.
This was previously avoided by the “once overflowing, stop re-measuring” assumption, but that assumption no longer holds once measurement is tied to the flat list being mounted. A fix is to keep observing width regardless of isOverflowing (e.g. observe the bar container and sum/measure its content, or keep the flat list mounted but visually hidden) so elementsTotalWidth reflects the current content size.
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/react-devtools-shared/src/devtools/views/Components/OwnersStack.js
Line: 183:210
Comment:
**Width measurement never updates**
When `isOverflowing` becomes `true`, the flat list unmounts and `OwnerStackFlatList` stops calling `setElementsTotalWidth`, but `elementsTotalWidth` can still increase as the dropdown contents grow (drilling deeper). Since `useIsOverflowing(elementsBarRef, elementsTotalWidth)` depends on this value, the component can get stuck in the overflowing UI and never return to the flat list when there’s actually enough space.
This was previously avoided by the “once overflowing, stop re-measuring” assumption, but that assumption no longer holds once measurement is tied to the flat list being mounted. A fix is to keep observing width regardless of `isOverflowing` (e.g. observe the bar container and sum/measure its content, or keep the flat list mounted but visually hidden) so `elementsTotalWidth` reflects the current content size.
How can I resolve this? If you propose a fix, please make it concise.|
Upstream PR was closed or merged. Code is synced via branch mirror. |
Mirror of facebook/react#35705
Original author: eps1lon
Summary
Stacked on react/react#35700
This avoids a common confusion with the Suspense breadcrumbs by making it clearer that this is a hierarchy. Applied the same styling to the Owner Stack in the Components tab.
Required a refactor how we measure the combined item size which isolates individual Components better and actually uses ResizeObserver instead of just recalculating when the number of owners changes.
How did you test this change?
CleanShot.2026-02-05.at.18.01.17.mp4