Skip to content

TUI Stage 4.5a: focus system (tree, manager, traversal, key routing) - #36

Merged
xvrh merged 17 commits into
masterfrom
claude/eager-curie-629e4e
May 17, 2026
Merged

TUI Stage 4.5a: focus system (tree, manager, traversal, key routing)#36
xvrh merged 17 commits into
masterfrom
claude/eager-curie-629e4e

Conversation

@xvrh

@xvrh xvrh commented May 17, 2026

Copy link
Copy Markdown
Owner

Summary

Adds a focus system to the Flutter-style terminal-UI framework in app/lib/src/tui/ — the first half of the "interactivity" stage, and the prerequisite for a real interactive TUI app.

  • Focus treeFocusNode/FocusScopeNode running parallel to the element tree; a hand-rolled minimal listenable (no ChangeNotifier, preserving the zero-pub-dependency rule).
  • FocusManager — owned by TuiBinding; holds the primary focus, applies pending focus changes at the top of each frame (before buildScope), and routes key events down the focus chain.
  • Focus/FocusScope widgets — own/adopt focus nodes, attach them via a _FocusMarker InheritedWidget, and re-expose hasFocus so descendants rebuild on focus change through the existing Stage 4 machinery.
  • TraversalReadingOrderTraversalPolicy (Tab order by post-layout geometry), DirectionalFocusTraversalPolicy (arrow keys), FocusTraversalGroup.
  • Key routingrunApp pumps terminal.keys into FocusManager.handleKeyEvent; unhandled Tab/Shift-Tab/arrows hit a built-in traversal fallback. That fallback is the deliberate seam Stage 4.5b will replace with declarative Shortcuts/Actions.
  • RenderObject.globalOffset — a read-only geometry helper for traversal.
  • Demosfocus_demo.dart (2x2 grid + nested FocusScope) and focus_playground.dart (2x3 counter-card grid exercising traversal, per-card onKeyEvent, focus-chain bubbling).

Design spec: docs/superpowers/specs/2026-05-16-tui-stage4.5a-focus-system-design.md
Implementation plan: docs/superpowers/plans/2026-05-16-tui-stage4.5a-focus-system.md

Built TDD-style in 13 reviewed increments. The Actions/Intents/Shortcuts declarative key-binding layer is intentionally deferred to Stage 4.5b.

Test plan

  • cd app && flutter test — 363/363 pass (5 new focus suites + global_offset_test.dart, no regressions)
  • cd app && flutter analyze — clean
  • dart tool/prepare_submit.dart — no diff
  • Manual smoke (interactive terminal): cd app && dart run examples/tui/focus_playground.dart — Tab/Shift-Tab cycle focus, arrows navigate the grid, +/-/space adjust the focused card, q quits cleanly
  • Manual smoke: cd app && dart run examples/tui/focus_demo.dart

🤖 Generated with Claude Code

xvrh and others added 17 commits May 16, 2026 21:39
Specs the focus tree, FocusManager, Focus/FocusScope widgets, traversal
policies, and key-event routing — the first half of the interactivity
stage. The Actions/Intents/Shortcuts layer is deferred to Stage 4.5b.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
An interactive demo exercising the whole focus system — Tab/arrow
traversal, per-card onKeyEvent handling, focus-chain bubbling, and
hasFocus-driven highlighting.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@xvrh
xvrh merged commit e95fdd3 into master May 17, 2026
1 check passed
@xvrh
xvrh deleted the claude/eager-curie-629e4e branch May 17, 2026 09:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant