Is your feature request related to a problem? Please describe.
KeyboardChatScrollView already computes whether the scroll view is effectively at the end for keyboardLiftBehavior="whenAtEnd", but that state is currently internal.
For chat-style UIs, apps often need the same signal for:
- showing or hiding a "scroll to bottom" / "jump to latest" button
- enabling follow-mode while streaming new assistant content
- tracking whether unread content is accumulating below the viewport
Today the app has to re-implement that logic outside the component. That is awkward because KeyboardChatScrollView already owns the relevant scroll metrics and keyboard-aware padding behavior, so app-side heuristics can drift from the component's internal definition of "at end".
Describe the solution you'd like
Expose an optional isAtEnd?: SharedValue<boolean> prop on KeyboardChatScrollView.
When provided, the component would update that shared value on the UI thread using the same internal scroll metrics and isScrollAtEnd(...) logic it already uses for keyboardLiftBehavior="whenAtEnd".
Example:
const isAtEnd = useSharedValue(true);
<KeyboardChatScrollView
isAtEnd={isAtEnd}
keyboardLiftBehavior="whenAtEnd"
/>
This keeps the public API narrow while still exposing the high-level state chat apps actually need.
Describe alternatives you've considered
- Expose raw scroll position instead.
I think that is a less ideal API for this use case. Most consumers do not need raw scrollY; they need the semantic "is the user pinned to the latest content?" state. Exposing raw scroll metrics also leaks more implementation detail and pushes more edge-case handling into app code.
- Recompute "at end" in the app.
This works imperfectly, especially once keyboard lift behavior, bottom padding, composer growth, and inverted/non-inverted behavior are involved. The component already has the authoritative inputs, so surfacing that result is more reliable.
- Expose a callback instead of a shared value.
A callback is usable, but a SharedValue<boolean> fits the existing Reanimated-driven API surface better and avoids bouncing this state back to JS for consumers that want to animate directly from it.
Additional context
- This would be an additive API change.
- The implementation can be JS-only in
KeyboardChatScrollView.
- Internally, the component already has everything needed:
scroll, layout, size, and isScrollAtEnd(...).
- This is especially helpful for AI chat and messenger-style screens that need a jump-to-latest button that stays in sync with the component's own
whenAtEnd behavior.
Is your feature request related to a problem? Please describe.
KeyboardChatScrollViewalready computes whether the scroll view is effectively at the end forkeyboardLiftBehavior="whenAtEnd", but that state is currently internal.For chat-style UIs, apps often need the same signal for:
Today the app has to re-implement that logic outside the component. That is awkward because
KeyboardChatScrollViewalready owns the relevant scroll metrics and keyboard-aware padding behavior, so app-side heuristics can drift from the component's internal definition of "at end".Describe the solution you'd like
Expose an optional
isAtEnd?: SharedValue<boolean>prop onKeyboardChatScrollView.When provided, the component would update that shared value on the UI thread using the same internal scroll metrics and
isScrollAtEnd(...)logic it already uses forkeyboardLiftBehavior="whenAtEnd".Example:
This keeps the public API narrow while still exposing the high-level state chat apps actually need.
Describe alternatives you've considered
I think that is a less ideal API for this use case. Most consumers do not need raw
scrollY; they need the semantic "is the user pinned to the latest content?" state. Exposing raw scroll metrics also leaks more implementation detail and pushes more edge-case handling into app code.This works imperfectly, especially once keyboard lift behavior, bottom padding, composer growth, and inverted/non-inverted behavior are involved. The component already has the authoritative inputs, so surfacing that result is more reliable.
A callback is usable, but a
SharedValue<boolean>fits the existing Reanimated-driven API surface better and avoids bouncing this state back to JS for consumers that want to animate directly from it.Additional context
KeyboardChatScrollView.scroll,layout,size, andisScrollAtEnd(...).whenAtEndbehavior.