2026 04 19_graph_canvas_input_accessibility_followon_plan - mark-ik/graphshell GitHub Wiki
Status: Implemented (landed 2026-04-23)
Scope: Redesign the graph-canvas input/interaction features that the
earlier egui_graphs-based implementations did not meet the project's
standards bar for. These are explicitly not part of the egui_graphs
retirement baseline โ they need design work, not just plumbing rework.
Parent: ../../../archive_docs/checkpoint_2026-04-19/graphshell_docs/implementation_strategy/shell/2026-04-18_egui_graphs_retirement_plan.md (archived 2026-04-19)
Standards bar: Firefox-consistent where Firefox has a precedent, WAI-ARIA conformant for composite widgets, ergonomic for both pointer and keyboard users, modular (each feature independently gated and testable), effective (resolves a real user need).
Each feature below was in service before M2, was orphaned when M2 landed
the graph-canvas live path, and is being re-landed on graph-canvas + CanvasCamera.
The egui_graphs-era implementation does not meet the standards bar above as
drawn. Each entry describes the gap and the redesign direction.
Previous shape: Right-drag rectangle selection, or Shift+Left-drag (user-preference gate).
Problems:
- Right-drag conflicts with Firefox's convention that right-click/right-drag surface a context menu. The current code suppresses the context menu when the lasso completes a drag, which is an active compensation.
- No keyboard equivalent โ fails WAI-ARIA composite-widget selection patterns. Users who cannot use a pointer cannot perform multi-selection.
Redesign:
- Default pointer gesture: Shift+Left-drag rectangle select. Right-drag surfaces the context menu; remove the right-drag lasso default.
- Keep right-drag lasso as a user preference for power users, but not the default.
- Add keyboard multi-select:
Shift+Arrowextends selection in spatial direction;Ctrl+Shift+Aselect all visible;Ctrl+Aalready exists. - Route through
ActionRegistryso bindings are user-remappable (per the project's Control UI/UX principle). - Build against
graph_canvas::engine::InteractionEngine's existingLassoBegin/LassoUpdate/LassoCompletestate machine.
Previous shape: Tab / Shift+Tab cycles nodes in NodeIndex order.
Problems:
-
NodeIndexorder is arbitrary to the user โ not spatial, not temporal, not semantic. - No ARIA role/label on the graph surface; screen readers announce nothing.
- No focus-change live-region announcement.
- Tab cycles every node; WAI-ARIA composite-widget convention is that Tab enters/exits the widget while arrow keys navigate within.
Redesign:
- Graph surface gets
role="application"(orrole="graphicsdocument"if the assistive tech supports it) witharia-labeldescribing the view. - Arrow keys navigate spatially between visible nodes (nearest neighbor in the arrow direction, tie-break by index). This matches how every other graph editor works.
- Tab enters the graph surface (if not focused) or leaves it (if focused); does not cycle individual nodes.
- Focus change emits an ARIA live-region announcement with the focused node's accessibility name.
- Integrate with Graphshell's existing semantic-tagging system
(
render/semantic_tags.rs) for richer announcements.
Previous shape: Hover a node/edge, tooltip appears.
Problems:
- Hover-only affordance. Keyboard users never see it. Touch users never see it. Screen readers never announce it.
- Fails the project's Control UI/UX principle ("Every control surface must be operable with the active input mode without requiring the other").
- No dismiss affordance (Esc should close).
Redesign:
- Hover and focus both trigger the tooltip (for pointer and keyboard users respectively).
- Tooltip content exposed via
aria-describedbyon the focused node element (synthetic focus target in the graph surface's DOM-equivalent accessibility tree). -
Escapedismisses; pointer-leave / focus-leave dismisses. - Live-region update on focus change (see 1.2).
- Consider integrating with the existing semantic badges in
render/semantic_tags.rsto surface the same information in both the tooltip and the accessibility announcement.
Previous shape: Raw + / - keys trigger zoom; 0 resets.
Problems:
- Raw
+/-conflicts with any text input on the graph surface (future inline edit, search-on-graph, etc.) - Not Firefox-consistent. Firefox uses
Ctrl+=/Ctrl+-/Ctrl+0.
Redesign:
- Rebind to
Ctrl+=(zoom in),Ctrl+-(zoom out),Ctrl+0(reset zoom). - On macOS also accept
Cmd+=/Cmd+-/Cmd+0. - Route through
ActionRegistry; user-remappable. - Apply against
CanvasCamera.zoom. - Preserve the existing zoom clamp (
0.1to10.0or per-view min/max).
All four features above can land independently once the baseline retirement (parent plan) is complete. None blocks the others.
Prerequisites from the baseline:
-
CanvasCamerais the single camera authority (baseline ยง1.C) -
canvas_bridge::collect_canvas_eventshandles all portable input translation (baseline ยง1.D) -
ProjectedScene::hit_proxiesprovides node/edge hit testing (already done)
Additional infrastructure to add in this follow-on:
- Semantic accessibility projection over
ProjectedScene(needed for 1.2, 1.3) - ActionRegistry entries for the new bindings (needed for 1.1, 1.4)
- Live-region host adapter (egui + iced) โ placeholder trait, real implementation depends on each host's accessibility story
- Do not reintroduce the
egui_graphsdependency for any of these features. - Do not implement the egui host adapter's accessibility layer under the assumption that iced's layer will look the same โ keep the portable seam minimal and let hosts supply their own AT integration.
- Do not design for Gamepad input in this follow-on; that's covered by the Control UI/UX plan.
- Plan created alongside egui_graphs retirement baseline.
- Default lasso gesture landed as
Shift+Left-drag; right-drag remains available as a preference without owning the default graph-surface gesture. - Spatial keyboard traversal landed on the graph surface: arrow keys move between visible nodes,
Shift+Arrowextends selection,Ctrl+Shift+Aselects visible nodes, andCtrl+Aremains select-all. - Graph-surface focus announcements landed with semantic-tag and lifecycle detail, and the accessibility bridge now exposes the graph surface as an application-style canvas with descriptive keyboard guidance.
- Graph-surface tooltips now surface for hovered nodes and edges as well as focused nodes, support
Escapedismissal, and clear once the hover/focus target changes. - Zoom shortcuts now route through remappable bindings (
Ctrl+=,Ctrl+-,Ctrl+0, with command-key parity where the binding system maps command to control semantics).