component
message-scroller
Chat ScrollView: newest-turn open, follows streamed replies, holds scrolled-up reader, requests history at top.
chatscrollconversationmessagescontainershadcn

On iPad
The same installed source at a regular width. It adapts its layout without a separate design.


Install
With the sweetui tool (brew install mangobyte-dev/tap/sweetui):
sweetui install message-scroller --destination Sources/YourFeature/ComponentsInstalls in order: avatar 0.2.1, bubble 0.1.1, message 0.1.1, message-scroller 0.1.1. Point --destination at a folder inside the consuming target's sources.
Usage
// messages is your own model collection; each element is Identifiable
// with an id, a text, and isMine.
@State private var position: String?
@State private var isFollowing = true
MessageScroller(position: $position, isFollowing: $isFollowing) {
ForEach(messages) { message in
MessageRow {
Text(message.text)
}
.registryVariant(message.isMine ? .outgoing : .incoming)
.id(message.id)
}
}Accessibility contract
- Native ScrollView; VoiceOver, three-finger scroll work; hides nothing.
- Pinned to newest turn (bottom anchor).
- Pinned within 8 points of bottom; else holds on new turns.
- 40 points from top: onReachTop fires once per height; prepend re-arms.
- Row order = caller order. Give rows .id for scrollPosition.
Details
| Kind | component |
| Version | 0.1.1 |
| Platforms | iOS 26.0+ |
| Dependencies | message, avatar |
| Source | Registry/sources/components/MessageScroller.swift |
| Xcode preview | Message Scroller |