Repository: facebook/react
Pull request: Create more realistic containers in DevTools fixture

https://github.com/facebook/react/pull/33516 added a layout switch for which side devtools is attached. Unfortunately, it pushed content outside of the viewport while truncating the content (which can be seen by disabling `contain`). This makes it annoying to work on the overall layout in devtools (specifically scrollable areas).

This PR preserves the overall fixture layout while making sure the content of devtools and inspected app aren't truncated.

Before:

https://github.com/user-attachments/assets/f62c8eff-426e-44b0-92e3-1295bc6348c1

After:

https://github.com/user-attachments/assets/e579474e-53f4-4677-bd97-9470e776a611





Changed files:
filename: packages/react-devtools-shared/src/devtools/views/SuspenseTab/SuspenseTab.js
patch: @@ -295,7 +295,7 @@ function SuspenseTab(_: {}) {
           ref={resizeTreeListRef}>
           <SuspenseTreeList />
         </div>
-        <div className={styles.ResizeBarWrapper}>
+        <div className={styles.ResizeBarWrapper} hidden={treeListHidden}>
           <div
             onPointerDown={onResizeStart}
             onPointerMove={onResizeTreeList}
@@ -327,7 +327,7 @@ function SuspenseTab(_: {}) {
           </footer>
         </div>
       </div>
-      <div className={styles.ResizeBarWrapper}>
+      <div className={styles.ResizeBarWrapper} hidden={inspectedElementHidden}>
         <div
           onPointerDown={onResizeStart}
           onPointerMove={onResizeTree}

filename: packages/react-devtools-shell/index.html
patch: @@ -8,9 +8,9 @@
   <style>
     #panes {
       display: grid;
-      height: 100%;
-      width: 100%;
+      gap: 5px;
       position: relative;
+      overflow: hidden;
     }
 
     #divider {
@@ -41,21 +41,21 @@
       height: 100%;
       width: 100%;
       border: none;
+      overflow-y: auto;
     }
 
     #devtools {
       height: 100%;
       width: 100%;
-      overflow: hidden;
+      overflow-y: auto;
       z-index: 10000001;
     }
 
     body {
-      display: flex;
       height: 100vh;
       width: 100vw;
-      contain: strict;
-      flex-direction: column;
+      display: grid;
+      grid-template-rows: auto 1fr;
       margin: 0;
       padding: 0;
       font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial,
@@ -128,11 +128,13 @@
     function setLayout(layoutType, splitRatio) {
       const panes = document.getElementById('panes');
       if (layoutType === 'topbottom') {
-        panes.style.gridTemplateColumns = '100%'; // Full width for each row
-        panes.style.gridTemplateRows = `${splitRatio * 100}% ${(1 - splitRatio) * 100}%`;
+        panes.style.setProperty('--top-row-height', `${splitRatio * 100}%`);
+        panes.style.gridTemplateRows = "var(--top-row-height) 1fr";
+        panes.style.gridTemplateColumns = null;
       } else if (layoutType === 'leftright') {
-        panes.style.gridTemplateRows = '100%'; // Full height for each column
-        panes.style.gridTemplateColumns = `${splitRatio * 100}% ${(1 - splitRatio) * 100}%`;
+        panes.style.setProperty('--left-column-width', `${splitRatio * 100}%`);
+        panes.style.gridTemplateRows = null;
+        panes.style.gridTemplateColumns = "var(--left-column-width) 1fr";
       }
     }
     layout.addEventListener('change', () => {
@@ -147,12 +149,12 @@
       if (layoutType === 'topbottom') {
         // For top/bottom layout, divider should be horizontal (spanning across)
         divider.className = 'horizontal-divider';
-        divider.style.top = `calc(${splitRatio * 100}% - 2.5px)`;
+        divider.style.top = `calc(${splitRatio * 100}%)`;
         divider.style.left = '0';
       } else {
         // For left/right layout, divider should be vertical (spanning down)
         divider.className = 'vertical-divider';
-        divider.style.left = `calc(${splitRatio * 100}% - 2.5px)`;
+        divider.style.left = `calc(${splitRatio * 100}%)`;
         divider.style.top = '0';
       }
     }