feat(dashboard): extend shift+click suggestions to sidebar navigation

- Click handler: sidebar <a> and <summary> are no longer excluded;
  e.preventDefault() stops navigation while shift is held
- _inferWidgetName: sidebar-first branch returns nav link text,
  section heading text, or "Navigation" fallback
- pageName is "Navigation" for sidebar clicks (not the current page title)
- CSS: sidebar a and summary highlighted (dashed indigo outline + tint)
  when shift is held, same as main content widgets

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-18 01:29:13 +01:00
parent 1f1da56533
commit e7565ce789

View File

@@ -149,7 +149,9 @@ function _ensureStyles() {
.impr-mode-shift #observablehq-main h2,
.impr-mode-shift #observablehq-main h3,
.impr-mode-shift #observablehq-main h4,
.impr-mode-shift #observablehq-main [data-widget-name] {
.impr-mode-shift #observablehq-main [data-widget-name],
.impr-mode-shift #observablehq-sidebar a,
.impr-mode-shift #observablehq-sidebar summary {
outline: 1px dashed rgba(99, 102, 241, 0.45);
background: rgba(99, 102, 241, 0.055) !important;
border-radius: 4px;
@@ -161,6 +163,15 @@ function _ensureStyles() {
/* ── Widget name inference ─────────────────────────────────────────────── */
function _inferWidgetName(target) {
// 0. Sidebar navigation: nav link text or section heading
if (target.closest("#observablehq-sidebar")) {
const link = target.closest("a");
if (link) return link.textContent.trim() || "Nav link";
const summary = target.closest("summary");
if (summary) return summary.textContent.trim() || "Nav section";
return target.textContent.trim() || "Navigation";
}
// 1. Explicit data-widget-name on self or ancestor
let el = target;
while (el && el !== document.body) {
@@ -238,15 +249,19 @@ export function initImprovementModal({ apiBase = "http://127.0.0.1:8000", domain
document.addEventListener("click", (e) => {
if (!e.shiftKey) return;
// Don't intercept shift-clicks on form controls or links
if (e.target.matches("input, textarea, select, a, button")) return;
const inSidebar = !!e.target.closest("#observablehq-sidebar");
// Block shift-clicks on form controls; allow sidebar links (preventDefault stops navigation)
if (!inSidebar && e.target.matches("input, textarea, select, a, button")) return;
if (inSidebar && e.target.matches("input, textarea, select")) return;
e.preventDefault();
const widgetName = _inferWidgetName(e.target);
const pageName = document.title
? document.title.replace(" Custodian State Hub", "").trim()
: (location.pathname.replace(/^\//, "") || "Overview");
const pageName = inSidebar
? "Navigation"
: (document.title
? document.title.replace(" Custodian State Hub", "").trim()
: (location.pathname.replace(/^\//, "") || "Overview"));
// Remove any open modal
document.getElementById("_impr-root")?.remove();