From c5b4a0dd0775e504a9823e0040490049f8067aa9 Mon Sep 17 00:00:00 2001 From: Chris Kolbu Date: Fri, 17 Mar 2023 16:38:50 +1100 Subject: [PATCH] Settings screen Accessibility tweaks (#1258) * Remove `.button` trait from `Link`s on Account Settings screen SwiftUI currently sets both the `.button` and `.link` traits on these elements, which is a failure for WCAG 2.1 4.12: Name, Role, Value: https://www.w3.org/WAI/WCAG21/Understanding/name-role-value.html There is a radar for this issue: FB11507660 * Improve accessibility by making `AppAccountView`s a Button Previously, the component elements of the `fullView` would be rendered as 3-4 individual views that would _all_ be interactive and perform the same action. Now, as a Button, only one accessibility element is vended. * Fix account label color --------- Co-authored-by: Thomas Ricouard --- .../App/Tabs/Settings/SettingsTab.swift | 2 + .../Sources/AppAccount/AppAccountView.swift | 100 +++++++++--------- 2 files changed, 53 insertions(+), 49 deletions(-) diff --git a/IceCubesApp/App/Tabs/Settings/SettingsTab.swift b/IceCubesApp/App/Tabs/Settings/SettingsTab.swift index 3cd82c46..bef91763 100644 --- a/IceCubesApp/App/Tabs/Settings/SettingsTab.swift +++ b/IceCubesApp/App/Tabs/Settings/SettingsTab.swift @@ -208,6 +208,7 @@ struct SettingsTabs: View { Link(destination: URL(string: "https://github.com/Dimillian/IceCubesApp")!) { Label("settings.app.source", systemImage: "link") } + .accessibilityRemoveTraits(.isButton) .tint(theme.labelColor) NavigationLink(destination: SupportAppView()) { @@ -218,6 +219,7 @@ struct SettingsTabs: View { Link(destination: reviewURL) { Label("settings.rate", systemImage: "link") } + .accessibilityRemoveTraits(.isButton) .tint(theme.labelColor) } diff --git a/Packages/AppAccount/Sources/AppAccount/AppAccountView.swift b/Packages/AppAccount/Sources/AppAccount/AppAccountView.swift index 747ba33e..13b8bce1 100644 --- a/Packages/AppAccount/Sources/AppAccount/AppAccountView.swift +++ b/Packages/AppAccount/Sources/AppAccount/AppAccountView.swift @@ -4,6 +4,7 @@ import Env import SwiftUI public struct AppAccountView: View { + @EnvironmentObject private var theme: Theme @EnvironmentObject private var routerPath: RouterPath @EnvironmentObject private var appAccounts: AppAccountsManager @EnvironmentObject private var preferences: UserPreferences @@ -41,55 +42,7 @@ public struct AppAccountView: View { } private var fullView: some View { - HStack { - if let account = viewModel.account { - ZStack(alignment: .topTrailing) { - AvatarView(url: account.avatar) - if viewModel.appAccount.id == appAccounts.currentAccount.id { - Image(systemName: "checkmark.circle.fill") - .foregroundStyle(.white, .green) - .offset(x: 5, y: -5) - } else if viewModel.showBadge, - let token = viewModel.appAccount.oauthToken, - preferences.getNotificationsCount(for: token) > 0 - { - let notificationsCount = preferences.getNotificationsCount(for: token) - ZStack { - Circle() - .fill(.red) - Text(notificationsCount > 99 ? "99+" : String(notificationsCount)) - .foregroundColor(.white) - .font(.system(size: 9)) - } - .frame(width: 20, height: 20) - .offset(x: 5, y: -5) - } - } - } else { - ProgressView() - Text(viewModel.appAccount.accountName ?? viewModel.acct) - .font(.scaledSubheadline) - .foregroundColor(.gray) - .padding(.leading, 6) - } - VStack(alignment: .leading) { - if let account = viewModel.account { - EmojiTextApp(.init(stringValue: account.safeDisplayName), emojis: account.emojis) - Text("\(account.username)@\(viewModel.appAccount.server)") - .font(.scaledSubheadline) - .emojiSize(Font.scaledSubheadlineFont.emojiSize) - .emojiBaselineOffset(Font.scaledSubheadlineFont.emojiBaselineOffset) - .foregroundColor(.gray) - } - } - if viewModel.isInNavigation { - Spacer() - Image(systemName: "chevron.right") - .foregroundColor(.gray) - } - } - .contentShape(Rectangle()) - .onTapGesture { + Button { if appAccounts.currentAccount.id == viewModel.appAccount.id, let account = viewModel.account { @@ -103,6 +56,55 @@ public struct AppAccountView: View { HapticManager.shared.fireHaptic(of: .notification(.success)) } } + } label: { + HStack { + if let account = viewModel.account { + ZStack(alignment: .topTrailing) { + AvatarView(url: account.avatar) + if viewModel.appAccount.id == appAccounts.currentAccount.id { + Image(systemName: "checkmark.circle.fill") + .foregroundStyle(.white, .green) + .offset(x: 5, y: -5) + } else if viewModel.showBadge, + let token = viewModel.appAccount.oauthToken, + preferences.getNotificationsCount(for: token) > 0 + { + let notificationsCount = preferences.getNotificationsCount(for: token) + ZStack { + Circle() + .fill(.red) + Text(notificationsCount > 99 ? "99+" : String(notificationsCount)) + .foregroundColor(.white) + .font(.system(size: 9)) + } + .frame(width: 20, height: 20) + .offset(x: 5, y: -5) + } + } + } else { + ProgressView() + Text(viewModel.appAccount.accountName ?? viewModel.acct) + .font(.scaledSubheadline) + .foregroundColor(.gray) + .padding(.leading, 6) + } + VStack(alignment: .leading) { + if let account = viewModel.account { + EmojiTextApp(.init(stringValue: account.safeDisplayName), emojis: account.emojis) + .foregroundColor(theme.labelColor) + Text("\(account.username)@\(viewModel.appAccount.server)") + .font(.scaledSubheadline) + .emojiSize(Font.scaledSubheadlineFont.emojiSize) + .emojiBaselineOffset(Font.scaledSubheadlineFont.emojiBaselineOffset) + .foregroundColor(.gray) + } + } + if viewModel.isInNavigation { + Spacer() + Image(systemName: "chevron.right") + .foregroundColor(.gray) + } + } } } }