Associate the room address field helper text and error with the field

The address field already had an accessibility label, but the section's
helper text and validation error were only shown in a separate footer and
weren't conveyed to VoiceOver when focusing the field. Compose them into the
field's accessibility hint.

Addresses #5258.
This commit is contained in:
Mauro Romito
2026-06-22 12:57:49 +02:00
parent 9f92e181b0
commit d4e7cbfdbe
3 changed files with 19 additions and 5 deletions
@@ -12,12 +12,23 @@ import SwiftUI
struct EditRoomAddressListRow: View {
@Binding var aliasLocalPart: String
var serverName: String
var shouldDisplayError: Bool
/// The error to display, if any. Also associated with the field for VoiceOver.
var errorDescription: String?
/// The section's helper text, associated with the field for VoiceOver.
var footerText: String?
private var fullAddress: String {
"#\(aliasLocalPart):\(serverName)"
}
/// Associates the helper text and any error with the field, as they're otherwise
/// only shown in a separate section footer.
private var accessibilityHint: String {
[L10n.a11yEditRoomAddressHint(fullAddress), footerText, errorDescription]
.compactMap { $0 }
.joined(separator: "\n")
}
var body: some View {
ListRow(kind: .custom {
HStack(spacing: 0) {
@@ -34,7 +45,7 @@ struct EditRoomAddressListRow: View {
.foregroundStyle(.compound.textPrimary)
.padding(.horizontal, 8)
.accessibilityLabel(L10n.a11yAddress)
.accessibilityHint(L10n.a11yEditRoomAddressHint(fullAddress))
.accessibilityHint(accessibilityHint)
Text(":\(serverName)")
.font(.compound.bodyLG)
.foregroundStyle(.compound.textSecondary)
@@ -42,7 +53,7 @@ struct EditRoomAddressListRow: View {
}
.padding(ListRowPadding.textFieldInsets)
.environment(\.layoutDirection, .leftToRight)
.errorBackground(shouldDisplayError)
.errorBackground(errorDescription != nil)
})
}
}
@@ -193,7 +193,8 @@ struct CreateRoomScreen: View {
Section {
EditRoomAddressListRow(aliasLocalPart: aliasBinding,
serverName: context.viewState.serverName,
shouldDisplayError: context.viewState.aliasErrors.errorDescription != nil)
errorDescription: context.viewState.aliasErrors.errorDescription,
footerText: L10n.screenCreateRoomRoomAddressSectionFooter)
.focused($focus, equals: .alias)
.id(Focus.alias)
} header: {
@@ -16,7 +16,9 @@ struct EditRoomAddressScreen: View {
Form {
Section {
EditRoomAddressListRow(aliasLocalPart: $context.desiredAliasLocalPart,
serverName: context.viewState.serverName, shouldDisplayError: context.viewState.aliasErrors.errorDescription != nil)
serverName: context.viewState.serverName,
errorDescription: context.viewState.aliasErrors.errorDescription,
footerText: L10n.screenEditRoomAddressRoomAddressSectionFooter)
.onChange(of: context.desiredAliasLocalPart) { _, newAliasLocalPart in
context.desiredAliasLocalPart = newAliasLocalPart.lowercased()
}