diff --git a/.Jules/palette.md b/.Jules/palette.md index 756b081e..28c2f236 100644 --- a/.Jules/palette.md +++ b/.Jules/palette.md @@ -8,3 +8,7 @@ ## 2026-06-06 - Ensure Symmetry in Accessibility and Tooltips for SwiftUI Icon Buttons **Learning:** In macOS SwiftUI applications, icon-only buttons often have either `.help()` (for hover tooltips) or `.accessibilityLabel()` (for VoiceOver), but frequently lack both. Both are necessary because they serve different user interaction models—`.help` for visual hover feedback and `.accessibilityLabel` for screen readers. **Action:** When adding or reviewing icon-only buttons in SwiftUI, always ensure symmetry by defining both `.help("Description")` and `.accessibilityLabel("Description")` to cover all accessibility and usability vectors. + +## 2024-05-19 - [Missing Accessibility on Dynamic Form Dictionary Buttons] +**Learning:** Icon-only buttons used for adding/removing items in dynamic dictionary forms (e.g., webhook headers with `plus.circle.fill` and `minus.circle.fill`) are frequent vectors for missing accessibility labels and tooltips, because they are often implemented with plain button styles without considering screen reader context. +**Action:** Always verify that inline addition/removal buttons in repeated form elements have explicit `.help()` and `.accessibilityLabel()` modifiers attached to them to ensure they can be understood and navigated accurately by all users. diff --git a/XboxControllerMapper/XboxControllerMapper/Views/MainWindow/ActionMappingEditor.swift b/XboxControllerMapper/XboxControllerMapper/Views/MainWindow/ActionMappingEditor.swift index 0b982c18..8f32d271 100644 --- a/XboxControllerMapper/XboxControllerMapper/Views/MainWindow/ActionMappingEditor.swift +++ b/XboxControllerMapper/XboxControllerMapper/Views/MainWindow/ActionMappingEditor.swift @@ -380,6 +380,8 @@ struct ActionMappingEditor: View { .foregroundColor(.red) } .buttonStyle(.plain) + .help("Remove header") + .accessibilityLabel("Remove header") } } @@ -401,6 +403,8 @@ struct ActionMappingEditor: View { .foregroundColor(.green) } .buttonStyle(.plain) + .help("Add header") + .accessibilityLabel("Add header") .disabled(state.newWebhookHeaderKey.isEmpty) } } diff --git a/XboxControllerMapper/XboxControllerMapper/Views/MainWindow/ChordMappingSheet.swift b/XboxControllerMapper/XboxControllerMapper/Views/MainWindow/ChordMappingSheet.swift index 3749c560..21a28373 100644 --- a/XboxControllerMapper/XboxControllerMapper/Views/MainWindow/ChordMappingSheet.swift +++ b/XboxControllerMapper/XboxControllerMapper/Views/MainWindow/ChordMappingSheet.swift @@ -624,6 +624,8 @@ struct ChordMappingSheet: View, ControllerTypeProviding { .foregroundColor(.red) } .buttonStyle(.plain) + .help("Remove header") + .accessibilityLabel("Remove header") } } @@ -645,6 +647,8 @@ struct ChordMappingSheet: View, ControllerTypeProviding { .foregroundColor(.green) } .buttonStyle(.plain) + .help("Add header") + .accessibilityLabel("Add header") .disabled(newWebhookHeaderKey.isEmpty) } }