feat: keyboard waves A/B — global shortcut registry, question row machine, Esc-cancel dictation
Wave A (owner key map): registry in src/core/keyboard.ts + KeyboardShortcuts
provider; Cmd+D dictation, Cmd+K model picker, Shift+Tab thinking cycle,
Cmd+B sidebar, Cmd+Shift+F sessions search, Alt+arrows session cycle,
Alt+Enter open, Cmd+G graph, Cmd+N new, F2 rename, ? cheat sheet. Tab
fully suppressed; Esc chain popover > dictation > abort (local stream).
Esc now CANCELS dictation (discard) — flush stays on Cmd+D/Stop. Owner
bug reports fixed: focus outline removed, Alt+Enter setState-in-render,
Cmd+F graph node search (surface-scoped lh:kbd-find).
Wave B: question dock row machine — arrows walk options + dont-know/Other
with wrap + ring highlight, Space picks (mirrors click semantics), Enter
submits when canSubmit; typing surfaces and in-dock keys keep native
behavior. aria-checked={isSel} restored on option buttons.
docs/keyboard.md records the full map.
This commit is contained in:
@@ -598,6 +598,14 @@ export function GraphView() {
|
||||
|
||||
// Search panel state: the query text + the settings section toggle.
|
||||
const [query, setQuery] = useState("");
|
||||
// ⌘F (shortcut wave C): the find event focuses the node search —
|
||||
// surface-scoped, dispatched as lh:kbd-find (only this page listens).
|
||||
const searchInputRef = useRef<HTMLInputElement>(null);
|
||||
useEffect(() => {
|
||||
const onFind = () => searchInputRef.current?.focus();
|
||||
window.addEventListener("lh:kbd-find", onFind);
|
||||
return () => window.removeEventListener("lh:kbd-find", onFind);
|
||||
}, []);
|
||||
// Render settings: SERVER-persisted (data/render-settings.json via
|
||||
// /api/graph/render-settings) — sizes AND the region/physics sections
|
||||
// (user-facing since 2026-09-13; the dev-session era is over). Loaded
|
||||
@@ -991,6 +999,7 @@ export function GraphView() {
|
||||
<div className="relative">
|
||||
<SearchIcon className="absolute left-2.5 top-1/2 size-3.5 -translate-y-1/2 text-muted-foreground" />
|
||||
<input
|
||||
ref={searchInputRef}
|
||||
value={query}
|
||||
onChange={(e) => setQuery(e.target.value)}
|
||||
placeholder="Search nodes…"
|
||||
|
||||
Reference in New Issue
Block a user