<!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">
<iframe id="target"></iframe>
<div id="divider"></div>
<div id="devtools"></div>
</div>
<script src="dist/app-devtools.js"></script>
<script type="module">
let layoutType = 'leftright';
let splitRatio = 0.5;
let isDragging = false;
const layout = document.getElementById('layout');
function setLayout(layoutType, splitRatio) {
const panes = document.getElementById('panes');
if (layoutType === 'topbottom') {
panes.style.gridTemplateColumns = '100%';
panes.style.gridTemplateRows = `${splitRatio * 100}% ${(1 - splitRatio) * 100}%`;
} else if (layoutType === 'leftright') {
panes.style.gridTemplateRows = '100%';
panes.style.gridTemplateColumns = `${splitRatio * 100}% ${(1 - splitRatio) * 100}%`;
}
}
layout.addEventListener('change', () => {
layoutType = layout.value;
setLayout(layoutType, splitRatio);
updateDividerPosition();
});
const divider = document.getElementById('divider');
function updateDividerPosition() {
if (layoutType === 'topbottom') {
divider.className = 'horizontal-divider';
divider.style.top = `calc(${splitRatio * 100}% - 2.5px)`;
divider.style.left = '0';
} else {
divider.className = 'vertical-divider';
divider.style.left = `calc(${splitRatio * 100}% - 2.5px)`;
divider.style.top = '0';
}
}
divider.addEventListener('mousedown', (e) => {
isDragging = true;
divider.classList.add('dragging');
const iframe = document.getElementById('target');
iframe.style.pointerEvents = 'none';
e.preventDefault();
});
document.addEventListener('mousemove', (e) => {
if (!isDragging) return;
const panes = document.getElementById('panes');
const rect = panes.getBoundingClientRect();
if (layoutType === 'topbottom') {
const newRatio = Math.max(0.1, Math.min(0.9, (e.clientY - rect.top) / rect.height));
splitRatio = newRatio;
} else {
const newRatio = Math.max(0.1, Math.min(0.9, (e.clientX - rect.left) / rect.width));
splitRatio = newRatio;
}
setLayout(layoutType, splitRatio);
updateDividerPosition();
});
document.addEventListener('mouseup', () => {
if (isDragging) {
isDragging = false;
divider.classList.remove('dragging');
const iframe = document.getElementById('target');
iframe.style.pointerEvents = 'auto';
}
});
setLayout(
layoutType,
splitRatio,
);
updateDividerPosition();
</script>
</body>
</html>