fix(editor-v2): reserve editor slot to stop layout shift on mount
The previous flicker fix hid the textarea via CSS but display: none removes it from layout entirely — so the page rendered with zero height where the editor would go, then cm6 mounted and pushed the surrounding form down by its full height (CLS). Wrap each editor textarea in <div class="editor-mount" style="min-height: …rem"> so the slot is reserved before cm6 mounts. The wrapper is a flex column with cm6 as flex: 1 so cm6 fills the reserved space rather than collapsing to content-height with a gap below (the seeded blueprint has 2 chars of content; without flex the editor would shrink to one line). Min-heights calibrated to rows × ~1.25rem + ~1.5rem chrome: - config (rows=8) → 12rem - files (rows=14) → 19rem - script (rows=20) → 27rem .cm-editor's own min-height: 8em rule removed — the wrapper is the floor now, and the inner cm6 stretches to fill via flex. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
fd0d96b349
commit
b915f2e766
3 changed files with 15 additions and 4 deletions
|
|
@ -9,10 +9,21 @@
|
||||||
* in _editor_assets.html un-hides for JS-disabled users. */
|
* in _editor_assets.html un-hides for JS-disabled users. */
|
||||||
textarea[data-editor-language] { display: none; }
|
textarea[data-editor-language] { display: none; }
|
||||||
|
|
||||||
|
/* Wrapper that reserves layout space before cm6 mounts, sized by the
|
||||||
|
* inline `min-height` style each call site sets to match the original
|
||||||
|
* textarea's `rows`. cm6 is a flex child that fills the reserved space
|
||||||
|
* (otherwise short content would render cm6 small with a gap below). */
|
||||||
|
.editor-mount {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.editor-mount > .cm-editor {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
.cm-editor {
|
.cm-editor {
|
||||||
border: var(--line);
|
border: var(--line);
|
||||||
border-radius: var(--radius-s);
|
border-radius: var(--radius-s);
|
||||||
min-height: 8em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.cm-editor.cm-focused {
|
.cm-editor.cm-focused {
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@
|
||||||
<pre class="config-preview" aria-label="Auto-loaded overlay configs">{% for o in exposed %}exec {{ o.name }}.cfg
|
<pre class="config-preview" aria-label="Auto-loaded overlay configs">{% for o in exposed %}exec {{ o.name }}.cfg
|
||||||
{% endfor %}</pre>
|
{% endfor %}</pre>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<textarea name="config" rows="8" spellcheck="false" data-editor-language="srccfg">{{ config_lines | join('\n') }}</textarea>
|
<div class="editor-mount" style="min-height: 12rem"><textarea name="config" rows="8" spellcheck="false" data-editor-language="srccfg">{{ config_lines | join('\n') }}</textarea></div>
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
<button type="submit">Save blueprint</button>
|
<button type="submit">Save blueprint</button>
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@
|
||||||
<form method="post" action="/overlays/{{ overlay.id }}/script" class="stack">
|
<form method="post" action="/overlays/{{ overlay.id }}/script" class="stack">
|
||||||
<input type="hidden" name="csrf_token" value="{{ session.get('csrf_token', '') }}">
|
<input type="hidden" name="csrf_token" value="{{ session.get('csrf_token', '') }}">
|
||||||
<label>Bash script
|
<label>Bash script
|
||||||
<textarea name="script" rows="20" spellcheck="false" data-editor-language="bash">{{ overlay.script or "" }}</textarea>
|
<div class="editor-mount" style="min-height: 27rem"><textarea name="script" rows="20" spellcheck="false" data-editor-language="bash">{{ overlay.script or "" }}</textarea></div>
|
||||||
</label>
|
</label>
|
||||||
<p class="muted">Runs sandboxed against the overlay directory mounted at <code>/overlay</code>.</p>
|
<p class="muted">Runs sandboxed against the overlay directory mounted at <code>/overlay</code>.</p>
|
||||||
{% if not latest_build_is_running %}
|
{% if not latest_build_is_running %}
|
||||||
|
|
@ -186,7 +186,7 @@
|
||||||
</label>
|
</label>
|
||||||
<label class="files-editor-field">
|
<label class="files-editor-field">
|
||||||
<span class="files-field-label">Content</span>
|
<span class="files-field-label">Content</span>
|
||||||
<textarea class="files-editor-content" rows="14" spellcheck="false" data-editor-language="auto"></textarea>
|
<div class="editor-mount" style="min-height: 19rem"><textarea class="files-editor-content" rows="14" spellcheck="false" data-editor-language="auto"></textarea></div>
|
||||||
</label>
|
</label>
|
||||||
<div class="files-editor-meta muted">
|
<div class="files-editor-meta muted">
|
||||||
<span class="files-editor-byte-count">UTF-8 · 0 bytes</span>
|
<span class="files-editor-byte-count">UTF-8 · 0 bytes</span>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue