Update Send button bg color (#5170)

* Update Send button bg color

Change the gradient bg to accent/rest.

* Tidy-up ComposerToolbar to match iOS 18 Figma.

Also simplifies the tests a bit.

* Add a .glassEffect to Compound's SendButton.

* Add a border to TimelineReplyView.

Also use the same sizes in both the message bubbles and the composer.

* Change icon size and container in message bubbles

- Container size = 36x36px
- Icon size = 24x24px

* Update icon of reply contents to be 24x24

* Update the VoiceMessageButton to match the designs.

* Adopt Liquid Glass in the ComposerToolbar.

* Generate and fix snapshots.

---------

Co-authored-by: Doug <douglase@element.io>
This commit is contained in:
Aaron Thornburgh
2026-03-25 18:42:10 +01:00
committed by GitHub
parent 51a3350f0b
commit b4d6fe43c3
181 changed files with 790 additions and 719 deletions

View File

@@ -8,40 +8,62 @@
import SwiftUI
/// The button component for sending messages and media.
///
/// The button's size is 44pt x 44pt on iOS 26 and later, and 36pt x 36pt on iOS 18 and earlier.
public struct SendButton: View {
@Environment(\.isEnabled) private var isEnabled
@Environment(\.colorScheme) private var colorScheme
public enum Mode { case send, edit }
/// Whether the button is for sending a new message or editing an existing one.
private let mode: Mode
/// The action to perform when the user triggers the button.
private let action: () -> Void
private var icon: KeyPath<CompoundIcons, Image> {
switch mode {
case .send: \.sendSolid
case .edit: \.check
}
}
private var iconColor: Color {
guard isEnabled else { return .compound.iconQuaternary }
return colorScheme == .light ? .compound.iconOnSolidPrimary : .compound.iconPrimary
}
private var gradient: Gradient {
isEnabled ? .compound.action : .init(colors: [.clear])
private var backgroundColor: Color {
isEnabled ? .compound.bgAccentRest : .clear
}
/// Creates a send button that performs the provided action.
public init(action: @escaping () -> Void) {
public init(mode: Mode = .send, action: @escaping () -> Void) {
self.mode = mode
self.action = action
}
public var body: some View {
Button(action: action) {
CompoundIcon(\.sendSolid, size: .medium, relativeTo: .compound.headingLG)
.foregroundStyle(iconColor)
.scaledPadding(6, relativeTo: .compound.headingLG)
.background { buttonShape }
label
.compositingGroup()
}
}
var buttonShape: some View {
Circle()
.fill(LinearGradient(gradient: gradient, startPoint: .top, endPoint: .bottom))
@ViewBuilder
public var label: some View {
if #available(iOS 26, *), isEnabled, !ProcessInfo.processInfo.isRunningTests {
baseIcon
.glassEffect(.regular.tint(backgroundColor).interactive(), in: .circle)
} else {
baseIcon
.background(backgroundColor, in: .circle)
}
}
var baseIcon: some View {
CompoundIcon(icon, size: .medium, relativeTo: .compound.headingLG)
.foregroundStyle(iconColor)
.scaledPadding(Compound.supportsGlass ? 10 : 6, relativeTo: .compound.headingLG)
}
}
@@ -66,6 +88,8 @@ public struct SendButton_Previews: PreviewProvider, TestablePreview {
SendButton { }
.disabled(true)
SendButton { }
SendButton(mode: .edit) { }
}
}
}

View File

@@ -0,0 +1,14 @@
//
// Copyright 2026 Element Creations Ltd.
//
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
// Please see LICENSE files in the repository root for full details.
//
import Foundation
extension ProcessInfo {
var isRunningTests: Bool {
environment["XCTestBundlePath"] != nil
}
}

View File

@@ -0,0 +1,16 @@
//
// Copyright 2026 Element Creations Ltd.
//
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
// Please see LICENSE files in the repository root for full details.
//
import SwiftUI
public var supportsGlass: Bool {
if #available(iOS 26, *) {
true
} else {
false
}
}

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:acfb01682b484e788e3fd8f883977baaf488cc7cea84da845fbe0bab8185733d
size 79822
oid sha256:9dbba8e66eeb5c78a165952f3dcf2773708178f4d6e4a4a527e69b81b950ceb2
size 76551

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8857d2a0cc92634cf7f55390e9fd5a3b23bc496ebc25c2bd4fb660bb191c04d1
size 39502
oid sha256:5f972698dc7c7d720205c3ce53426a43b28a638778c1d238341c84fc85542f69
size 35696