Files
fiddle/public/js/resizer.js
root 7f51af17a3 Add editor experience features: auto-run, layouts, resizable panels, Emmet, vim/emacs
- Auto-run toggle with localStorage persistence (toolbar checkbox)
- Layout selector: default, top/bottom, editor-only, preview-only
- Resizable panels via drag dividers with double-click reset
- Emmet abbreviation expansion for HTML, CSS, and JSX
- Vim and Emacs keybinding modes with lazy-loaded CDN libraries
- Shared preferences module for localStorage management
- Editor hooks for tab switch and mode change callbacks
2026-02-26 11:19:14 -06:00

92 lines
2.5 KiB
JavaScript

import { getPref, setPref } from './preferences.js';
import { relayoutEditors } from './editors.js';
let grid = null;
let colDivider = null;
let rowDivider = null;
let dragging = null; // 'col' | 'row' | null
export function initResizer() {
grid = document.querySelector('.grid');
colDivider = document.getElementById('divider-col');
rowDivider = document.getElementById('divider-row');
if (!grid || !colDivider || !rowDivider) return;
// Restore saved sizes
const saved = getPref('panelSizes');
if (saved) applySizes(saved);
// Column divider (horizontal drag)
colDivider.addEventListener('mousedown', (e) => startDrag(e, 'col'));
colDivider.addEventListener('dblclick', () => resetSizes());
// Row divider (vertical drag)
rowDivider.addEventListener('mousedown', (e) => startDrag(e, 'row'));
rowDivider.addEventListener('dblclick', () => resetSizes());
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', onMouseUp);
}
function startDrag(e, type) {
e.preventDefault();
dragging = type;
document.body.classList.add('resizing');
}
function onMouseMove(e) {
if (!dragging) return;
const rect = grid.getBoundingClientRect();
if (dragging === 'col') {
const x = e.clientX - rect.left;
const total = rect.width;
const pct = Math.max(0.15, Math.min(0.85, x / total));
const left = pct;
const right = 1 - pct;
grid.style.gridTemplateColumns = `${left}fr 4px ${right}fr`;
} else if (dragging === 'row') {
const y = e.clientY - rect.top;
const total = rect.height;
const pct = Math.max(0.15, Math.min(0.85, y / total));
const top = pct;
const bottom = 1 - pct;
grid.style.gridTemplateRows = `${top}fr 4px ${bottom}fr`;
}
relayoutEditors();
}
function onMouseUp() {
if (!dragging) return;
dragging = null;
document.body.classList.remove('resizing');
// Persist current sizes
const sizes = {
cols: grid.style.gridTemplateColumns || null,
rows: grid.style.gridTemplateRows || null,
};
setPref('panelSizes', sizes);
relayoutEditors();
}
function applySizes(sizes) {
if (sizes.cols) grid.style.gridTemplateColumns = sizes.cols;
if (sizes.rows) grid.style.gridTemplateRows = sizes.rows;
}
export function resetSizes() {
grid.style.gridTemplateColumns = '';
grid.style.gridTemplateRows = '';
setPref('panelSizes', null);
relayoutEditors();
}
export function clearInlineSizes() {
grid.style.gridTemplateColumns = '';
grid.style.gridTemplateRows = '';
}