JSFiddle - React, Tailwind, and code Playground
by ckissi
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Code Editor</title>
<link rel="stylesheet" href="/style.css" />
</head>
<body>
<div class="toolbar">
<button id="toggle-layout" class="toolbar-btn">
Toggle Layout
</button>
</div>
<div class="editor" data-layout="split">
<div class="left-pane">
<div class="pane" id="html-pane">
<div class="pane-header">HTML</div>
<textarea id="html-editor" spellcheck="false"></textarea>
</div>
<div class="resizer" data-direction="vertical"></div>
<div class="pane" id="css-pane">
<div class="pane-header">CSS</div>
<textarea id="css-editor" spellcheck="false"></textarea>
</div>
<div class="resizer" data-direction="vertical"></div>
<div class="pane" id="js-pane">
<div class="pane-header">JavaScript</div>
<textarea id="js-editor" spellcheck="false"></textarea>
</div>
</div>
<div class="resizer" data-direction="horizontal"></div>
<div class="right-pane">
<div class="pane preview-container">
<div class="pane-header">
Preview
<button id="run-btn">Run</button>
</div>
<iframe id="preview-frame"></iframe>
</div>
</div>
</div>
<script type="module" src="/main.js"></script>
</body>
</html>
CSS
:root {
--header-height: 40px;
--toolbar-height: 50px;
--resizer-size: 4px;
--header-bg: #1a1a1a;
--pane-bg: #242424;
--resizer-color: #444;
--text-color: #fff;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
color: var(--text-color);
background-color: var(--pane-bg);
height: 100vh;
overflow: hidden;
display: flex;
flex-direction: column;
}
.toolbar {
height: var(--toolbar-height);
background: var(--header-bg);
display: flex;
align-items: center;
padding: 0 1rem;
border-bottom: 1px solid var(--resizer-color);
}
.toolbar-btn {
padding: 6px 16px;
background: #646cff;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 0.9rem;
}
.toolbar-btn:hover {
background: #747bff;
}
.editor {
display: flex;
flex: 1;
gap: var(--resizer-size);
padding: var(--resizer-size);
}
/* Grid Layout */
.editor[data-layout="grid"] {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(3, 1fr);
gap: var(--resizer-size);
}
.editor[data-layout="grid"] #html-pane {
grid-column: 1;
grid-row: 1;
}
.editor[data-layout="grid"] #css-pane {
grid-column: 1;
grid-row: 2;
}
.editor[data-layout="grid"] #js-pane {
grid-column: 1;
grid-row: 3;
}
.editor[data-layout="grid"] .preview-container {
grid-column: 2;
grid-row: 1 / span 3;
}
/* Split Layout */
.editor[data-layout="split"] {
flex-direction: row;
}
.editor[data-layout="split"] .editors-container {
display: flex;
flex-direction: column;
gap: var(--resizer-size);
width: 50%;
}
.editor[data-layout="split"] .preview-container {
width: 50%;
}
.pane {
background: var(--pane-bg);
border-radius: 4px;
overflow: hidden;
flex: 1;
display: flex;
flex-direction: column;
min-height: 0;
}
.pane-header {
height: var(--header-height);
background: var(--header-bg);
padding: 0 1rem;
display:...
JavaScript
// Layout management
function initializeLayout() {
const editor = document.querySelector('.editor');
const toggleBtn = document.getElementById('toggle-layout');
const leftPane = document.querySelector('.left-pane');
const rightPane = document.querySelector('.right-pane');
const jsPane = document.getElementById('js-pane');
toggleBtn.addEventListener('click', () => {
const currentLayout = editor.dataset.layout;
const newLayout = currentLayout === 'split' ? 'split2' : 'split';
editor.dataset.layout = newLayout;
if (newLayout === 'split2') {
// Move JS pane to right side
rightPane.insertBefore(jsPane, rightPane.firstChild);
} else {
// Move JS pane back to left side
const cssPane = document.getElementById('css-pane');
leftPane.insertBefore(jsPane, null);
}
// Reset flex styles when switching layouts
const containers = document.querySelectorAll('.pane');
containers.forEach(container => {
container.style.flex = '1';
container.style.width = '';
});
});
}
// Initialize resizable panes
function initializeResizers() {
const resizers = document.querySelectorAll('.resizer');
resizers.forEach(resizer => {
resizer.addEventListener('mousedown', startResize);
});
}
function startResize(e) {
e.preventDefault();
const resizer = e.target;
const direction = resizer.dataset.direction;
const isHorizontal = direction === 'horizontal';
const prevSibling = resizer.previousElementSibling;
const nextSibling = resizer.nextElementSibling;
// Get initial dimensions
const initialSize = isHorizontal
? prevSibling.offsetWidth
: prevSibling.offsetHeight;
const initialPos = isHorizontal ? e.clientX : e.clientY;
// Add event listeners for resize
document.addEventListener('mousemove', resize);
document.addEventListener('mouseup', stopResize);
function resize(e) {
const currentPos = isHorizontal ? e.clientX : e.clientY;
...