From 96dbca61705506823c2e14adb683d2b7bfb22f30 Mon Sep 17 00:00:00 2001 From: Kenny Lee Date: Mon, 26 Jan 2026 16:30:20 -0800 Subject: [PATCH] feat(macos): add scroll-to-bottom button in webchat Add a floating button with down chevron that appears when scrolled up from the bottom of the conversation. Tapping it smoothly scrolls to the latest messages. Uses ultraThinMaterial background with subtle shadow. Closes #2466 Co-Authored-By: Claude Opus 4.5 --- .../Sources/ClawdbotChatUI/ChatView.swift | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/apps/shared/ClawdbotKit/Sources/ClawdbotChatUI/ChatView.swift b/apps/shared/ClawdbotKit/Sources/ClawdbotChatUI/ChatView.swift index 44399a3e6..7df7a1d99 100644 --- a/apps/shared/ClawdbotKit/Sources/ClawdbotChatUI/ChatView.swift +++ b/apps/shared/ClawdbotKit/Sources/ClawdbotChatUI/ChatView.swift @@ -118,6 +118,29 @@ public struct ClawdbotChatView: View { } self.messageListOverlay + + if !self.isPinnedToBottom, self.hasPerformedInitialScroll { + VStack { + Spacer() + Button { + withAnimation(.snappy(duration: 0.22)) { + self.scrollPosition = self.scrollerBottomID + } + } label: { + Image(systemName: "chevron.down") + .font(.system(size: 14, weight: .semibold)) + .foregroundStyle(.primary) + .frame(width: 32, height: 32) + .background(.ultraThinMaterial, in: Circle()) + .shadow(color: .black.opacity(0.12), radius: 4, y: 2) + } + .buttonStyle(.plain) + .padding(.bottom, 8) + } + .frame(maxWidth: .infinity) + .transition(.opacity.combined(with: .scale(scale: 0.8))) + .animation(.easeOut(duration: 0.15), value: self.isPinnedToBottom) + } } // Ensure the message list claims vertical space on the first layout pass. .frame(maxHeight: .infinity, alignment: .top)