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 155d054be7
commit b9c121db82
47 changed files with 280 additions and 144 deletions

View File

@@ -55,10 +55,6 @@ extension AccessibilityTests {
try await performAccessibilityAudit(named: "BadgeLabel_Previews")
}
func testBigIcon() async throws {
try await performAccessibilityAudit(named: "BigIcon_Previews")
}
func testBlockedUsersScreen() async throws {
try await performAccessibilityAudit(named: "BlockedUsersScreen_Previews")
}

View File

@@ -1426,7 +1426,6 @@
FB595EC9C00AB32F39034055 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A37E2FACFD041CE466223CD /* SceneDelegate.swift */; };
FBD402E3170EB1ED0D1AA672 /* EncryptionKeyProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2355398E4A55DA5A89128AD1 /* EncryptionKeyProvider.swift */; };
FBF09B6C900415800DDF2A21 /* EmojiProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C113E0CB7E15E9765B1817A /* EmojiProvider.swift */; };
FC0EEFF630F34899953BB950 /* BigIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01FD1171FF40E34D707FD00 /* BigIcon.swift */; };
FC10228E73323BDC09526F97 /* Mapbox in Frameworks */ = {isa = PBXBuildFile; productRef = C1BF15833233CD3BDB7E2B1D /* Mapbox */; };
FC31493979ED1FDF7D5EA3F9 /* KeychainController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E36CB905A2B9EC2C92A2DA7C /* KeychainController.swift */; };
FCD3F2B82CAB29A07887A127 /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = DE8DC9B3FBA402117DC4C49F /* Kingfisher */; };
@@ -2645,7 +2644,6 @@
CF19027E7FFA5E63D148873A /* CreateRoomScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateRoomScreenViewModel.swift; sourceTree = "<group>"; };
CF847A34FC4C8C937CD39E08 /* LabsScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabsScreenViewModelProtocol.swift; sourceTree = "<group>"; };
CFFA5E881D281810AB428EA3 /* RoomPowerLevelsProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomPowerLevelsProxy.swift; sourceTree = "<group>"; };
D01FD1171FF40E34D707FD00 /* BigIcon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BigIcon.swift; sourceTree = "<group>"; };
D03D7ECAC68C2FFB8CF01BCB /* DeactivateAccountScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeactivateAccountScreen.swift; sourceTree = "<group>"; };
D046ABB22E680F7C5054441B /* SecurityAndPrivacyScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecurityAndPrivacyScreenViewModelProtocol.swift; sourceTree = "<group>"; };
D071F86CD47582B9196C9D16 /* UserDiscoverySection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDiscoverySection.swift; sourceTree = "<group>"; };
@@ -3664,7 +3662,6 @@
CC743C7A85E3171BCBF0A653 /* AvatarHeaderView.swift */,
9A028783CFFF861C5E44FFB1 /* BadgeLabel.swift */,
C1FA515B3B0D61EF1E907D2D /* BadgeView.swift */,
D01FD1171FF40E34D707FD00 /* BigIcon.swift */,
07934EF08BB39353E4A94272 /* BlurEffectView.swift */,
8CC23C63849452BC86EA2852 /* ButtonStyle.swift */,
FEC4B431B0117BDEE697DB4A /* ComposerDisabledView.swift */,
@@ -7777,7 +7774,6 @@
A4B0BAD62A12ED76BD611B79 /* BadgeView.swift in Sources */,
2B52B2A5A6496C5C0F952776 /* BannedRoomProxy.swift in Sources */,
7F0B6EB5CB52D7B7A2BB7D15 /* BannedRoomProxyMock.swift in Sources */,
FC0EEFF630F34899953BB950 /* BigIcon.swift in Sources */,
38546A6010A2CF240EC9AF73 /* BindableState.swift in Sources */,
EB9F4688006B52E69DF5358F /* BlankFormCoordinator.swift in Sources */,
369BF960E52BBEE61F8A5BD1 /* BlockedUsersScreen.swift in Sources */,

View File

@@ -1,6 +0,0 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -1,15 +0,0 @@
{
"images" : [
{
"filename" : "authentication_server_selection_icon.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true
}
}

View File

@@ -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

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")

View File

@@ -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,

View File

@@ -6,6 +6,7 @@
// Please see LICENSE files in the repository root for full details.
//
import Compound
import SwiftUI
struct LoginScreen: View {

View File

@@ -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)

View File

@@ -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)
}
}

View File

@@ -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.

View File

@@ -83,12 +83,6 @@ extension PreviewTests {
}
}
func testBigIcon() async throws {
for (index, preview) in BigIcon_Previews._allPreviews.enumerated() {
try await assertSnapshots(matching: preview, step: index)
}
}
func testBlockedUsersScreen() async throws {
for (index, preview) in BlockedUsersScreen_Previews._allPreviews.enumerated() {
try await assertSnapshots(matching: preview, step: index)

View File

@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:521c3f78b534dfe2f97b09d756e1ecbd482658243c237002a46e2a7bd0a7e84c
size 86830

View File

@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:521c3f78b534dfe2f97b09d756e1ecbd482658243c237002a46e2a7bd0a7e84c
size 86830

View File

@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c28eda1e4566f734bdbed8d6582237b2d3c2c37eab26d5e056080622e0c2697d
size 45905

View File

@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c28eda1e4566f734bdbed8d6582237b2d3c2c37eab26d5e056080622e0c2697d
size 45905

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:65f11d9d64084017db57740ee3fab3ae8fe2ce971e967ea5c43d3a48d0452f5c
size 105193
oid sha256:2a62c7fe22d25682dd772dc20b32acfdfb0bd04a62eae471d8733e236516df0a
size 104899

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:874e0e25ef2149ee221e8c24e6c12ac37b4ba2f59667f343b4f442e2703ff93c
size 102567
oid sha256:acbf50c12cf185a5e72126feea38366bc342b79553b9c04ed4ef7327cc5cf674
size 102273

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d1b107a84876aebc62b7daace8637f3e02a85064f079f1930a397b16f84b0944
size 119923
oid sha256:b25b9603fd62313e8d45b2a3e7d333e2583dc0f8415b10d4fd3b37dfdd1e1d7a
size 119594

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c51ceba48485ebdd9f85b32c9ade903901f76ae126b215674ecbc6e451666651
size 114022
oid sha256:935cf635d776903df59823cb380a310e058deefb02f006da4f5021e86fd1caba
size 113644

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:00b988434e1f2d4286ac1242c4219e7c47fc4fd4c0d8c2224aae8f99c1973d2b
size 111586
oid sha256:5fff679c5ebb919994a8664aa7599b45615390ad5f4999293ea155b80b6a8507
size 111200

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c780ed18f082a99977442d74ece9acf5e39515ae0dc21bf2e5e42a9fbb72f4da
size 145500
oid sha256:de92bdbcec0069afd40902e1bbba90986d86ea985df68f0b5712f80cc92a1fdc
size 145150

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:cee9857f1d27aa0e15f4ccd5a76752e5d17bd827d67568b3d8aa73b038ee0e49
size 58428
oid sha256:a9ecb376eba35842c05108d80852cf8a2b5d80c376c4123ec8f59811bb17e866
size 58109

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:52b698f7a9037c94a84d85223ee4a9087b0562778d2b7082f2336c6852c23e66
size 56162
oid sha256:35dc04486f13ec49bc15eb1977044f4cb82a69b962361439a5ac5cd98ddf2b36
size 55841

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8f2fb268806570ce860ca95cec6f16e9a1e82d174b5db1c4091a1ac360fb56a2
size 79143
oid sha256:c1b7e7c8240b8e26a61e5e9e0629ca5dee5dbbf5526f72a6b4ead9a58bf01818
size 78763

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:1c69ae73028295d184409c5f40381be0170d8a9545637f79e876a5def60e93d4
size 71385
oid sha256:e41491b89f794549a4ce882f1e992430228eb5d3e64c6046e2877ac1d35baa87
size 71057

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:68d4f1ac9e9a652f09edc9e4ecd16e44ee5407d9ebe3c757ec9590169799f415
size 69196
oid sha256:7b669690e17a4d6edf908408244c232f5932705d7c86c92f8109b1ac94ca3657
size 68870

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:5125f28f57c2b3f09933a6ad60573e02d990a27aefe2451c335878ecf952b052
size 111584
oid sha256:47e7a98645f3a7f86ffc65a29deb23f0cc51fb82e2a429b39c15976ca235311d
size 111260

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:681cb7bf3f99a8ee978b6c3ecf3c414f8dd3b51a596352fa046142fdfb9ee4f8
size 166622
oid sha256:a4f3e048fbb9737b589d04eec3fb3e381aa9087c63f738fa2d74d39fcc8063a1
size 167724

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:da1d6fbe942c8441576828796a4657ac0501721fe9a6b98193df71e9c00b511b
size 169798
oid sha256:065fb5a4b59f27bac3dd3a208012f8927fd3f73d2baf4edc9d2fbc2fb02365c6
size 168928

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:eeb11a6b8f7a9f247259ed50893039a75e6146c397430653ae47ba8bb15598aa
size 114933
oid sha256:1a74092a4e7c4f5cee38a05d20f035b859e217dd0c6ec2f68fbd8fe2cc080c5e
size 114415

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a23581863ff955aa6003874be20cb7d8a41d08a872e81d158d95a78deddface3
size 133476
oid sha256:058edb77398e0e692ea948a0d3f945faaa41ea81e80034db1f59dd57620edb4d
size 132759

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:453387e79e9c17e32d436d04e985843321870fde2ecc0907862ac535869c3ca3
size 97393
oid sha256:49741fa0f9807bd3f26625a56049c4a7f7f900db769f9eff7eaf6112d3177b54
size 96879

View File

@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c165e34b7cafc3c2a3732b92df5783d92cdba4807a39a7cf03f1b675fee8f9ad
size 106036
oid sha256:b834de3af3399e405bfd3fb73ff21a912b0e643a6cef224faa2744940d26eec8
size 105647

View File

@@ -9,6 +9,7 @@
/* Begin PBXBuildFile section */
70AC7B23011C802F750E470E /* Pods_Compound_Inspector.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D2E28F45EEA9A8DE6AFB10E9 /* Pods_Compound_Inspector.framework */; };
912974102A864F5E004BEA88 /* ListScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9129740F2A864F5E004BEA88 /* ListScreen.swift */; };
912EA03C2EF18F1F006485DF /* TitleAndIconScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 912EA03B2EF18F1D006485DF /* TitleAndIconScreen.swift */; };
9132C62D2A72708400EAEF3D /* ActionSheetScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9132C62C2A72708400EAEF3D /* ActionSheetScreen.swift */; };
9132C62F2A72785500EAEF3D /* AlertScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9132C62E2A72785400EAEF3D /* AlertScreen.swift */; };
9132C6312A7280A500EAEF3D /* ContextMenuScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9132C6302A7280A500EAEF3D /* ContextMenuScreen.swift */; };
@@ -21,6 +22,7 @@
917F562F28256DD800D19543 /* SidebarList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 917F562E28256DD800D19543 /* SidebarList.swift */; };
9184AC022825741600227C3A /* ScreenContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9184AC012825741600227C3A /* ScreenContent.swift */; };
9188246A2A2DE882001606AE /* Screen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 918824692A2DE882001606AE /* Screen.swift */; };
91A6CAA02EF1844E0090A2B4 /* BigIconScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91A6CA9F2EF184470090A2B4 /* BigIconScreen.swift */; };
91B2EA9928CA05B900A90A83 /* Compound in Frameworks */ = {isa = PBXBuildFile; productRef = 91B2EA9828CA05B900A90A83 /* Compound */; };
91B2EA9C28CA064800A90A83 /* ColorsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91B2EA9B28CA064800A90A83 /* ColorsScreen.swift */; };
91B946812A29062300F187EF /* IconsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91B946802A29062300F187EF /* IconsScreen.swift */; };
@@ -43,6 +45,7 @@
/* Begin PBXFileReference section */
9129740F2A864F5E004BEA88 /* ListScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListScreen.swift; sourceTree = "<group>"; };
912EA03B2EF18F1D006485DF /* TitleAndIconScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TitleAndIconScreen.swift; sourceTree = "<group>"; };
9132C62C2A72708400EAEF3D /* ActionSheetScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionSheetScreen.swift; sourceTree = "<group>"; };
9132C62E2A72785400EAEF3D /* AlertScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertScreen.swift; sourceTree = "<group>"; };
9132C6302A7280A500EAEF3D /* ContextMenuScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContextMenuScreen.swift; sourceTree = "<group>"; };
@@ -59,6 +62,7 @@
917F563028256DDC00D19543 /* TextFieldsScreen.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextFieldsScreen.swift; sourceTree = "<group>"; };
9184AC012825741600227C3A /* ScreenContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenContent.swift; sourceTree = "<group>"; };
918824692A2DE882001606AE /* Screen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Screen.swift; sourceTree = "<group>"; };
91A6CA9F2EF184470090A2B4 /* BigIconScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BigIconScreen.swift; sourceTree = "<group>"; };
91AB476A2A0E774E00D961AE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
91B2EA9728CA048200A90A83 /* compound-ios */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = "compound-ios"; path = ..; sourceTree = "<group>"; };
91B2EA9B28CA064800A90A83 /* ColorsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorsScreen.swift; sourceTree = "<group>"; };
@@ -170,9 +174,11 @@
91B2EA9A28CA05F300A90A83 /* Components */ = {
isa = PBXGroup;
children = (
91A6CA9F2EF184470090A2B4 /* BigIconScreen.swift */,
917F562A28256DCD00D19543 /* ButtonsScreen.swift */,
9129740F2A864F5E004BEA88 /* ListScreen.swift */,
917F563028256DDC00D19543 /* TextFieldsScreen.swift */,
912EA03B2EF18F1D006485DF /* TitleAndIconScreen.swift */,
);
path = Components;
sourceTree = "<group>";
@@ -307,8 +313,10 @@
917F561C28256DB800D19543 /* CompoundInspectorApp.swift in Sources */,
9132C6332A72850200EAEF3D /* ShareSheetScreen.swift in Sources */,
917C22F829C380A200B35660 /* FontsScreen.swift in Sources */,
91A6CAA02EF1844E0090A2B4 /* BigIconScreen.swift in Sources */,
9188246A2A2DE882001606AE /* Screen.swift in Sources */,
9184AC022825741600227C3A /* ScreenContent.swift in Sources */,
912EA03C2EF18F1F006485DF /* TitleAndIconScreen.swift in Sources */,
912974102A864F5E004BEA88 /* ListScreen.swift in Sources */,
9132C6312A7280A500EAEF3D /* ContextMenuScreen.swift in Sources */,
9132C62F2A72785500EAEF3D /* AlertScreen.swift in Sources */,

View File

@@ -0,0 +1,26 @@
//
// Copyright 2025 New Vector Ltd
//
// SPDX-License-Identifier: AGPL-3.0-only
// Please see LICENSE in the repository root for full details.
//
import Compound
import SwiftUI
struct BigIconScreen: View {
var body: some View {
ScreenContent(navigationTitle: "Big Icon") {
BigIcon_Previews.states
}
}
}
struct BigIconScreen_Previews: PreviewProvider {
static var previews: some View {
NavigationStack {
BigIconScreen()
}
.previewLayout(.fixed(width: 375, height: 700))
}
}

View File

@@ -0,0 +1,26 @@
//
// Copyright 2025 New Vector Ltd
//
// SPDX-License-Identifier: AGPL-3.0-only
// Please see LICENSE in the repository root for full details.
//
import Compound
import SwiftUI
struct TitleAndIconScreen: View {
var body: some View {
ScreenContent(navigationTitle: "Title & Icon") {
TitleAndIcon_Previews.states
}
}
}
struct TitleAndIconScreen_Previews: PreviewProvider {
static var previews: some View {
NavigationStack {
TitleAndIconScreen()
}
.previewLayout(.fixed(width: 375, height: 700))
}
}

View File

@@ -29,6 +29,8 @@ enum Screen: Hashable, View {
case buttons
/// Text field styles.
case textFields
/// The `BigIcon` component.
case bigIcon
/// The system's confirmation dialog component
case actionSheet
@@ -53,6 +55,7 @@ enum Screen: Hashable, View {
case .labels: EmptyView()
case .buttons: ButtonsScreen()
case .textFields: EmptyView()
case .bigIcon: BigIconScreen()
case .actionSheet: ActionSheetScreen()
case .alert: AlertScreen()

View File

@@ -45,6 +45,12 @@ struct SidebarList: View {
NavigationLink(value: Screen.list) {
Label("List", systemImage: "list.bullet.clipboard")
}
NavigationLink(value: Screen.bigIcon) {
Label("Big Icon", systemImage: "square.dashed")
}
NavigationLink(value: Screen.bigIcon) {
Label("Title & Icon", systemImage: "richtext.page")
}
}
}

View File

@@ -13,7 +13,7 @@ public struct SendButton: View {
@Environment(\.colorScheme) private var colorScheme
/// The action to perform when the user triggers the button.
public let action: () -> Void
private let action: () -> Void
private var iconColor: Color {
guard isEnabled else { return .compound.iconQuaternary }

View File

@@ -6,14 +6,13 @@
// 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 {
public struct BigIcon: View {
public enum Style {
case defaultSolid
case `default`
case alertSolid
@@ -47,16 +46,21 @@ struct BigIcon: View {
}
/// The icon that is shown.
let icon: KeyPath<CompoundIcons, Image>
var style: Style = .defaultSolid
private let icon: KeyPath<CompoundIcons, Image>
private let style: Style
var body: some View {
public init(icon: KeyPath<CompoundIcons, Image>, style: Style = .defaultSolid) {
self.icon = icon
self.style = style
}
public var body: some View {
CompoundIcon(icon, size: .custom(32), relativeTo: .compound.headingLG)
.modifier(BigIconModifier(style: style))
}
}
extension Image {
public 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 {
@@ -85,32 +89,36 @@ private struct BigIconModifier: ViewModifier {
// MARK: - Previews
struct BigIcon_Previews: PreviewProvider, TestablePreview {
static var previews: some View {
public struct BigIcon_Previews: PreviewProvider, TestablePreview {
public static var previews: some View {
VStack(spacing: 40) {
HStack(spacing: 20) {
BigIcon(icon: \.lockSolid)
Image(systemName: "hourglass")
.bigIcon()
Image(asset: Asset.Images.serverSelectionIcon)
Image(systemSymbol: .serverRack)
.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)
}
states
}
}
public static var states: some View {
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)
}
}
}

View File

@@ -0,0 +1,103 @@
//
// Copyright 2025 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
/// Our standard screen header that includes a title and icon along with
/// optional subtitle and button components.
///
/// **Note:** By default this component includes the standard padding
/// specified in the Figma, however you may need to customise it using
/// the `insets` parameter.
public struct TitleAndIcon: View {
private let title: String
private let subtitle: String?
private let icon: KeyPath<CompoundIcons, Image>
private let iconStyle: BigIcon.Style
private let button: ButtonDetails?
private let insets: EdgeInsets
public init(title: String,
subtitle: String? = nil,
icon: KeyPath<CompoundIcons, Image>,
iconStyle: BigIcon.Style,
button: ButtonDetails? = nil,
insets: EdgeInsets = .init(top: 24, leading: 24, bottom: 40, trailing: 24)) {
self.title = title
self.subtitle = subtitle
self.icon = icon
self.iconStyle = iconStyle
self.button = button
self.insets = insets
}
public var body: some View {
VStack(spacing: 16) {
BigIcon(icon: icon, style: iconStyle)
VStack(spacing: 8) {
Text(title)
.foregroundColor(.compound.textPrimary)
.font(.compound.headingMDBold)
.multilineTextAlignment(.center)
if let subtitle {
Text(subtitle)
.foregroundColor(.compound.textSecondary)
.font(.compound.bodyMD)
.multilineTextAlignment(.center)
}
}
if let button {
Button(button.title, action: button.action)
.buttonStyle(.compound(.tertiary, size: .small))
}
}
.padding(insets)
}
}
public extension TitleAndIcon {
/// Everything required to construct the `TitleAndIcon` view's optional button.
struct ButtonDetails {
public let title: String
public let action: () -> Void
init(title: String, action: @escaping () -> Void) {
self.title = title
self.action = action
}
}
}
// MARK: - Previews
public struct TitleAndIcon_Previews: PreviewProvider, TestablePreview {
public static var previews: some View {
states
}
public static var states: some View {
VStack(spacing: 20) {
TitleAndIcon(title: "Headline",
icon: \.circle,
iconStyle: .defaultSolid)
TitleAndIcon(title: "Headline",
subtitle: "Description goes here",
icon: \.circle,
iconStyle: .defaultSolid)
TitleAndIcon(title: "Headline",
subtitle: "Description goes here",
icon: \.circle,
iconStyle: .defaultSolid,
button: .init(title: "Learn more") { })
}
}
}

View File

@@ -1,4 +1,4 @@
// Generated using Sourcery 2.2.6 https://github.com/krzysztofzablocki/Sourcery
// Generated using Sourcery 2.3.0 https://github.com/krzysztofzablocki/Sourcery
// DO NOT EDIT
// swiftlint:disable all
@@ -11,6 +11,12 @@ extension PreviewTests {
// MARK: - PreviewProvider
func testBigIcon() async throws {
for (index, preview) in BigIcon_Previews._allPreviews.enumerated() {
try await assertSnapshots(matching: preview, step: index)
}
}
func testCompoundButtonStyle() async throws {
for (index, preview) in CompoundButtonStyle_Previews._allPreviews.enumerated() {
try await assertSnapshots(matching: preview, step: index)
@@ -106,6 +112,12 @@ extension PreviewTests {
try await assertSnapshots(matching: preview, step: index)
}
}
func testTitleAndIcon() async throws {
for (index, preview) in TitleAndIcon_Previews._allPreviews.enumerated() {
try await assertSnapshots(matching: preview, step: index)
}
}
}
// swiftlint:enable all

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:331ca045d1cf2a934949e4d036e6319cc3d2d7b7c6dfa8e0da72d4aea14131bc
size 86689

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d3f5bf778a60fc5619035c4ffb6b77b27477261a2addf1a0da7e2c01b23451af
size 45807

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:64e82affdf3abe32d17b942a3f8eda1b417c2c86c183b3584fbd1f17fd6c7ad4
size 98586

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:4a6e5b16fa2324399611d629a869d4eb15a085ae78de6275969f4d503a3e93d4
size 56345