Move BigIcon into Compound and add a new TitleAndIcon component. (#4866)

* Move BigIcon into Compound.

* Replace the old server selection image asset with the \.host icon.

* Add a new TitleAndIcon component to Compound.

* Add the ability to override TitleAndIcon's padding.
This commit is contained in:
Doug
2025-12-16 16:01:26 +00:00
committed by GitHub
parent b668de8908
commit 85ebf4d1ce
47 changed files with 280 additions and 144 deletions
@@ -1,6 +0,0 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -1,15 +0,0 @@
{
"images" : [
{
"filename" : "authentication_server_selection_icon.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true
}
}
@@ -1,3 +0,0 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M28.25 17.75H3.75C1.825 17.75 0.25 19.325 0.25 21.25V28.25C0.25 30.175 1.825 31.75 3.75 31.75H28.25C30.175 31.75 31.75 30.175 31.75 28.25V21.25C31.75 19.325 30.175 17.75 28.25 17.75ZM7.25 28.25C5.325 28.25 3.75 26.675 3.75 24.75C3.75 22.825 5.325 21.25 7.25 21.25C9.175 21.25 10.75 22.825 10.75 24.75C10.75 26.675 9.175 28.25 7.25 28.25ZM28.25 0.25H3.75C1.825 0.25 0.25 1.825 0.25 3.75V10.75C0.25 12.675 1.825 14.25 3.75 14.25H28.25C30.175 14.25 31.75 12.675 31.75 10.75V3.75C31.75 1.825 30.175 0.25 28.25 0.25ZM7.25 10.75C5.325 10.75 3.75 9.175 3.75 7.25C3.75 5.325 5.325 3.75 7.25 3.75C9.175 3.75 10.75 5.325 10.75 7.25C10.75 9.175 9.175 10.75 7.25 10.75Z" fill="#737D8C"/>
</svg>

Before

Width:  |  Height:  |  Size: 788 B

-1
View File
@@ -30,7 +30,6 @@ internal enum Asset {
}
internal enum Images {
internal static let appLogo = ImageAsset(name: "images/app-logo")
internal static let serverSelectionIcon = ImageAsset(name: "images/server-selection-icon")
internal static let backgroundBottom = ImageAsset(name: "images/background-bottom")
internal static let closeRte = ImageAsset(name: "images/close-rte")
internal static let composerAttachment = ImageAsset(name: "images/composer-attachment")
@@ -1,117 +0,0 @@
//
// Copyright 2025 Element Creations Ltd.
// Copyright 2022-2025 New Vector Ltd.
//
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
// Please see LICENSE files in the repository root for full details.
//
import Compound
import SwiftUI
/// An image that is styled for use as the main/top/hero screen icon. This component
/// takes a compound icon. If you would like to apply it to an SFSymbol, you can call
/// the `bigIcon()` modifier directly on the Image.
struct BigIcon: View {
enum Style {
case defaultSolid
case `default`
case alertSolid
case alert
case successSolid
case success
var foregroundColor: Color {
switch self {
case .defaultSolid, .default:
.compound.iconSecondary
case .alertSolid, .alert:
.compound.iconCriticalPrimary
case .successSolid, .success:
.compound.iconSuccessPrimary
}
}
var backgroundFillColor: Color {
switch self {
case .defaultSolid:
.compound.bgSubtleSecondary
case .alertSolid:
.compound.bgCriticalSubtle
case .successSolid:
.compound.bgSuccessSubtle
case .default, .alert, .success:
.compound.bgCanvasDefault
}
}
}
/// The icon that is shown.
let icon: KeyPath<CompoundIcons, Image>
var style: Style = .defaultSolid
var body: some View {
CompoundIcon(icon, size: .custom(32), relativeTo: .compound.headingLG)
.modifier(BigIconModifier(style: style))
}
}
extension Image {
/// Styles the image for use as the main/top/hero screen icon. You should prefer
/// the BigIcon component when possible, by using an icon from Compound.
func bigIcon(insets: CGFloat = 16, style: BigIcon.Style = .defaultSolid) -> some View {
resizable()
.renderingMode(.template)
.aspectRatio(contentMode: .fit)
.scaledPadding(insets, relativeTo: .compound.headingLG)
.modifier(BigIconModifier(style: style))
}
}
private struct BigIconModifier: ViewModifier {
let style: BigIcon.Style
func body(content: Content) -> some View {
content
.scaledFrame(size: 64, relativeTo: .compound.headingLG)
.foregroundColor(style.foregroundColor)
.background {
RoundedRectangle(cornerRadius: 14)
.fill(style.backgroundFillColor)
}
.accessibilityHidden(true)
}
}
// MARK: - Previews
struct BigIcon_Previews: PreviewProvider, TestablePreview {
static var previews: some View {
VStack(spacing: 40) {
HStack(spacing: 20) {
BigIcon(icon: \.lockSolid)
Image(systemName: "hourglass")
.bigIcon()
Image(asset: Asset.Images.serverSelectionIcon)
.bigIcon(insets: 19)
}
VStack(spacing: 20) {
HStack(spacing: 20) {
BigIcon(icon: \.helpSolid)
BigIcon(icon: \.helpSolid, style: .default)
}
HStack(spacing: 20) {
BigIcon(icon: \.errorSolid, style: .alertSolid)
BigIcon(icon: \.errorSolid, style: .alert)
}
HStack(spacing: 20) {
BigIcon(icon: \.checkCircleSolid, style: .successSolid)
BigIcon(icon: \.checkCircleSolid, style: .success)
}
}
}
}
}
@@ -21,7 +21,6 @@ enum TestablePreviewsDictionary {
"AuthenticationStartScreen_Previews" : AuthenticationStartScreen_Previews.self,
"AvatarHeaderView_Previews" : AvatarHeaderView_Previews.self,
"BadgeLabel_Previews" : BadgeLabel_Previews.self,
"BigIcon_Previews" : BigIcon_Previews.self,
"BlockedUsersScreen_Previews" : BlockedUsersScreen_Previews.self,
"BloomModifier_Previews" : BloomModifier_Previews.self,
"BugReportScreen_Previews" : BugReportScreen_Previews.self,
@@ -6,6 +6,7 @@
// Please see LICENSE files in the repository root for full details.
//
import Compound
import SwiftUI
struct LoginScreen: View {
@@ -6,6 +6,7 @@
// Please see LICENSE files in the repository root for full details.
//
import Compound
import SwiftUI
struct ServerSelectionScreen: View {
@@ -32,8 +33,7 @@ struct ServerSelectionScreen: View {
/// The title, message and icon at the top of the screen.
var header: some View {
VStack(spacing: 8) {
Image(asset: Asset.Images.serverSelectionIcon)
.bigIcon(insets: 19)
BigIcon(icon: \.host)
.padding(.bottom, 8)
Text(L10n.screenChangeServerTitle)
@@ -12,7 +12,7 @@ struct LinkNewDeviceScreen: View {
@Bindable var context: LinkNewDeviceScreenViewModel.Context
var body: some View {
FullscreenDialog(topPadding: 24) {
FullscreenDialog(topPadding: 0) {
mainContent
} bottomContent: {
buttons
@@ -28,33 +28,15 @@ struct LinkNewDeviceScreen: View {
var mainContent: some View {
switch context.viewState.mode {
case .loading, .readyToLink:
VStack(spacing: 16) {
BigIcon(icon: \.computer, style: .default)
Text(L10n.screenLinkNewDeviceRootTitle)
.font(.compound.headingMDBold)
.foregroundColor(.compound.textPrimary)
.multilineTextAlignment(.center)
}
.padding(.horizontal, 8)
TitleAndIcon(title: L10n.screenLinkNewDeviceRootTitle,
icon: \.computer,
iconStyle: .default)
.padding(.horizontal, -16) // Remove the FullscreenDialog's default padding in this state.
case .notSupported:
VStack(spacing: 16) {
BigIcon(icon: \.errorSolid, style: .alertSolid)
VStack(spacing: 8) {
Text(L10n.screenLinkNewDeviceErrorNotSupportedTitle)
.font(.compound.headingMDBold)
.foregroundColor(.compound.textPrimary)
.multilineTextAlignment(.center)
Text(L10n.screenLinkNewDeviceErrorNotSupportedSubtitle)
.font(.compound.bodyMD)
.foregroundColor(.compound.textSecondary)
.multilineTextAlignment(.center)
}
}
.padding(.horizontal, 24)
.padding(.bottom, 40)
TitleAndIcon(title: L10n.screenLinkNewDeviceErrorNotSupportedTitle,
subtitle: L10n.screenLinkNewDeviceErrorNotSupportedSubtitle,
icon: \.errorSolid,
iconStyle: .alertSolid)
}
}
@@ -6,6 +6,7 @@
// Please see LICENSE files in the repository root for full details.
//
import Compound
import SwiftUI
/// A prompt that asks the user whether they would like to enable Analytics or not.