feat(voyage): implement renderTopbar with badge--scope-voyage and breadcrumb

This commit is contained in:
Kjell Tore Guttormsen 2026-05-10 16:15:02 +02:00
commit 0eb56edb6d

View file

@ -475,15 +475,7 @@
</head>
<body>
<a class="visually-hidden" href="#main">Skip to main content</a>
<header class="app-header">
<div class="app-header__title">Voyage Annotation Playground</div>
<div class="app-header__meta">v4.2 · brief / plan / review</div>
<div class="app-header__actions" role="group" aria-label="Hovednavigasjon">
<button type="button" class="theme-toggle" data-action="toggle-theme" aria-label="Bytt tema">
<span data-theme-label aria-hidden="true"></span>
</button>
</div>
</header>
<header class="app-header" id="app-header" data-renderable></header>
<main id="main">
<section
class="guide-panel guide-panel--info"
@ -799,6 +791,41 @@ playground first-run shows a complete round-trip-able artifact.
return fm;
}
// ---- v4.3 Step 8 — renderTopbar -----------------------------------
// Generate dynamic app-header from a crumb-array. Each entry:
// { label: 'Hjem', href: '#' } → trailing entry has no href
// Pattern follows llm-security-playground.html renderTopbar; voyage
// tokens via badge--scope-voyage.
function renderTopbar(crumb) {
var host = document.getElementById('app-header');
if (!host) return;
var items = Array.isArray(crumb) && crumb.length ? crumb : [{ label: 'Voyage' }];
var crumbHtml = items.map(function (c, i) {
var sep = i > 0 ? '<span aria-hidden="true"> · </span>' : '';
var label = escapeHtml(c.label || '');
var node = c.href
? '<a href="' + escapeHtml(c.href) + '">' + label + '</a>'
: '<span aria-current="page">' + label + '</span>';
return sep + node;
}).join('');
host.innerHTML =
'<a class="app-header__brand" href="#main-content">' +
'<span class="app-header__brand-mark" aria-hidden="true">V</span>' +
'<span>Voyage Annotation Playground</span>' +
'<span class="badge badge--scope-voyage">Voyage</span>' +
'</a>' +
'<nav class="app-header__breadcrumb" aria-label="Brødsmuler">' +
crumbHtml +
'</nav>' +
'<div class="app-header__spacer"></div>' +
'<div class="app-header__actions" role="group" aria-label="Hovednavigasjon">' +
'<button type="button" class="btn btn--primary" data-action="open-project-picker">Velg prosjektmappe</button>' +
'<button type="button" class="theme-toggle" data-action="toggle-theme" aria-label="Bytt tema">' +
'<span data-theme-label aria-hidden="true"></span>' +
'</button>' +
'</div>';
}
// ---- DOM wiring ----------------------------------------------------
function $(id) { return document.getElementById(id); }
@ -1504,6 +1531,10 @@ playground first-run shows a complete round-trip-able artifact.
// Sun icon (☀) in dark mode, moon icon (☾) in light mode. Click toggles
// data-theme + colorScheme, persists to localStorage('voyage-theme').
wireThemeToggle();
// Step 8 (v4.3) — initial topbar render with single-crumb (voyage root).
// renderDashboard / drill-down (Wave 3) re-renders with deeper crumbs.
renderTopbar([{ label: 'Hjem' }]);
}
function setThemeLabel(theme) {