[DevTools] Shrink/Deshrink Owners breadcrumbs on any resizes (#35694)
Sebastian "Sebbie" Silbermann committed
Feb 5, 2026 at 12:08 UTC
bb53387716e96912cbfb48d92655bc23882798ff
1 file changed
+22
-14
packages/react-devtools-shared/src/devtools/views/hooks.js
+22
-14
@@ -112,30 +112,38 @@ export function useEditableValue(
112
}
113
114
export function useIsOverflowing(
115
- containerRef: {current: HTMLDivElement | null, ...},
115
+ containerRef: {current: HTMLDivElement | null},
116
totalChildWidth: number,
117
): boolean {
118
const [isOverflowing, setIsOverflowing] = useState<boolean>(false);
119
120
// It's important to use a layout effect, so that we avoid showing a flash of overflowed content.
121
useLayoutEffect(() => {
122
- if (containerRef.current === null) {
123
- return () => {};
122
+ const container = containerRef.current;
123
+ if (container === null) {
124
+ return;
125
}
126
126
- const container = ((containerRef.current: any): HTMLDivElement);
127
-
128
- const handleResize = () =>
129
- setIsOverflowing(container.clientWidth <= totalChildWidth);
127
+ // ResizeObserver on the global did not fire for the extension.
128
+ // We need to grab the ResizeObserver from the container's window.
129
+ const ResizeObserver = container.ownerDocument.defaultView.ResizeObserver;
130
+ const observer = new ResizeObserver(entries => {
131
+ const entry = entries[0];
132
+ const contentWidth = entry.contentRect.width;
133
+ setIsOverflowing(
134
+ contentWidth <=
135
+ // We need to treat the box as overflowing when you're just
136
+ // about to overflow.
137
+ // Otherwise you won't be able to resize panes with custom resize handles.
138
+ // Previously we were relying on clientWidth which is already rounded.
139
+ // We don't want to read that again since that would trigger another layout.
140
+ totalChildWidth + 1,
141
+ );
142
+ });
143
131
- handleResize();
144
+ observer.observe(container);
145
133
- // It's important to listen to the ownerDocument.defaultView to support the browser extension.
134
- // Here we use portals to render individual tabs (e.g. Profiler),
135
- // and the root document might belong to a different window.
136
- const ownerWindow = container.ownerDocument.defaultView;
137
- ownerWindow.addEventListener('resize', handleResize);
138
- return () => ownerWindow.removeEventListener('resize', handleResize);
146
+ return observer.disconnect.bind(observer);
147
}, [containerRef, totalChildWidth]);
148
149
return isOverflowing;