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
This commit is contained in:
@@ -47,11 +47,11 @@ button:hover { background: var(--accent-hover); }
|
||||
}
|
||||
.btn-small:hover { color: var(--text); background: var(--border); }
|
||||
|
||||
/* Grid layout — 2 columns: editor | preview+console */
|
||||
/* Grid layout — 2 columns with dividers: editor | divider | preview+console */
|
||||
.grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-template-rows: 1fr 1fr;
|
||||
grid-template-columns: 1fr 4px 1fr;
|
||||
grid-template-rows: 1fr 4px 1fr;
|
||||
height: calc(100vh - var(--toolbar-h));
|
||||
}
|
||||
.panel { position: relative; border: 1px solid var(--border); overflow: hidden; display: flex; flex-direction: column; }
|
||||
@@ -65,9 +65,39 @@ button:hover { background: var(--accent-hover); }
|
||||
}
|
||||
|
||||
/* Editor panel — full left column */
|
||||
.panel-editor { grid-column: 1; grid-row: 1 / 3; display: flex; flex-direction: column; }
|
||||
.panel-preview { grid-column: 2; grid-row: 1; }
|
||||
.panel-console { grid-column: 2; grid-row: 2; }
|
||||
.panel-editor { grid-column: 1; grid-row: 1 / 4; display: flex; flex-direction: column; }
|
||||
.divider-col { grid-column: 2; grid-row: 1 / 4; cursor: col-resize; background: var(--border); }
|
||||
.divider-col:hover { background: var(--accent); }
|
||||
.panel-preview { grid-column: 3; grid-row: 1; }
|
||||
.divider-row { grid-column: 3; grid-row: 2; cursor: row-resize; background: var(--border); }
|
||||
.divider-row:hover { background: var(--accent); }
|
||||
.panel-console { grid-column: 3; grid-row: 3; }
|
||||
|
||||
/* Disable iframe pointer-events while dragging */
|
||||
body.resizing iframe { pointer-events: none; }
|
||||
|
||||
/* Layout variants */
|
||||
.layout-top-bottom .panel-editor { grid-column: 1 / 4; grid-row: 1; }
|
||||
.layout-top-bottom .divider-col { display: none; }
|
||||
.layout-top-bottom .panel-preview { grid-column: 1; grid-row: 3; }
|
||||
.layout-top-bottom .divider-row { grid-column: 1 / 4; grid-row: 2; cursor: row-resize; }
|
||||
.layout-top-bottom .panel-console { grid-column: 2 / 4; grid-row: 3; }
|
||||
.layout-top-bottom {
|
||||
grid-template-columns: 1fr 4px 1fr;
|
||||
grid-template-rows: 1fr 4px 1fr;
|
||||
}
|
||||
|
||||
.layout-editor-only .panel-editor { grid-column: 1 / 4; grid-row: 1 / 4; }
|
||||
.layout-editor-only .divider-col,
|
||||
.layout-editor-only .divider-row,
|
||||
.layout-editor-only .panel-preview,
|
||||
.layout-editor-only .panel-console { display: none; }
|
||||
|
||||
.layout-preview-only .panel-preview { grid-column: 1 / 4; grid-row: 1 / 4; }
|
||||
.layout-preview-only .divider-col,
|
||||
.layout-preview-only .divider-row,
|
||||
.layout-preview-only .panel-editor,
|
||||
.layout-preview-only .panel-console { display: none; }
|
||||
|
||||
/* Tab bar */
|
||||
.tab-bar {
|
||||
@@ -139,6 +169,41 @@ button:hover { background: var(--accent-hover); }
|
||||
.console-info { color: #3dc9b0; }
|
||||
.console-debug { color: #888; }
|
||||
|
||||
/* Vim status bar */
|
||||
.vim-status-bar {
|
||||
display: none;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
padding: 0 10px;
|
||||
font-family: 'Cascadia Code', 'Fira Code', monospace;
|
||||
font-size: 12px;
|
||||
background: var(--surface);
|
||||
color: var(--text-dim);
|
||||
border-top: 1px solid var(--border);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* Auto-run toggle */
|
||||
.auto-run-toggle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
font-size: 12px;
|
||||
color: var(--text-dim);
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
.auto-run-toggle input { cursor: pointer; }
|
||||
|
||||
/* Dividers */
|
||||
.divider { background: var(--border); transition: background 0.15s; z-index: 2; }
|
||||
|
||||
/* Layout/keybinding selects — match framework select */
|
||||
#layout-mode, #keybinding-mode {
|
||||
background: var(--bg); color: var(--text); border: 1px solid var(--border);
|
||||
padding: 4px 6px; border-radius: 4px; font-size: 12px; cursor: pointer;
|
||||
}
|
||||
|
||||
/* Toast */
|
||||
.toast {
|
||||
position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%);
|
||||
|
||||
Reference in New Issue
Block a user