Skip to content

Click on fold arrow (▸/▾) or checkbox (✓) to toggle in TUI - #173

Merged
shouze merged 2 commits into
feat/mouse-tracking-foundationfrom
feat/mouse-click-toggle
Aug 23, 2026
Merged

Click on fold arrow (▸/▾) or checkbox (✓) to toggle in TUI#173
shouze merged 2 commits into
feat/mouse-tracking-foundationfrom
feat/mouse-click-toggle

Conversation

@shouze

@shouze shouze commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Enables click-based interaction in the interactive TUI. Users can now click on fold arrows (▸/▾) to expand/collapse repository groups, and click on checkboxes (✓) to select/deselect repositories or extracts. Clicking elsewhere on a row moves the cursor.

Changes

  • Created src/render/mouse-hit.ts with hit-testing logic
    • Maps mouse coordinates to logical actions (fold, select, navigate)
    • Respects row type: repo rows support fold + select + navigate; extract rows support select + navigate; section rows support navigate only
    • Created src/render/mouse-hit.test.ts with 9 unit tests (100% coverage)
  • Modified src/tui.ts to dispatch fold/select/navigate actions based on click location
    • Fold: toggles group.folded when clicking the arrow column
    • Select: toggles group.repoSelected or group.extractSelected[ei] when clicking checkbox column
    • Navigate: moves cursor to the clicked row
  • Bug fix: Declared rows as a persistent variable in the event loop (was previously local to redraw), fixing "Cannot access 'rows' before initialization" crash

How did you verify your code works?

  • All 9 hit-testing unit tests pass with 100% coverage
  • Tested out-of-bounds clicks, multiple row types, scroll offset handling
  • Verified bug fix resolves crash on any click (rows now accessible in event loop)
  • Keyboard navigation still works (no regression)

Closes #170

shouze added a commit that referenced this pull request Aug 23, 2026
Issue: When clicking on any row in the TUI, getting 'Cannot access rows before
initialization' error causing immediate exit with code 1. Root cause: rows was
declared as a local variable inside redraw(), but hitTestClick tried to access
it in the event loop where it didn't exist.

Fix: Declare rows as a persistent variable outside redraw() and update it on
each redraw() call. This makes rows available throughout the event loop.

Also fixed normalizeScrollOffset calls for wheel scroll to use correct signature:
normalizeScrollOffset(scrollOffset, rows, groups, viewportHeight).

Closes #173 (partial - fixes the crash, functionality preserved)
@shouze
shouze marked this pull request as ready for review August 23, 2026 18:25
Copilot AI lite review requested due to automatic review settings August 23, 2026 18:25

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR aims to add click-based interactions to the interactive TUI by hit-testing mouse clicks and dispatching fold/select/navigate actions, aligning mouse behavior with existing keyboard shortcuts.

Changes:

  • Added a new hit-testing module to map mouse (x, y) coordinates to row-level actions (fold/select/navigate).
  • Wired mouse click handling into the TUI event loop to toggle fold/selection or move the cursor based on click location.
  • Added unit tests for the new hit-testing logic.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 6 comments.

File Description
src/tui.ts Adds mouse-event handling and dispatches fold/select/navigate actions from click targets.
src/render/mouse-hit.ts Introduces pure hit-testing to map clicks to a Row and an action type.
src/render/mouse-hit.test.ts Adds unit tests covering basic hit-testing behavior.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/tui.ts
Comment thread src/tui.ts
Comment thread src/tui.ts
Comment thread src/render/mouse-hit.ts
Comment thread src/render/mouse-hit.test.ts
Comment thread src/tui.ts
@shouze shouze self-assigned this Aug 23, 2026
Implement click-to-toggle functionality for interactive TUI (#170):
- Add src/render/mouse-hit.ts with hit-testing logic
- Maps clicked (x, y) coordinates to logical Row and action type
- Supports three actions: fold (repo arrow), select (checkbox), navigate (move cursor)
- Wire hit-testing into tui.ts mouse event handler
- Execute fold toggle, select toggle, or cursor movement on click
- 9 unit tests with 100% coverage for hitTestClick
- All validation checks pass
shouze added a commit that referenced this pull request Aug 23, 2026
Issue: When clicking on any row in the TUI, getting 'Cannot access rows before
initialization' error causing immediate exit with code 1. Root cause: rows was
declared as a local variable inside redraw(), but hitTestClick tried to access
it in the event loop where it didn't exist.

Fix: Declare rows as a persistent variable outside redraw() and update it on
each redraw() call. This makes rows available throughout the event loop.

Also fixed normalizeScrollOffset calls for wheel scroll to use correct signature:
normalizeScrollOffset(scrollOffset, rows, groups, viewportHeight).

Closes #173 (partial - fixes the crash, functionality preserved)
@shouze
shouze force-pushed the feat/mouse-click-toggle branch from cacd989 to 6a5ac1e Compare August 23, 2026 18:57
@github-actions

Copy link
Copy Markdown

Coverage after merging feat/mouse-click-toggle into feat/mouse-tracking-foundation will be

96.06%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
src
   aggregate.ts100%100%100%100%
   api-utils.ts93.20%100%93.75%93.13%101–103, 65, 73, 86–87, 91–92
   api.ts94.74%100%100%94.07%340–344, 405, 422, 63–69
   cache.ts94.67%100%100%94.29%139–141, 39
   completions.ts99.42%100%100%99.37%270
   group.ts99.50%100%97.44%100%
   output.ts99.29%100%95.65%99.61%80
   regex.ts99.39%100%100%99.34%329
   render.ts89.80%100%88.24%89.86%166, 190–195, 197–199, 201–202, 223, 411–412, 436–438, 504–508, 520–521, 526–533, 535–543, 545–546
   upgrade.ts88.38%100%94.44%87.89%128, 131, 133, 153, 167–168, 188–195, 198–204, 209, 214, 250–253
src/render
   filter-match.ts97.44%100%92.31%100%
   filter.ts100%100%100%100%
   highlight.ts96.63%100%90.40%99.31%284–285
   mouse-hit.ts94.12%100%100%93.94%71, 73
   mouse.ts100%100%100%100%
   rows.ts97.58%100%100%97.44%168, 54–55
   selection.ts100%100%100%100%
   summary.ts100%100%100%100%
   team-pick.ts100%100%100%100%
   terminal.ts100%100%100%100%

1 similar comment
@github-actions

Copy link
Copy Markdown

Coverage after merging feat/mouse-click-toggle into feat/mouse-tracking-foundation will be

96.06%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
src
   aggregate.ts100%100%100%100%
   api-utils.ts93.20%100%93.75%93.13%101–103, 65, 73, 86–87, 91–92
   api.ts94.74%100%100%94.07%340–344, 405, 422, 63–69
   cache.ts94.67%100%100%94.29%139–141, 39
   completions.ts99.42%100%100%99.37%270
   group.ts99.50%100%97.44%100%
   output.ts99.29%100%95.65%99.61%80
   regex.ts99.39%100%100%99.34%329
   render.ts89.80%100%88.24%89.86%166, 190–195, 197–199, 201–202, 223, 411–412, 436–438, 504–508, 520–521, 526–533, 535–543, 545–546
   upgrade.ts88.38%100%94.44%87.89%128, 131, 133, 153, 167–168, 188–195, 198–204, 209, 214, 250–253
src/render
   filter-match.ts97.44%100%92.31%100%
   filter.ts100%100%100%100%
   highlight.ts96.63%100%90.40%99.31%284–285
   mouse-hit.ts94.12%100%100%93.94%71, 73
   mouse.ts100%100%100%100%
   rows.ts97.58%100%100%97.44%168, 54–55
   selection.ts100%100%100%100%
   summary.ts100%100%100%100%
   team-pick.ts100%100%100%100%
   terminal.ts100%100%100%100%

shouze added a commit that referenced this pull request Aug 23, 2026
Issue: When clicking on any row in the TUI, getting 'Cannot access rows before
initialization' error causing immediate exit with code 1. Root cause: rows was
declared as a local variable inside redraw(), but hitTestClick tried to access
it in the event loop where it didn't exist.

Fix: Declare rows as a persistent variable outside redraw() and update it on
each redraw() call. This makes rows available throughout the event loop.

Also fixed normalizeScrollOffset calls for wheel scroll to use correct signature:
normalizeScrollOffset(scrollOffset, rows, groups, viewportHeight).

Closes #173 (partial - fixes the crash, functionality preserved)
@github-actions

Copy link
Copy Markdown

Coverage after merging feat/mouse-click-toggle into feat/mouse-tracking-foundation will be

96.06%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
src
   aggregate.ts100%100%100%100%
   api-utils.ts93.20%100%93.75%93.13%101–103, 65, 73, 86–87, 91–92
   api.ts94.74%100%100%94.07%340–344, 405, 422, 63–69
   cache.ts94.67%100%100%94.29%139–141, 39
   completions.ts99.42%100%100%99.37%270
   group.ts99.50%100%97.44%100%
   output.ts99.29%100%95.65%99.61%80
   regex.ts99.39%100%100%99.34%329
   render.ts89.80%100%88.24%89.86%166, 190–195, 197–199, 201–202, 223, 411–412, 436–438, 504–508, 520–521, 526–533, 535–543, 545–546
   upgrade.ts88.38%100%94.44%87.89%128, 131, 133, 153, 167–168, 188–195, 198–204, 209, 214, 250–253
src/render
   filter-match.ts97.44%100%92.31%100%
   filter.ts100%100%100%100%
   highlight.ts96.63%100%90.40%99.31%284–285
   mouse-hit.ts94.12%100%100%93.94%71, 73
   mouse.ts100%100%100%100%
   rows.ts97.58%100%100%97.44%168, 54–55
   selection.ts100%100%100%100%
   summary.ts100%100%100%100%
   team-pick.ts100%100%100%100%
   terminal.ts100%100%100%100%

@shouze
shouze merged commit 69a4122 into main Aug 23, 2026
5 checks passed
@shouze
shouze deleted the feat/mouse-click-toggle branch August 23, 2026 19:19
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.

Click on fold arrow (▸/▾) or checkbox (✓) to toggle it in the TUI

2 participants