style: add macos chat glass background

This commit is contained in:
Peter Steinberger
2025-12-22 19:55:17 +01:00
parent 15e468f5dd
commit 3412ff7003
4 changed files with 56 additions and 17 deletions

View File

@@ -45,7 +45,10 @@ struct ClawdisChatComposer: View {
.background( .background(
RoundedRectangle(cornerRadius: 18, style: .continuous) RoundedRectangle(cornerRadius: 18, style: .continuous)
.fill(ClawdisChatTheme.composerBackground) .fill(ClawdisChatTheme.composerBackground)
.shadow(color: .black.opacity(0.08), radius: 10, y: 4)) .overlay(
RoundedRectangle(cornerRadius: 18, style: .continuous)
.strokeBorder(ClawdisChatTheme.composerBorder, lineWidth: 1))
.shadow(color: .black.opacity(0.12), radius: 12, y: 6))
#if os(macOS) #if os(macOS)
.onDrop(of: [.fileURL], isTargeted: nil) { providers in .onDrop(of: [.fileURL], isTargeted: nil) { providers in
self.handleDrop(providers) self.handleDrop(providers)

View File

@@ -238,7 +238,7 @@ private struct ChatMessageBody: View {
if self.style == .onboarding { if self.style == .onboarding {
return ClawdisChatTheme.onboardingAssistantBorder return ClawdisChatTheme.onboardingAssistantBorder
} }
return Color.black.opacity(0.08) return Color.white.opacity(0.08)
} }
private var bubbleBorderWidth: CGFloat { private var bubbleBorderWidth: CGFloat {
@@ -321,7 +321,7 @@ struct ChatTypingIndicatorBubble: View {
.fill(ClawdisChatTheme.assistantBubble)) .fill(ClawdisChatTheme.assistantBubble))
.overlay( .overlay(
RoundedRectangle(cornerRadius: 16, style: .continuous) RoundedRectangle(cornerRadius: 16, style: .continuous)
.strokeBorder(Color.black.opacity(0.08), lineWidth: 1)) .strokeBorder(Color.white.opacity(0.08), lineWidth: 1))
.frame(maxWidth: ChatUIConstants.bubbleMaxWidth, alignment: .leading) .frame(maxWidth: ChatUIConstants.bubbleMaxWidth, alignment: .leading)
} }
} }
@@ -340,7 +340,7 @@ struct ChatStreamingAssistantBubble: View {
.fill(ClawdisChatTheme.assistantBubble)) .fill(ClawdisChatTheme.assistantBubble))
.overlay( .overlay(
RoundedRectangle(cornerRadius: 16, style: .continuous) RoundedRectangle(cornerRadius: 16, style: .continuous)
.strokeBorder(Color.black.opacity(0.08), lineWidth: 1)) .strokeBorder(Color.white.opacity(0.08), lineWidth: 1))
.frame(maxWidth: ChatUIConstants.bubbleMaxWidth, alignment: .leading) .frame(maxWidth: ChatUIConstants.bubbleMaxWidth, alignment: .leading)
} }
} }
@@ -374,7 +374,7 @@ struct ChatPendingToolsBubble: View {
.fill(ClawdisChatTheme.assistantBubble)) .fill(ClawdisChatTheme.assistantBubble))
.overlay( .overlay(
RoundedRectangle(cornerRadius: 16, style: .continuous) RoundedRectangle(cornerRadius: 16, style: .continuous)
.strokeBorder(Color.black.opacity(0.08), lineWidth: 1)) .strokeBorder(Color.white.opacity(0.08), lineWidth: 1))
.frame(maxWidth: ChatUIConstants.bubbleMaxWidth, alignment: .leading) .frame(maxWidth: ChatUIConstants.bubbleMaxWidth, alignment: .leading)
} }
} }

View File

@@ -15,6 +15,40 @@ enum ClawdisChatTheme {
#endif #endif
} }
@ViewBuilder
static var background: some View {
#if os(macOS)
ZStack {
LinearGradient(
colors: [
Color(nsColor: .windowBackgroundColor).opacity(0.85),
Color.black.opacity(0.92)
],
startPoint: .topLeading,
endPoint: .bottomTrailing)
RadialGradient(
colors: [
Color(nsColor: .systemOrange).opacity(0.18),
.clear
],
center: .topLeading,
startRadius: 40,
endRadius: 320)
RadialGradient(
colors: [
Color(nsColor: .systemTeal).opacity(0.16),
.clear
],
center: .topTrailing,
startRadius: 40,
endRadius: 280)
Color.black.opacity(0.12)
}
#else
Color(uiColor: .systemBackground)
#endif
}
static var card: Color { static var card: Color {
#if os(macOS) #if os(macOS)
Color(nsColor: .textBackgroundColor) Color(nsColor: .textBackgroundColor)
@@ -23,11 +57,11 @@ enum ClawdisChatTheme {
#endif #endif
} }
static var subtleCard: Color { static var subtleCard: AnyShapeStyle {
#if os(macOS) #if os(macOS)
Color(nsColor: .textBackgroundColor).opacity(0.55) AnyShapeStyle(.ultraThinMaterial)
#else #else
Color(uiColor: .secondarySystemBackground).opacity(0.9) AnyShapeStyle(Color(uiColor: .secondarySystemBackground).opacity(0.9))
#endif #endif
} }
@@ -41,7 +75,9 @@ enum ClawdisChatTheme {
static var assistantBubble: Color { static var assistantBubble: Color {
#if os(macOS) #if os(macOS)
Color(nsColor: .controlBackgroundColor) let base = NSColor.controlBackgroundColor
let blended = base.blended(withFraction: 0.18, of: .white) ?? base
return Color(nsColor: blended).opacity(0.88)
#else #else
Color(uiColor: .secondarySystemBackground) Color(uiColor: .secondarySystemBackground)
#endif #endif
@@ -75,24 +111,24 @@ enum ClawdisChatTheme {
#endif #endif
} }
static var composerBackground: Color { static var composerBackground: AnyShapeStyle {
#if os(macOS) #if os(macOS)
Color(nsColor: .windowBackgroundColor) AnyShapeStyle(.ultraThinMaterial)
#else #else
Color(uiColor: .systemBackground) AnyShapeStyle(Color(uiColor: .systemBackground))
#endif #endif
} }
static var composerField: Color { static var composerField: AnyShapeStyle {
#if os(macOS) #if os(macOS)
Color(nsColor: .textBackgroundColor) AnyShapeStyle(.thinMaterial)
#else #else
Color(uiColor: .secondarySystemBackground) AnyShapeStyle(Color(uiColor: .secondarySystemBackground))
#endif #endif
} }
static var composerBorder: Color { static var composerBorder: Color {
Color.secondary.opacity(0.2) Color.white.opacity(0.12)
} }
static var divider: Color { static var divider: Color {

View File

@@ -44,7 +44,7 @@ public struct ClawdisChatView: View {
public var body: some View { public var body: some View {
ZStack { ZStack {
ClawdisChatTheme.surface ClawdisChatTheme.background
.ignoresSafeArea() .ignoresSafeArea()
VStack(spacing: Layout.stackSpacing) { VStack(spacing: Layout.stackSpacing) {