iOS VoiceOver accessibility overhaul — 67 files
New framework: - AccessibilityLabels.swift: centralized A11y struct with VoiceOver strings - AccessibilityModifiers.swift: reusable .a11yHeader, .a11yDecorative, .a11yButton, .a11yCard, .a11yStatValue View extensions Shared components: decorative elements hidden, stat views combined, status/priority badges labeled, error views announced, empty states grouped Cards: ResidenceCard, TaskCard, DynamicTaskCard, ContractorCard, DocumentCard, WarrantyCard — all grouped with combined labels, chevrons hidden, action buttons labeled Main screens: Login, Register, Residences, Tasks, Contractors, Documents — toolbar buttons labeled, section headers marked, form field hints added Onboarding: all 10 views — header traits, button hints, task selection state, progress indicator, decorative backgrounds hidden Profile/Subscription: toggle hints, theme selection state, feature comparison table accessibility, subscription button labels iOS build verified: BUILD SUCCEEDED
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
import Foundation
|
||||
|
||||
/// Centralized accessibility labels for VoiceOver
|
||||
/// These labels provide human-readable descriptions for screen reader users
|
||||
struct A11y {
|
||||
|
||||
// MARK: - Authentication
|
||||
struct Auth {
|
||||
static let loginButton = "Sign in"
|
||||
static let appleSignIn = "Sign in with Apple"
|
||||
static let googleSignIn = "Sign in with Google"
|
||||
static let forgotPassword = "Forgot password"
|
||||
static let signUp = "Create account"
|
||||
static let passwordToggle = "Toggle password visibility"
|
||||
static let appLogo = "honeyDue app logo"
|
||||
}
|
||||
|
||||
// MARK: - Navigation
|
||||
struct Navigation {
|
||||
static let residencesTab = "Properties"
|
||||
static let tasksTab = "Tasks"
|
||||
static let contractorsTab = "Contractors"
|
||||
static let documentsTab = "Documents"
|
||||
static let settingsButton = "Settings"
|
||||
static let addButton = "Add"
|
||||
static let backButton = "Back"
|
||||
static let closeButton = "Close"
|
||||
static let editButton = "Edit"
|
||||
static let deleteButton = "Delete"
|
||||
static let saveButton = "Save"
|
||||
static let cancelButton = "Cancel"
|
||||
}
|
||||
|
||||
// MARK: - Residence
|
||||
struct Residence {
|
||||
static func card(name: String, taskCount: Int, overdueCount: Int) -> String {
|
||||
"\(name), \(taskCount) tasks, \(overdueCount) overdue"
|
||||
}
|
||||
static let addProperty = "Add new property"
|
||||
static let primaryBadge = "Primary property"
|
||||
static func openInMaps(address: String) -> String { "Open \(address) in Maps" }
|
||||
static func shareCode(code: String) -> String { "Share code: \(code)" }
|
||||
static let copyShareCode = "Copy share code"
|
||||
static let generateShareCode = "Generate new share code"
|
||||
static func removeUser(name: String) -> String { "Remove \(name) from property" }
|
||||
}
|
||||
|
||||
// MARK: - Task
|
||||
struct Task {
|
||||
static func card(title: String, priority: String, dueDate: String) -> String {
|
||||
"\(title), \(priority) priority, due \(dueDate)"
|
||||
}
|
||||
static let addTask = "Add new task"
|
||||
static let taskActions = "Task actions"
|
||||
static func priorityBadge(level: String) -> String { "Priority: \(level)" }
|
||||
static func statusBadge(status: String) -> String { "Status: \(status)" }
|
||||
static func completionCount(count: Int) -> String { "View \(count) completions" }
|
||||
static func rating(value: Int) -> String { "Rated \(value) out of 5" }
|
||||
static let markInProgress = "Mark as in progress"
|
||||
static let completeTask = "Complete task"
|
||||
static let archiveTask = "Archive task"
|
||||
static let cancelTask = "Cancel task"
|
||||
}
|
||||
|
||||
// MARK: - Contractor
|
||||
struct Contractor {
|
||||
static func card(name: String, company: String?, specialty: String) -> String {
|
||||
[name, company, specialty].compactMap { $0 }.joined(separator: ", ")
|
||||
}
|
||||
static let addContractor = "Add new contractor"
|
||||
static func toggleFavorite(name: String, isFavorite: Bool) -> String {
|
||||
isFavorite ? "Remove \(name) from favorites" : "Add \(name) to favorites"
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Document
|
||||
struct Document {
|
||||
static func card(title: String, type: String) -> String { "\(title), \(type)" }
|
||||
static let addDocument = "Add new document"
|
||||
}
|
||||
|
||||
// MARK: - Common
|
||||
struct Common {
|
||||
static func stat(value: String, label: String) -> String { "\(value) \(label)" }
|
||||
static let decorative = "" // For .accessibilityHidden(true)
|
||||
static let retryButton = "Try again"
|
||||
static let dismissError = "Dismiss error"
|
||||
static func photo(index: Int) -> String { "Photo \(index)" }
|
||||
static let removePhoto = "Remove photo"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user