(s: ScrollBoxHandle, amount: number)
| 850 | // naturally re-pins (matches typical chat-app behavior). Returns the |
| 851 | // resulting sticky state so callers can propagate it. |
| 852 | function scrollDown(s: ScrollBoxHandle, amount: number): boolean { |
| 853 | const max = Math.max(0, s.getScrollHeight() - s.getViewportHeight()); |
| 854 | // Include pendingDelta: scrollBy accumulates into pendingScrollDelta |
| 855 | // without updating scrollTop, so getScrollTop() alone is stale within |
| 856 | // a batch of wheel events. Without this, wheeling to the bottom never |
| 857 | // re-enables sticky scroll. |
| 858 | const effectiveTop = s.getScrollTop() + s.getPendingDelta(); |
| 859 | if (effectiveTop + amount >= max) { |
| 860 | s.scrollToBottom(); |
| 861 | return true; |
| 862 | } |
| 863 | s.scrollBy(amount); |
| 864 | return false; |
| 865 | } |
| 866 | |
| 867 | // Wheel-up past scrollTop=0 clamps via scrollTo(0), clearing |
| 868 | // pendingScrollDelta so aggressive wheel bursts (e.g. MX Master free-spin) |
no test coverage detected