From 6db7c72511cd6548824616a9e01600c44832edc4 Mon Sep 17 00:00:00 2001 From: Kjell Tore Guttormsen Date: Sun, 10 May 2026 17:09:26 +0200 Subject: [PATCH] feat(voyage): implement hidden-by-default sidebar-rail with ordered list + filter + jumplist count MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Step 19 of v4.3 playground plan. Sidebar now default aria-hidden=true (translateX collapses panel, leaves 40px FAB rail). FAB toggle has data-action=toggle-sidebar for keyboard binding (] in Step 20). New annotation-list section in sidebar panel: - filter radiogroup: Alle (default), Åpne (unresolved), Resolved - voyage-jumplist ordered list with numbered badges matching the gutter-badge ordering (sorted by line ASC) - aria-live jumplist count: "X av N" (filtered/total) - click list-item -> setActiveAnchor + scrollIntoView + data-active renderAnnotationList wires into mountRender so list refreshes on every render. Filter state (voyageFilterState) persists across renders within the session. Trace: SC6, research/04 Dim 1 (hidden-by-default) + Insight 1 + Recommendation sidebar/navigation. --- .../voyage/playground/voyage-playground.html | 181 +++++++++++++++++- .../playground/voyage-playground.test.mjs | 29 +++ 2 files changed, 201 insertions(+), 9 deletions(-) diff --git a/plugins/voyage/playground/voyage-playground.html b/plugins/voyage/playground/voyage-playground.html index b8f7101..aa8bccc 100644 --- a/plugins/voyage/playground/voyage-playground.html +++ b/plugins/voyage/playground/voyage-playground.html @@ -555,6 +555,78 @@ } .voyage-fab__badge[hidden] { display: none; } + /* v4.3 Step 19 — annotation-list (sidebar): filter buttons + ordered list + jumplist count */ + .voyage-annotation-list { + display: flex; + flex-direction: column; + padding: var(--space-3); + border-bottom: 1px solid var(--color-border-subtle); + } + .voyage-annotation-list__header { + display: flex; + align-items: center; + justify-content: space-between; + gap: var(--space-2); + margin-bottom: var(--space-2); + } + .voyage-annotation-list__filter { + display: inline-flex; + gap: var(--space-1); + } + .voyage-filter-btn { + padding: 0.15rem 0.5rem; + border: 1px solid var(--color-border-subtle); + background: var(--color-surface); + border-radius: var(--radius-sm); + cursor: pointer; + font-size: var(--font-size-xs); + } + .voyage-filter-btn[aria-pressed="true"] { + background: var(--color-scope-voyage); + color: #fff; + border-color: var(--color-scope-voyage); + } + .voyage-annotation-list__count { + font-size: var(--font-size-xs); + color: var(--color-text-tertiary, var(--color-text-secondary)); + white-space: nowrap; + } + .voyage-annotation-list__items { + list-style: none; + padding: 0; + margin: 0; + max-height: 30vh; + overflow-y: auto; + } + .voyage-annotation-list__items li { + padding: var(--space-2); + border-radius: var(--radius-sm); + cursor: pointer; + font-size: var(--font-size-sm); + display: flex; + align-items: center; + gap: var(--space-2); + } + .voyage-annotation-list__items li:hover { + background: var(--color-bg-soft); + } + .voyage-annotation-list__items li[data-active="true"] { + background: rgba(255, 235, 59, 0.18); + } + .voyage-annotation-list__items .voyage-jumplist-num { + flex: 0 0 auto; + width: 1.25rem; + height: 1.25rem; + border-radius: 50%; + background: var(--color-scope-voyage); + color: #fff; + font-size: 0.7rem; + font-weight: 600; + display: inline-flex; + align-items: center; + justify-content: center; + } + /* Tabs */ [role="tablist"].voyage-tabs { display: flex; @@ -816,20 +888,23 @@ - +