Make mindmap navigation more intuitive (active node, keyboard traversal, clearer controls) #212
Labels
No labels
prio_critical
prio_low
type_bug
type_contact
type_issue
type_lead
type_question
type_story
type_task
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
lhumina_code/hero_whiteboard#212
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Make mindmap navigation more intuitive (active node, keyboard traversal, clearer controls)
Background
User feedback: navigating and editing a mindmap is not intuitive. Today the per-node affordances are faint always-on glyphs and keyboard actions only ever apply to the root node, so there is no sense of "where you are" in the tree and no fast way to move/build it. Reference tools (e.g. Miro) make the active node and the add/collapse controls clearly visible.
Current behavior (
static/web/js/whiteboard/mindmap.js,static/web/js/whiteboard/shortcuts.js):+(add child) and+/-(collapse) glyph; low-contrast and small hit area.handleWidgetShortcut, mindmap branch) only acts on the root: Tab adds a child to root, Space collapses root, L flips direction.Objective
Add an "active node" concept inside a selected mindmap with a clear visual highlight, full keyboard traversal/editing, and more visible Miro-style on-node controls — without regressing existing rendering, undo/redo, sync, or locking.
Requirements
Active node + visible selection state
state.activeNodeon the mindmap; default to the root when the mindmap becomes the single selected object.Keyboard traversal and editing (only when a single mindmap is selected and not locked; ignore while an inline editor input is focused)
snapshotBefore/persistMindmapMutationpattern.Clearer on-node controls (Miro-style)
+on the child side, faint by default and emphasized on node hover (mouseenter/mouseleave toggling opacity, no full re-render).Files to modify
crates/hero_whiteboard_admin/static/web/js/whiteboard/mindmap.js- active-node state + highlight, parent/sibling/first-child lookups, new exported actions (set active, move active, add child/sibling to active, delete active, edit active), redesigned circular controls with hover emphasis.crates/hero_whiteboard_admin/static/web/js/whiteboard/shortcuts.js- extend thetype === 'mindmap'branch ofhandleWidgetShortcutto drive the new active-node actions (arrows, Tab, Enter, Delete/Backspace, F2, Space).Implementation plan
Step 1: Active-node state, lookups, and highlight (mindmap.js)
state.activeNode(node ref); helperfindParent(tree, node); helpers for first child / previous-next sibling.drawNodes, when the node is the active node, add a highlight (extra accent stroke/halo). Add amm-nodeclick handler that sets the active node and re-renders.activeNodeto root on selection; exposesetActiveFromSelection(group)and clear on deselect.Dependencies: none
Step 2: Active-node actions API (mindmap.js)
moveActive(group, dir),addChildToActive(group),addSiblingToActive(group),deleteActive(group),editActive(group),toggleCollapseActive(group), reusingaddChildToNode/deleteNode/editMindmapNodeand the history+sync pattern. New-node actions set the new node active and open its editor.Dependencies: Step 1
Step 3: Redesigned circular controls with hover emphasis (mindmap.js)
+, both with backgrounds and larger hit areas; default add-child opacity low, raised on node hover via mouseenter/mouseleave + batchDraw.Dependencies: Step 1
Step 4: Keyboard wiring (shortcuts.js)
handleWidgetShortcut: arrows ->moveActive; Tab ->addChildToActive; Enter ->addSiblingToActive; Delete/Backspace ->deleteActive; F2 ->editActive; Space ->toggleCollapseActive; keep L = flip. Guard against firing while an inline input is focused.Dependencies: Steps 1-2
Acceptance criteria
Notes
Nodes are plain tree objects without ids or parent pointers; active node is tracked by object reference (stable across re-render) and parent is resolved by walking the tree. Keyboard handling must no-op while an inline
<input>/<textarea>editor is focused so typing is not intercepted.Implemented: active node, keyboard traversal, clearer controls
Changes
static/web/js/whiteboard/mindmap.jsstate.activeNode, defaults to root) with a dashed highlight halo that is repositioned (not re-rendered) on plain selection clicks, so double-click-to-edit keeps working.findParent,nodeExists,visibleChildren,findNodeRect,updateActiveHighlight,ensureActive,setActive.moveActive(arrow traversal resolved against layout direction),addChildToActive,addSiblingToActive,deleteActive(refuses root, reselects a sensible neighbor),editActive,toggleCollapseActive. New-node actions set the new node active and open its inline editor.makeCircleBtn): collapse/expand is a single circle showing the hidden direct-child count when collapsed and a minus when expanded; add-child is a+circle that is faint by default and brightens on node/button hover, with a real (larger) hit area.addChildToNodenow accepts an insert index, sets the new node active, and returns it.static/web/js/whiteboard/shortcuts.jshandleWidgetShortcutto drive the active node: Arrows = traverse; Tab = add child + edit; Enter = add sibling + edit; F2 = edit; Delete/Backspace = delete active node (on the root it falls through so the whole mindmap is deleted); Space = collapse active; L = flip direction.Verification
Rust workspace lib tests (no regression):
Traversal logic test (replicates moveActive/deleteActive against a sample tree, both layout directions):
Deployed locally (release build, installed, service restarted); the served
mindmap.jsandshortcuts.jscarry the changes.Manual check needed (no browser automation in this environment)
Select a mindmap, then: click a node to highlight it; use arrows to move; Tab/Enter to add child/sibling; Delete to remove; hover a node to reveal the brighter + button; collapse a branch to see the count badge.