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
57 lines
1.6 KiB
Swift
57 lines
1.6 KiB
Swift
import SwiftUI
|
|
|
|
struct PriorityBadge: View {
|
|
let priority: String
|
|
|
|
var body: some View {
|
|
HStack(spacing: 5) {
|
|
Image(systemName: priorityIcon)
|
|
.font(.system(size: 10, weight: .bold))
|
|
|
|
Text(priority.capitalized)
|
|
.font(.system(size: 11, weight: .semibold, design: .rounded))
|
|
}
|
|
.padding(.horizontal, 10)
|
|
.padding(.vertical, 5)
|
|
.foregroundColor(priorityColor)
|
|
.background(
|
|
Capsule()
|
|
.fill(priorityColor.opacity(0.12))
|
|
.overlay(
|
|
Capsule()
|
|
.stroke(priorityColor.opacity(0.2), lineWidth: 1)
|
|
)
|
|
)
|
|
.accessibilityElement(children: .combine)
|
|
.accessibilityLabel(A11y.Task.priorityBadge(level: priority.capitalized))
|
|
}
|
|
|
|
private var priorityIcon: String {
|
|
switch priority.lowercased() {
|
|
case "high": return "exclamationmark.triangle.fill"
|
|
case "medium": return "exclamationmark.circle.fill"
|
|
case "low": return "minus.circle.fill"
|
|
default: return "circle.fill"
|
|
}
|
|
}
|
|
|
|
private var priorityColor: Color {
|
|
switch priority.lowercased() {
|
|
case "high": return Color.appError
|
|
case "medium": return Color.appAccent
|
|
case "low": return Color.appPrimary
|
|
default: return Color.appTextSecondary
|
|
}
|
|
}
|
|
}
|
|
|
|
#Preview {
|
|
VStack(spacing: 12) {
|
|
PriorityBadge(priority: "high")
|
|
PriorityBadge(priority: "medium")
|
|
PriorityBadge(priority: "low")
|
|
}
|
|
.padding()
|
|
.background(WarmGradientBackground())
|
|
}
|