Compare commits

...

2 commits

Author SHA1 Message Date
a6cb847f2f fix(browse): YAML editor cut off at viewport bottom
.preview-pane__body was flex: 1 + display: flex; flex-direction:
column but without min-height: 0. The flex item's default
min-height is min-content (its natural content size), so when the
YAML editor's CodeMirror viewport carried many lines, the body
grew to fit the editor instead of letting the editor scroll
internally. The chain ran out of viewport before reaching the
editor's bottom edge; the body's own scroll bottomed out at a
height that still cropped the last few lines.

Adding min-height: 0 lets the body shrink to its flex-allocated
size so CodeMirror's internal scroll takes over correctly. Same
root cause as the standard flex+overflow papercut documented in
half the CSS guides on the internet — fine to add unconditionally,
no other consumers of .preview-pane__body care.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 12:27:49 -05:00
889aa78589 refactor(browse): drop status-bar footer, route messages to toasts
The persistent #statusBar strip held whatever last-action message
was written ("Loaded N items", "Created folder X", error text, …)
and stuck around indefinitely, overlapping content while adding
little value. Deleted the strip; existing statusInfo/statusError
call sites now thunk through window.zddc.toast (the shared toast
helper every tool already bundles).

  - Same function signatures: events.statusInfo /
    events.statusError keep working without touching the 70+ call
    sites across app.js, download.js, events.js, etc.
  - plan-review.js had its own private statusInfo/statusError pair
    (duplicated the DOM write); updated to route through
    zddc.toast as well.
  - statusClear becomes a no-op — toasts fade on their own (5s
    info, 8s error via cap-toast) and the toast helper's
    single-toast policy guarantees only the latest is visible.

Removed: #statusBar div from template.html, .status-bar / .is-error
/ .is-info / --error / --info rules from base.css and tree.css.
Zero remaining `statusBar` or `status-bar` references in the built
browse.html. Full Playwright suite green (243/0/4).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 12:19:40 -05:00
5 changed files with 23 additions and 49 deletions

View file

@ -26,21 +26,6 @@ body {
/* .hidden lives in shared/base.css; no per-tool override needed. */
/* Status bar — shows transient errors/info */
.status-bar {
padding: 0.4rem 1rem;
background: var(--bg-secondary);
border-top: 1px solid var(--border);
font-size: 0.85rem;
color: var(--text-muted);
min-height: 1.6rem;
line-height: 1.6rem;
flex-shrink: 0;
}
.status-bar--error { color: #b00020; }
.status-bar--info { color: var(--primary); }
/* Read-only banner for the YAML editor surfaced by preview-yaml.js
when the listing's `writable` bit was false. CodeMirror's readOnly
mode has no built-in visual signal beyond the disabled caret, so a

View file

@ -244,6 +244,11 @@ body {
.preview-pane__body {
flex: 1;
min-height: 0; /* critical: lets the flex child shrink to fit
the viewport instead of growing to its
content's natural size (which clips the
YAML editor's bottom when there are many
lines, even with the editor's own scroll) */
overflow: auto;
display: flex;
flex-direction: column;
@ -575,21 +580,6 @@ body {
color: var(--text-muted);
}
/* ── Status bar ──────────────────────────────────────────────────────────── */
.status-bar {
padding: 0.4rem 1rem;
background: var(--bg-secondary);
border-top: 1px solid var(--border);
font-size: 0.8rem;
color: var(--text-muted);
min-height: 1.6rem;
flex-shrink: 0;
}
.status-bar.is-error { color: var(--danger); }
.status-bar.is-info { color: var(--text); }
/* ── Markdown plugin (right-pane internals when a .md is selected) ──────── */
/* CSS-Grid shell mirroring mdedit's layout: sidebar on the LEFT
(front matter top + TOC bottom), content on the RIGHT (informational

View file

@ -10,18 +10,21 @@
// call time, not at IIFE-eval time.
function previewMod() { return window.app.modules.preview; }
// Notifications route through the shared toast helper (shared/
// toast.js) — there's no persistent footer strip in browse. Same
// signatures as before so the 70+ existing call sites work
// unchanged; statusClear is a no-op (toasts fade on their own and
// single-toast policy guarantees only the latest is visible).
function status(msg, kind) {
var el = document.getElementById('statusBar');
if (!el) return;
el.textContent = msg || '';
el.classList.remove('status-bar--error', 'status-bar--info');
if (kind === 'error') el.classList.add('status-bar--error');
if (kind === 'info') el.classList.add('status-bar--info');
if (!msg) return;
if (!window.zddc || typeof window.zddc.toast !== 'function') return;
var level = kind === 'error' ? 'error' : 'info';
window.zddc.toast(msg, level);
}
function statusError(msg) { status(msg, 'error'); }
function statusInfo(msg) { status(msg, 'info'); }
function statusClear() { status('', null); }
function statusClear() { /* no-op — toasts fade on their own */ }
async function pickLocalDir() {
if (typeof window.showDirectoryPicker !== 'function') {

View file

@ -32,19 +32,17 @@
var REVIEW_OFFSET_DAYS = 7;
var RESPONSE_OFFSET_DAYS = 14;
// Notifications go through the shared toast helper — there's no
// persistent footer strip in browse anymore.
function statusInfo(msg) {
var el = document.getElementById('statusBar');
if (!el) return;
el.textContent = msg || '';
el.classList.remove('status-bar--error');
el.classList.add('status-bar--info');
if (msg && window.zddc && typeof window.zddc.toast === 'function') {
window.zddc.toast(msg, 'info');
}
}
function statusError(msg) {
var el = document.getElementById('statusBar');
if (!el) return;
el.textContent = msg || '';
el.classList.remove('status-bar--info');
el.classList.add('status-bar--error');
if (msg && window.zddc && typeof window.zddc.toast === 'function') {
window.zddc.toast(msg, 'error');
}
}
// Compute today + N days as a YYYY-MM-DD string.

View file

@ -98,8 +98,6 @@
</div>
</main>
<div id="statusBar" class="status-bar"></div>
<!-- Help Panel -->
<aside id="help-panel" class="help-panel" hidden aria-labelledby="help-panel-title">
<div class="help-panel__header">