feat(maestro): port the sidebar to React

Ports catalog.ts's tree renderer to components under
src/components/sidebar/, following docs/SIDEBAR.md: two-line cards
behind a 5px activity rail, adaptive meta line (duration, detail,
program, diff stat), collapsible folders, j/k walk, inline rename and a
right-click menu.

The nav walk reads a pure model (model.ts) rather than the DOM, so the
rule that an expanded folder header is skipped and a collapsed one is
not is testable without a render. Rail motion needs @keyframes, so it
stays in sidebar.css rather than the Tailwind config.

Closes #244
This commit is contained in:
Miguel Palhas
2026-09-09 00:21:13 +01:00
parent b286323c9c
commit e8e98baf4d
13 changed files with 1343 additions and 0 deletions
+16
View File
@@ -0,0 +1,16 @@
import { useEffect, useState } from "react";
/** A clock that ticks at least every `intervalMs` while the page is visible.
* docs/SIDEBAR.md asks for a re-render at least every 30s so the duration's
* cutover points land within one tick. */
export function useNow(intervalMs = 30_000): number {
const [now, setNow] = useState(() => Date.now());
useEffect(() => {
const id = setInterval(() => {
if (document.visibilityState !== "visible") return;
setNow(Date.now());
}, intervalMs);
return () => clearInterval(id);
}, [intervalMs]);
return now;
}