mirror of
https://github.com/zebrajr/react.git
synced 2025-12-06 12:20:20 +01:00
## Summary This PR adds a 'Layout' selector to the devtools shell main example, as well as a resizable split pane, allowing more realistic testing of how the devtools behaves when used in a vertical or horizontal layout and at different sizes (e.g. when resizing the Chrome Dev Tools pane). ## How did you test this change? https://github.com/user-attachments/assets/81179413-7b46-47a9-bc52-4f7ec414e8be
214 lines
6.0 KiB
HTML
214 lines
6.0 KiB
HTML
<!doctype html>
|
|
<html>
|
|
|
|
<head>
|
|
<meta charset="utf8">
|
|
<title>React DevTools</title>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<style>
|
|
#panes {
|
|
display: grid;
|
|
height: 100%;
|
|
width: 100%;
|
|
position: relative;
|
|
}
|
|
|
|
#divider {
|
|
position: absolute;
|
|
z-index: 10000002;
|
|
background-color: #ccc;
|
|
transition: background-color 0.2s;
|
|
}
|
|
|
|
#divider:hover,
|
|
#divider.dragging {
|
|
background-color: #aaa;
|
|
}
|
|
|
|
#divider.horizontal-divider {
|
|
width: 100%;
|
|
height: 5px;
|
|
cursor: row-resize;
|
|
}
|
|
|
|
#divider.vertical-divider {
|
|
width: 5px;
|
|
height: 100%;
|
|
cursor: col-resize;
|
|
}
|
|
|
|
#target {
|
|
height: 100%;
|
|
width: 100%;
|
|
border: none;
|
|
}
|
|
|
|
#devtools {
|
|
height: 100%;
|
|
width: 100%;
|
|
overflow: hidden;
|
|
z-index: 10000001;
|
|
}
|
|
|
|
body {
|
|
display: flex;
|
|
height: 100vh;
|
|
width: 100vw;
|
|
contain: strict;
|
|
flex-direction: column;
|
|
margin: 0;
|
|
padding: 0;
|
|
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial,
|
|
sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;
|
|
font-size: 12px;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.optionsRow {
|
|
width: 100%;
|
|
display: flex;
|
|
padding: 0.25rem;
|
|
background: aliceblue;
|
|
border-bottom: 1px solid lightblue;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.optionsRowSpacer {
|
|
flex: 1;
|
|
}
|
|
</style>
|
|
</head>
|
|
|
|
<body>
|
|
<div class="optionsRow">
|
|
<button id="mountButton">Unmount test app</button>
|
|
<div class="optionsRowSpacer"> </div>
|
|
<span>
|
|
<a href="/multi.html">multi DevTools</a>
|
|
|
|
|
<a href="/e2e.html">e2e tests</a>
|
|
|
|
|
<a href="/e2e-regression.html">e2e regression tests</a>
|
|
|
|
|
<a href="/perf-regression.html">perf regression tests</a>
|
|
</span>
|
|
|
|
<label style="margin-left: 4px">
|
|
Layout:
|
|
<select id="layout">
|
|
<option value="leftright">Left/Right Split</option>
|
|
<option value="topbottom">Top/Bottom Split</option>
|
|
</select></label>
|
|
</div>
|
|
|
|
<div id="panes">
|
|
<!-- React test app (shells/dev/app) is injected here -->
|
|
<!-- DevTools backend (shells/dev/src) is injected here -->
|
|
<!-- global "hook" is defined on the iframe's contentWindow -->
|
|
<iframe id="target"></iframe>
|
|
|
|
<!-- Draggable divider between panes -->
|
|
<div id="divider"></div>
|
|
|
|
<!-- DevTools frontend UI (shells/dev/src) renders here -->
|
|
<div id="devtools"></div>
|
|
</div>
|
|
|
|
<!-- This script installs the hook, injects the backend, and renders the DevTools UI -->
|
|
<!-- In DEV mode, this file is served by the Webpack dev server -->
|
|
<!-- For production builds, it's built by Webpack and uploaded from the local file system -->
|
|
<script src="dist/app-devtools.js"></script>
|
|
<script type="module">
|
|
let layoutType = 'leftright';
|
|
let splitRatio = 0.5;
|
|
let isDragging = false;
|
|
|
|
// handle layout changes
|
|
const layout = document.getElementById('layout');
|
|
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}%`;
|
|
} else if (layoutType === 'leftright') {
|
|
panes.style.gridTemplateRows = '100%'; // Full height for each column
|
|
panes.style.gridTemplateColumns = `${splitRatio * 100}% ${(1 - splitRatio) * 100}%`;
|
|
}
|
|
}
|
|
layout.addEventListener('change', () => {
|
|
layoutType = layout.value;
|
|
setLayout(layoutType, splitRatio);
|
|
updateDividerPosition(); // Ensure divider updates when layout changes
|
|
});
|
|
|
|
// handle changing the split ratio
|
|
const divider = document.getElementById('divider');
|
|
function updateDividerPosition() {
|
|
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.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.top = '0';
|
|
}
|
|
}
|
|
|
|
// Add event listeners for dragging
|
|
divider.addEventListener('mousedown', (e) => {
|
|
isDragging = true;
|
|
divider.classList.add('dragging');
|
|
|
|
// Disable pointer events on the iframe to prevent it from capturing mouse events
|
|
const iframe = document.getElementById('target');
|
|
iframe.style.pointerEvents = 'none';
|
|
|
|
e.preventDefault(); // Prevent text selection during drag
|
|
});
|
|
|
|
document.addEventListener('mousemove', (e) => {
|
|
if (!isDragging) return;
|
|
|
|
const panes = document.getElementById('panes');
|
|
const rect = panes.getBoundingClientRect();
|
|
|
|
if (layoutType === 'topbottom') {
|
|
// Calculate new split ratio based on vertical position
|
|
const newRatio = Math.max(0.1, Math.min(0.9, (e.clientY - rect.top) / rect.height));
|
|
splitRatio = newRatio;
|
|
} else {
|
|
// Calculate new split ratio based on horizontal position
|
|
const newRatio = Math.max(0.1, Math.min(0.9, (e.clientX - rect.left) / rect.width));
|
|
splitRatio = newRatio;
|
|
}
|
|
|
|
// Update layout and divider position
|
|
setLayout(layoutType, splitRatio);
|
|
updateDividerPosition();
|
|
});
|
|
|
|
document.addEventListener('mouseup', () => {
|
|
if (isDragging) {
|
|
isDragging = false;
|
|
divider.classList.remove('dragging');
|
|
|
|
// Re-enable pointer events on the iframe
|
|
const iframe = document.getElementById('target');
|
|
iframe.style.pointerEvents = 'auto';
|
|
}
|
|
});
|
|
|
|
// Initialize
|
|
setLayout(
|
|
layoutType,
|
|
splitRatio,
|
|
);
|
|
updateDividerPosition();
|
|
</script>
|
|
</body>
|
|
|
|
</html>
|