Skip to content

fix(tui): migrate to ControlledScrollView with onContentHeightChange - #577

Merged
avoidwork merged 8 commits into
mainfrom
fix/scroll-offset-method
Jul 20, 2026
Merged

fix(tui): migrate to ControlledScrollView with onContentHeightChange#577
avoidwork merged 8 commits into
mainfrom
fix/scroll-offset-method

Conversation

@avoidwork

@avoidwork avoidwork commented Jul 20, 2026

Copy link
Copy Markdown
Owner

Description

Migrate the message list from uncontrolled ScrollView to controlled ControlledScrollView from ink-scroll-view. The scroll position is now managed via scrollOffset state and updated through the onContentHeightChange callback, providing more reliable scroll-to-bottom behavior during streaming.

Also fixes getMaxScrollOffsetgetBottomOffset API usage, optimizes re-render triggers to only fire on actual content changes, prunes pub/sub topics for messages that fall off the render slice, and improves _reset cleanup.

Type of Change

  • Bugfix (non-breaking change which fixes an issue)

Testing

Lint passes with npm run lint. No code changes require test updates — the scroll behavior is UI-level and tested via the TUI integration tests.

Coverage

  • Line coverage maintained

Checklist

  • npm run lint passes
  • Tests pass with maintained line coverage
  • No forbidden patterns used
  • Conventional Commit style applied

- getMaxScrollOffset() is not part of ink-scroll-view API
- Replaced with documented getBottomOffset() method
- This fixes broken scroll-up detection where isUserScrollingRef
  would never be set due to silent undefined fallback
- Remove unnecessary triggerRender() from updateMessage — bubbles update
  themselves via pub/sub without parent re-render
- Replace remeasure() with remeasureItem(lastIdx) during scroll to avoid
  O(n) layout thrashing on every update
- Fix ref dependency in scroll position check (lastMsgCountRef.current
  doesn't trigger re-renders)
- Prune pub/sub topics for messages that fall off the render slice
- Reset _messageIdCounter in _reset() for test isolation
- Use string-based content hash instead of sum to avoid collisions
…nly when content changes

- Only call triggerRender() in updateMessage when content actually changed
- Metadata-only updates (tool calls, status, etc.) still use pub/sub only
- Preserves scroll behavior while avoiding unnecessary parent re-renders
@avoidwork avoidwork changed the title fix(tui): use correct getBottomOffset API for scroll detection fix(tui): migrate to ControlledScrollView with onContentHeightChange Jul 20, 2026
@avoidwork
avoidwork merged commit cf41e38 into main Jul 20, 2026
2 checks passed
@avoidwork
avoidwork deleted the fix/scroll-offset-method branch July 20, 2026 10:40
@avoidwork avoidwork mentioned this pull request Jul 20, 2026
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