TUI Stage 4.5b: Actions / Intents / Shortcuts - #37
Merged
Conversation
The declarative key-binding layer — Intent/Action/Actions and Shortcuts/ShortcutManager — plus migration of the 4.5a built-in traversal fallback onto default shortcuts wired to rootScope.onKeyEvent. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Eight TDD tasks: actions.dart, shortcuts.dart, traversal intents/actions, the Shortcuts widget + default map, rootScope wiring, fallback deletion, demo, and docs. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rage Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds rootShortcutManager to TuiBinding, wired onto FocusManager.rootScope.onKeyEvent in attachRootWidget, so Tab/arrows/Enter/Escape route through defaultShortcuts()/defaultTraversalActions() out of the box. Also fixes FocusTraversalPolicy._move to focus the first/last node when the current primary focus is a scope node not itself in the traversal list. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Update roadmap and TUI README to record Stage 4.5b (Actions/Intents/Shortcuts) as complete, add its spec/plan links, and replace the deferred-limitation bullet with the accurate done state. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…sAction direction Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds the declarative key-binding layer to the TUI framework (
app/lib/src/tui/) — the second half of the interactivity stage, building on the Stage 4.5a focus system.actions.dart—Intent,Action<T>, and theActionswidget (chainedType → Actionlookup), plus the standardActivateIntent/DismissIntent.shortcuts.dart—ShortcutMap(Map<KeyEvent, Intent>),ShortcutManager, theShortcutswidget, anddefaultShortcuts().focus_traversal.dart(NextFocusIntent/PreviousFocusIntent/DirectionalFocusIntent+ actions).FocusManager._handleTraversalKey(and_directional/_policyFor/defaultTraversalPolicy) deleted. The default key bindings (Tab/arrows → traversal, Enter → Activate, Escape → Dismiss) are now installed onrootScope.onKeyEventvia a rootShortcutManager, wired byattachRootWidget.rootScopeis the last node in every dispatch chain, so traversal still works even when nothing is focused.shortcuts_demo.dart— a 2×2 grid exercising default traversal, per-panel Enter-to-activate counters, a localShortcutsoverride, and Escape-to-quit.Design: full transcription of Flutter's Actions/Intents/Shortcuts, trimmed for the TUI (no
ActionDispatcher, noContextAction, noShortcutActivator—KeyEvent's value equality lets a plain map serve as the shortcut map). See the design spec and plan.Note: a latent bug in
FocusTraversalPolicy._movewas fixed along the way —next()/previous()from a scope node with a single traversable descendant previously returnedfalse; it now focuses that descendant. This is what makes Tab-from-nothing-focused work.Test Plan
flutter analyzecleancd app && flutter test— all 381 tests passdart tool/prepare_submit.dartproduces no diffactions_test.dart,shortcuts_test.dart, traversal-action additions tofocus_traversal_test.dartcd app && dart run examples/tui/shortcuts_demo.dartin a real terminal — Tab/arrows traverse, Enter/+increment counters, Esc/qquit🤖 Generated with Claude Code