@samitouri / QOS-React-2 / commits / bb53387716

[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;